提交 00677493 编写于 作者: E Evan Hauck

Start work on local functions

上级 b7ae5c34
......@@ -1038,7 +1038,7 @@ private bool IsBindingImplicitlyTypedLocal(LocalSymbol symbol)
}
return false;
}
private BoundExpression BindNonMethod(SimpleNameSyntax node, Symbol symbol, DiagnosticBag diagnostics, LookupResultKind resultKind, bool isError)
{
// Events are handled later as we don't know yet if we are binding to the event or it's backing field.
......
......@@ -74,7 +74,7 @@ private void LookupSymbolsWithFallback(LookupResult result, string name, int ari
{
Debug.Assert(result.IsClear);
Debug.Assert(options.AreValid());
for (var scope = this; scope != null && !result.IsMultiViable; scope = scope.Next)
{
if (!result.IsClear)
......
......@@ -45,6 +45,9 @@ public virtual BoundStatement BindStatement(StatementSyntax node, DiagnosticBag
case SyntaxKind.LocalDeclarationStatement:
result = BindDeclarationStatement((LocalDeclarationStatementSyntax)node, diagnostics);
break;
case SyntaxKind.LocalFunctionStatement:
result = BindLocalFunctionStatement((LocalFunctionStatementSyntax)node, diagnostics);
break;
case SyntaxKind.ExpressionStatement:
result = BindExpressionStatement((ExpressionStatementSyntax)node, diagnostics);
break;
......@@ -406,6 +409,48 @@ private BoundStatement BindGoto(GotoStatementSyntax node, DiagnosticBag diagnost
}
}
private BoundStatement BindLocalFunctionStatement(LocalFunctionStatementSyntax node, DiagnosticBag diagnostics)
{
// TODO (search keyword: fzoo)
var localSymbol = this.LookupLocalFunction(node.Identifier);
//SourceLocalSymbol localSymbol = this.LookupLocal(node.Identifier);
//
//AliasSymbol alias;
//var type = this.BindType(node.Type, diagnostics, out alias);
//BoundTypeExpression boundType = new BoundTypeExpression(node.Type, alias, type);
//
//InMethodBinder methodBinder = new InMethodBinder(null, this);
//
//var parameterBuilder = ArrayBuilder<BoundParameter>.GetInstance();
//
//foreach (var parameter in node.ParameterList.Parameters)
//{
// // TODO
//}
//
//var parameterArray = parameterBuilder.ToImmutableAndFree();
//
//BoundBlock block;
//if (node.Body != null)
//{
// // TODO: GetBinder(node.Body)
// block = this.BindBlock(node.Body, diagnostics);
//}
//else if (node.ExpressionBody != null)
//{
// block = this.BindExpressionBodyAsBlock(node.ExpressionBody, diagnostics);
//}
//else
//{
// block = null;
//}
//
//return new BoundLocalFunctionDeclaration(node, localSymbol, boundType, parameterArray, block);
return new BoundLocalFunctionStatement(node);
}
public BoundExpressionStatement BindExpressionStatement(ExpressionStatementSyntax node, DiagnosticBag diagnostics)
{
return BindExpressionStatement(node, node.Expression, node.AllowsAnyExpression, diagnostics);
......@@ -846,7 +891,7 @@ private ImmutableArray<BoundExpression> BindDeclaratorArguments(VariableDeclarat
private SourceLocalSymbol LocateDeclaredVariableSymbol(VariableDeclaratorSyntax declarator, TypeSyntax typeSyntax)
{
SourceLocalSymbol localSymbol = this.LookupLocal(declarator.Identifier);
SourceLocalSymbol localSymbol = (SourceLocalSymbol)this.LookupLocal(declarator.Identifier);
// In error scenarios with misplaced code, it is possible we can't bind the local declaration.
// This occurs through the semantic model. In that case concoct a plausible result.
......@@ -2053,6 +2098,11 @@ protected virtual SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
return Next.LookupLocal(nameToken);
}
protected virtual LocalFunctionMethodSymbol LookupLocalFunction(SyntaxToken nameToken)
{
return Next.LookupLocalFunction(nameToken);
}
public BoundBlock BindBlock(BlockSyntax node, DiagnosticBag diagnostics)
{
var blockBinder = this.GetBinder(node);
......@@ -3248,6 +3298,14 @@ internal virtual ImmutableArray<LocalSymbol> Locals
}
}
internal virtual ImmutableArray<LocalFunctionMethodSymbol> LocalFunctions
{
get
{
return this.Next.LocalFunctions;
}
}
internal virtual ImmutableArray<LabelSymbol> Labels
{
get
......
......@@ -28,6 +28,11 @@ protected override ImmutableArray<LocalSymbol> BuildLocals()
return BuildLocals(_statements);
}
protected override ImmutableArray<LocalFunctionMethodSymbol> BuildLocalFunctions()
{
return BuildLocalFunctions(_statements);
}
protected override ImmutableArray<LabelSymbol> BuildLabels()
{
ArrayBuilder<LabelSymbol> labels = null;
......
......@@ -40,6 +40,11 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
return null;
}
protected override LocalFunctionMethodSymbol LookupLocalFunction(SyntaxToken nameToken)
{
return null;
}
internal override bool IsAccessibleHelper(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref HashSet<DiagnosticInfo> useSiteDiagnostics, ConsList<Symbol> basesBeingResolved)
{
failedThroughTypeCheck = false;
......@@ -200,6 +205,15 @@ internal override ImmutableArray<LocalSymbol> Locals
}
}
internal override ImmutableArray<LocalFunctionMethodSymbol> LocalFunctions
{
get
{
// There's supposed to be a LocalScopeBinder (or other overrider of this method) in the chain.
throw ExceptionUtilities.Unreachable;
}
}
internal override ImmutableArray<LabelSymbol> Labels
{
get
......
......@@ -206,5 +206,10 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
{
return null;
}
protected override LocalFunctionMethodSymbol LookupLocalFunction(SyntaxToken nameToken)
{
return null;
}
}
}
......@@ -80,6 +80,11 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
return null;
}
protected override LocalFunctionMethodSymbol LookupLocalFunction(SyntaxToken nameToken)
{
return null;
}
internal override Symbol ContainingMemberOrLambda
{
get
......
......@@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp
internal partial class LocalScopeBinder : Binder
{
private ImmutableArray<LocalSymbol> _locals;
private ImmutableArray<LocalFunctionMethodSymbol> _localFunctions;
private ImmutableArray<LabelSymbol> _labels;
internal LocalScopeBinder(Binder next)
......@@ -41,6 +42,24 @@ protected virtual ImmutableArray<LocalSymbol> BuildLocals()
{
return ImmutableArray<LocalSymbol>.Empty;
}
internal sealed override ImmutableArray<LocalFunctionMethodSymbol> LocalFunctions
{
get
{
if (_localFunctions.IsDefault)
{
ImmutableInterlocked.InterlockedCompareExchange(ref _localFunctions, BuildLocalFunctions(), default(ImmutableArray<LocalFunctionMethodSymbol>));
}
return _localFunctions;
}
}
protected virtual ImmutableArray<LocalFunctionMethodSymbol> BuildLocalFunctions()
{
return ImmutableArray<LocalFunctionMethodSymbol>.Empty;
}
internal sealed override ImmutableArray<LabelSymbol> Labels
{
......@@ -74,6 +93,20 @@ protected virtual ImmutableArray<LabelSymbol> BuildLabels()
}
}
private SmallDictionary<string, LocalFunctionMethodSymbol> _lazyLocalFunctionsMap;
private SmallDictionary<string, LocalFunctionMethodSymbol> LocalFunctionsMap
{
get
{
if (_lazyLocalFunctionsMap == null && this.LocalFunctions.Length > 0)
{
_lazyLocalFunctionsMap = BuildMap(this.LocalFunctions);
}
return _lazyLocalFunctionsMap;
}
}
private SmallDictionary<string, LabelSymbol> _lazyLabelsMap;
private SmallDictionary<string, LabelSymbol> LabelsMap
{
......@@ -145,6 +178,42 @@ protected ImmutableArray<LocalSymbol> BuildLocals(SyntaxList<StatementSyntax> st
return ImmutableArray<LocalSymbol>.Empty;
}
protected ImmutableArray<LocalFunctionMethodSymbol> BuildLocalFunctions(SyntaxList<StatementSyntax> statements)
{
ArrayBuilder<LocalFunctionMethodSymbol> locals = null;
foreach (var statement in statements)
{
var innerStatement = statement;
// drill into any LabeledStatements -- atomic LabelStatements have been bound into
// wrapped LabeledStatements by this point
while (innerStatement.Kind() == SyntaxKind.LabeledStatement)
{
innerStatement = ((LabeledStatementSyntax)innerStatement).Statement;
}
if (innerStatement.Kind() == SyntaxKind.LocalFunctionStatement)
{
var decl = (LocalFunctionStatementSyntax)innerStatement;
if (locals == null)
{
locals = ArrayBuilder<LocalFunctionMethodSymbol>.GetInstance();
}
var localSymbol = MakeLocalFunction(decl);
locals.Add(localSymbol);
}
}
if (locals != null)
{
return locals.ToImmutableAndFree();
}
return ImmutableArray<LocalFunctionMethodSymbol>.Empty;
}
protected SourceLocalSymbol MakeLocal(VariableDeclarationSyntax declaration, VariableDeclaratorSyntax declarator, LocalDeclarationKind kind)
{
return SourceLocalSymbol.MakeLocal(
......@@ -156,6 +225,15 @@ protected SourceLocalSymbol MakeLocal(VariableDeclarationSyntax declaration, Var
declarator.Initializer);
}
protected LocalFunctionMethodSymbol MakeLocalFunction(LocalFunctionStatementSyntax declaration)
{
return new LocalFunctionMethodSymbol(
this,
this.ContainingType, // TODO fzoo
declaration,
declaration.Location);
}
protected void BuildLabels(SyntaxList<StatementSyntax> statements, ref ArrayBuilder<LabelSymbol> labels)
{
var containingMethod = (MethodSymbol)this.ContainingMemberOrLambda;
......@@ -201,6 +279,26 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
return base.LookupLocal(nameToken);
}
protected override LocalFunctionMethodSymbol LookupLocalFunction(SyntaxToken nameToken)
{
LocalFunctionMethodSymbol result = null;
if (LocalFunctionsMap != null && LocalFunctionsMap.TryGetValue(nameToken.ValueText, out result))
{
if (result.NameToken == nameToken) return result;
// in error cases we might have more than one declaration of the same name in the same scope
foreach (var local in this.LocalFunctions)
{
if (local.NameToken == nameToken)
{
return local;
}
}
}
return base.LookupLocalFunction(nameToken);
}
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
......@@ -230,6 +328,16 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
result.MergeEqual(originalBinder.CheckViability(localSymbol, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved));
}
}
var localFunctionsMap = this.LocalFunctionsMap;
if (localFunctionsMap != null && (options & LookupOptions.NamespaceAliasesOnly) == 0)
{
LocalFunctionMethodSymbol localSymbol;
if (localFunctionsMap.TryGetValue(name, out localSymbol))
{
result.MergeEqual(originalBinder.CheckViability(localSymbol, arity, options, null, diagnose, ref useSiteDiagnostics, basesBeingResolved));
}
}
}
protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo result, LookupOptions options, Binder originalBinder)
......
......@@ -101,6 +101,18 @@ override protected ImmutableArray<LocalSymbol> BuildLocals()
return builder.ToImmutableAndFree();
}
protected override ImmutableArray<LocalFunctionMethodSymbol> BuildLocalFunctions()
{
var builder = ArrayBuilder<LocalFunctionMethodSymbol>.GetInstance();
foreach (var section in _switchSyntax.Sections)
{
builder.AddRange(BuildLocalFunctions(section.Statements));
}
return builder.ToImmutableAndFree();
}
internal override GeneratedLabelSymbol BreakLabel
{
get
......
......@@ -589,6 +589,19 @@
<Node Name="BoundMultipleLocalDeclarations" Base="BoundStatement">
<Field Name="LocalDeclarations" Type="ImmutableArray&lt;BoundLocalDeclaration&gt;"/>
</Node>
<!--
Bound node that represents a local function declaration:
void Foo() { }
-->
<Node Name="BoundLocalFunctionStatement" Base="BoundStatement">
<!--
<Field Name="LocalSymbol" Type="LocalSymbol"/>
<Field Name="ReturnType" Type="BoundTypeExpression"/>
<Field Name="Parameters" Type="ImmutableArray&lt;BoundParameter&gt;"/>
<Field Name="Body" Type="BoundBlock" Null="allow"/>
-->
</Node>
<!--
A node specially to represent the idea of
......
......@@ -900,4 +900,4 @@
<Import Project="..\..\..\..\build\VSL.Imports.Closed.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -1161,7 +1161,7 @@ private NamedTypeSymbol GetDeclaredType(DelegateDeclarationSyntax declarationSyn
var name = declarationSyntax.Identifier.ValueText;
return GetDeclaredNamedType(declarationSyntax, name);
}
private NamedTypeSymbol GetDeclaredNamedType(CSharpSyntaxNode declarationSyntax, string name)
{
Debug.Assert(declarationSyntax != null);
......@@ -1192,7 +1192,7 @@ private NamespaceOrTypeSymbol GetDeclaredNamespaceOrType(CSharpSyntaxNode declar
{
return GetDeclaredType(delegateDeclarationSyntax);
}
return null;
}
......
......@@ -315,5 +315,10 @@ public override BoundNode VisitSwitchSection(BoundSwitchSection node, bool lastS
return null;
}
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
{
return node; // TODO (search keyword: fzoo)
}
}
}
......@@ -1400,6 +1400,11 @@ public override BoundNode VisitFixedStatement(BoundFixedStatement node)
return result;
}
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
{
return node; // TODO (search keyword: fzoo)
}
public override BoundNode VisitSequence(BoundSequence node)
{
DeclareVariables(node.Locals);
......
......@@ -7899,8 +7899,12 @@ private LabeledStatementSyntax ParseLabeledStatement()
return _syntaxFactory.LabeledStatement(label, colon, statement);
}
private LocalDeclarationStatementSyntax ParseLocalDeclarationStatement()
private StatementSyntax ParseLocalDeclarationStatement()
{
LocalFunctionStatementSyntax syntax;
if (ParseLocalFunctionStatement(out syntax))
return syntax;
TypeSyntax type;
var mods = _pool.Allocate();
var variables = _pool.AllocateSeparated<VariableDeclaratorSyntax>();
......@@ -7979,6 +7983,38 @@ private static bool IsDeclarationModifier(SyntaxKind kind)
}
}
private bool ParseLocalFunctionStatement(out LocalFunctionStatementSyntax decl)
{
ResetPoint resetPoint = this.GetResetPoint();
TypeSyntax type = this.ParseType(false);
SyntaxToken identifier = this.EatToken(SyntaxKind.IdentifierToken);
if (this.CurrentToken.Kind != SyntaxKind.OpenParenToken)
{
this.Reset(ref resetPoint);
this.Release(ref resetPoint);
decl = null;
return false;
}
this.Release(ref resetPoint);
ParameterListSyntax paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: false);
BlockSyntax blockBody;
ArrowExpressionClauseSyntax expressionBody;
SyntaxToken semicolon;
this.ParseBlockAndExpressionBodiesWithSemicolon(out blockBody, out expressionBody, out semicolon);
decl = _syntaxFactory.LocalFunctionStatement(
type,
identifier,
paramList,
blockBody,
expressionBody,
semicolon);
decl = CheckForBlockAndExpressionBody(blockBody, expressionBody, decl);
return true;
}
private ExpressionStatementSyntax ParseExpressionStatement()
{
return ParseExpressionStatement(this.ParseExpressionCore());
......
......@@ -1171,6 +1171,22 @@ Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.Update(Micr
Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.WithDeclaration(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.AddBodyStatements(params Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.AddParameterListParameters(params Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Body.get -> Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Identifier.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.ParameterList.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.ReturnType.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.SemicolonToken.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithBody(Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithExpressionBody(Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithIdentifier(Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithParameterList(Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithReturnType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax
......@@ -2176,6 +2192,7 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.LineDirectiveTrivia = 8558 -> Microsoft
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LineKeyword = 8475 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.List = 1 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LocalDeclarationStatement = 8793 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LocalFunctionStatement = 8830 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LockKeyword = 8337 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LockStatement = 8818 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
Microsoft.CodeAnalysis.CSharp.SyntaxKind.LogicalAndExpression = 8676 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
......@@ -2634,6 +2651,7 @@ override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLetClause(Micro
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLineDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.LineDirectiveTriviaSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLiteralExpression(Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLocalDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLockStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitMakeRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MakeRefExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitMemberAccessExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
......@@ -3060,6 +3078,8 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax.Accept(Mic
override Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax.Accept<TResult>(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult> visitor) -> TResult
override Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void
override Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax.Accept<TResult>(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult> visitor) -> TResult
override Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void
override Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Accept<TResult>(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult> visitor) -> TResult
override Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void
override Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax.Accept<TResult>(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult> visitor) -> TResult
override Microsoft.CodeAnalysis.CSharp.Syntax.MakeRefExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void
......@@ -3722,6 +3742,10 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LiteralExpression(Microsoft.C
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalDeclarationStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalDeclarationStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, string identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LockStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LockStatement(Microsoft.CodeAnalysis.SyntaxToken lockKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.MakeRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.MakeRefExpressionSyntax
......@@ -4176,6 +4200,7 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLetClause(Microso
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLineDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.LineDirectiveTriviaSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLiteralExpression(Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLockStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitMakeRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MakeRefExpressionSyntax node) -> void
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitMemberAccessExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax node) -> void
......@@ -4363,6 +4388,7 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLetClaus
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLineDirectiveTrivia(Microsoft.CodeAnalysis.CSharp.Syntax.LineDirectiveTriviaSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLiteralExpression(Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLocalDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitLockStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LockStatementSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitMakeRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MakeRefExpressionSyntax node) -> TResult
virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult>.VisitMemberAccessExpression(Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax node) -> TResult
......
......@@ -280,6 +280,7 @@ public override void VisitMethod(IMethodSymbol symbol)
case MethodKind.Ordinary:
case MethodKind.DelegateInvoke:
case MethodKind.ReducedExtension:
case MethodKind.LocalFunction:
//containing type will be the delegate type, name will be Invoke
builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.Name));
break;
......
......@@ -960,6 +960,8 @@ MethodKind IMethodSymbol.MethodKind
return MethodKind.ReducedExtension;
case MethodKind.StaticConstructor:
return MethodKind.StaticConstructor;
case MethodKind.LocalFunction:
return MethodKind.LocalFunction;
default:
throw ExceptionUtilities.UnexpectedValue(this.MethodKind);
}
......
......@@ -436,4 +436,135 @@ protected override TypeSymbol InferTypeOfVarVariable(DiagnosticBag diagnostics)
}
}
}
internal class LocalFunctionMethodSymbol : SourceMethodSymbol
{
private readonly Binder _binder;
private readonly LocalFunctionStatementSyntax _syntax;
private ImmutableArray<ParameterSymbol> _parameters;
private TypeSymbol _returnType;
private bool _isVararg;
public LocalFunctionMethodSymbol(
Binder binder,
NamedTypeSymbol containingType,
LocalFunctionStatementSyntax syntax,
Location location) :
base(
containingType,
syntax.GetReference(),
syntax.Body?.GetReference() ?? syntax.ExpressionBody?.GetReference(),
location)
{
_binder = binder;
_syntax = syntax;
// It is an error to be an extension method, but we need to compute it to report it
var firstParam = syntax.ParameterList.Parameters.FirstOrDefault();
bool isExtensionMethod = firstParam != null &&
!firstParam.IsArgList &&
firstParam.Modifiers.Any(SyntaxKind.ThisKeyword);
this.MakeFlags(
MethodKind.LocalFunction,
DeclarationModifiers.None,
returnsVoid: false, // will be fixed in MethodChecks
isExtensionMethod: isExtensionMethod);
}
public override string Name
{
get
{
return _syntax.Identifier.ValueText;
}
}
public SyntaxToken NameToken
{
get
{
return _syntax.Identifier;
}
}
public override bool IsVararg
{
get
{
EnsureLazyInitFinished();
return _isVararg;
}
}
public override ImmutableArray<ParameterSymbol> Parameters
{
get
{
EnsureLazyInitFinished();
return _parameters;
}
}
public override TypeSymbol ReturnType
{
get
{
EnsureLazyInitFinished();
return _returnType;
}
}
public override ImmutableArray<TypeParameterSymbol> TypeParameters
{
get
{
return ImmutableArray<TypeParameterSymbol>.Empty;
}
}
internal override bool GenerateDebugInfo
{
get
{
return true;
}
}
internal override bool IsExpressionBodied
{
get
{
return _syntax.ExpressionBody != null;
}
}
private void EnsureLazyInitFinished()
{
if (_returnType == null)
return;
DiagnosticBag diagnostics = DiagnosticBag.GetInstance();
MethodChecks(diagnostics, _binder);
diagnostics.Free();
}
private void MethodChecks(DiagnosticBag diagnostics, Binder parameterBinder)
{
SyntaxToken arglistToken;
_parameters = ParameterHelpers.MakeParameters(parameterBinder, this, _syntax.ParameterList, true, out arglistToken, diagnostics);
_isVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword);
_returnType = parameterBinder.BindType(_syntax.ReturnType, diagnostics);
this.SetReturnsVoid(_returnType.SpecialType == SpecialType.System_Void);
this.CheckEffectiveAccessibility(_returnType, _parameters, diagnostics);
if (IsExtensionMethod)
{
diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, Locations[0]);
}
}
protected override void MethodChecks(DiagnosticBag diagnostics)
{
MethodChecks(diagnostics, _binder);
}
}
}
......@@ -324,6 +324,8 @@ private static SyntaxToken GetFirstIncludedToken(StatementSyntax statement, bool
case SyntaxKind.YieldReturnStatement:
case SyntaxKind.YieldBreakStatement:
return ((YieldStatementSyntax)statement).YieldKeyword;
case SyntaxKind.LocalFunctionStatement:
return statement.GetFirstToken();
default:
throw ExceptionUtilities.UnexpectedValue(statement.Kind());
}
......@@ -399,6 +401,13 @@ private static SyntaxToken GetFirstExcludedToken(StatementSyntax statement)
case SyntaxKind.YieldReturnStatement:
case SyntaxKind.YieldBreakStatement:
return ((YieldStatementSyntax)statement).SemicolonToken;
case SyntaxKind.LocalFunctionStatement:
LocalFunctionStatementSyntax localFunctionStmt = (LocalFunctionStatementSyntax)statement;
if (localFunctionStmt.Body != null)
return GetFirstExcludedToken(localFunctionStmt.Body);
if (localFunctionStmt.SemicolonToken != null)
return localFunctionStmt.SemicolonToken;
return localFunctionStmt.ParameterList.GetLastToken();
default:
throw ExceptionUtilities.UnexpectedValue(statement.Kind());
}
......
......@@ -413,7 +413,7 @@
<FactoryComment>
<summary>Creates a ConditionalAccessExpressionSyntax node.</summary>
</FactoryComment>
</Node>
</Node>
<Node Name="MemberBindingExpressionSyntax" Base="ExpressionSyntax">
<Kind Name="MemberBindingExpression"/>
<Field Name="OperatorToken" Type="SyntaxToken">
......@@ -434,7 +434,7 @@
<summary>Creates an MemberBindingExpressionSyntax node.</summary>
</FactoryComment>
</Node>
<Node Name="ElementBindingExpressionSyntax" Base="ExpressionSyntax">
<Node Name="ElementBindingExpressionSyntax" Base="ExpressionSyntax">
<Kind Name="ElementBindingExpression"/>
<Field Name="ArgumentList" Type="BracketedArgumentListSyntax">
<PropertyComment>
......@@ -1633,6 +1633,25 @@
<Kind Name="CloseBraceToken"/>
</Field>
</Node>
<Node Name="LocalFunctionStatementSyntax" Base="StatementSyntax">
<Kind Name="LocalFunctionStatement"/>
<Field Name="ReturnType" Type="TypeSyntax"/>
<Field Name="Identifier" Type="SyntaxToken">
<PropertyComment>
<summary>Gets the identifier.</summary>
</PropertyComment>
<Kind Name="IdentifierToken"/>
</Field>
<Field Name="ParameterList" Type="ParameterListSyntax"/>
<Field Name="Body" Type="BlockSyntax" Optional="true"/>
<Field Name="ExpressionBody" Type="ArrowExpressionClauseSyntax" Optional="true" />
<Field Name="SemicolonToken" Type="SyntaxToken" Optional="true">
<PropertyComment>
<summary>Gets the optional semicolon token.</summary>
</PropertyComment>
<Kind Name="SemicolonToken"/>
</Field>
</Node>
<Node Name="LocalDeclarationStatementSyntax" Base="StatementSyntax">
<Kind Name="LocalDeclarationStatement"/>
<Field Name="Modifiers" Type="SyntaxList&lt;SyntaxToken&gt;">
......
......@@ -467,6 +467,9 @@ public enum SyntaxKind : ushort
CatchFilterClause = 8828,
FinallyClause = 8829,
// statements that didn't fit above
LocalFunctionStatement = 8830,
// declarations
CompilationUnit = 8840,
GlobalStatement = 8841,
......
......@@ -712,6 +712,7 @@ Microsoft.CodeAnalysis.MethodKind.EventRaise = 6 -> Microsoft.CodeAnalysis.Metho
Microsoft.CodeAnalysis.MethodKind.EventRemove = 7 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.ExplicitInterfaceImplementation = 8 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.LambdaMethod = 0 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.LocalFunction = 17 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.Ordinary = 10 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.PropertyGet = 11 -> Microsoft.CodeAnalysis.MethodKind
Microsoft.CodeAnalysis.MethodKind.PropertySet = 12 -> Microsoft.CodeAnalysis.MethodKind
......
......@@ -94,6 +94,11 @@ public enum MethodKind
/// <summary>
/// Declare Sub or Function.
/// </summary>
DeclareMethod = 16
DeclareMethod = 16,
/// <summary>
/// Method is declared inside of another method.
/// </summary>
LocalFunction = 17
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册