| File: Microsoft\CSharp\RuntimeBinder\Semantics\Symbols\AggregateSymbol.cs | Web Access |
| Project: src\runtime\src\libraries\Microsoft.CSharp\src\Microsoft.CSharp.csproj (Microsoft.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using Microsoft.CSharp.RuntimeBinder.Syntax; namespace Microsoft.CSharp.RuntimeBinder.Semantics { // Name used for AGGDECLs in the symbol table. // AggregateSymbol - a symbol representing an aggregate type. These are classes, // interfaces, and structs. Parent is a namespace or class. Children are methods, // properties, and member variables, and types (including its own AGGTYPESYMs). [RequiresDynamicCode(Binder.DynamicCodeWarning)] internal sealed class AggregateSymbol : NamespaceOrAggregateSymbol { public Type AssociatedSystemType; public Assembly AssociatedAssembly; // The instance type. Created when first needed. private AggregateType _atsInst; private AggregateType _pBaseClass; // For a class/struct/enum, the base class. For iface: unused. private AggregateType _pUnderlyingType; // For enum, the underlying type. For iface, the resolved CoClass. Not used for class/struct. private TypeArray _ifaces; // The explicit base interfaces for a class or interface. private TypeArray _ifacesAll; // Recursive closure of base interfaces ordered so an iface appears before all of its base ifaces. private TypeArray _typeVarsThis; // Type variables for this generic class, as declarations. private TypeArray _typeVarsAll; // The type variables for this generic class and all containing classes. // First UD conversion operator. This chain is for this type only (not base types). // The hasConversion flag indicates whether this or any base types have UD conversions. private MethodSymbol _pConvFirst; // ------------------------------------------------------------------------ // // Put members that are bits under here in a contiguous section. // // ------------------------------------------------------------------------ private AggKindEnum _aggKind; // Where this came from - fabricated, source, import // Fabricated AGGs have isSource == true but hasParseTree == false. // N.B.: in incremental builds, it is quite possible for // isSource==TRUE and hasParseTree==FALSE. Be // sure you use the correct variable for what you are trying to do! // Predefined private bool _isPredefined; // A special predefined type. private PredefinedType _iPredef; // index of the predefined type, if isPredefined. // Flags private bool _isAbstract; // Can it be instantiated? private bool _isSealed; // Can it be derived from? // Constructors private bool _hasPubNoArgCtor; // Whether it has a public instance constructor taking no args // User defined operators private bool _isSkipUDOps; // Never check for user defined operators on this type (eg, decimal, string, delegate). // When this is unset we don't know if we have conversions. When this // is set it indicates if this type or any base type has user defined // conversion operators private bool? _hasConversion; // ---------------------------------------------------------------------------- // AggregateSymbol // ---------------------------------------------------------------------------- public AggregateSymbol GetBaseAgg() { return _pBaseClass?.OwningAggregate; } public AggregateType getThisType() { if (_atsInst == null) { Debug.Assert(GetTypeVars() == GetTypeVarsAll() || isNested()); AggregateType pOuterType = isNested() ? GetOuterAgg().getThisType() : null; _atsInst = TypeManager.GetAggregate(this, pOuterType, GetTypeVars()); } //Debug.Assert(GetTypeVars().Size == atsInst.GenericArguments.Count); return _atsInst; } public bool FindBaseAgg(AggregateSymbol agg) { for (AggregateSymbol aggT = this; aggT != null; aggT = aggT.GetBaseAgg()) { if (aggT == agg) return true; } return false; } public NamespaceOrAggregateSymbol Parent => parent as NamespaceOrAggregateSymbol; public bool isNested() => parent is AggregateSymbol; public AggregateSymbol GetOuterAgg() => parent as AggregateSymbol; public bool isPredefAgg(PredefinedType pt) { return _isPredefined && (PredefinedType)_iPredef == pt; } // ---------------------------------------------------------------------------- // The following are the Accessor functions for AggregateSymbol. // ---------------------------------------------------------------------------- public AggKindEnum AggKind() { return (AggKindEnum)_aggKind; } public void SetAggKind(AggKindEnum aggKind) { // NOTE: When importing can demote types: // - enums with no underlying type go to struct // - delegates which are abstract or have no .ctor/Invoke method goto class _aggKind = aggKind; //An interface is always abstract if (aggKind == AggKindEnum.Interface) { SetAbstract(true); } } public bool IsClass() { return AggKind() == AggKindEnum.Class; } public bool IsDelegate() { return AggKind() == AggKindEnum.Delegate; } public bool IsInterface() { return AggKind() == AggKindEnum.Interface; } public bool IsStruct() { return AggKind() == AggKindEnum.Struct; } public bool IsEnum() { return AggKind() == AggKindEnum.Enum; } public bool IsValueType() { return AggKind() == AggKindEnum.Struct || AggKind() == AggKindEnum.Enum; } public bool IsRefType() { return AggKind() == AggKindEnum.Class || AggKind() == AggKindEnum.Interface || AggKind() == AggKindEnum.Delegate; } public bool IsStatic() { return (_isAbstract && _isSealed); } public bool IsAbstract() { return _isAbstract; } public void SetAbstract(bool @abstract) { _isAbstract = @abstract; } public bool IsPredefined() { return _isPredefined; } public void SetPredefined(bool predefined) { _isPredefined = predefined; } public PredefinedType GetPredefType() { return (PredefinedType)_iPredef; } public void SetPredefType(PredefinedType predef) { _iPredef = predef; } public bool IsSealed() { return _isSealed; } public void SetSealed(bool @sealed) { _isSealed = @sealed; } //////////////////////////////////////////////////////////////////////////////// [RequiresUnreferencedCode(Binder.TrimmerWarning)] public bool HasConversion() { SymbolTable.AddConversionsForType(AssociatedSystemType); if (!_hasConversion.HasValue) { // ok, we tried defining all the conversions, and we didn't get anything // for this type. However, we will still think this type has conversions // if it's base type has conversions. _hasConversion = GetBaseAgg() != null && GetBaseAgg().HasConversion(); } return _hasConversion.Value; } //////////////////////////////////////////////////////////////////////////////// public void SetHasConversion() { _hasConversion = true; } //////////////////////////////////////////////////////////////////////////////// public bool HasPubNoArgCtor() { return _hasPubNoArgCtor; } public void SetHasPubNoArgCtor(bool hasPubNoArgCtor) { _hasPubNoArgCtor = hasPubNoArgCtor; } public bool IsSkipUDOps() { return _isSkipUDOps; } public void SetSkipUDOps(bool skipUDOps) { _isSkipUDOps = skipUDOps; } public TypeArray GetTypeVars() { return _typeVarsThis; } public void SetTypeVars(TypeArray typeVars) { if (typeVars == null) { _typeVarsThis = null; _typeVarsAll = null; } else { TypeArray outerTypeVars; if (GetOuterAgg() != null) { Debug.Assert(GetOuterAgg().GetTypeVars() != null); Debug.Assert(GetOuterAgg().GetTypeVarsAll() != null); outerTypeVars = GetOuterAgg().GetTypeVarsAll(); } else { outerTypeVars = TypeArray.Empty; } _typeVarsThis = typeVars; _typeVarsAll = TypeArray.Concat(outerTypeVars, typeVars); } } public TypeArray GetTypeVarsAll() { return _typeVarsAll; } public AggregateType GetBaseClass() { return _pBaseClass; } public void SetBaseClass(AggregateType baseClass) { _pBaseClass = baseClass; } public AggregateType GetUnderlyingType() { return _pUnderlyingType; } public void SetUnderlyingType(AggregateType underlyingType) { _pUnderlyingType = underlyingType; } public TypeArray GetIfaces() { return _ifaces; } public void SetIfaces(TypeArray ifaces) { _ifaces = ifaces; } public TypeArray GetIfacesAll() { return _ifacesAll; } public void SetIfacesAll(TypeArray ifacesAll) { _ifacesAll = ifacesAll; } public MethodSymbol GetFirstUDConversion() { return _pConvFirst; } public void SetFirstUDConversion(MethodSymbol conv) { _pConvFirst = conv; } public bool InternalsVisibleTo(Assembly assembly) => TypeManager.InternalsVisibleTo(AssociatedAssembly, assembly); } }