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)); }
///////////////////////////////////////////////////////////////////////////////// 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(); }
// // 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); }
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); }