GetOuterAgg() public method

public GetOuterAgg ( ) : AggregateSymbol
return AggregateSymbol
Beispiel #1
0
        public AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll)
        {
            Debug.Assert(typeArgsAll != null && typeArgsAll.Count == agg.GetTypeVarsAll().Count);

            if (typeArgsAll.Count == 0)
            {
                return(agg.getThisType());
            }

            AggregateSymbol aggOuter = agg.GetOuterAgg();

            if (aggOuter == null)
            {
                return(GetAggregate(agg, null, typeArgsAll));
            }

            int cvarOuter = aggOuter.GetTypeVarsAll().Count;

            Debug.Assert(cvarOuter <= typeArgsAll.Count);

            TypeArray     typeArgsOuter = _BSymmgr.AllocParams(cvarOuter, typeArgsAll, 0);
            TypeArray     typeArgsInner = _BSymmgr.AllocParams(agg.GetTypeVars().Count, typeArgsAll, cvarOuter);
            AggregateType atsOuter      = GetAggregate(aggOuter, typeArgsOuter);

            return(GetAggregate(agg, atsOuter, typeArgsInner));
        }
Beispiel #2
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeArray GetAggregateTypeParameters(Type type, AggregateSymbol agg)
        {
            if (type.GetTypeInfo().IsGenericType)
            {
                Type genericDefinition = type.GetTypeInfo().GetGenericTypeDefinition();
                Type[] genericArguments = genericDefinition.GetGenericArguments();
                List<CType> ctypes = new List<CType>();
                int outerParameters = agg.isNested() ? agg.GetOuterAgg().GetTypeVarsAll().size : 0;

                for (int i = 0; i < genericArguments.Length; i++)
                {
                    // Suppose we have the following:
                    //
                    // class A<A1, A2, ..., An> 
                    // {
                    //     class B<B1, B2, ..., Bm>
                    //     {
                    //     }
                    // }
                    //
                    // B will have m+n generic arguments - { A1, A2, ..., An, B1, B2, ..., Bn }.
                    // As we enumerate these, we need to skip type parameters whose GenericParameterPosition
                    // is less than n, since the first n type parameters are { A1, A2, ..., An }. 

                    Type t = genericArguments[i];

                    if (t.GenericParameterPosition < outerParameters)
                    {
                        continue;
                    }

                    CType ctype = null;
                    if (t.IsGenericParameter && t.DeclaringType == genericDefinition)
                    {
                        ctype = LoadClassTypeParameter(agg, t);
                    }
                    else
                    {
                        ctype = GetCTypeFromType(t);
                    }

                    // We check to make sure we own the type parameter - this is because we're
                    // currently calculating TypeArgsThis, NOT TypeArgsAll.
                    if (ctype.AsTypeParameterType().GetOwningSymbol() == agg)
                    {
                        ctypes.Add(ctype);
                    }
                }
                return _bsymmgr.AllocParams(ctypes.Count, ctypes.ToArray());
            }
            return BSYMMGR.EmptyTypeArray();
        }
Beispiel #3
0
        //
        // SymbolLoader forwarders (end)
        /////////////////////////////////////////////////////////////////////////////////

        //
        // Utility methods
        //
        private ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
        {
            Debug.Assert(symCheck != null);
            Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
            Debug.Assert(typeThru == null ||
                         typeThru is AggregateType ||
                         typeThru is TypeParameterType ||
                         typeThru is ArrayType ||
                         typeThru is NullableType ||
                         typeThru is ErrorType);

            switch (symCheck.GetAccess())
            {
            default:
                throw Error.InternalCompilerError();
            //return ACCESSERROR.ACCESSERROR_NOACCESS;

            case ACCESS.ACC_UNKNOWN:
                return(ACCESSERROR.ACCESSERROR_NOACCESS);

            case ACCESS.ACC_PUBLIC:
                return(ACCESSERROR.ACCESSERROR_NOERROR);

            case ACCESS.ACC_PRIVATE:
            case ACCESS.ACC_PROTECTED:
                if (symWhere == null)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                break;

            case ACCESS.ACC_INTERNAL:
            case ACCESS.ACC_INTERNALPROTECTED:       // Check internal, then protected.

                if (symWhere == null)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                if (symWhere.SameAssemOrFriend(symCheck))
                {
                    return(ACCESSERROR.ACCESSERROR_NOERROR);
                }
                if (symCheck.GetAccess() == ACCESS.ACC_INTERNAL)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                break;
            }

            // Find the inner-most enclosing AggregateSymbol.
            AggregateSymbol aggWhere = null;

            for (Symbol symT = symWhere; symT != null; symT = symT.parent)
            {
                if (symT is AggregateSymbol aggSym)
                {
                    aggWhere = aggSym;
                    break;
                }
                if (symT is AggregateDeclaration aggDec)
                {
                    aggWhere = aggDec.Agg();
                    break;
                }
            }

            if (aggWhere == null)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            // Should always have atsCheck for private and protected access check.
            // We currently don't need it since access doesn't respect instantiation.
            // We just use symWhere.parent as AggregateSymbol instead.
            AggregateSymbol aggCheck = symCheck.parent as AggregateSymbol;

            // First check for private access.
            for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg())
            {
                if (agg == aggCheck)
                {
                    return(ACCESSERROR.ACCESSERROR_NOERROR);
                }
            }

            if (symCheck.GetAccess() == ACCESS.ACC_PRIVATE)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            // Handle the protected case - which is the only real complicated one.
            Debug.Assert(symCheck.GetAccess() == ACCESS.ACC_PROTECTED || symCheck.GetAccess() == ACCESS.ACC_INTERNALPROTECTED);

            // Check if symCheck is in aggWhere or a base of aggWhere,
            // or in an outer agg of aggWhere or a base of an outer agg of aggWhere.

            AggregateType atsThru = null;

            if (typeThru != null && !symCheck.isStatic)
            {
                atsThru = SymbolLoader.GetAggTypeSym(typeThru);
            }

            // Look for aggCheck among the base classes of aggWhere and outer aggs.
            bool found = false;

            for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg())
            {
                Debug.Assert(agg != aggCheck); // We checked for this above.

                // Look for aggCheck among the base classes of agg.
                if (agg.FindBaseAgg(aggCheck))
                {
                    found = true;
                    // aggCheck is a base class of agg. Check atsThru.
                    // For non-static protected access to be legal, atsThru must be an instantiation of
                    // agg or a CType derived from an instantiation of agg. In this case
                    // all that matters is that agg is in the base AggregateSymbol chain of atsThru. The
                    // actual AGGTYPESYMs involved don't matter.
                    if (atsThru == null || atsThru.getAggregate().FindBaseAgg(agg))
                    {
                        return(ACCESSERROR.ACCESSERROR_NOERROR);
                    }
                }
            }

            // the CType in which the method is being called has no relationship with the
            // CType on which the method is defined surely this is NOACCESS and not NOACCESSTHRU
            if (found == false)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            return((atsThru == null) ? ACCESSERROR.ACCESSERROR_NOACCESS : ACCESSERROR.ACCESSERROR_NOACCESSTHRU);
        }
Beispiel #4
0
        public AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll)
        {
            Debug.Assert(typeArgsAll != null && typeArgsAll.Size == agg.GetTypeVarsAll().Size);

            if (typeArgsAll.size == 0)
                return agg.getThisType();

            AggregateSymbol aggOuter = agg.GetOuterAgg();

            if (aggOuter == null)
                return GetAggregate(agg, null, typeArgsAll);

            int cvarOuter = aggOuter.GetTypeVarsAll().Size;
            Debug.Assert(cvarOuter <= typeArgsAll.Size);

            TypeArray typeArgsOuter = _BSymmgr.AllocParams(cvarOuter, typeArgsAll, 0);
            TypeArray typeArgsInner = _BSymmgr.AllocParams(agg.GetTypeVars().Size, typeArgsAll, cvarOuter);
            AggregateType atsOuter = GetAggregate(aggOuter, typeArgsOuter);

            return GetAggregate(agg, atsOuter, typeArgsInner);
        }