Skip to content

Commit

Permalink
Move CapturedVariables to function scope and add ReferencedVariables.
Browse files Browse the repository at this point in the history
The captured variables are not applicable for non-function
scopes it was moved to IFunctionScope and IScope now
has ReferencedVariables which are variables referenced
by the scope or its children.
  • Loading branch information
GGG-KILLER committed Apr 9, 2021
1 parent 50ac8aa commit db2ccf4
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 28 deletions.
28 changes: 26 additions & 2 deletions src/Compilers/Lua/Portable/Scoping/IFunctionScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ public interface IFunctionScope : IScope
/// The parameters
/// </summary>
IEnumerable<IVariable> Parameters { get; }

/// <summary>
/// Contains the variables that are captured by this scope.
/// Variables captured by the scope are variables that weren't declared
/// on the scope but are used in it.
/// </summary>
IEnumerable<IVariable> CapturedVariables { get; }
}

internal interface IFunctionScopeInternal : IScopeInternal, IFunctionScope
Expand All @@ -21,20 +28,37 @@ internal interface IFunctionScopeInternal : IScopeInternal, IFunctionScope

internal class FunctionScope : Scope, IFunctionScopeInternal
{
private readonly IList<IVariable> _parameters = new List<IVariable>();
private readonly IList<IVariableInternal> _parameters = new List<IVariableInternal>();
private readonly HashSet<IVariableInternal> _capturedVariables = new HashSet<IVariableInternal>();

public FunctionScope(SyntaxNode node, IScopeInternal? parent) : base(ScopeKind.Function, node, parent)
{
Parameters = SpecializedCollections.ReadOnlyEnumerable(_parameters);
CapturedVariables = SpecializedCollections.ReadOnlyEnumerable(_capturedVariables);
}

public IEnumerable<IVariable> Parameters { get; }
public IEnumerable<IVariableInternal> Parameters { get; }

IEnumerable<IVariable> IFunctionScope.Parameters => Parameters;

public IEnumerable<IVariableInternal> CapturedVariables { get; }

IEnumerable<IVariable> IFunctionScope.CapturedVariables => CapturedVariables;

public IVariableInternal AddParameter(string name, SyntaxNode declaration)
{
var parameter = CreateVariable(VariableKind.Parameter, name, declaration);
_parameters.Add(parameter);
return parameter;
}

public override void AddReferencedVariable(IVariableInternal variable)
{
if (_declaredVariables.Contains(variable))
return;
_capturedVariables.Add(variable);
variable.AddCapturingScope(this);
base.AddReferencedVariable(variable);
}
}
}
34 changes: 14 additions & 20 deletions src/Compilers/Lua/Portable/Scoping/IScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ public interface IScope
IEnumerable<IVariable> DeclaredVariables { get; }

/// <summary>
/// Contains the variables that are captured by this scope.
/// Variables captured by the scope are variables that weren't declared
/// on the scope but are used in it.
/// Variables that are referenced by this scope.
/// </summary>
IEnumerable<IVariable> CapturedVariables { get; }
IEnumerable<IVariable> ReferencedVariables { get; }

/// <summary>
/// The goto labels contained within this scope.
Expand All @@ -52,7 +50,7 @@ internal interface IScopeInternal : IScope
bool TryGetVariable(string name, [NotNullWhen(true)] out IVariableInternal? variable);
IVariableInternal GetOrCreateVariable(VariableKind kind, string name, SyntaxNode? declaration = null);
IVariableInternal CreateVariable(VariableKind kind, string name, SyntaxNode? declaration = null);
void AddCapturedVariable(IVariableInternal variable);
void AddReferencedVariable(IVariableInternal variable);

bool TryGetLabel(string name, [NotNullWhen(true)] out IGotoLabelInternal? label);
IGotoLabelInternal GetOrCreateLabel(string name, GotoLabelStatementSyntax label);
Expand All @@ -61,18 +59,18 @@ internal interface IScopeInternal : IScope

internal class Scope : IScopeInternal
{
private readonly IDictionary<string, IVariableInternal> _variables = new Dictionary<string, IVariableInternal>(StringComparer.Ordinal);
private readonly ISet<IVariableInternal> _declaredVariables = new HashSet<IVariableInternal>();
private readonly ISet<IVariableInternal> _capturedVariables = new HashSet<IVariableInternal>();
private readonly IDictionary<string, IGotoLabelInternal> _labels = new Dictionary<string, IGotoLabelInternal>(StringComparer.Ordinal);
protected readonly IDictionary<string, IVariableInternal> _variables = new Dictionary<string, IVariableInternal>(StringComparer.Ordinal);
protected readonly ISet<IVariableInternal> _declaredVariables = new HashSet<IVariableInternal>();
protected readonly ISet<IVariableInternal> _referencedVariables = new HashSet<IVariableInternal>();
protected readonly IDictionary<string, IGotoLabelInternal> _labels = new Dictionary<string, IGotoLabelInternal>(StringComparer.Ordinal);

public Scope(ScopeKind kind, SyntaxNode? node, IScopeInternal? parent)
{
Kind = kind;
Node = node;
Parent = parent;
DeclaredVariables = SpecializedCollections.ReadOnlyEnumerable(_declaredVariables);
CapturedVariables = SpecializedCollections.ReadOnlyEnumerable(_capturedVariables);
ReferencedVariables = SpecializedCollections.ReadOnlyEnumerable(_referencedVariables);
GotoLabels = SpecializedCollections.ReadOnlyEnumerable(_labels.Values);
}

Expand All @@ -88,9 +86,9 @@ public Scope(ScopeKind kind, SyntaxNode? node, IScopeInternal? parent)

IEnumerable<IVariable> IScope.DeclaredVariables => DeclaredVariables;

public IEnumerable<IVariableInternal> CapturedVariables { get; }
public IEnumerable<IVariableInternal> ReferencedVariables { get; }

IEnumerable<IVariable> IScope.CapturedVariables => CapturedVariables;
IEnumerable<IVariable> IScope.ReferencedVariables => ReferencedVariables;

public IEnumerable<IGotoLabelInternal> GotoLabels { get; }

Expand All @@ -107,7 +105,7 @@ public IVariableInternal GetOrCreateVariable(VariableKind kind, string name, Syn
if (!TryGetVariable(name, out var variable))
variable = CreateVariable(kind, name, declaration);

_capturedVariables.Add(variable);
_referencedVariables.Add(variable);
RoslynDebug.Assert(variable.Kind == kind);
return variable;
}
Expand All @@ -123,16 +121,12 @@ public IVariableInternal CreateVariable(VariableKind kind, string name, SyntaxNo
return variable;
}

public void AddCapturedVariable(IVariableInternal variable)
public virtual void AddReferencedVariable(IVariableInternal variable)
{
if (_declaredVariables.Contains(variable))
return;
if (Kind == ScopeKind.Function)
{
_capturedVariables.Add(variable);
variable.AddCapturingScope(this);
}
Parent?.AddCapturedVariable(variable);
_referencedVariables.Add(variable);
Parent?.AddReferencedVariable(variable);
}

public bool TryGetLabel(string name, [NotNullWhen(true)] out IGotoLabelInternal? label) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public override void VisitVarArgExpression(VarArgExpressionSyntax node)
_variables[node] = variable;
variable.AddReadLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);
}

public override void VisitIdentifierName(IdentifierNameSyntax node)
Expand All @@ -104,7 +104,7 @@ public override void VisitIdentifierName(IdentifierNameSyntax node)
_variables[node] = variable;
variable.AddReadLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);
}

public override void VisitAssignmentStatement(AssignmentStatementSyntax node)
Expand All @@ -121,7 +121,7 @@ public override void VisitAssignmentStatement(AssignmentStatementSyntax node)
_variables[assignee] = variable;
variable.AddWriteLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);
}
else
{
Expand All @@ -141,7 +141,7 @@ public override void VisitCompoundAssignmentStatement(CompoundAssignmentStatemen
_variables[identifierName] = variable;
variable.AddWriteLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);
}
else
{
Expand Down Expand Up @@ -268,7 +268,7 @@ public override void VisitLocalVariableDeclarationStatement(LocalVariableDeclara
_variables[name] = variable;
variable.AddWriteLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);
}
}

Expand All @@ -278,7 +278,7 @@ public override void VisitLocalFunctionDeclarationStatement(LocalFunctionDeclara
_variables[node.Name] = variable;
variable.AddWriteLocation(node);
variable.AddReferencingScope(Scope);
Scope.AddCapturedVariable(variable);
Scope.AddReferencedVariable(variable);

var scope = CreateFunctionScope(node);
try
Expand Down

0 comments on commit db2ccf4

Please sign in to comment.