Prexonite, a .NET hosted scripting language with a focus on meta-programming and embedded DSLs
0

Configure Feed

Select the types of activity you want to include in your feed.

PRX-29: add warning for unqualified import

`namespace import x;` doesn't do anything. Either `x` is already in scope (in which case, this is a no-op) or `x` is not in scope (which results in an error symbol being declared).

For now, I've decided not to immediately emit an error for unresolved symbols. Not 100% sure if I'm going to keep imports this way.

The rationale is that Prexonite Script doesn't have robust IDE support and thus micro-managing imports is painful. Having a compilation fail because of an unused but unresolved import sounds annoying to me.

Also:
- Introduce `GetNextPosition` method. See PRX-57

Christian Klauser (Sep 4, 2021, 12:26 PM +0200) 75fa9304 0702e298

+53 -6
+10 -1
Prexonite/Compiler/Grammar/Parser.GlobalScope.atg
··· 1025 1025 ISourcePosition pos; 1026 1026 ISymbolView<Symbol> sourceScope = null; 1027 1027 var hasWildcard = false; 1028 + var sourcePosition = GetNextPosition(); 1028 1029 .) 1029 1030 = 1030 1031 NsTransferSource<out hasWildcard, out specRoot> ··· 1040 1041 } 1041 1042 else 1042 1043 { 1043 - var symId = specRoot[specRoot.Count-1]; 1044 + var symId = specRoot[^1]; 1044 1045 specRoot = specRoot.WithSuffixDropped(1); 1046 + if (specRoot.Count == 0) 1047 + { 1048 + var msg = string.Format(Resources.Parser_NsTransferSpec_Import_has_no_effect_0, symId); 1049 + Loader.ReportMessage(Message.Warning( 1050 + msg, 1051 + sourcePosition, 1052 + MessageClasses.UnqualifiedImport)); 1053 + } 1045 1054 sourceScope = _resolveNamespace(Symbols, pos, specRoot); 1046 1055 directives.Add(SymbolTransferDirective.CreateRename(pos,symId,symId)); 1047 1056 }
+1
Prexonite/Compiler/MessageClasses.cs
··· 32 32 public const string InvalidSymbolInterpretation = "ES.InvalidSymbolInterpretation"; 33 33 public const string SymbolConflict = "ES.SymbolConflict"; 34 34 public const string SymbolNotResolved = "ES.SymbolNotResolved"; 35 + public const string UnqualifiedImport = "ES.UnqualifiedImport"; 35 36 36 37 #region Parser 37 38
+3
Prexonite/Properties/Resources.resx
··· 466 466 <data name="BuiltInTypeCommandBase_DoExpand_0_for_type_1_requires_an_arity_integer_as_the_first_argument" xml:space="preserve"> 467 467 <value>{0} for type {1} requires an arity (integer) as the first argument.</value> 468 468 </data> 469 + <data name="Parser_NsTransferSpec_Import_has_no_effect_0" xml:space="preserve"> 470 + <value>Import of symbol `{0}` has no effect. Did you mean `{0}(*)`?</value> 471 + </data> 469 472 </root>
+22
PrexoniteTests/Tests/Translation.cs
··· 1440 1440 } 1441 1441 1442 1442 [Test] 1443 + public void WarningUnqualifiedNamespace() 1444 + { 1445 + var ldr = new Loader(options); 1446 + Compile(ldr, @" 1447 + namespace import unknown; 1448 + "); 1449 + Assert.That(ldr.Warnings.Where(m => m.MessageClass == MessageClasses.UnqualifiedImport), Is.Not.Empty); 1450 + Assert.That(ldr.Warnings.Count, Is.EqualTo(1), "Warning count"); 1451 + } 1452 + 1453 + [Test] 1454 + public void ErrorUnresolvedNamespace() 1455 + { 1456 + var ldr = CompileInvalid(@" 1457 + namespace a {} 1458 + namespace import a.b.c; 1459 + "); 1460 + Assert.That(ldr.Errors.Where(m => m.MessageClass == MessageClasses.NamespaceExcepted), Is.Not.Empty); 1461 + Assert.That(ldr.ErrorCount, Is.EqualTo(1)); 1462 + } 1463 + 1464 + [Test] 1443 1465 public void ErrorDoubleColonInGlobalNamespaceImport() 1444 1466 { 1445 1467 var ldr = CompileInvalid(@"
+17 -5
Tools/Parser.frame
··· 66 66 errors.parentParser = this; 67 67 } 68 68 69 - 70 - public Prexonite.Compiler.ISourcePosition GetPosition() 71 - { 72 - return new Prexonite.Compiler.SourcePosition(scanner.File, t.line, t.col); 73 - } 69 + /// <summary> 70 + /// Constructs the position of the last token. 71 + /// </summary> 72 + /// <returns>The position of the last token.</returns> 73 + public Prexonite.Compiler.ISourcePosition GetPosition() 74 + { 75 + return new Prexonite.Compiler.SourcePosition(scanner.File, t.line, t.col); 76 + } 77 + 78 + /// <summary> 79 + /// Constructs the position of the next (look-ahead) token. 80 + /// </summary> 81 + /// <returns>The position of the next (look-ahead) token.</returns> 82 + public Prexonite.Compiler.ISourcePosition GetNextPosition() 83 + { 84 + return new Prexonite.Compiler.SourcePosition(scanner.File, la.line, la.col); 85 + } 74 86 75 87 [DebuggerNonUserCode] 76 88 void SynErr (int n) {