// // SymbolLoader forwarders (end) ///////////////////////////////////////////////////////////////////////////////// // // Utility methods // protected 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.IsAggregateType() || typeThru.IsTypeParameterType() || typeThru.IsArrayType() || typeThru.IsNullableType() || typeThru.IsErrorType()); 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; } // 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.AsAggregateSymbol() instead. AggregateSymbol aggCheck = symCheck.parent.AsAggregateSymbol(); // Find the inner-most enclosing AggregateSymbol. AggregateSymbol aggWhere = null; for (Symbol symT = symWhere; symT != null; symT = symT.parent) { if (symT.IsAggregateSymbol()) { aggWhere = symT.AsAggregateSymbol(); break; } if (symT.IsAggregateDeclaration()) { aggWhere = symT.AsAggregateDeclaration().Agg(); break; } } if (aggWhere == null) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } // 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 whice 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 void ErrAppendSym(Symbol sym, SubstContext pctx, bool fArgs) { switch (sym.getKind()) { case SYMKIND.SK_NamespaceDeclaration: // for namespace declarations just convert the namespace ErrAppendSym(sym.AsNamespaceDeclaration().NameSpace(), null); break; case SYMKIND.SK_GlobalAttributeDeclaration: ErrAppendName(sym.name); break; case SYMKIND.SK_AggregateDeclaration: ErrAppendSym(sym.AsAggregateDeclaration().Agg(), pctx); break; case SYMKIND.SK_AggregateSymbol: { // Check for a predefined class with a special "nice" name for // error reported. string text = PredefinedTypes.GetNiceName(sym.AsAggregateSymbol()); if (text != null) { // Found a nice name. ErrAppendString(text); } else if (sym.AsAggregateSymbol().IsAnonymousType()) { ErrAppendId(MessageID.AnonymousType); break; } else { ErrAppendParentSym(sym, pctx); ErrAppendName(sym.name); ErrAppendTypeParameters(sym.AsAggregateSymbol().GetTypeVars(), pctx, true); } break; } case SYMKIND.SK_MethodSymbol: ErrAppendMethod(sym.AsMethodSymbol(), pctx, fArgs); break; case SYMKIND.SK_PropertySymbol: ErrAppendProperty(sym.AsPropertySymbol(), pctx); break; case SYMKIND.SK_EventSymbol: ErrAppendEvent(sym.AsEventSymbol(), pctx); break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: case SYMKIND.SK_NamespaceSymbol: if (sym == getBSymmgr().GetRootNS()) { ErrAppendId(MessageID.GlobalNamespace); } else { ErrAppendParentSym(sym, null); ErrAppendName(sym.name); } break; case SYMKIND.SK_FieldSymbol: ErrAppendParentSym(sym, pctx); ErrAppendName(sym.name); break; case SYMKIND.SK_TypeParameterSymbol: if (null == sym.name) { // It's a standard type variable. if (sym.AsTypeParameterSymbol().IsMethodTypeParameter()) ErrAppendChar('!'); ErrAppendChar('!'); ErrAppendPrintf("{0}", sym.AsTypeParameterSymbol().GetIndexInTotalParameters()); } else ErrAppendName(sym.name); break; case SYMKIND.SK_LocalVariableSymbol: case SYMKIND.SK_LabelSymbol: case SYMKIND.SK_TransparentIdentifierMemberSymbol: // Generate symbol name. ErrAppendName(sym.name); break; case SYMKIND.SK_Scope: case SYMKIND.SK_LambdaScope: default: // Shouldn't happen. Debug.Assert(false, "Bad symbol kind"); break; } }