From bb06a726e432d25a11a217672d686c9ada552e96 Mon Sep 17 00:00:00 2001 From: LPeter1997 Date: Sat, 2 Nov 2024 18:33:46 +0100 Subject: [PATCH] More simplification --- .../Symbols/Script/ScriptModuleSymbol.cs | 67 +++++++------------ .../Symbols/Source/SourceModuleSymbol.cs | 5 -- src/Draco.Compiler/Internal/Symbols/Symbol.cs | 4 +- 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/src/Draco.Compiler/Internal/Symbols/Script/ScriptModuleSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Script/ScriptModuleSymbol.cs index 2a5380c82..89b1a65f8 100644 --- a/src/Draco.Compiler/Internal/Symbols/Script/ScriptModuleSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Script/ScriptModuleSymbol.cs @@ -84,30 +84,26 @@ private ImmutableArray BindMembers(IBinderProvider binderProvider) // Non-declaration statements are compiled into an initializer method if (statement is not DeclarationStatementSyntax decl) continue; - // Build the symbol(s) - foreach (var member in this.BuildMember(decl.Declaration)) - { - var earlierMember = result.FirstOrDefault(s => s.Name == member.Name); - result.Add(member); - - // We check for illegal shadowing - if (earlierMember is null) continue; - - // Overloading is legal - if (member is FunctionSymbol && earlierMember is FunctionSymbol) continue; - - // If the illegal member is special name, it was cascaded from a declaration with multiple symbols, - // like an autoprop, skip it - if (member.IsSpecialName) continue; - - // Illegal - var syntax = member.DeclaringSyntax; - Debug.Assert(syntax is not null); - binderProvider.DiagnosticBag.Add(Diagnostic.Create( - template: SymbolResolutionErrors.IllegalShadowing, - location: syntax.Location, - formatArgs: member.Name)); - } + var member = this.BuildMember(decl.Declaration); + if (member is null) continue; + + var earlierMember = result.FirstOrDefault(s => s.Name == member.Name); + result.Add(member); + result.AddRange(GetAdditionalSymbols(member)); + + // We check for illegal shadowing + if (earlierMember is null) continue; + + // Overloading is legal + if (member is FunctionSymbol && earlierMember is FunctionSymbol) continue; + + // Illegal + var syntax = member.DeclaringSyntax; + Debug.Assert(syntax is not null); + binderProvider.DiagnosticBag.Add(Diagnostic.Create( + template: SymbolResolutionErrors.IllegalShadowing, + location: syntax.Location, + formatArgs: member.Name)); } // We add a function to evaluate the script @@ -137,28 +133,17 @@ private ScriptBinding BindScriptBindings(IBinderProvider binderProvider) return binder.BindScript(this, binderProvider.DiagnosticBag); } - private IEnumerable BuildMember(DeclarationSyntax decl) => decl switch + private Symbol? BuildMember(DeclarationSyntax decl) => decl switch { ImportDeclarationSyntax - or UnexpectedDeclarationSyntax => [], - FunctionDeclarationSyntax f => [this.BuildFunction(f)], - VariableDeclarationSyntax v when v.FieldModifier is not null => [this.BuildField(v)], - VariableDeclarationSyntax v when v.FieldModifier is null => this.BuildAutoProperty(v), - ModuleDeclarationSyntax m => [this.BuildModule(m)], + or UnexpectedDeclarationSyntax => null, + FunctionDeclarationSyntax f => new ScriptFunctionSymbol(this, f), + VariableDeclarationSyntax v when v.FieldModifier is not null => new ScriptFieldSymbol(this, v), + VariableDeclarationSyntax v when v.FieldModifier is null => new ScriptAutoPropertySymbol(this, v), + ModuleDeclarationSyntax m => this.BuildModule(m), _ => throw new ArgumentOutOfRangeException(nameof(decl)), }; - private ScriptFunctionSymbol BuildFunction(FunctionDeclarationSyntax syntax) => new(this, syntax); - private ScriptFieldSymbol BuildField(VariableDeclarationSyntax syntax) => new(this, syntax); - private IEnumerable BuildAutoProperty(VariableDeclarationSyntax syntax) - { - var property = new ScriptAutoPropertySymbol(this, syntax); - yield return property; - if (property.Getter is not null) yield return property.Getter; - if (property.Setter is not null) yield return property.Setter; - yield return property.BackingField; - } - private SourceModuleSymbol BuildModule(ModuleDeclarationSyntax syntax) { // We need to wrap it into a merged module declaration diff --git a/src/Draco.Compiler/Internal/Symbols/Source/SourceModuleSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Source/SourceModuleSymbol.cs index 664fce64c..337a54694 100644 --- a/src/Draco.Compiler/Internal/Symbols/Source/SourceModuleSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Source/SourceModuleSymbol.cs @@ -85,11 +85,6 @@ private ImmutableArray BindMembers(IBinderProvider binderProvider) // Overloading is legal if (member is FunctionSymbol && earlierMember is FunctionSymbol) continue; - // NOTE: An illegal shadowing can be caused by a property, which introduces additional synthetized symbols - // like the backing field - // We check for these synthetized symbols and if they are special-named, we ignore them - if (member.IsSpecialName) continue; - // Illegal var syntax = member.DeclaringSyntax; Debug.Assert(syntax is not null); diff --git a/src/Draco.Compiler/Internal/Symbols/Symbol.cs b/src/Draco.Compiler/Internal/Symbols/Symbol.cs index c4d8453be..05b0589a1 100644 --- a/src/Draco.Compiler/Internal/Symbols/Symbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Symbol.cs @@ -9,6 +9,7 @@ using Draco.Compiler.Internal.Symbols.Generic; using Draco.Compiler.Internal.Symbols.Metadata; using Draco.Compiler.Internal.Symbols.Source; +using Draco.Compiler.Internal.Symbols.Syntax; using Draco.Compiler.Internal.Symbols.Synthetized; using Draco.Compiler.Internal.Utilities; @@ -332,6 +333,7 @@ private protected string GenericsToString() _ => throw new InvalidOperationException($"illegal visibility modifier token {kind}"), }; + // TODO: We could have this as a base member for symbols /// /// Retrieves additional symbols for the given symbol that should live in the same scope as the symbol itself. /// This returns the constructor functions for types for example. @@ -347,7 +349,7 @@ public static IEnumerable GetAdditionalSymbols(Symbol symbol) // For non-abstract types we provide constructor functions foreach (var ctor in typeSymbol.Constructors) yield return new ConstructorFunctionSymbol(ctor); break; - case SourceAutoPropertySymbol autoProp: + case SyntaxAutoPropertySymbol autoProp: // For auto-properties we provide the backing field and the accessors in the same scope if (autoProp.Getter is not null) yield return autoProp.Getter; if (autoProp.Setter is not null) yield return autoProp.Setter;