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

Change LocalFunctionMethodSymbol base class to MethodSymbol

上级 fea05ade
......@@ -420,7 +420,7 @@ private BoundStatement BindLocalFunctionStatement(LocalFunctionStatementSyntax n
// This occurs through the semantic model. In that case concoct a plausible result.
if (localSymbol == null)
{
localSymbol = new LocalFunctionMethodSymbol(this, this.ContainingType, this.ContainingMemberOrLambda, node, node.Identifier.GetLocation());
localSymbol = new LocalFunctionMethodSymbol(this, this.ContainingType, this.ContainingMemberOrLambda, node);
}
else
{
......@@ -478,7 +478,7 @@ private BoundStatement BindLocalFunctionStatement(LocalFunctionStatementSyntax n
block = null;
hasErrors = true;
}
return new BoundLocalFunctionStatement(node, localSymbol, block, hasErrors);
}
......@@ -2163,7 +2163,7 @@ internal static BoundBlock BindBlock(BlockSyntax node, DiagnosticBag diagnostics
if (blockBinder.IsDirectlyInIterator)
{
var method = blockBinder.ContainingMemberOrLambda as SourceMethodSymbol;
var method = blockBinder.ContainingMemberOrLambda as MethodSymbol;
if ((object)method != null)
{
method.IteratorElementType = blockBinder.GetIteratorElementType(null, diagnostics);
......
......@@ -42,7 +42,7 @@ protected virtual ImmutableArray<LocalSymbol> BuildLocals()
{
return ImmutableArray<LocalSymbol>.Empty;
}
internal sealed override ImmutableArray<LocalFunctionMethodSymbol> LocalFunctions
{
get
......@@ -192,7 +192,7 @@ protected ImmutableArray<LocalFunctionMethodSymbol> BuildLocalFunctions(SyntaxLi
{
innerStatement = ((LabeledStatementSyntax)innerStatement).Statement;
}
if (innerStatement.Kind() == SyntaxKind.LocalFunctionStatement)
{
var decl = (LocalFunctionStatementSyntax)innerStatement;
......@@ -231,8 +231,7 @@ protected LocalFunctionMethodSymbol MakeLocalFunction(LocalFunctionStatementSynt
this,
this.ContainingType,
this.ContainingMemberOrLambda,
declaration,
declaration.Identifier.GetLocation());
declaration);
}
protected void BuildLabels(SyntaxList<StatementSyntax> statements, ref ArrayBuilder<LabelSymbol> labels)
......@@ -422,7 +421,7 @@ private bool ReportConflictWithLocal(Symbol local, Symbol newSymbol, string name
diagnostics.Add(ErrorCode.ERR_QueryRangeVariableOverrides, newLocation, name);
return true;
}
Debug.Assert(false, "what else can be declared inside a local scope?");
return false;
}
......
......@@ -1487,6 +1487,12 @@ private static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationSta
}
}
if (iterator.IsVararg)
{
// error CS1636: __arglist is not allowed in the parameter list of iterators
diagnostics.Add(ErrorCode.ERR_VarargsIterator, iterator.Locations[0]);
}
var sourceIterator = iterator as SourceMethodSymbol;
if (sourceIterator != null)
{
......@@ -1494,12 +1500,6 @@ private static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationSta
{
diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceIterator.Locations[0]);
}
if (sourceIterator.IsVararg)
{
// error CS1636: __arglist is not allowed in the parameter list of iterators
diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceIterator.Locations[0]);
}
}
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
using System.Diagnostics;
using System.Threading;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
internal class LocalFunctionMethodSymbol : SourceMethodSymbol
internal class LocalFunctionMethodSymbol : MethodSymbol
{
private readonly Binder _binder;
private readonly LocalFunctionStatementSyntax _syntax;
private readonly Symbol _containingSymbol;
private readonly DeclarationModifiers _declarationModifiers;
private ImmutableArray<ParameterSymbol> _parameters;
private ImmutableArray<TypeParameterSymbol> _typeParameters;
private TypeSymbol _returnType;
private TypeSymbol _iteratorElementType;
private bool _isVararg;
public LocalFunctionMethodSymbol(
Binder binder,
NamedTypeSymbol containingType,
Symbol containingSymbol,
LocalFunctionStatementSyntax syntax,
Location location) :
base(
containingType,
syntax.GetReference(),
syntax.Body?.GetReference() ?? syntax.ExpressionBody?.GetReference(),
location)
LocalFunctionStatementSyntax syntax)
{
_binder = binder;
_syntax = syntax;
_containingSymbol = containingSymbol;
// 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,
(_containingSymbol.IsStatic ? DeclarationModifiers.Static : 0) | syntax.Modifiers.ToDeclarationModifiers(),
returnsVoid: false, // will be fixed in MethodChecks
isExtensionMethod: isExtensionMethod);
_declarationModifiers = (_containingSymbol.IsStatic ? DeclarationModifiers.Static : 0) | syntax.Modifiers.ToDeclarationModifiers();
}
public sealed override Symbol ContainingSymbol
......@@ -68,6 +61,22 @@ public SyntaxToken NameToken
}
}
public override ImmutableArray<Location> Locations
{
get
{
return ImmutableArray.Create<Location>(_syntax.Identifier.GetLocation());
}
}
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get
{
return ImmutableArray.Create<SyntaxReference>(_syntax.GetReference());
}
}
public override bool IsVararg
{
get
......@@ -94,6 +103,14 @@ public override TypeSymbol ReturnType
return _returnType;
}
}
public override bool ReturnsVoid
{
get
{
EnsureLazyInitFinished();
return _returnType.SpecialType == SpecialType.System_Void;
}
}
public override ImmutableArray<TypeParameterSymbol> TypeParameters
{
......@@ -106,23 +123,77 @@ public override ImmutableArray<TypeParameterSymbol> TypeParameters
return _typeParameters;
}
}
internal override bool GenerateDebugInfo
public override bool IsExtensionMethod
{
get
{
return true;
// It is an error to be an extension method, but we need to compute it to report it
var firstParam = _syntax.ParameterList.Parameters.FirstOrDefault();
return firstParam != null &&
!firstParam.IsArgList &&
firstParam.Modifiers.Any(SyntaxKind.ThisKeyword);
}
}
internal override bool IsExpressionBodied
internal override TypeSymbol IteratorElementType
{
get
{
return _syntax.ExpressionBody != null;
return _iteratorElementType;
}
set
{
Debug.Assert((object)_iteratorElementType == null || _iteratorElementType == value);
Interlocked.CompareExchange(ref _iteratorElementType, value, null);
}
}
internal override bool GenerateDebugInfo => true;
public override MethodKind MethodKind => MethodKind.LocalFunction;
public override int Arity => TypeParameters.Length;
internal override bool HasSpecialName => false;
internal override MethodImplAttributes ImplementationAttributes => default(MethodImplAttributes);
internal override bool HasDeclarativeSecurity => false;
internal override MarshalPseudoCustomAttributeData ReturnValueMarshallingInformation => null;
internal override bool RequiresSecurityObject => false;
public override bool HidesBaseMethodsByName => false;
public override ImmutableArray<TypeSymbol> TypeArguments => TypeParameters.Cast<TypeParameterSymbol, TypeSymbol>();
public override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations => ImmutableArray<MethodSymbol>.Empty;
public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers => ImmutableArray<CustomModifier>.Empty;
public override Symbol AssociatedSymbol => null;
internal override CallingConvention CallingConvention => CallingConvention.Default;
public override Accessibility DeclaredAccessibility => Accessibility.Private;
public override bool IsAsync => (_declarationModifiers & DeclarationModifiers.Async) != 0;
public override bool IsStatic => (_declarationModifiers & DeclarationModifiers.Static) != 0;
public override bool IsVirtual => (_declarationModifiers & DeclarationModifiers.Virtual) != 0;
public override bool IsOverride => (_declarationModifiers & DeclarationModifiers.Override) != 0;
public override bool IsAbstract => (_declarationModifiers & DeclarationModifiers.Abstract) != 0;
public override bool IsSealed => (_declarationModifiers & DeclarationModifiers.Sealed) != 0;
public override bool IsExtern => (_declarationModifiers & DeclarationModifiers.Extern) != 0;
internal override ObsoleteAttributeData ObsoleteAttributeData => null;
public override DllImportData GetDllImportData() => null;
internal override ImmutableArray<string> GetAppliedConditionalSymbols() => ImmutableArray<string>.Empty;
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false;
internal override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false) => false;
internal override IEnumerable<SecurityAttribute> GetSecurityInformation()
{
throw ExceptionUtilities.Unreachable;
}
internal override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
{
throw ExceptionUtilities.Unreachable;
}
internal override bool TryGetThisParameter(out ParameterSymbol thisParameter)
{
// Local function symbols have no "this" parameter
thisParameter = null;
return true;
}
private void EnsureLazyInitFinished()
{
if (_returnType != null)
......@@ -148,8 +219,6 @@ private void MethodChecks(DiagnosticBag diagnostics, Binder parameterBinder)
_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]);
......@@ -193,7 +262,7 @@ private ImmutableArray<TypeParameterSymbol> MakeTypeParameters(DiagnosticBag dia
this,
name,
ordinal,
locations,
ImmutableArray.Create(location),
ImmutableArray.Create(parameter.GetReference()));
result.Add(typeParameter);
......@@ -202,11 +271,6 @@ private ImmutableArray<TypeParameterSymbol> MakeTypeParameters(DiagnosticBag dia
return result.ToImmutableAndFree();
}
protected override void MethodChecks(DiagnosticBag diagnostics)
{
MethodChecks(diagnostics, _binder);
}
public override int GetHashCode()
{
// this is what lambdas do (do not use hashes of other fields)
......
......@@ -334,7 +334,7 @@ protected virtual void LazyAsyncMethodChecks(CancellationToken cancellationToken
state.NotePartComplete(CompletionPart.FinishAsyncMethodChecks);
}
public override Symbol ContainingSymbol
public sealed override Symbol ContainingSymbol
{
get
{
......
......@@ -159,34 +159,32 @@ public void InstanceClosure()
class Program
{
int x;
int w;
void A(int y)
int A(int y)
{
void Local()
{
A(x + y);
}
if (y != 0)
{
Console.WriteLine(y);
}
else
int x = 1;
int Local1(int z)
{
Local();
int Local2()
{
return Local1(x + y + w);
}
return z != -1 ? z : Local2();
}
return Local1(-1);
}
static void Main(string[] args)
{
var prog = new Program();
prog.x = 2;
prog.A(0);
prog.w = 3;
Console.WriteLine(prog.A(2));
}
}
";
var comp = CompileAndVerify(source, expectedOutput: @"
2
6
");
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册