Skip to content

Commit

Permalink
More simplification
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Nov 2, 2024
1 parent 35e0a51 commit bb06a72
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 47 deletions.
67 changes: 26 additions & 41 deletions src/Draco.Compiler/Internal/Symbols/Script/ScriptModuleSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,30 +84,26 @@ private ImmutableArray<Symbol> 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
Expand Down Expand Up @@ -137,28 +133,17 @@ private ScriptBinding BindScriptBindings(IBinderProvider binderProvider)
return binder.BindScript(this, binderProvider.DiagnosticBag);
}

private IEnumerable<Symbol> 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<Symbol> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ private ImmutableArray<Symbol> 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);
Expand Down
4 changes: 3 additions & 1 deletion src/Draco.Compiler/Internal/Symbols/Symbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
/// <summary>
/// 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.
Expand All @@ -347,7 +349,7 @@ public static IEnumerable<Symbol> 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;
Expand Down

0 comments on commit bb06a72

Please sign in to comment.