protected int MakeMemberSlot(BoundExpression receiverOpt, Symbol member) { int containingSlot = -1; if (member.RequiresInstanceReceiver()) { if (receiverOpt is null) { return(-1); } containingSlot = MakeSlot(receiverOpt); if (containingSlot < 0) { return(-1); } } return(GetOrCreateSlot(member, containingSlot)); }
/// <summary> /// Checks if 'symbol' is accessible from within 'within', which must be a NamedTypeSymbol /// or an AssemblySymbol. /// </summary> /// <remarks> /// Note that NamedTypeSymbol, if available, is the type that is associated with the binder /// that found the 'symbol', not the inner-most type that contains the access to the /// 'symbol'. /// <para> /// If 'symbol' is accessed off of an expression then 'throughTypeOpt' is the type of that /// expression. This is needed to properly do protected access checks. Sets /// "failedThroughTypeCheck" to true if this protected check failed. /// </para> /// <para> /// This function is expected to be called a lot. As such, it avoids memory /// allocations in the function itself (including not making any iterators). This means /// that certain helper functions that could otherwise be called are inlined in this method to /// prevent the overhead of returning collections or enumerators. /// </para> /// </remarks> private static bool IsSymbolAccessibleCore( Symbol symbol, Symbol within, // must be assembly or named type symbol TypeSymbol throughTypeOpt, out bool failedThroughTypeCheck, CSharpCompilation compilation, ref HashSet <DiagnosticInfo> useSiteDiagnostics, ConsList <TypeSymbol> basesBeingResolved = null) { Debug.Assert((object)symbol != null); Debug.Assert((object)within != null); Debug.Assert(within.IsDefinition); Debug.Assert(within is NamedTypeSymbol || within is AssemblySymbol); failedThroughTypeCheck = false; switch (symbol.Kind) { case SymbolKind.ArrayType: return(IsSymbolAccessibleCore(((ArrayTypeSymbol)symbol).ElementType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.PointerType: return(IsSymbolAccessibleCore(((PointerTypeSymbol)symbol).PointedAtType, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.NamedType: return(IsNamedTypeAccessible((NamedTypeSymbol)symbol, within, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.Alias: return(IsSymbolAccessibleCore(((AliasSymbol)symbol).Target, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.Discard: return(IsSymbolAccessibleCore(((DiscardSymbol)symbol).TypeWithAnnotations.Type, within, null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)); case SymbolKind.FunctionPointer: var funcPtr = (FunctionPointerTypeSymbol)symbol; if (!IsSymbolAccessibleCore(funcPtr.Signature.ReturnType, within, throughTypeOpt: null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)) { return(false); } foreach (var param in funcPtr.Signature.Parameters) { if (!IsSymbolAccessibleCore(param.Type, within, throughTypeOpt: null, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics, basesBeingResolved)) { return(false); } } return(true); case SymbolKind.ErrorType: // Always assume that error types are accessible. return(true); case SymbolKind.TypeParameter: case SymbolKind.Parameter: case SymbolKind.Local: case SymbolKind.Label: case SymbolKind.Namespace: case SymbolKind.DynamicType: case SymbolKind.Assembly: case SymbolKind.NetModule: case SymbolKind.RangeVariable: case SymbolKind.Method when((MethodSymbol)symbol).MethodKind == MethodKind.LocalFunction: // These types of symbols are always accessible (if visible). return(true); case SymbolKind.Method: case SymbolKind.Property: case SymbolKind.Event: case SymbolKind.Field: if (!symbol.RequiresInstanceReceiver()) { // static members aren't accessed "through" an "instance" of any type. So we // null out the "through" instance here. This ensures that we'll understand // accessing protected statics properly. throughTypeOpt = null; } return(IsMemberAccessible(symbol.ContainingType, symbol.DeclaredAccessibility, within, throughTypeOpt, out failedThroughTypeCheck, compilation, ref useSiteDiagnostics)); default: throw ExceptionUtilities.UnexpectedValue(symbol.Kind); } }