|
2 | 2 | #include "nixf/Basic/Diagnostic.h" |
3 | 3 | #include "nixf/Basic/Nodes/Attrs.h" |
4 | 4 | #include "nixf/Basic/Nodes/Lambda.h" |
| 5 | +#include "nixf/Sema/PrimOpInfo.h" |
5 | 6 |
|
6 | 7 | using namespace nixf; |
7 | 8 |
|
@@ -108,11 +109,28 @@ void VariableLookupAnalysis::lookupVar(const ExprVar &Var, |
108 | 109 | } |
109 | 110 | Results.insert({&Var, LookupResult{LookupResultKind::FromWith, Def}}); |
110 | 111 | } else { |
111 | | - // Otherwise, this variable is undefined. |
112 | | - Results.insert({&Var, LookupResult{LookupResultKind::Undefined, nullptr}}); |
113 | | - Diagnostic &Diag = |
114 | | - Diags.emplace_back(Diagnostic::DK_UndefinedVariable, Var.range()); |
115 | | - Diag << Var.id().name(); |
| 112 | + // Check if this is a primop. |
| 113 | + switch (lookupGlobalPrimOpInfo(Name)) { |
| 114 | + case PrimopLookupResult::Found: |
| 115 | + Results.insert({&Var, LookupResult{LookupResultKind::PrimOp, nullptr}}); |
| 116 | + break; |
| 117 | + case PrimopLookupResult::PrefixedFound: { |
| 118 | + Diagnostic &D = |
| 119 | + Diags.emplace_back(Diagnostic::DK_PrimOpNeedsPrefix, Var.range()); |
| 120 | + D.fix("use `builtins.` prefix") |
| 121 | + .edit(TextEdit::mkInsertion(Var.range().lCur(), "builtins.")); |
| 122 | + Results.insert({&Var, LookupResult{LookupResultKind::PrimOp, nullptr}}); |
| 123 | + break; |
| 124 | + } |
| 125 | + case PrimopLookupResult::NotFound: |
| 126 | + // Otherwise, this variable is undefined. |
| 127 | + Results.insert( |
| 128 | + {&Var, LookupResult{LookupResultKind::Undefined, nullptr}}); |
| 129 | + Diagnostic &Diag = |
| 130 | + Diags.emplace_back(Diagnostic::DK_UndefinedVariable, Var.range()); |
| 131 | + Diag << Var.id().name(); |
| 132 | + break; |
| 133 | + } |
116 | 134 | } |
117 | 135 | } |
118 | 136 |
|
@@ -344,129 +362,20 @@ void VariableLookupAnalysis::dfs(const Node &Root, |
344 | 362 | void VariableLookupAnalysis::runOnAST(const Node &Root) { |
345 | 363 | // Create a basic env |
346 | 364 | DefBuilder DB; |
347 | | - std::vector<std::string> Builtins{ |
348 | | - "__add", |
349 | | - "__fetchurl", |
350 | | - "__isFloat", |
351 | | - "__seq", |
352 | | - "break", |
353 | | - "__addDrvOutputDependencies", |
354 | | - "__filter", |
355 | | - "__isFunction", |
356 | | - "__sort", |
| 365 | + std::vector<std::string> BaseEnv{ |
357 | 366 | "builtins", |
358 | | - "__addErrorContext", |
359 | | - "__filterSource", |
360 | | - "__isInt", |
361 | | - "__split", |
362 | | - "derivation", |
363 | | - "__all", |
364 | | - "__findFile", |
365 | | - "__isList", |
366 | | - "__splitVersion", |
367 | | - "derivationStrict", |
368 | | - "__any", |
369 | | - "__flakeRefToString", |
370 | | - "__isPath", |
371 | | - "__storeDir", |
372 | | - "dirOf", |
373 | | - "__appendContext", |
374 | | - "__floor", |
375 | | - "__isString", |
376 | | - "__storePath", |
377 | | - "false", |
378 | | - "__attrNames", |
379 | | - "__foldl'", |
380 | | - "__langVersion", |
381 | | - "__stringLength", |
382 | | - "fetchGit", |
383 | | - "__attrValues", |
384 | | - "__fromJSON", |
385 | | - "__length", |
386 | | - "__sub", |
387 | | - "fetchMercurial", |
388 | | - "__bitAnd", |
389 | | - "__functionArgs", |
390 | | - "__lessThan", |
391 | | - "__substring", |
392 | | - "fetchTarball", |
393 | | - "__bitOr", |
394 | | - "__genList", |
395 | | - "__listToAttrs", |
396 | | - "__tail", |
397 | | - "fetchTree", |
398 | | - "__bitXor", |
399 | | - "__genericClosure", |
400 | | - "__mapAttrs", |
401 | | - "__toFile", |
402 | | - "fromTOML", |
403 | | - "__catAttrs", |
404 | | - "__getAttr", |
405 | | - "__match", |
406 | | - "__toJSON", |
407 | | - "import", |
408 | | - "__ceil", |
409 | | - "__getContext", |
410 | | - "__mul", |
411 | | - "__toPath", |
412 | | - "isNull", |
413 | | - "__compareVersions", |
414 | | - "__getEnv", |
415 | | - "__nixPath", |
416 | | - "__toXML", |
417 | | - "map", |
418 | | - "__concatLists", |
419 | | - "__getFlake", |
420 | | - "__nixVersion", |
421 | | - "__trace", |
422 | | - "null", |
423 | | - "__concatMap", |
424 | | - "__groupBy", |
425 | | - "__parseDrvName", |
426 | | - "__traceVerbose", |
427 | | - "placeholder", |
428 | | - "__concatStringsSep", |
429 | | - "__hasAttr", |
430 | | - "__parseFlakeRef", |
431 | | - "__tryEval", |
432 | | - "removeAttrs", |
433 | | - "__convertHash", |
434 | | - "__hasContext", |
435 | | - "__partition", |
436 | | - "__typeOf", |
437 | | - "scopedImport", |
438 | | - "__currentSystem", |
439 | | - "__hashFile", |
440 | | - "__path", |
441 | | - "__unsafeDiscardOutputDependency", |
442 | | - "throw", |
443 | | - "__currentTime", |
444 | | - "__hashString", |
445 | | - "__pathExists", |
446 | | - "__unsafeDiscardStringContext", |
447 | | - "toString", |
448 | | - "__deepSeq", |
449 | | - "__head", |
450 | | - "__readDir", |
451 | | - "__unsafeGetAttrPos", |
452 | | - "true", |
453 | | - "__div", |
454 | | - "__intersectAttrs", |
455 | | - "__readFile", |
456 | | - "__zipAttrsWith", |
457 | | - "__elem", |
458 | | - "__isAttrs", |
459 | | - "__readFileType", |
460 | | - "abort", |
461 | | - "__elemAt", |
462 | | - "__isBool", |
463 | | - "__replaceStrings", |
464 | | - "baseNameOf", |
465 | 367 | // This is an undocumented keyword actually. |
466 | 368 | "__curPos", |
467 | 369 | }; |
468 | 370 |
|
469 | | - for (const auto &Builtin : Builtins) |
| 371 | + for (const auto &[Name, Info] : PrimOpsInfo) { |
| 372 | + if (!Info.Internal && !Name.starts_with("__")) { |
| 373 | + // Only add non-internal primops without "__" prefix. |
| 374 | + BaseEnv.push_back(Name); |
| 375 | + } |
| 376 | + } |
| 377 | + |
| 378 | + for (const auto &Builtin : BaseEnv) |
470 | 379 | DB.addBuiltin(Builtin); |
471 | 380 |
|
472 | 381 | auto Env = std::make_shared<EnvNode>(nullptr, DB.finish(), nullptr); |
|
0 commit comments