public virtual ACCESSERROR CheckAccess2(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()); #if DEBUG switch (symCheck.getKind()) { default: break; case SYMKIND.SK_MethodSymbol: case SYMKIND.SK_PropertySymbol: case SYMKIND.SK_FieldSymbol: case SYMKIND.SK_EventSymbol: Debug.Assert(atsCheck != null); break; } #endif // DEBUG ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru); if (ACCESSERROR.ACCESSERROR_NOERROR != error) { return error; } // Check the accessibility of the return CType. CType CType = symCheck.getType(); if (CType == null) { return ACCESSERROR.ACCESSERROR_NOERROR; } // For members of AGGSYMs, atsCheck should always be specified! Debug.Assert(atsCheck != null); if (atsCheck.getAggregate().IsSource()) { // We already check the "at least as accessible as" rules. // Does this always work for generics? // Could we get a bad CType argument in typeThru? // Maybe call CheckTypeAccess on typeThru? return ACCESSERROR.ACCESSERROR_NOERROR; } // Substitute on the CType. if (atsCheck.GetTypeArgsAll().size > 0) { CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck); } return CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS; }
private static void InsertChildNoGrow(Symbol child) { switch (child.getKind()) { case SYMKIND.SK_Scope: case SYMKIND.SK_LocalVariableSymbol: return; } RuntimeBinder.EnsureLockIsTaken(); if (s_dictionary.TryGetValue(new Key(child.name, child.parent), out Symbol sym)) { // Link onto the end of the symbol chain here. while (sym?.nextSameName != null) { sym = sym.nextSameName; } Debug.Assert(sym != null && sym.nextSameName == null); sym.nextSameName = child; } else { s_dictionary.Add(new Key(child.name, child.parent), child); } }
private void InsertChildNoGrow(Symbol child) { switch (child.getKind()) { case SYMKIND.SK_Scope: case SYMKIND.SK_LocalVariableSymbol: return; } Key k = new Key(child.name, child.parent); Symbol sym; if (_dictionary.TryGetValue(k, out sym)) { // Link onto the end of the symbol chain here. while (sym != null && sym.nextSameName != null) { sym = sym.nextSameName; } Debug.Assert(sym != null && sym.nextSameName == null); sym.nextSameName = child; } else { _dictionary.Add(k, child); } }
public virtual ACCESSERROR CheckAccess2(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()); #if DEBUG switch (symCheck.getKind()) { default: break; case SYMKIND.SK_MethodSymbol: case SYMKIND.SK_PropertySymbol: case SYMKIND.SK_FieldSymbol: case SYMKIND.SK_EventSymbol: Debug.Assert(atsCheck != null); break; } #endif // DEBUG ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru); if (ACCESSERROR.ACCESSERROR_NOERROR != error) { return(error); } // Check the accessibility of the return CType. CType CType = symCheck.getType(); if (CType == null) { return(ACCESSERROR.ACCESSERROR_NOERROR); } // For members of AGGSYMs, atsCheck should always be specified! Debug.Assert(atsCheck != null); if (atsCheck.getAggregate().IsSource()) { // We already check the "at least as accessible as" rules. // Does this always work for generics? // Could we get a bad CType argument in typeThru? // Maybe call CheckTypeAccess on typeThru? return(ACCESSERROR.ACCESSERROR_NOERROR); } // Substitute on the CType. if (atsCheck.GetTypeArgsAll().size > 0) { CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck); } return(CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS); }
public virtual ACCESSERROR CheckAccess2(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); #if DEBUG switch (symCheck.getKind()) { case SYMKIND.SK_MethodSymbol: case SYMKIND.SK_PropertySymbol: case SYMKIND.SK_FieldSymbol: case SYMKIND.SK_EventSymbol: Debug.Assert(atsCheck != null); break; } #endif // DEBUG ACCESSERROR error = CheckAccessCore(symCheck, atsCheck, symWhere, typeThru); if (ACCESSERROR.ACCESSERROR_NOERROR != error) { return(error); } // Check the accessibility of the return CType. CType CType = symCheck.getType(); if (CType == null) { return(ACCESSERROR.ACCESSERROR_NOERROR); } // For members of AGGSYMs, atsCheck should always be specified! Debug.Assert(atsCheck != null); // Substitute on the CType. if (atsCheck.GetTypeArgsAll().Count > 0) { CType = SymbolLoader.GetTypeManager().SubstType(CType, atsCheck); } return(CheckTypeAccess(CType, symWhere) ? ACCESSERROR.ACCESSERROR_NOERROR : ACCESSERROR.ACCESSERROR_NOACCESS); }
/****************************************************************************** * Search just the given type (not any bases). Returns true iff it finds * something (which will have been recorded by RecordType). * * pfHideByName is set to true iff something was found that hides all * members of base types (eg, a hidebyname method). ******************************************************************************/ private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName) { bool fFoundSome = false; MethPropWithType mwpInsert; pfHideByName = false; // Make sure this type is accessible. It may not be due to private inheritance // or friend assemblies. bool fInaccess = !GetSemanticChecker().CheckTypeAccess(typeCur, _symWhere); if (fInaccess && (_csym != 0 || _swtInaccess != null)) { return(false); } // Loop through symbols. Symbol symCur = null; for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.getAggregate(), symbmask_t.MASK_ALL); symCur != null; symCur = GetSymbolLoader().LookupNextSym(symCur, typeCur.getAggregate(), symbmask_t.MASK_ALL)) { // Check for arity. switch (symCur.getKind()) { case SYMKIND.SK_MethodSymbol: // For non-zero arity, only methods of the correct arity are considered. // For zero arity, don't filter out any methods since we do type argument // inferencing. if (_arity > 0 && symCur.AsMethodSymbol().typeVars.size != _arity) { if (!_swtBadArity) { _swtBadArity.Set(symCur, typeCur); } continue; } break; case SYMKIND.SK_AggregateSymbol: // For types, always filter on arity. if (symCur.AsAggregateSymbol().GetTypeVars().size != _arity) { if (!_swtBadArity) { _swtBadArity.Set(symCur, typeCur); } continue; } break; case SYMKIND.SK_TypeParameterSymbol: if ((_flags & MemLookFlags.TypeVarsAllowed) == 0) { continue; } if (_arity > 0) { if (!_swtBadArity) { _swtBadArity.Set(symCur, typeCur); } continue; } break; default: // All others are only considered when arity is zero. if (_arity > 0) { if (!_swtBadArity) { _swtBadArity.Set(symCur, typeCur); } continue; } break; } // Check for user callability. if (symCur.IsOverride() && !symCur.IsHideByName()) { if (!_swtOverride) { _swtOverride.Set(symCur, typeCur); } continue; } if ((_flags & MemLookFlags.UserCallable) != 0 && symCur.IsMethodOrPropertySymbol() && !symCur.AsMethodOrPropertySymbol().isUserCallable()) { bool bIsIndexedProperty = false; // If its an indexed property method symbol, let it through. if (symCur.IsMethodSymbol() && symCur.AsMethodSymbol().isPropertyAccessor() && ((symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 1) || (symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 0))) { bIsIndexedProperty = true; } if (!bIsIndexedProperty) { if (!_swtInaccess) { _swtInaccess.Set(symCur, typeCur); } continue; } } if (fInaccess || !GetSemanticChecker().CheckAccess(symCur, typeCur, _symWhere, _typeQual)) { // Not accessible so get the next sym. if (!_swtInaccess) { _swtInaccess.Set(symCur, typeCur); } if (fInaccess) { return(false); } continue; } // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags. if (((_flags & MemLookFlags.Ctor) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().IsConstructor()) || ((_flags & MemLookFlags.Operator) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().isOperator) || ((_flags & MemLookFlags.Indexer) == 0) != (!symCur.IsPropertySymbol() || !symCur.AsPropertySymbol().isIndexer())) { if (!_swtBad) { _swtBad.Set(symCur, typeCur); } continue; } // We can't call CheckBogus on methods or indexers because if the method has the wrong // number of parameters people don't think they should have to /r the assemblies containing // the parameter types and they complain about the resulting CS0012 errors. if (!symCur.IsMethodSymbol() && (_flags & MemLookFlags.Indexer) == 0 && GetSemanticChecker().CheckBogus(symCur)) { // A bogus member - we can't use these, so only record them for error reporting. if (!_swtBogus) { _swtBogus.Set(symCur, typeCur); } continue; } // if we are in a calling context then we should only find a property if it is delegate valued if ((_flags & MemLookFlags.MustBeInvocable) != 0) { if ((symCur.IsFieldSymbol() && !IsDelegateType(symCur.AsFieldSymbol().GetType(), typeCur) && !IsDynamicMember(symCur)) || (symCur.IsPropertySymbol() && !IsDelegateType(symCur.AsPropertySymbol().RetType, typeCur) && !IsDynamicMember(symCur))) { if (!_swtBad) { _swtBad.Set(symCur, typeCur); } continue; } } if (symCur.IsMethodOrPropertySymbol()) { mwpInsert = new MethPropWithType(symCur.AsMethodOrPropertySymbol(), typeCur); _methPropWithTypeList.Add(mwpInsert); } // We have a visible symbol. fFoundSome = true; if (_swtFirst) { if (!typeCur.isInterfaceType()) { // Non-interface case. Debug.Assert(_fMulti || typeCur == _prgtype[0]); if (!_fMulti) { if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol() #if !CSEE // The isEvent bit is only set on symbols which come from source... // This is not a problem for the compiler because the field is only // accessible in the scope in which it is declared, // but in the EE we ignore accessibility... && _swtFirst.Field().isEvent #endif ) { // m_swtFirst is just the field behind the event symCur so ignore symCur. continue; } else if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol()) { // symCur is the matching event. continue; } goto LAmbig; } if (_swtFirst.Sym.getKind() != symCur.getKind()) { if (typeCur == _prgtype[0]) { goto LAmbig; } // This one is hidden by the first one. This one also hides any more in base types. pfHideByName = true; continue; } } // Interface case. // m_fMulti : n n n y y y y y // same-kind : * * * y n n n n // fDiffHidden: * * * * y n n n // meth : * * * * * y n * can n happen? just in case, we better handle it.... // hack : n * y * * y * n // meth-2 : * n y * * * * * // res : A A S R H H A A else if (!_fMulti) { // Give method groups priority. if (/* !GetSymbolLoader().options.fLookupHack ||*/ !symCur.IsMethodSymbol()) { goto LAmbig; } _swtAmbigWarn = _swtFirst; // Erase previous results so we'll record this method as the first. _prgtype = new List <AggregateType>(); _csym = 0; _swtFirst.Clear(); _swtAmbig.Clear(); } else if (_swtFirst.Sym.getKind() != symCur.getKind()) { if (!typeCur.fDiffHidden) { // Give method groups priority. if (/*!GetSymbolLoader().options.fLookupHack ||*/ !_swtFirst.Sym.IsMethodSymbol()) { goto LAmbig; } if (!_swtAmbigWarn) { _swtAmbigWarn.Set(symCur, typeCur); } } // This one is hidden by another. This one also hides any more in base types. pfHideByName = true; continue; } } RecordType(typeCur, symCur); if (symCur.IsMethodOrPropertySymbol() && symCur.AsMethodOrPropertySymbol().isHideByName) { pfHideByName = true; } // We've found a symbol in this type but need to make sure there aren't any conflicting // syms here, so keep searching the type. } Debug.Assert(!fInaccess || !fFoundSome); return(fFoundSome); LAmbig: // Ambiguous! if (!_swtAmbig) { _swtAmbig.Set(symCur, typeCur); } pfHideByName = true; return(true); }
public ErrArgSymKind(Symbol sym) { eak = ErrArgKind.SymKind; eaf = ErrArgFlags.None; sk = sym.getKind(); if (sk == SYMKIND.SK_AssemblyQualifiedNamespaceSymbol) { if (!String.IsNullOrEmpty(sym.AsAssemblyQualifiedNamespaceSymbol().GetNS().name.Text)) { // Non-empty namespace name means it's not the root // so treat it like a namespace instead of an alias sk = SYMKIND.SK_NamespaceSymbol; } else { // An empty namespace name means it's just an alias for the root sk = SYMKIND.SK_ExternalAliasDefinitionSymbol; } } }
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; } }