提交 a13c0278 编写于 作者: C ChuckStoner

Added virtual members to Binder to reduce dependencies on containing...

Added virtual members to Binder to reduce dependencies on containing type/member when binding "this" and "base"
(new members: ThisType, IsScriptClass, and IsInstanceMemberContext) and changed LookupSymbolsInSingleBinder from protected to internal. (changeset 1306929)
上级 3b93f44b
......@@ -94,7 +94,7 @@ private BoundExpression SelectField(SimpleNameSyntax node, BoundExpression recei
return result;
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & LookupOptions.NamespaceAliasesOnly) != 0) return;
......
......@@ -268,6 +268,21 @@ internal NamedTypeSymbol ContainingType
}
}
internal virtual bool IsInstanceMemberContext(out SymbolKind kind)
{
return this.next.IsInstanceMemberContext(out kind);
}
internal virtual bool IsScriptClass
{
get { return this.next.IsScriptClass; }
}
internal virtual NamedTypeSymbol ThisType
{
get { return this.next.ThisType; }
}
internal ParameterSymbol ThisParameter
{
get { return this.ContainingMemberOrLambda.EnclosingThisSymbol(); }
......
......@@ -140,22 +140,23 @@ private BoundExpression BindAnonymousObjectCreation(AnonymousObjectCreationExpre
/// </summary>
private bool IsAnonymousTypesAllowed()
{
if ((object)this.ContainingMemberOrLambda == null)
var member = this.ContainingMemberOrLambda;
if ((object)member == null)
{
return false;
}
switch (this.ContainingMemberOrLambda.Kind)
switch (member.Kind)
{
case SymbolKind.Method:
return true;
case SymbolKind.Field:
return !((FieldSymbol)this.ContainingMemberOrLambda).IsConst;
return !((FieldSymbol)member).IsConst;
case SymbolKind.NamedType:
// allow usage of anonymous types in script classes
return ((NamedTypeSymbol)this.ContainingMemberOrLambda).IsScriptClass;
return this.IsScriptClass;
}
return false;
......
......@@ -465,7 +465,7 @@ private bool MemberGroupFinalValidationAccessibilityChecks(BoundExpression recei
}
else if (WasImplicitReceiver(receiverOpt))
{
if (InFieldInitializer && !ContainingType.IsScriptClass || InConstructorInitializer || InAttributeArgument)
if (InFieldInitializer && !IsScriptClass || InConstructorInitializer || InAttributeArgument)
{
CSharpSyntaxNode errorNode = node;
if (node.Parent != null && node.Parent.Kind == SyntaxKind.InvocationExpression)
......@@ -480,7 +480,8 @@ private bool MemberGroupFinalValidationAccessibilityChecks(BoundExpression recei
// If we could access the member thru implicit "this" the receiver would be a BoundThisReference.
// If it is null it means that the instance member is inaccessible.
if (receiverOpt == null || ContainingMember().IsStatic)
SymbolKind kind;
if (receiverOpt == null || !this.IsInstanceMemberContext(out kind))
{
Error(diagnostics, ErrorCode.ERR_ObjectRequired, node, memberSymbol);
return true;
......
......@@ -26,10 +26,10 @@ internal partial class Binder
/// <returns>True if a reference to "this" is available.</returns>
private bool HasThis(bool isExplicit, out bool inStaticContext)
{
var member = this.ContainingMemberOrLambda.ContainingNonLambdaMember();
if (member.IsStatic)
SymbolKind kind;
if (!this.IsInstanceMemberContext(out kind))
{
inStaticContext = member.Kind == SymbolKind.Field || member.Kind == SymbolKind.Method || member.Kind == SymbolKind.Property;
inStaticContext = (kind == SymbolKind.Field) || (kind == SymbolKind.Method) || (kind == SymbolKind.Property);
return false;
}
......@@ -40,8 +40,7 @@ private bool HasThis(bool isExplicit, out bool inStaticContext)
return false;
}
var containingType = member.ContainingType;
bool inTopLevelScriptMember = (object)containingType != null && containingType.IsScriptClass;
bool inTopLevelScriptMember = this.IsScriptClass;
// "this" is not allowed in field initializers (that are not script variable initializers):
if (InFieldInitializer && !inTopLevelScriptMember)
......@@ -1241,17 +1240,17 @@ private BoundExpression SynthesizeMethodGroupReceiver(CSharpSyntaxNode syntax, A
// base type of the current type, then there should be a "this" associated with the
// method group. Otherwise, it should be null.
var currentType = this.ContainingType;
var thisType = this.ThisType;
var declaringType = members[0].ContainingType;
var instanceType = (NamedTypeSymbol)declaringType.OriginalDefinition;
if (SynthesizeMethodGroupReceiverIsInstanceTypeOrAnyBaseInstanceType(instanceType, currentType))
if (SynthesizeMethodGroupReceiverIsInstanceTypeOrAnyBaseInstanceType(instanceType, thisType))
{
return ThisReference(syntax, wasCompilerGenerated: true);
return ThisReference(syntax, thisType, wasCompilerGenerated: true);
}
else
{
return TryBindInteractiveReceiver(syntax, this.ContainingMemberOrLambda, currentType, declaringType);
return TryBindInteractiveReceiver(syntax, this.ContainingMemberOrLambda, thisType, declaringType);
}
}
......@@ -1578,13 +1577,13 @@ private BoundExpression SynthesizeReceiver(SimpleNameSyntax node, Symbol member,
return null;
}
var currentType = this.ContainingType;
var thisType = this.ThisType;
HashSet<DiagnosticInfo> useSiteDiagnostics = null;
if (currentType.IsEqualToOrDerivedFrom(member.ContainingType, ignoreDynamic: false, useSiteDiagnostics: ref useSiteDiagnostics))
if (thisType.IsEqualToOrDerivedFrom(member.ContainingType, ignoreDynamic: false, useSiteDiagnostics: ref useSiteDiagnostics))
{
bool hasErrors = false;
if (InFieldInitializer && !currentType.IsScriptClass)
if (InFieldInitializer && !this.IsScriptClass)
{
//can't access "this" in field initializers
Error(diagnostics, ErrorCode.ERR_FieldInitRefNonstatic, node, member);
......@@ -1599,11 +1598,8 @@ private BoundExpression SynthesizeReceiver(SimpleNameSyntax node, Symbol member,
else
{
// not an instance member if the container is a type, like when binding default parameter values.
var containingMember = ContainingMember();
bool locationIsInstanceMember = !containingMember.IsStatic &&
(containingMember.Kind != SymbolKind.NamedType || currentType.IsScriptClass);
if (!locationIsInstanceMember)
SymbolKind kind;
if (!IsInstanceMemberContext(out kind) || (kind == SymbolKind.NamedType))
{
// error CS0120: An object reference is required for the non-static field, method, or property '{0}'
Error(diagnostics, ErrorCode.ERR_ObjectRequired, node, member);
......@@ -1612,11 +1608,11 @@ private BoundExpression SynthesizeReceiver(SimpleNameSyntax node, Symbol member,
}
hasErrors = hasErrors || IsRefOrOutThisParameterCaptured(node, diagnostics);
return ThisReference(node, hasErrors, wasCompilerGenerated: true);
return ThisReference(node, thisType, hasErrors, wasCompilerGenerated: true);
}
else
{
return TryBindInteractiveReceiver(node, this.ContainingMemberOrLambda, currentType, member.ContainingType);
return TryBindInteractiveReceiver(node, this.ContainingMemberOrLambda, thisType, member.ContainingType);
}
}
......@@ -1763,12 +1759,13 @@ private BoundThisReference BindThis(ThisExpressionSyntax node, DiagnosticBag dia
hasErrors = IsRefOrOutThisParameterCaptured(node, diagnostics);
}
return ThisReference(node, hasErrors);
var thisType = this.ThisType;
return ThisReference(node, thisType, hasErrors);
}
private BoundThisReference ThisReference(CSharpSyntaxNode node, bool hasErrors = false, bool wasCompilerGenerated = false)
private BoundThisReference ThisReference(CSharpSyntaxNode node, NamedTypeSymbol thisTypeOpt, bool hasErrors = false, bool wasCompilerGenerated = false)
{
return new BoundThisReference(node, this.ContainingType ?? CreateErrorType(), hasErrors) { WasCompilerGenerated = wasCompilerGenerated };
return new BoundThisReference(node, thisTypeOpt ?? CreateErrorType(), hasErrors) { WasCompilerGenerated = wasCompilerGenerated };
}
private bool IsRefOrOutThisParameterCaptured(CSharpSyntaxNode node, DiagnosticBag diagnostics)
......@@ -1787,7 +1784,8 @@ private bool IsRefOrOutThisParameterCaptured(CSharpSyntaxNode node, DiagnosticBa
private BoundBaseReference BindBase(BaseExpressionSyntax node, DiagnosticBag diagnostics)
{
NamedTypeSymbol baseType = (object)this.ContainingType == null ? null : this.ContainingType.BaseTypeNoUseSiteDiagnostics;
var thisType = this.ThisType;
var baseType = (object)thisType == null ? null : thisType.BaseTypeNoUseSiteDiagnostics;
bool hasErrors = true;
bool inStaticContext;
......@@ -3975,7 +3973,7 @@ private static bool IsNegativeConstantForArraySize(BoundExpression expression)
errorLocation = constructor.Locations[0];
}
BoundExpression receiver = new BoundThisReference(nonNullSyntax, initializerType) { WasCompilerGenerated = true };
BoundExpression receiver = ThisReference(nonNullSyntax, initializerType, wasCompilerGenerated: true);
if (initializerType.IsErrorType())
{
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Symbols;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -30,6 +31,17 @@ internal override Symbol ContainingMemberOrLambda
{
get { return this.containingMemberOrLambda; }
}
internal override bool IsInstanceMemberContext(out SymbolKind kind)
{
kind = this.containingMemberOrLambda.Kind;
// Skip lambdas.
if ((kind == SymbolKind.Method) && ((MethodSymbol)this.containingMemberOrLambda).MethodKind == MethodKind.LambdaMethod)
{
return base.IsInstanceMemberContext(out kind);
}
return !this.containingMemberOrLambda.IsStatic;
}
}
/// <summary>
......
......@@ -268,7 +268,7 @@ private static ImmutableArray<LocalSymbol> GetInitializationScopeLocals(ArrayBui
}
Binder scriptClassBinder = binderFactory.GetBinder(initializerNode);
Debug.Assert(((ImplicitNamedTypeSymbol)scriptClassBinder.ContainingMemberOrLambda).IsScriptClass);
Debug.Assert(scriptClassBinder.IsScriptClass);
if (generateDebugInfo && firstDebugImports == null)
{
......
......@@ -91,7 +91,7 @@ private void LookupSymbolsWithFallback(LookupResult result, string name, int ari
}
}
protected virtual void LookupSymbolsInSingleBinder(
internal virtual void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
}
......
......@@ -123,6 +123,21 @@ internal override Symbol ContainingMemberOrLambda
}
}
internal override NamedTypeSymbol ThisType
{
get { return null; }
}
internal override bool IsScriptClass
{
get { return false; }
}
internal override bool IsInstanceMemberContext(out SymbolKind kind)
{
throw ExceptionUtilities.Unreachable;
}
internal override Binder GetBinder(CSharpSyntaxNode node)
{
return null;
......
......@@ -45,6 +45,17 @@ internal override Binder GetBinder(CSharpSyntaxNode node)
return this.BinderMap.TryGetValue(node, out binder) ? binder : Next.GetBinder(node);
}
internal override bool IsInstanceMemberContext(out SymbolKind kind)
{
kind = this.memberSymbol.Kind;
// Skip lambdas.
if ((kind == SymbolKind.Method) && ((MethodSymbol)this.memberSymbol).MethodKind == MethodKind.LambdaMethod)
{
return base.IsInstanceMemberContext(out kind);
}
return !this.memberSymbol.IsStatic;
}
private SmallDictionary<CSharpSyntaxNode, Binder> BinderMap
{
get
......
......@@ -4,8 +4,6 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -27,7 +25,7 @@ private TypeSymbol GetHostObjectType()
return result;
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
var hostObjectType = GetHostObjectType();
......
......@@ -5,8 +5,6 @@
using System.Diagnostics;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -112,6 +110,26 @@ internal override Symbol ContainingMemberOrLambda
}
}
internal override bool IsInstanceMemberContext(out SymbolKind kind)
{
kind = this.container.Kind;
return !this.container.IsStatic;
}
internal override bool IsScriptClass
{
get
{
var type = this.container as NamedTypeSymbol;
return ((object)type != null) && type.IsScriptClass;
}
}
internal override NamedTypeSymbol ThisType
{
get { return this.container as NamedTypeSymbol; }
}
internal override bool IsAccessible(Symbol symbol, TypeSymbol accessThroughType, out bool failedThroughTypeCheck, ref HashSet<DiagnosticInfo> useSiteDiagnostics, ConsList<Symbol> basesBeingResolved = null)
{
var type = container as NamedTypeSymbol;
......@@ -151,7 +169,7 @@ internal override bool SupportsExtensionMethods
}
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
Debug.Assert(result.IsClear);
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -89,6 +88,12 @@ internal override Symbol ContainingMemberOrLambda
}
}
internal override bool IsInstanceMemberContext(out SymbolKind kind)
{
kind = SymbolKind.Method;
return !this.methodSymbol.IsStatic;
}
internal void MakeIterator()
{
if (this.iteratorInfo == null)
......@@ -190,7 +195,7 @@ private TypeSymbol GetIteratorElementTypeFromReturnType(TypeSymbol returnType, C
return null;
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if (parameterMap == null || (options & LookupOptions.NamespaceAliasesOnly) != 0) return;
......
......@@ -442,7 +442,7 @@ protected override SourceLocalSymbol LookupLocal(SyntaxToken nameToken)
return base.LookupLocal(nameToken);
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
Debug.Assert(options.AreValid());
......
......@@ -3,8 +3,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -38,7 +36,7 @@ protected virtual ImmutableArray<NamespaceOrTypeAndUsingDirective> GetConsolidat
throw ExceptionUtilities.Unreachable;
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & LookupOptions.NamespaceAliasesOnly) != 0)
......
......@@ -2,12 +2,11 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -75,7 +74,7 @@ internal override TypeSymbol GetIteratorElementType(YieldStatementSyntax node, D
return CreateErrorType();
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & LookupOptions.NamespaceAliasesOnly) != 0) return;
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -35,7 +33,7 @@ protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo res
}
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.MustBeInvocableIfMember)) != 0)
......
using System.Collections.Immutable;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -53,7 +52,7 @@ protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo res
}
}
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.MustBeInvocableIfMember)) != 0)
......
......@@ -3,8 +3,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -19,7 +17,7 @@ internal WithTypeParametersBinder(Binder next)
// TODO: Change this to a data structure that won't allocate enumerators
protected abstract MultiDictionary<string, TypeParameterSymbol> TypeParameterMap { get; }
protected override void LookupSymbolsInSingleBinder(
internal override void LookupSymbolsInSingleBinder(
LookupResult result, string name, int arity, ConsList<Symbol> basesBeingResolved, LookupOptions options, Binder originalBinder, bool diagnose, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
{
if ((options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.MustBeInvocableIfMember)) != 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册