From 91db04d69ba74cfa75371d87da5347b049574c83 Mon Sep 17 00:00:00 2001 From: LPeter1997 Date: Sun, 3 Nov 2024 17:41:50 +0100 Subject: [PATCH] Simplified --- .../Internal/Binding/Binder_Expression.cs | 2 +- .../Symbols/Source/SourceFunctionSymbol.cs | 3 +- .../Symbols/Syntax/SyntaxFunctionSymbol.cs | 51 ++++++++++--------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs b/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs index a6a9d5f2d..638991f1f 100644 --- a/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs +++ b/src/Draco.Compiler/Internal/Binding/Binder_Expression.cs @@ -734,7 +734,7 @@ private BindingTask BindThisExpression(ThisExpressionSyntax syn } // Check, if the function has a this argument - var thisArg = function.ThisArgument; + var thisArg = function.ThisParameter; if (thisArg is null) { // No, report error diff --git a/src/Draco.Compiler/Internal/Symbols/Source/SourceFunctionSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Source/SourceFunctionSymbol.cs index b743878bc..5c3b9bf32 100644 --- a/src/Draco.Compiler/Internal/Symbols/Source/SourceFunctionSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Source/SourceFunctionSymbol.cs @@ -27,12 +27,11 @@ public SourceFunctionSymbol(Symbol containingSymbol, FunctionDeclaration declara { } - public override bool IsStatic => this.ThisArgument == null; - public override void Bind(IBinderProvider binderProvider) { this.BindAttributesIfNeeded(binderProvider); this.BindGenericParametersIfNeeded(binderProvider); + this.BindThisParameterIfNeeded(binderProvider); this.BindParametersIfNeeded(binderProvider); // Force binding of parameters, as the type is lazy too foreach (var param in this.Parameters.Cast()) param.Bind(binderProvider); diff --git a/src/Draco.Compiler/Internal/Symbols/Syntax/SyntaxFunctionSymbol.cs b/src/Draco.Compiler/Internal/Symbols/Syntax/SyntaxFunctionSymbol.cs index 2ba7d9626..d63a029be 100644 --- a/src/Draco.Compiler/Internal/Symbols/Syntax/SyntaxFunctionSymbol.cs +++ b/src/Draco.Compiler/Internal/Symbols/Syntax/SyntaxFunctionSymbol.cs @@ -22,6 +22,7 @@ internal abstract class SyntaxFunctionSymbol( public override Symbol ContainingSymbol => containingSymbol; public override FunctionDeclarationSyntax DeclaringSyntax => syntax; public override string Name => this.DeclaringSyntax.Name.Text; + public override bool IsStatic => this.ThisParameter is null; public override Api.Semantics.Visibility Visibility => GetVisibilityFromTokenKind(this.DeclaringSyntax.VisibilityModifier?.Kind); @@ -35,15 +36,11 @@ internal abstract class SyntaxFunctionSymbol( public override ImmutableArray Parameters => this.BindParametersIfNeeded(this.DeclaringCompilation!); private ImmutableArray parameters; - public SourceThisParameterSymbol? ThisArgument - { - get - { - this.BindParametersIfNeeded(this.DeclaringCompilation!); - return this.thisArgument; - } - } - private SourceThisParameterSymbol? thisArgument; + /// + /// An optional this parameter, if the function is an instance method. + /// + public ParameterSymbol? ThisParameter => this.BindThisParameterIfNeeded(this.DeclaringCompilation!); + private ParameterSymbol? thisParameter; public override TypeSymbol ReturnType => this.BindReturnTypeIfNeeded(this.DeclaringCompilation!); private TypeSymbol? returnType; @@ -101,6 +98,16 @@ private ImmutableArray BindGenericParameters(IBinderProvide return genericParams.ToImmutable(); } + protected ParameterSymbol? BindThisParameterIfNeeded(IBinderProvider binderProvider) => + InterlockedUtils.InitializeMaybeNull(ref this.thisParameter, () => this.BindThisParameter(binderProvider)); + + private ParameterSymbol? BindThisParameter(IBinderProvider binderProvider) + { + if (this.DeclaringSyntax.ParameterList.Values.FirstOrDefault() is not ThisParameterSyntax thisSyntax) return null; + + return new SourceThisParameterSymbol(this, thisSyntax); + } + protected ImmutableArray BindParametersIfNeeded(IBinderProvider binderProvider) => InterlockedUtils.InitializeDefault(ref this.parameters, () => this.BindParameters(binderProvider)); @@ -109,29 +116,25 @@ private ImmutableArray BindParameters(IBinderProvider binderPro var parameterSyntaxes = this.DeclaringSyntax.ParameterList.Values.ToList(); var parameters = ImmutableArray.CreateBuilder(); - var isInstance = null as SourceThisParameterSymbol; - - for (var i = 0; i < parameterSyntaxes.Count; ++i) + // NOTE: If the first parameter is 'this', we skip it + var start = parameterSyntaxes.FirstOrDefault() is ThisParameterSyntax ? 1 : 0; + for (var i = start; i < parameterSyntaxes.Count; ++i) { var syntax = parameterSyntaxes[i]; - - if (syntax is ThisParameterSyntax thisParameter) + if (syntax is ThisParameterSyntax thisSyntax) { - var asSymbol = new SourceThisParameterSymbol(this, thisParameter); - if (i == 0) - { - this.thisArgument = asSymbol; - isInstance = asSymbol; - continue; - } + // NOTE: Do we want to construct an error here, or regular symbol is fine? + // Error, 'this' at an illegal place + var thisSymbol = new SourceThisParameterSymbol(this, thisSyntax); + parameters.Add(thisSymbol); binderProvider.DiagnosticBag.Add(Diagnostic.Create( template: SymbolResolutionErrors.ThisParameterNotFirst, - location: thisParameter.Location)); - parameters.Add(asSymbol); + location: thisSyntax.Location)); continue; } - var parameterSyntax = (NormalParameterSyntax)syntax; + // We assume it's a regular parameter + var parameterSyntax = (NormalParameterSyntax)syntax; var parameterName = parameterSyntax.Name.Text; var usedBefore = parameters.Any(p => p.Name == parameterName);