public CMethodIterator(CSemanticChecker checker, SymbolLoader symLoader, Name name, TypeArray containingTypes, CType @object, CType qualifyingType, AggregateDeclaration context, bool allowBogusAndInaccessible, bool allowExtensionMethods, int arity, EXPRFLAG flags, symbmask_t mask) { Debug.Assert(name != null); Debug.Assert(symLoader != null); Debug.Assert(checker != null); Debug.Assert(containingTypes != null); _pSemanticChecker = checker; _pSymbolLoader = symLoader; _pCurrentType = null; _pCurrentSym = null; _pName = name; _pContainingTypes = containingTypes; _pQualifyingType = qualifyingType; _pContext = context; _bAllowBogusAndInaccessible = allowBogusAndInaccessible; _nArity = arity; _flags = flags; _mask = mask; _nCurrentTypeCount = 0; _bIsCheckingInstanceMethods = true; _bAtEnd = false; _bCurrentSymIsBogus = false; _bCurrentSymIsInaccessible = false; _bcanIncludeExtensionsInResults = allowExtensionMethods; _bEndIterationAtCurrentExtensionList = false; }
// ---------------------------------------------------------------------------- // NamespaceOrAggregateSymbol // ---------------------------------------------------------------------------- // Compare to ParentSymbol::AddToChildList public void AddDecl(AggregateDeclaration decl) { Debug.Assert(decl != null); Debug.Assert(IsNamespaceSymbol() || IsAggregateSymbol()); Debug.Assert(decl.IsAggregateDeclaration()); Debug.Assert(!IsNamespaceSymbol()); // If parent is set it should be set to us! Debug.Assert(decl.bag == null || decl.bag == this); // There shouldn't be a declNext. Debug.Assert(decl.declNext == null); if (_declLast == null) { Debug.Assert(_declFirst == null); _declFirst = _declLast = decl; } else { _declLast.declNext = decl; _declLast = decl; #if DEBUG // Validate our chain. AggregateDeclaration pdecl; for (pdecl = _declFirst; pdecl?.declNext != null; pdecl = pdecl.declNext) { } Debug.Assert(pdecl == null || (pdecl == _declLast && pdecl.declNext == null)); #endif } decl.declNext = null; decl.bag = this; }
public PropertySymbol CreateProperty(Name name, ParentSymbol parent, AggregateDeclaration declaration) { PropertySymbol sym = newBasicSym(SYMKIND.SK_PropertySymbol, name, parent).AsPropertySymbol(); sym.declaration = declaration; Debug.Assert(sym != null); return(sym); }
public MethodSymbol CreateMethod(Name name, ParentSymbol parent, AggregateDeclaration declaration) { MethodSymbol sym = newBasicSym(SYMKIND.SK_MethodSymbol, name, parent).AsMethodSymbol(); sym.declaration = declaration; return(sym); }
public IndexerSymbol CreateIndexer(Name name, ParentSymbol parent, Name realName, AggregateDeclaration declaration) { IndexerSymbol sym = (IndexerSymbol)newBasicSym(SYMKIND.SK_IndexerSymbol, name, parent); sym.setKind(SYMKIND.SK_PropertySymbol); sym.isOperator = true; sym.declaration = declaration; Debug.Assert(sym != null); return sym; }
// Members of aggs public FieldSymbol CreateMemberVar(Name name, ParentSymbol parent, AggregateDeclaration declaration, int iIteratorLocal) { Debug.Assert(name != null); FieldSymbol sym = newBasicSym(SYMKIND.SK_FieldSymbol, name, parent).AsFieldSymbol(); sym.declaration = declaration; Debug.Assert(sym != null); return(sym); }
public AggregateDeclaration CreateAggregateDecl(AggregateSymbol agg, AggregateDeclaration declOuter) { Debug.Assert(agg != null); //Debug.Assert(declOuter == null || declOuter.Bag() == agg.Parent); // DECLSYMs are not parented like named symbols. AggregateDeclaration sym = newBasicSym(SYMKIND.SK_AggregateDeclaration, agg.name, null) as AggregateDeclaration; declOuter?.AddToChildList(sym); agg.AddDecl(sym); Debug.Assert(sym != null); return(sym); }
public CMethodIterator(CSemanticChecker checker, SymbolLoader symLoader, Name name, TypeArray containingTypes, CType qualifyingType, AggregateDeclaration context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) { Debug.Assert(name != null); Debug.Assert(symLoader != null); Debug.Assert(checker != null); Debug.Assert(containingTypes != null); Debug.Assert(containingTypes.Count != 0); _semanticChecker = checker; _symbolLoader = symLoader; _name = name; _containingTypes = containingTypes; _qualifyingType = qualifyingType; _context = context; _arity = arity; _flags = flags; _mask = mask; _nonTrailingNamedArguments = nonTrailingNamedArguments; }
public EventSymbol CreateEvent(Name name, ParentSymbol parent, AggregateDeclaration declaration) { EventSymbol sym = newBasicSym(SYMKIND.SK_EventSymbol, name, parent).AsEventSymbol(); sym.declaration = declaration; Debug.Assert(sym != null); return (sym); }
public MethodSymbol CreateMethod(Name name, ParentSymbol parent, AggregateDeclaration declaration) { MethodSymbol sym = newBasicSym(SYMKIND.SK_MethodSymbol, name, parent).AsMethodSymbol(); sym.declaration = declaration; return sym; }
// Members of aggs public FieldSymbol CreateMemberVar(Name name, ParentSymbol parent, AggregateDeclaration declaration, int iIteratorLocal) { Debug.Assert(name != null); FieldSymbol sym = newBasicSym(SYMKIND.SK_FieldSymbol, name, parent).AsFieldSymbol(); sym.declaration = declaration; Debug.Assert(sym != null); return (sym); }
private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, AggregateType typeSrc, out CType typeDst) { Debug.Assert(typeSrc != null); Debug.Assert(typeSrc.IsInterfaceType || typeSrc.IsDelegateType); typeDst = null; AggregateSymbol aggSym = typeSrc.OwningAggregate; AggregateType aggOpenType = aggSym.getThisType(); if (!semanticChecker.CheckTypeAccess(aggOpenType, context)) { // if the aggregate symbol itself is not accessible, then forget it, there is no // variance that will help us arrive at an accessible type. return(false); } TypeArray typeArgs = typeSrc.TypeArgsThis; TypeArray typeParams = aggOpenType.TypeArgsThis; CType[] newTypeArgsTemp = new CType[typeArgs.Count]; for (int i = 0; i < newTypeArgsTemp.Length; i++) { CType typeArg = typeArgs[i]; if (semanticChecker.CheckTypeAccess(typeArg, context)) { // we have an accessible argument, this position is not a problem. newTypeArgsTemp[i] = typeArg; continue; } if (!typeArg.IsReferenceType || !((TypeParameterType)typeParams[i]).Covariant) { // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail. return(false); } newTypeArgsTemp[i] = GetBestAccessibleType(semanticChecker, context, typeArg); // now we either have a value type (which must be accessible due to the above // check, OR we have an inaccessible type (which must be a ref type). In either // case, the recursion worked out and we are OK to vary this argument. } TypeArray newTypeArgs = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp); CType intermediateType = GetAggregate(aggSym, typeSrc.OuterType, newTypeArgs); // All type arguments were varied successfully, which means now we must be accessible. But we could // have violated constraints. Let's check that out. if (!TypeBind.CheckConstraints(semanticChecker, errHandling: null, intermediateType, CheckConstraintsFlags.NoErrors)) { return(false); } typeDst = intermediateType; Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); return(true); }
private Symbol NewBasicSymbol( SYMKIND kind, Name name, ParentSymbol parent) { Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); _symbolTable.InsertChild(parent, sym); } return(sym); }
public CMethodIterator GetMethodIterator( CSemanticChecker pChecker, SymbolLoader pSymLoader, CType pObject, CType pQualifyingType, AggregateDeclaration pContext, bool allowBogusAndInaccessible, bool allowExtensionMethods, int arity, EXPRFLAG flags, symbmask_t mask) { Debug.Assert(pSymLoader != null); CMethodIterator iterator = new CMethodIterator(pChecker, pSymLoader, _pName, ContainingTypes, pObject, pQualifyingType, pContext, allowBogusAndInaccessible, allowExtensionMethods, arity, flags, mask); return(iterator); }
protected Symbol newBasicSym( SYMKIND kind, Name name, ParentSymbol parent) { // The parser creates names with PN_MISSING when attempting to recover from errors // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM) // so that they are never found when doing lookup. if (name == m_pMissingNameNode) { name = m_pMissingNameSym; } Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_NamespaceDeclaration: sym = new NamespaceDeclaration(); sym.name = name; break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: sym = new AssemblyQualifiedNamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_TransparentIdentifierMemberSymbol: sym = new TransparentIdentifierMemberSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_LabelSymbol: sym = new LabelSymbol(); sym.name = name; break; case SYMKIND.SK_GlobalAttributeDeclaration: sym = new GlobalAttributeDeclaration(); sym.name = name; break; case SYMKIND.SK_UnresolvedAggregateSymbol: sym = new UnresolvedAggregateSymbol(); sym.name = name; break; case SYMKIND.SK_InterfaceImplementationMethodSymbol: sym = new InterfaceImplementationMethodSymbol(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; case SYMKIND.SK_ParentSymbol: sym = new ParentSymbol(); sym.name = name; break; case SYMKIND.SK_IteratorFinallyMethodSymbol: sym = new IteratorFinallyMethodSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); m_pSymTable.InsertChild(parent, sym); } return (sym); }
protected Symbol newBasicSym( SYMKIND kind, Name name, ParentSymbol parent) { // The parser creates names with PN_MISSING when attempting to recover from errors // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM) // so that they are never found when doing lookup. if (name == m_pMissingNameNode) { name = m_pMissingNameSym; } Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_NamespaceDeclaration: sym = new NamespaceDeclaration(); sym.name = name; break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: sym = new AssemblyQualifiedNamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_TransparentIdentifierMemberSymbol: sym = new TransparentIdentifierMemberSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_LabelSymbol: sym = new LabelSymbol(); sym.name = name; break; case SYMKIND.SK_GlobalAttributeDeclaration: sym = new GlobalAttributeDeclaration(); sym.name = name; break; case SYMKIND.SK_UnresolvedAggregateSymbol: sym = new UnresolvedAggregateSymbol(); sym.name = name; break; case SYMKIND.SK_InterfaceImplementationMethodSymbol: sym = new InterfaceImplementationMethodSymbol(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; case SYMKIND.SK_ParentSymbol: sym = new ParentSymbol(); sym.name = name; break; case SYMKIND.SK_IteratorFinallyMethodSymbol: sym = new IteratorFinallyMethodSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); m_pSymTable.InsertChild(parent, sym); } return(sym); }
public PropertySymbol CreateProperty(Name name, ParentSymbol parent, AggregateDeclaration declaration) { PropertySymbol sym = newBasicSym(SYMKIND.SK_PropertySymbol, name, parent).AsPropertySymbol(); Debug.Assert(sym != null); sym.declaration = declaration; return (sym); }
private bool TryArrayVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, ArrayType typeSrc, out CType typeDst) { Debug.Assert(typeSrc != null); // We are here because we have an array type with an inaccessible element type. If possible, // we should create a new array type that has an accessible element type for which a // conversion exists. CType elementType = typeSrc.ElementType; // Covariant array conversions exist for reference types only. if (elementType.IsReferenceType) { CType destElement = GetBestAccessibleType(semanticChecker, context, elementType); typeDst = GetArray(destElement, typeSrc.Rank, typeSrc.IsSZArray); Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); return(true); } typeDst = null; return(false); }
public IndexerSymbol CreateIndexer(Name name, ParentSymbol parent, Name realName, AggregateDeclaration declaration) { IndexerSymbol sym = (IndexerSymbol)newBasicSym(SYMKIND.SK_IndexerSymbol, name, parent); sym.setKind(SYMKIND.SK_PropertySymbol); sym.isOperator = true; sym.declaration = declaration; Debug.Assert(sym != null); return(sym); }
public CMethodIterator GetMethodIterator( CSemanticChecker pChecker, SymbolLoader pSymLoader, CType pQualifyingType, AggregateDeclaration pContext, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) { Debug.Assert(pSymLoader != null); CMethodIterator iterator = new CMethodIterator(pChecker, pSymLoader, _pName, ContainingTypes, pQualifyingType, pContext, arity, flags, mask, nonTrailingNamedArguments); return(iterator); }
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // RUNTIME BINDER ONLY CHANGE // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! internal CType GetBestAccessibleType(CSemanticChecker semanticChecker, AggregateDeclaration context, CType typeSrc) { // This method implements the "best accessible type" algorithm for determining the type // of untyped arguments in the runtime binder. It is also used in method type inference // to fix type arguments to types that are accessible. // The new type is returned in an out parameter. The result will be true (and the out param // non-null) only when the algorithm could find a suitable accessible type. Debug.Assert(semanticChecker != null); Debug.Assert(typeSrc != null); Debug.Assert(!(typeSrc is ParameterModifierType)); Debug.Assert(!(typeSrc is PointerType)); if (semanticChecker.CheckTypeAccess(typeSrc, context)) { // If we already have an accessible type, then use it. return(typeSrc); } // These guys have no accessibility concerns. Debug.Assert(!(typeSrc is VoidType) && !(typeSrc is TypeParameterType)); if (typeSrc is AggregateType aggSrc) { for (;;) { if ((aggSrc.IsInterfaceType || aggSrc.IsDelegateType) && TryVarianceAdjustmentToGetAccessibleType(semanticChecker, context, aggSrc, out CType typeDst)) { // If we have an interface or delegate type, then it can potentially be varied by its type arguments // to produce an accessible type, and if that's the case, then return that. // Example: IEnumerable<PrivateConcreteFoo> --> IEnumerable<PublicAbstractFoo> Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); return(typeDst); } // We have an AggregateType, so recurse on its base class. AggregateType baseType = aggSrc.BaseClass; if (baseType == null) { // This happens with interfaces, for instance. But in that case, the // conversion to object does exist, is an implicit reference conversion, // and is guaranteed to be accessible, so we will use it. return(GetPredefAgg(PredefinedType.PT_OBJECT).getThisType()); } if (semanticChecker.CheckTypeAccess(baseType, context)) { return(baseType); } // baseType is always an AggregateType, so no need for logic of other types. aggSrc = baseType; } } if (typeSrc is ArrayType arrSrc) { if (TryArrayVarianceAdjustmentToGetAccessibleType(semanticChecker, context, arrSrc, out CType typeDst)) { // Similarly to the interface and delegate case, arrays are covariant in their element type and // so we can potentially produce an array type that is accessible. // Example: PrivateConcreteFoo[] --> PublicAbstractFoo[] Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, context)); return(typeDst); } // We have an inaccessible array type for which we could not earlier find a better array type // with a covariant conversion, so the best we can do is System.Array. return(GetPredefAgg(PredefinedType.PT_ARRAY).getThisType()); } Debug.Assert(typeSrc is NullableType); // We have an inaccessible nullable type, which means that the best we can do is System.ValueType. return(GetPredefAgg(PredefinedType.PT_VALUE).getThisType()); }