示例#1
0
        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));
        }
示例#2
0
        /// <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);
            }
        }