public void Construct(NamedTypeSymbol functype, Action<CodeGenerator> binder_builder) { var callsitetype = _factory.CallSite_T.Construct(functype); // TODO: check if it wasn't constructed already _target.SetContainingType((SubstitutedNamedTypeSymbol)callsitetype); _fld.SetFieldType(callsitetype); _callsite_create = (MethodSymbol)_factory.CallSite_T_Create.SymbolAsMember(callsitetype); // create callsite // static .cctor { var cctor = _factory.CctorBuilder; // fld = CallSite<T>.Create( <BINDER> ) var fldPlace = this.Place; fldPlace.EmitStorePrepare(cctor); var cctor_cg = new CodeGenerator(cctor, _factory._cg.Module, _factory._cg.Diagnostics, _factory._cg.DeclaringCompilation.Options.OptimizationLevel, false, _factory._container, null, null); binder_builder(cctor_cg); cctor.EmitCall(_factory._cg.Module, _factory._cg.Diagnostics, ILOpCode.Call, this.CallSite_Create); fldPlace.EmitStore(cctor); // } }
public GenericTypeInstanceReference(NamedTypeSymbol underlyingNamedType) : base(underlyingNamedType) { Debug.Assert(underlyingNamedType.IsDefinition); // Definition doesn't have custom modifiers on type arguments //Debug.Assert(!underlyingNamedType.HasTypeArgumentsCustomModifiers); }
internal SourceAttributeData( SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArguments, ImmutableArray<int> constructorArgumentsSourceIndices, ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments, bool hasErrors, bool isConditionallyOmitted) { Debug.Assert(!isConditionallyOmitted || (object)attributeClass != null && attributeClass.IsConditional); Debug.Assert(!constructorArguments.IsDefault); Debug.Assert(!namedArguments.IsDefault); Debug.Assert(constructorArgumentsSourceIndices.IsDefault || constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length); _attributeClass = attributeClass; _attributeConstructor = attributeConstructor; _constructorArguments = constructorArguments; _constructorArgumentsSourceIndices = constructorArgumentsSourceIndices; _namedArguments = namedArguments; _isConditionallyOmitted = isConditionallyOmitted; _hasErrors = hasErrors; _applicationNode = applicationNode; }
private static SmallDictionary<TypeParameterSymbol, TypeWithModifiers> ForType(NamedTypeSymbol containingType) { var substituted = containingType as SubstitutedNamedTypeSymbol; return (object)substituted != null ? new SmallDictionary<TypeParameterSymbol, TypeWithModifiers>(substituted.TypeSubstitution.Mapping, ReferenceEqualityComparer.Instance) : new SmallDictionary<TypeParameterSymbol, TypeWithModifiers>(ReferenceEqualityComparer.Instance); }
public DelegateConstructor(NamedTypeSymbol containingType, TypeSymbol objectType, TypeSymbol intPtrType) : base(containingType) { _parameters = ImmutableArray.Create<ParameterSymbol>( new SynthesizedParameterSymbol(this, objectType, 0, RefKind.None, "object"), new SynthesizedParameterSymbol(this, intPtrType, 1, RefKind.None, "method")); }
private void CacheTopLevelMetadataType( ref MetadataTypeName emittedName, NamedTypeSymbol result) { NamedTypeSymbol result1 = null; result1 = _emittedNameToTypeMap.GetOrAdd(emittedName.ToKey(), result); Debug.Assert(result1 == result); // object identity may differ in error cases }
internal SubstitutedNestedTypeSymbol(SubstitutedNamedTypeSymbol newContainer, NamedTypeSymbol originalDefinition) : base( newContainer: newContainer, map: newContainer.TypeSubstitution, originalDefinition: originalDefinition, // An Arity-0 member of an unbound type, e.g. A<>.B, is unbound. unbound: newContainer.IsUnboundGenericType && originalDefinition.Arity == 0) { }
public SynthesizedFieldSymbol( NamedTypeSymbol containing, TypeSymbol type, string name, Accessibility accessibility, ConstantValue constant) :this(containing, type, name, accessibility, true) { _const = constant; }
public SynthesizedPropertySymbol(NamedTypeSymbol containing, string name, bool isStatic, TypeSymbol type, Accessibility accessibility, MethodSymbol getter, MethodSymbol setter) { _containing = containing; _name = name; _accessibility = accessibility; _setMethod = setter; _getMethod = getter; _type = type; _isStatic = isStatic; }
internal RetargetingAttributeData( SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArguments, ImmutableArray<int> constructorArgumentsSourceIndices, ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments, bool hasErrors, bool isConditionallyOmitted) : base(applicationNode, attributeClass, attributeConstructor, constructorArguments, constructorArgumentsSourceIndices, namedArguments, hasErrors, isConditionallyOmitted) { }
internal SourceAttributeData(SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, bool hasErrors) : this( applicationNode, attributeClass, attributeConstructor, constructorArguments: ImmutableArray<TypedConstant>.Empty, constructorArgumentsSourceIndices: default(ImmutableArray<int>), namedArguments: ImmutableArray<KeyValuePair<string, TypedConstant>>.Empty, hasErrors: hasErrors, isConditionallyOmitted: false) { }
/// <summary> /// Substitute for a type declaration. May use alpha renaming if the container is substituted. /// </summary> private NamedTypeSymbol SubstituteMemberType(NamedTypeSymbol previous) { Debug.Assert((object)previous.ConstructedFrom == (object)previous); NamedTypeSymbol newContainingType = SubstituteNamedType(previous.ContainingType); if ((object)newContainingType == null) { return previous; } return previous.OriginalDefinition.AsMember(newContainingType); }
internal TypeMap(NamedTypeSymbol containingType, ImmutableArray<TypeParameterSymbol> typeParameters, ImmutableArray<TypeWithModifiers> typeArguments) : base(ForType(containingType)) { for (int i = 0; i < typeParameters.Length; i++) { TypeParameterSymbol tp = typeParameters[i]; TypeWithModifiers ta = typeArguments[i]; if (!ta.Is(tp)) { Mapping.Add(tp, ta); } } }
/// <summary> /// SubstType, but for NamedTypeSymbols only. This is used for concrete types, so no alpha substitution appears in the result. /// </summary> internal NamedTypeSymbol SubstituteNamedType(NamedTypeSymbol previous) { if (ReferenceEquals(previous, null)) return null; if (previous.IsUnboundGenericType) return previous; if (previous.IsAnonymousType) { //ImmutableArray<TypeSymbol> oldFieldTypes = AnonymousTypeManager.GetAnonymousTypePropertyTypes(previous); //ImmutableArray<TypeSymbol> newFieldTypes = SubstituteTypesWithoutModifiers(oldFieldTypes); //return (oldFieldTypes == newFieldTypes) ? previous : AnonymousTypeManager.ConstructAnonymousTypeSymbol(previous, newFieldTypes); throw new NotImplementedException(); } // TODO: we could construct the result's ConstructedFrom lazily by using a "deep" // construct operation here (as VB does), thereby avoiding alpha renaming in most cases. // Aleksey has shown that would reduce GC pressure if substitutions of deeply nested generics are common. NamedTypeSymbol oldConstructedFrom = previous.ConstructedFrom; NamedTypeSymbol newConstructedFrom = SubstituteMemberType(oldConstructedFrom); ImmutableArray<TypeSymbol> oldTypeArguments = previous.TypeArguments; //.TypeArgumentsNoUseSiteDiagnostics; bool changed = !ReferenceEquals(oldConstructedFrom, newConstructedFrom); //ImmutableArray<ImmutableArray<CustomModifier>> modifiers = previous.HasTypeArgumentsCustomModifiers ? previous.TypeArgumentsCustomModifiers : default(ImmutableArray<ImmutableArray<CustomModifier>>); ImmutableArray<ImmutableArray<CustomModifier>> modifiers = /*previous.HasTypeArgumentsCustomModifiers ? previous.TypeArgumentsCustomModifiers : */default(ImmutableArray<ImmutableArray<CustomModifier>>); var newTypeArguments = ArrayBuilder<TypeWithModifiers>.GetInstance(oldTypeArguments.Length); for (int i = 0; i < oldTypeArguments.Length; i++) { var oldArgument = modifiers.IsDefault ? new TypeWithModifiers(oldTypeArguments[i]) : new TypeWithModifiers(oldTypeArguments[i], modifiers[i]); var newArgument = oldArgument.SubstituteType(this); if (!changed && oldArgument != newArgument) { changed = true; } newTypeArguments.Add(newArgument); } if (!changed) { newTypeArguments.Free(); return previous; } return newConstructedFrom.ConstructIfGeneric(newTypeArguments.ToImmutableAndFree()); }
/// <summary> /// Enumerates base types and interfaces of given type (i.e. types that can contain methods that can be overriden). /// </summary> static IEnumerable<NamedTypeSymbol> EnumerateOverridableTypes(NamedTypeSymbol type) { Debug.Assert(type != null); for (var t = type.BaseType; t != null; t = t.BaseType) { yield return t; } // foreach (var t in type.AllInterfaces) { yield return t; } }
public SynthesizedFieldSymbol( NamedTypeSymbol containing, TypeSymbol type, string name, Accessibility accessibility, bool isStatic = false, bool isReadOnly = false) { _containing = containing; _name = name; _type = type; _accessibility = accessibility; _isStatic = isStatic; _isReadOnly = isReadOnly; }
public TypeParameterBounds( ImmutableArray<TypeSymbol> constraintTypes, ImmutableArray<NamedTypeSymbol> interfaces, NamedTypeSymbol effectiveBaseClass, TypeSymbol deducedBaseType) { Debug.Assert(!constraintTypes.IsDefault); Debug.Assert(!interfaces.IsDefault); Debug.Assert((object)effectiveBaseClass != null); Debug.Assert((object)deducedBaseType != null); this.ConstraintTypes = constraintTypes; this.Interfaces = interfaces; this.EffectiveBaseClass = effectiveBaseClass; this.DeducedBaseType = deducedBaseType; }
protected SubstitutedNamedTypeSymbol(Symbol newContainer, TypeMap map, NamedTypeSymbol originalDefinition, NamedTypeSymbol constructedFrom = null, bool unbound = false) { Debug.Assert(originalDefinition.IsDefinition); _originalDefinition = originalDefinition; _newContainer = newContainer; _inputMap = map; _unbound = unbound; // if we're substituting to create a new unconstructed type as a member of a constructed type, // then we must alpha rename the type parameters. if ((object)constructedFrom != null) { Debug.Assert(ReferenceEquals(constructedFrom.ConstructedFrom, constructedFrom)); _lazyTypeParameters = constructedFrom.TypeParameters; _lazyMap = map; } }
protected SubstitutedMethodSymbol(NamedTypeSymbol containingSymbol, TypeMap map, MethodSymbol originalDefinition, MethodSymbol constructedFrom) { Debug.Assert(originalDefinition.IsDefinition); _containingType = containingSymbol; this.originalDefinition = originalDefinition; _inputMap = map; if ((object)constructedFrom != null) { _constructedFrom = constructedFrom; Debug.Assert(ReferenceEquals(constructedFrom.ConstructedFrom, constructedFrom)); _lazyTypeParameters = constructedFrom.TypeParameters; _lazyMap = map; } else { _constructedFrom = this; } }
internal ConstructedNamedTypeSymbol(NamedTypeSymbol constructedFrom, ImmutableArray<TypeWithModifiers> typeArguments, bool unbound = false) : base(newContainer: constructedFrom.ContainingSymbol, map: new TypeMap(constructedFrom.ContainingType, constructedFrom.OriginalDefinition.TypeParameters, typeArguments), originalDefinition: constructedFrom.OriginalDefinition, constructedFrom: constructedFrom, unbound: unbound) { bool hasTypeArgumentsCustomModifiers = false; _typeArguments = typeArguments.SelectAsArray(a => { if (!a.CustomModifiers.IsDefaultOrEmpty) { hasTypeArgumentsCustomModifiers = true; } return a.Type; }); _hasTypeArgumentsCustomModifiers = hasTypeArgumentsCustomModifiers; _constructedFrom = constructedFrom; Debug.Assert(constructedFrom.Arity == typeArguments.Length); Debug.Assert(constructedFrom.Arity != 0); }
public Nested(NamedTypeSymbol containingType, ref MetadataTypeName emittedName) : this(containingType, ref emittedName, emittedName.ForcedArity == -1 || emittedName.ForcedArity == emittedName.InferredArity) { }
public ImmutableArray<ImmutableArray<CustomModifier>> GetTypeArgumentsCustomModifiersFor(NamedTypeSymbol originalDefinition) { Debug.Assert((object)originalDefinition != null); Debug.Assert(originalDefinition.IsDefinition); Debug.Assert(originalDefinition.Arity > 0); var result = ArrayBuilder<ImmutableArray<CustomModifier>>.GetInstance(originalDefinition.Arity); foreach (TypeParameterSymbol tp in originalDefinition.TypeArguments) { result.Add(SubstituteTypeParameter(tp).CustomModifiers); } return result.ToImmutableAndFree(); }
/// <summary> /// Helper for more complicated cases of Equals like when we have generic instantiations or types nested within them. /// </summary> private bool EqualsComplicatedCases(NamedTypeSymbol other, bool ignoreCustomModifiersAndArraySizesAndLowerBounds = false, bool ignoreDynamic = false) { if ((object)this.ContainingType != null && !this.ContainingType.Equals(other.ContainingType, ignoreCustomModifiersAndArraySizesAndLowerBounds, ignoreDynamic)) { return(false); } var thisIsNotConstructed = ReferenceEquals(ConstructedFrom, this); var otherIsNotConstructed = ReferenceEquals(other.ConstructedFrom, other); if (thisIsNotConstructed && otherIsNotConstructed) { // Note that the arguments might appear different here due to alpha-renaming. For example, given // class A<T> { class B<U> {} } // The type A<int>.B<int> is "constructed from" A<int>.B<1>, which may be a distinct type object // with a different alpha-renaming of B's type parameter every time that type expression is bound, // but these should be considered the same type each time. return(true); } if (((thisIsNotConstructed || otherIsNotConstructed) && !(ignoreCustomModifiersAndArraySizesAndLowerBounds && (this.HasTypeArgumentsCustomModifiers || other.HasTypeArgumentsCustomModifiers))) || this.IsUnboundGenericType != other.IsUnboundGenericType) { return(false); } bool hasTypeArgumentsCustomModifiers = this.HasTypeArgumentsCustomModifiers; if (!ignoreCustomModifiersAndArraySizesAndLowerBounds && hasTypeArgumentsCustomModifiers != other.HasTypeArgumentsCustomModifiers) { return(false); } var typeArguments = this.TypeArgumentsNoUseSiteDiagnostics.ToArray(); var otherTypeArguments = other.TypeArgumentsNoUseSiteDiagnostics.ToArray(); int count = typeArguments.Length; // since both are constructed from the same (original) type, they must have the same arity Debug.Assert(count == otherTypeArguments.Length); for (int i = 0; i < count; i++) { if (!typeArguments[i].Equals(otherTypeArguments[i], ignoreCustomModifiersAndArraySizesAndLowerBounds, ignoreDynamic)) { return(false); } } if (!ignoreCustomModifiersAndArraySizesAndLowerBounds && hasTypeArgumentsCustomModifiers) { Debug.Assert(other.HasTypeArgumentsCustomModifiers); for (int i = 0; i < count; i++) { if (!this.GetTypeArgumentCustomModifiers(i).SequenceEqual(other.GetTypeArgumentCustomModifiers(i))) { return(false); } } } return(true); }
/// <summary> /// Enumerates base types and interfaces of given type (i.e. types that can contain methods that can be overriden). /// </summary> static IEnumerable <NamedTypeSymbol> EnumerateOverridableTypes(NamedTypeSymbol type) { Debug.Assert(type != null); // ignoring System.Object (we don't override its methods from PHP) for (var t = type.BaseType; t != null && t.SpecialType != SpecialType.System_Object; t = t.BaseType) { yield return(t); } //yield return from type.AllInterfaces; // NOTE: this returns too much interfaces, we only needs the once that can introduce an abstract member: // // check interfaces which can introduce an abstract member only: // Queue <NamedTypeSymbol> typesWithInterfaces = null; // remember abstract types which interfaces have to be returned as well for (var t = type; t != null && t.SpecialType != SpecialType.System_Object; t = t.BaseType) { if (t.IsAbstract || t == type) { if (t.Interfaces.IsDefaultOrEmpty) { continue; } if (typesWithInterfaces == null) { typesWithInterfaces = new Queue <NamedTypeSymbol>(); } typesWithInterfaces.Enqueue(t); } else { // we don't have to check interfaces, // all the virtual members from interface were already implemented break; } } if (typesWithInterfaces != null) { var set = new HashSet <NamedTypeSymbol>(); // recursively get all interfaces from abstract types while (typesWithInterfaces.Count != 0) { var t = typesWithInterfaces.Dequeue(); if (set.Add(t)) { t.Interfaces.ForEach(typesWithInterfaces.Enqueue); } } foreach (var t in set) { if (t.IsInterface && t != type) // take only interfaces from the set of all base types { yield return(t); } } } }
/// <summary> /// Like SubstTypes, but for NamedTypeSymbols. /// </summary> internal ImmutableArray<NamedTypeSymbol> SubstituteNamedTypes(ImmutableArray<NamedTypeSymbol> original) { NamedTypeSymbol[] result = null; for (int i = 0; i < original.Length; i++) { var t = original[i]; var substituted = SubstituteNamedType(t); if (!Object.ReferenceEquals(substituted, t)) { if (result == null) { result = new NamedTypeSymbol[original.Length]; for (int j = 0; j < i; j++) { result[j] = original[j]; } } } if (result != null) { result[i] = substituted; } } return result != null ? result.AsImmutableOrNull() : original; }
/// <summary> /// Builds the visibility scope. /// </summary> public VisibilityScope(NamedTypeSymbol self, SourceRoutineSymbol routine) { Scope = self; ScopeIsDynamic = self.IsTraitType() || routine is SourceLambdaSymbol || (routine?.IsGlobalScope == true); }
private void ResolveBaseTypes(DiagnosticBag diagnostics) { Debug.Assert(_lazyInterfacesType.IsDefault); // not resolved yet // get possible type signature [ BaseType?, Interface1, ..., InterfaceN ] // Single slots may refer to a MissingTypeSymbol or an ambiguous type symbol var tsignature = ResolveTypeSignature(this, this.DeclaringCompilation).ToArray(); Debug.Assert(tsignature.Length >= 1); // [0] is base class // check all types are supported foreach (var t in tsignature) { if (t.Symbol != null) { if (t.Symbol.Arity != 0) { diagnostics.Add(CreateLocation(t.TypeRef.Span.ToTextSpan()), Errors.ErrorCode.ERR_NotYetImplemented, "Using generic types."); } if (t.Symbol is ErrorTypeSymbol err && err.CandidateReason != CandidateReason.Ambiguous) { diagnostics.Add(CreateLocation(t.TypeRef.Span.ToTextSpan()), Errors.ErrorCode.ERR_TypeNameCannotBeResolved, t.TypeRef.ClassName.ToString()); } } } if (!diagnostics.HasAnyErrors()) { // collect variations of possible base types var variations = Variations(tsignature.Select(t => t.Symbol).AsImmutable(), this.ContainingFile); // instantiate versions bool self = true; int lastVersion = 0; // the SourceTypeSymbol version, 0 ~ a single version, >0 ~ multiple version foreach (var v in variations) { if (self) { _lazyBaseType = v[0]; _lazyInterfacesType = v.RemoveAt(0); self = false; } else { // create next version of this type with already resolved type signature _nextVersion = new SourceTypeSymbol(_file, _syntax, v[0], v.RemoveAt(0), ++lastVersion) { //_lambdas = _lambdas, _nextVersion = _nextVersion }; // clone lambdas that use $this if (_lambdas != null) { foreach (var l in _lambdas.Where(l => l.UseThis)) { ((ILambdaContainerSymbol)_nextVersion).AddLambda(new SourceLambdaSymbol((LambdaFunctionExpr)l.Syntax, _nextVersion, l.UseThis)); } } } } if (lastVersion != 0) { _version = ++lastVersion; diagnostics.Add(CreateLocation(_syntax.HeadingSpan.ToTextSpan()), Errors.ErrorCode.WRN_AmbiguousDeclaration, this.FullName); } } else { // default: _lazyBaseType = tsignature[0].Symbol; _lazyInterfacesType = tsignature.Skip(1).Select(t => t.Item2).AsImmutable(); } // check for circular bases in all versions for (var t = this; t != null; t = t.NextVersion) { CheckForCircularBase(t, diagnostics); } }
internal void Update(NamedTypeSymbol symbol) { Contract.ThrowIfNull(symbol); Debug.Assert(this.Symbol == null); this.Symbol = symbol; }
private static bool IsAcceptableSystemTypeSymbol(NamedTypeSymbol candidate) { return(candidate.Kind != SymbolKind.ErrorType || !(candidate is MissingMetadataTypeSymbol)); }
/// <summary> /// Lookup an immediately nested type referenced from metadata, names should be /// compared case-sensitively. /// </summary> /// <param name="emittedTypeName"> /// Simple type name, possibly with generic name mangling. /// </param> /// <returns> /// Symbol for the type, or MissingMetadataSymbol if the type isn't found. /// </returns> internal virtual NamedTypeSymbol LookupMetadataType(ref MetadataTypeName emittedTypeName) { Debug.Assert(!emittedTypeName.IsNull); NamespaceOrTypeSymbol scope = this; if (scope.Kind == SymbolKind.ErrorType) { throw new NotImplementedException(); //return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName); } NamedTypeSymbol namedType = null; ImmutableArray <NamedTypeSymbol> namespaceOrTypeMembers; bool isTopLevel = scope.IsNamespace; //Debug.Assert(!isTopLevel || scope.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat) == emittedTypeName.NamespaceName); if (emittedTypeName.IsMangled) { Debug.Assert(!emittedTypeName.UnmangledTypeName.Equals(emittedTypeName.TypeName) && emittedTypeName.InferredArity > 0); if (emittedTypeName.ForcedArity == -1 || emittedTypeName.ForcedArity == emittedTypeName.InferredArity) { // Let's handle mangling case first. //namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.UnmangledTypeName); namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.FullName); foreach (var named in namespaceOrTypeMembers) { if (emittedTypeName.InferredArity == named.Arity && named.MangleName) { if ((object)namedType != null) { namedType = null; break; } namedType = named; } } } } else { Debug.Assert(ReferenceEquals(emittedTypeName.UnmangledTypeName, emittedTypeName.TypeName) && emittedTypeName.InferredArity == 0); } // Now try lookup without removing generic arity mangling. int forcedArity = emittedTypeName.ForcedArity; if (emittedTypeName.UseCLSCompliantNameArityEncoding) { // Only types with arity 0 are acceptable, we already examined types with mangled names. if (emittedTypeName.InferredArity > 0) { goto Done; } else if (forcedArity == -1) { forcedArity = 0; } else if (forcedArity != 0) { goto Done; } else { Debug.Assert(forcedArity == emittedTypeName.InferredArity); } } namespaceOrTypeMembers = scope.GetTypeMembers(emittedTypeName.FullName); foreach (var named in namespaceOrTypeMembers) { if (!named.MangleName && (forcedArity == -1 || forcedArity == named.Arity)) { if ((object)namedType != null) { namedType = null; break; } namedType = named; } } Done: if ((object)namedType == null) { return(new MissingMetadataTypeSymbol(emittedTypeName.FullName, emittedTypeName.ForcedArity, emittedTypeName.IsMangled)); //if (isTopLevel) //{ // return new MissingMetadataTypeSymbol.TopLevel(scope.ContainingModule, ref emittedTypeName); //} //else //{ // return new MissingMetadataTypeSymbol.Nested((NamedTypeSymbol)scope, ref emittedTypeName); //} } return(namedType); }
internal override bool Equals(TypeSymbol t2, bool ignoreCustomModifiersAndArraySizesAndLowerBounds = false, bool ignoreDynamic = false) { //Debug.Assert(!this.IsTupleType); if ((object)t2 == this) { return(true); } if ((object)t2 == null) { return(false); } if (ignoreDynamic) { if (t2.TypeKind == TypeKind.Dynamic) { // if ignoring dynamic, then treat dynamic the same as the type 'object' if (this.SpecialType == SpecialType.System_Object) { return(true); } } } //if ((comparison & TypeCompareKind.IgnoreTupleNames) != 0) //{ // // If ignoring tuple element names, compare underlying tuple types // if (t2.IsTupleType) // { // t2 = t2.TupleUnderlyingType; // if (this.Equals(t2, ignoreCustomModifiersAndArraySizesAndLowerBounds, ignoreDynamic)) return true; // } //} NamedTypeSymbol other = t2 as NamedTypeSymbol; if ((object)other == null) { return(false); } // Compare OriginalDefinitions. var thisOriginalDefinition = this.OriginalDefinition; var otherOriginalDefinition = other.OriginalDefinition; if (((object)this == (object)thisOriginalDefinition || (object)other == (object)otherOriginalDefinition) && !(ignoreCustomModifiersAndArraySizesAndLowerBounds && (this.HasTypeArgumentsCustomModifiers || other.HasTypeArgumentsCustomModifiers))) { return(false); } // CONSIDER: original definitions are not unique for missing metadata type // symbols. Therefore this code may not behave correctly if 'this' is List<int> // where List`1 is a missing metadata type symbol, and other is similarly List<int> // but for a reference-distinct List`1. if (thisOriginalDefinition != otherOriginalDefinition) { return(false); } // The checks above are supposed to handle the vast majority of cases. // More complicated cases are handled in a special helper to make the common case scenario simple/fast (fewer locals and smaller stack frame) return(EqualsComplicatedCases(other, ignoreCustomModifiersAndArraySizesAndLowerBounds, ignoreDynamic)); }
internal SubstitutedFieldSymbol(NamedTypeSymbol containingType, FieldSymbol substitutedFrom) : this(containingType, substitutedFrom, containingType) { }
internal SubstitutedFieldSymbol(NamedTypeSymbol containingType, FieldSymbol substitutedFrom, object token) { _containingType = containingType; _originalDefinition = substitutedFrom.OriginalDefinition as FieldSymbol; _token = token ?? _containingType; }
/// <summary> /// Returns a constructed named type symbol if 'type' is generic, otherwise just returns 'type' /// </summary> public static NamedTypeSymbol ConstructIfGeneric(this NamedTypeSymbol type, ImmutableArray <TypeWithModifiers> typeArguments) { Debug.Assert(type.TypeParameters.IsEmpty == (typeArguments.Length == 0)); return(type.TypeParameters.IsEmpty ? type : type.Construct(typeArguments, unbound: false)); }
//internal void DecodeSecurityAttribute<T>(Symbol targetSymbol, PhpCompilation compilation, ref DecodeWellKnownAttributeArguments<AttributeSyntax, BaseAttributeData, AttributeLocation> arguments) // where T : WellKnownAttributeData, ISecurityAttributeTarget, new() //{ // Debug.Assert(!this.HasErrors); // bool hasErrors; // DeclarativeSecurityAction action = DecodeSecurityAttributeAction(targetSymbol, compilation, arguments.AttributeSyntaxOpt, out hasErrors, arguments.Diagnostics); // if (!hasErrors) // { // T data = arguments.GetOrCreateData<T>(); // SecurityWellKnownAttributeData securityData = data.GetOrCreateData(); // securityData.SetSecurityAttribute(arguments.Index, action, arguments.AttributesCount); // if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PermissionSetAttribute)) // { // string resolvedPathForFixup = DecodePermissionSetAttribute(compilation, arguments.AttributeSyntaxOpt, arguments.Diagnostics); // if (resolvedPathForFixup != null) // { // securityData.SetPathForPermissionSetAttributeFixup(arguments.Index, resolvedPathForFixup, arguments.AttributesCount); // } // } // } //} //private DeclarativeSecurityAction DecodeSecurityAttributeAction(Symbol targetSymbol, PhpCompilation compilation, AttributeSyntax nodeOpt, out bool hasErrors, DiagnosticBag diagnostics) //{ // Debug.Assert((object)targetSymbol != null); // Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method); // Debug.Assert(this.IsSecurityAttribute(compilation)); // var ctorArgs = this.CommonConstructorArguments; // if (!ctorArgs.Any()) // { // // NOTE: Security custom attributes must have a valid SecurityAction as its first argument, we have none here. // // NOTE: Ideally, we should always generate 'CS7048: First argument to a security attribute must be a valid SecurityAction' for this case. // // NOTE: However, native compiler allows applying System.Security.Permissions.HostProtectionAttribute attribute without any argument and uses // // NOTE: SecurityAction.LinkDemand as the default SecurityAction in this case. We maintain compatibility with the native compiler for this case. // // BREAKING CHANGE: Even though the native compiler intends to allow only HostProtectionAttribute to be applied without any arguments, // // it doesn't quite do this correctly // // The implementation issue leads to the native compiler allowing any user defined security attribute with a parameterless constructor and a named property argument as the first // // attribute argument to have the above mentioned behavior, even though the comment clearly mentions that this behavior was intended only for the HostProtectionAttribute. // // We currently allow this case only for the HostProtectionAttribute. In future if need arises, we can exactly match native compiler's behavior. // if (this.IsTargetAttribute(targetSymbol, AttributeDescription.HostProtectionAttribute)) // { // hasErrors = false; // return DeclarativeSecurityAction.LinkDemand; // } // } // else // { // TypedConstant firstArg = ctorArgs.First(); // TypeSymbol firstArgType = (TypeSymbol)firstArg.Type; // if ((object)firstArgType != null && firstArgType.Equals(compilation.GetWellKnownType(WellKnownType.System_Security_Permissions_SecurityAction))) // { // return DecodeSecurityAction(firstArg, targetSymbol, nodeOpt, diagnostics, out hasErrors); // } // } // // CS7048: First argument to a security attribute must be a valid SecurityAction // diagnostics.Add(ErrorCode.ERR_SecurityAttributeMissingAction, nodeOpt != null ? nodeOpt.Name.Location : NoLocation.Singleton); // hasErrors = true; // return DeclarativeSecurityAction.None; //} //private DeclarativeSecurityAction DecodeSecurityAction(TypedConstant typedValue, Symbol targetSymbol, AttributeSyntax nodeOpt, DiagnosticBag diagnostics, out bool hasErrors) //{ // Debug.Assert((object)targetSymbol != null); // Debug.Assert(targetSymbol.Kind == SymbolKind.Assembly || targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method); // int securityAction = (int)typedValue.Value; // bool isPermissionRequestAction; // switch (securityAction) // { // case (int)DeclarativeSecurityAction.InheritanceDemand: // case (int)DeclarativeSecurityAction.LinkDemand: // if (this.IsTargetAttribute(targetSymbol, AttributeDescription.PrincipalPermissionAttribute)) // { // // CS7052: SecurityAction value '{0}' is invalid for PrincipalPermission attribute // string displayString; // Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); // diagnostics.Add(ErrorCode.ERR_PrincipalPermissionInvalidAction, syntaxLocation, displayString); // hasErrors = true; // return DeclarativeSecurityAction.None; // } // isPermissionRequestAction = false; // break; // case 1: // // Native compiler allows security action value 1 for security attributes on types/methods, even though there is no corresponding field in System.Security.Permissions.SecurityAction enum. // // We will maintain compatibility. // case (int)DeclarativeSecurityAction.Assert: // case (int)DeclarativeSecurityAction.Demand: // case (int)DeclarativeSecurityAction.PermitOnly: // case (int)DeclarativeSecurityAction.Deny: // isPermissionRequestAction = false; // break; // case (int)DeclarativeSecurityAction.RequestMinimum: // case (int)DeclarativeSecurityAction.RequestOptional: // case (int)DeclarativeSecurityAction.RequestRefuse: // isPermissionRequestAction = true; // break; // default: // { // // CS7049: Security attribute '{0}' has an invalid SecurityAction value '{1}' // string displayString; // Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); // diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidAction, syntaxLocation, nodeOpt != null ? nodeOpt.GetErrorDisplayName() : "", displayString); // hasErrors = true; // return DeclarativeSecurityAction.None; // } // } // // Validate security action for symbol kind // if (isPermissionRequestAction) // { // if (targetSymbol.Kind == SymbolKind.NamedType || targetSymbol.Kind == SymbolKind.Method) // { // // Types and methods cannot take permission requests. // // CS7051: SecurityAction value '{0}' is invalid for security attributes applied to a type or a method // string displayString; // Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); // diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod, syntaxLocation, displayString); // hasErrors = true; // return DeclarativeSecurityAction.None; // } // } // else // { // if (targetSymbol.Kind == SymbolKind.Assembly) // { // // Assemblies cannot take declarative security. // // CS7050: SecurityAction value '{0}' is invalid for security attributes applied to an assembly // string displayString; // Location syntaxLocation = GetSecurityAttributeActionSyntaxLocation(nodeOpt, typedValue, out displayString); // diagnostics.Add(ErrorCode.ERR_SecurityAttributeInvalidActionAssembly, syntaxLocation, displayString); // hasErrors = true; // return DeclarativeSecurityAction.None; // } // } // hasErrors = false; // return (DeclarativeSecurityAction)securityAction; //} //private static Location GetSecurityAttributeActionSyntaxLocation(AttributeSyntax nodeOpt, TypedConstant typedValue, out string displayString) //{ // if (nodeOpt == null) // { // displayString = ""; // return NoLocation.Singleton; // } // var argList = nodeOpt.ArgumentList; // if (argList == null || argList.Arguments.IsEmpty()) // { // // Optional SecurityAction parameter with default value. // displayString = typedValue.Value.ToString(); // return nodeOpt.Location; // } // AttributeArgumentSyntax argSyntax = argList.Arguments[0]; // displayString = argSyntax.ToString(); // return argSyntax.Location; //} ///// <summary> ///// Decodes PermissionSetAttribute applied in source to determine if it needs any fixup during codegen. ///// </summary> ///// <remarks> ///// PermissionSetAttribute needs fixup when it contains an assignment to the 'File' property as a single named attribute argument. ///// Fixup performed is ported from SecurityAttributes::FixUpPermissionSetAttribute. ///// It involves following steps: ///// 1) Verifying that the specified file name resolves to a valid path. ///// 2) Reading the contents of the file into a byte array. ///// 3) Convert each byte in the file content into two bytes containing hexadecimal characters. ///// 4) Replacing the 'File = fileName' named argument with 'Hex = hexFileContent' argument, where hexFileContent is the converted output from step 3) above. ///// ///// Step 1) is performed in this method, i.e. during binding. ///// Remaining steps are performed during serialization as we want to avoid retaining the entire file contents throughout the binding/codegen pass. ///// See <see cref="Microsoft.CodeAnalysis.CodeGen.PermissionSetAttributeWithFileReference"/> for remaining fixup steps. ///// </remarks> ///// <returns>String containing the resolved file path if PermissionSetAttribute needs fixup during codegen, null otherwise.</returns> //private string DecodePermissionSetAttribute(PhpCompilation compilation, AttributeSyntax nodeOpt, DiagnosticBag diagnostics) //{ // Debug.Assert(!this.HasErrors); // string resolvedFilePath = null; // var namedArgs = this.CommonNamedArguments; // if (namedArgs.Length == 1) // { // var namedArg = namedArgs[0]; // NamedTypeSymbol attrType = this.AttributeClass; // string filePropName = PermissionSetAttributeWithFileReference.FilePropertyName; // string hexPropName = PermissionSetAttributeWithFileReference.HexPropertyName; // if (namedArg.Key == filePropName && // PermissionSetAttributeTypeHasRequiredProperty(attrType, filePropName)) // { // // resolve file prop path // var fileName = (string)namedArg.Value.Value; // var resolver = compilation.Options.XmlReferenceResolver; // resolvedFilePath = (resolver != null) ? resolver.ResolveReference(fileName, baseFilePath: null) : null; // if (resolvedFilePath == null) // { // // CS7053: Unable to resolve file path '{0}' specified for the named argument '{1}' for PermissionSet attribute // Location argSyntaxLocation = nodeOpt != null ? nodeOpt.GetNamedArgumentSyntax(filePropName).Location : NoLocation.Singleton; // diagnostics.Add(ErrorCode.ERR_PermissionSetAttributeInvalidFile, argSyntaxLocation, fileName ?? "<null>", filePropName); // } // else if (!PermissionSetAttributeTypeHasRequiredProperty(attrType, hexPropName)) // { // // PermissionSetAttribute was defined in user source, but doesn't have the required Hex property. // // Native compiler still emits the file content as named assignment to 'Hex' property, but this leads to a runtime exception. // // We instead skip the fixup and emit the file property. // // CONSIDER: We may want to consider taking a breaking change and generating an error here. // return null; // } // } // } // return resolvedFilePath; //} // This method checks if the given PermissionSetAttribute type has a property member with the given propName which is writable, non-generic, public and of string type. private static bool PermissionSetAttributeTypeHasRequiredProperty(NamedTypeSymbol permissionSetType, string propName) { var members = permissionSetType.GetMembers(propName); if (members.Length == 1 && members[0].Kind == SymbolKind.Property) { var property = (PropertySymbol)members[0]; if ((object)property.Type != null && property.Type.SpecialType == SpecialType.System_String && property.DeclaredAccessibility == Accessibility.Public && property.GetMemberArity() == 0 && (object)property.SetMethod != null && property.SetMethod.DeclaredAccessibility == Accessibility.Public) { return true; } } return false; }
internal SynthesizedInstanceConstructor(NamedTypeSymbol containingType) { Debug.Assert((object)containingType != null); _containingType = containingType; }
internal MethodSymbol AsMember(NamedTypeSymbol newOwner) { Debug.Assert(this.IsDefinition); Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition)); return (newOwner == this.ContainingSymbol) ? this : new SubstitutedMethodSymbol((SubstitutedNamedTypeSymbol)newOwner, this); }
/// <summary> /// Lookup a top level type referenced from metadata, names should be /// compared case-sensitively. Detect cycles during lookup. /// </summary> /// <param name="emittedName"> /// Full type name, possibly with generic name mangling. /// </param> /// <param name="visitedAssemblies"> /// List of assemblies lookup has already visited (since type forwarding can introduce cycles). /// </param> /// <param name="digThroughForwardedTypes"> /// Take forwarded types into account. /// </param> internal sealed override NamedTypeSymbol LookupTopLevelMetadataTypeWithCycleDetection(ref MetadataTypeName emittedName, ConsList <AssemblySymbol> visitedAssemblies, bool digThroughForwardedTypes) { NamedTypeSymbol result = null; // This is a cache similar to the one used by MetaImport::GetTypeByName in native // compiler. The difference is that native compiler pre-populates the cache when it // loads types. Here we are populating the cache only with things we looked for, so that // next time we are looking for the same thing, the lookup is fast. This cache also // takes care of TypeForwarders. Gives about 8% win on subsequent lookups in some // scenarios. // // CONSIDER !!! // // However, it is questionable how often subsequent lookup by name is going to happen. // Currently it doesn't happen for TypeDef tokens at all, for TypeRef tokens, the // lookup by name is done once and the result is cached. So, multiple lookups by name // for the same type are going to happen only in these cases: // 1) Resolving GetType() in attribute application, type is encoded by name. // 2) TypeRef token isn't reused within the same module, i.e. multiple TypeRefs point to // the same type. // 3) Different Module refers to the same type, lookup once per Module (with exception of #2). // 4) Multitargeting - retargeting the type to a different version of assembly result = LookupTopLevelMetadataTypeInCache(ref emittedName); if ((object)result != null) { // We only cache result equivalent to digging through type forwarders, which // might produce an forwarder specific ErrorTypeSymbol. We don't want to // return that error symbol, unless digThroughForwardedTypes is true. if (digThroughForwardedTypes || (!result.IsErrorType() && (object)result.ContainingAssembly == (object)this)) { return(result); } // According to the cache, the type wasn't found, or isn't declared in this assembly (forwarded). throw new NotImplementedException(); //return new MissingMetadataTypeSymbol.TopLevel(this.Modules[0], ref emittedName); } else { // Now we will look for the type in each module of the assembly and pick the first type // we find, this is what native VB compiler does. var modules = this.Modules; var count = modules.Length; var i = 0; result = modules[i].LookupTopLevelMetadataType(ref emittedName); if (result is ErrorTypeSymbol) { for (i = 1; i < count; i++) { var newResult = modules[i].LookupTopLevelMetadataType(ref emittedName); // Hold on to the first missing type result, unless we found the type. if (!(newResult is ErrorTypeSymbol)) { result = newResult; break; } } } bool foundMatchInThisAssembly = (i < count); Debug.Assert(!foundMatchInThisAssembly || (object)result.ContainingAssembly == (object)this); if (!foundMatchInThisAssembly && digThroughForwardedTypes) { // We didn't find the type Debug.Assert(result is ErrorTypeSymbol); NamedTypeSymbol forwarded = TryLookupForwardedMetadataTypeWithCycleDetection(ref emittedName, visitedAssemblies); if ((object)forwarded != null) { result = forwarded; } } Debug.Assert((object)result != null); // Add result of the lookup into the cache if (digThroughForwardedTypes || foundMatchInThisAssembly) { CacheTopLevelMetadataType(ref emittedName, result); } return(result); } }
public SynthesizedCtorSymbol(NamedTypeSymbol /*!*/ container) : base(container, WellKnownMemberNames.InstanceConstructorName, false, false, container.DeclaringCompilation.CoreTypes.Void) { Debug.Assert(!container.IsStatic); }
///// <summary> ///// Count the number of custom modifiers in/on the return type ///// and parameters of the specified method. ///// </summary> //public static int CustomModifierCount(this MethodSymbol method) //{ // int count = 0; // count += method.ReturnTypeCustomModifiers.Length; // count += method.ReturnType.CustomModifierCount(); // foreach (ParameterSymbol param in method.Parameters) // { // count += param.CustomModifiers.Length; // count += param.Type.CustomModifierCount(); // } // return count; //} //public static int CustomModifierCount(this Symbol m) //{ // switch (m.Kind) // { // case SymbolKind.ArrayType: // case SymbolKind.ErrorType: // case SymbolKind.NamedType: // case SymbolKind.PointerType: // case SymbolKind.TypeParameter: // return ((TypeSymbol)m).CustomModifierCount(); // case SymbolKind.Event: // throw new NotImplementedException(); // //return ((EventSymbol)m).CustomModifierCount(); // case SymbolKind.Method: // return ((MethodSymbol)m).CustomModifierCount(); // case SymbolKind.Property: // return ((PropertySymbol)m).CustomModifierCount(); // default: // throw ExceptionUtilities.UnexpectedValue(m.Kind); // } //} //public static int CustomModifierCount(this EventSymbol e) //{ // return e.Type.CustomModifierCount(); //} ///// <summary> ///// Count the number of custom modifiers in/on the type ///// and parameters (for indexers) of the specified property. ///// </summary> //public static int CustomModifierCount(this PropertySymbol property) //{ // int count = 0; // count += property.TypeCustomModifiers.Length; // count += property.Type.CustomModifierCount(); // foreach (ParameterSymbol param in property.Parameters) // { // count += param.CustomModifiers.Length; // count += param.Type.CustomModifierCount(); // } // return count; //} internal static Symbol SymbolAsMember(this Symbol s, NamedTypeSymbol newOwner) { switch (s.Kind) { case SymbolKind.Field: return ((FieldSymbol)s).AsMember(newOwner); case SymbolKind.Method: return ((MethodSymbol)s).AsMember(newOwner); //case SymbolKind.NamedType: // return ((NamedTypeSymbol)s).AsMember(newOwner); case SymbolKind.Property: return ((PropertySymbol)s).AsMember(newOwner); //case SymbolKind.Event: // return ((EventSymbol)s).AsMember(newOwner); default: throw ExceptionUtilities.UnexpectedValue(s.Kind); } }
/// <summary> /// Gets type full qualified name. /// </summary> public static QualifiedName MakeQualifiedName(this NamedTypeSymbol type) { return(NameUtils.MakeQualifiedName(type.Name, type.NamespaceName, true)); }
public GenericNestedTypeInstanceReference(NamedTypeSymbol underlyingNamedType) : base(underlyingNamedType) { }
internal void Bind(Symbol symbol, SourceFileSymbol file) { Debug.Assert(symbol != null); if (_type == null) { // TODO: check the attribute can bi bound to symbol var type = (NamedTypeSymbol)symbol.DeclaringCompilation.GetTypeFromTypeRef(_tref); if (type.IsErrorTypeOrNull() || type.SpecialType == SpecialType.System_Object) { symbol.DeclaringCompilation.DeclarationDiagnostics.Add( Location.Create(file.SyntaxTree, _tref.Span.ToTextSpan()), Errors.ErrorCode.ERR_TypeNameCannotBeResolved, _tref.ToString()); type = new MissingMetadataTypeSymbol(_tref.ToString(), 0, false); } // bind arguments if (!TryResolveCtor(type, symbol.DeclaringCompilation, out _ctor, out _ctorArgs) && type.IsValidType()) { symbol.DeclaringCompilation.DeclarationDiagnostics.Add( Location.Create(file.SyntaxTree, _tref.Span.ToTextSpan()), Errors.ErrorCode.ERR_NoMatchingOverload, type.Name + "..ctor"); } // bind named parameters if (type.IsErrorTypeOrNull() || _properties.IsDefaultOrEmpty) { _namedArgs = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty; } else { var namedArgs = new KeyValuePair <string, TypedConstant> [_properties.Length]; for (int i = 0; i < namedArgs.Length; i++) { var prop = _properties[i]; var member = (Symbol)type.LookupMember <PropertySymbol>(prop.Key.Value) ?? (Symbol)type.LookupMember <FieldSymbol>(prop.Key.Value); if (member != null && TryBindTypedConstant(member.GetTypeOrReturnType(), prop.Value, symbol.DeclaringCompilation, out var arg)) { namedArgs[i] = new KeyValuePair <string, TypedConstant>(prop.Key.Value, arg); } else { throw new InvalidOperationException(); } } _namedArgs = namedArgs.AsImmutable(); } // _type = type; } }
bool TryResolveCtor(NamedTypeSymbol type, PhpCompilation compilation, out MethodSymbol ctor, out ImmutableArray <TypedConstant> args) { if (type.IsValidType()) { var candidates = type.InstanceConstructors; for (int i = 0; i < candidates.Length; i++) { var m = candidates[i]; if (m.DeclaredAccessibility != Accessibility.Public) { continue; // TODO: or current class context } if (m.IsGenericMethod) { Debug.Fail("unexpected"); continue; } // NS if (m.ParameterCount < _arguments.Length) { continue; // be strict } var match = true; var ps = m.Parameters; var boundargs = new TypedConstant[ps.Length]; for (var pi = 0; match && pi < ps.Length; pi++) { if (pi >= _arguments.Length) { //if (ps[pi].IsOptional) //{ // boundargs[pi] = ps[pi].ExplicitDefaultConstantValue.AsTypedConstant(); // continue; // ok //} //else { match = false; break; } } if (TryBindTypedConstant(ps[pi].Type, _arguments[pi], compilation, out var arg)) { boundargs[pi] = arg; } else { match = false; break; } } if (match) { ctor = m; args = boundargs.AsImmutable(); return(true); } } } // ctor = new MissingMethodSymbol(); args = ImmutableArray <TypedConstant> .Empty; return(false); }
internal TypeMap WithAlphaRename(NamedTypeSymbol oldOwner, NamedTypeSymbol newOwner, out ImmutableArray<TypeParameterSymbol> newTypeParameters) { Debug.Assert(oldOwner.ConstructedFrom == oldOwner); return WithAlphaRename(oldOwner.OriginalDefinition.TypeParameters, newOwner, out newTypeParameters); }
public DynamicOperationFactory(CodeGenerator cg, NamedTypeSymbol container) { Contract.ThrowIfNull(cg); _cg = cg; _compilation = cg.DeclaringCompilation; _container = container; }
internal virtual NamedTypeSymbol AsMember(NamedTypeSymbol newOwner) { Debug.Assert(this.IsDefinition); Debug.Assert(ReferenceEquals(newOwner.OriginalDefinition, this.ContainingSymbol.OriginalDefinition)); return(newOwner.IsDefinition ? this : new SubstitutedNestedTypeSymbol((SubstitutedNamedTypeSymbol)newOwner, this)); }
public static bool IsTopLevelType(this NamedTypeSymbol type) { return((object)type.ContainingType == null); }
public SpecializedNestedTypeReference(NamedTypeSymbol underlyingNamedType) : base(underlyingNamedType) { }
internal override TypeSymbol SubstituteTypeParameters( PEModuleSymbol moduleSymbol, TypeSymbol genericTypeDef, ImmutableArray <KeyValuePair <TypeSymbol, ImmutableArray <ModifierInfo <TypeSymbol> > > > arguments, ImmutableArray <bool> refersToNoPiaLocalType) { if (genericTypeDef is UnsupportedMetadataTypeSymbol) { return(genericTypeDef); } // Let's return unsupported metadata type if any argument is unsupported metadata type foreach (var arg in arguments) { if (arg.Key.Kind == SymbolKind.ErrorType && arg.Key is UnsupportedMetadataTypeSymbol) { return(new UnsupportedMetadataTypeSymbol()); } } NamedTypeSymbol genericType = (NamedTypeSymbol)genericTypeDef; //// See if it is or its enclosing type is a non-interface closed over NoPia local types. //ImmutableArray<AssemblySymbol> linkedAssemblies = moduleSymbol.ContainingAssembly.GetLinkedReferencedAssemblies(); //bool noPiaIllegalGenericInstantiation = false; //if (!linkedAssemblies.IsDefaultOrEmpty || moduleSymbol.Module.ContainsNoPiaLocalTypes()) //{ // NamedTypeSymbol typeToCheck = genericType; // int argumentIndex = refersToNoPiaLocalType.Length - 1; // do // { // if (!typeToCheck.IsInterface) // { // break; // } // else // { // argumentIndex -= typeToCheck.Arity; // } // typeToCheck = typeToCheck.ContainingType; // } // while ((object)typeToCheck != null); // for (int i = argumentIndex; i >= 0; i--) // { // if (refersToNoPiaLocalType[i] || // (!linkedAssemblies.IsDefaultOrEmpty && // MetadataDecoder.IsOrClosedOverATypeFromAssemblies(arguments[i].Key, linkedAssemblies))) // { // noPiaIllegalGenericInstantiation = true; // break; // } // } //} // Collect generic parameters for the type and its containers in the order // that matches passed in arguments, i.e. sorted by the nesting. ImmutableArray <TypeParameterSymbol> typeParameters = genericType.GetAllTypeParameters(); Debug.Assert(typeParameters.Length > 0); if (typeParameters.Length != arguments.Length) { return(new UnsupportedMetadataTypeSymbol()); } TypeMap substitution = new TypeMap(typeParameters, arguments.SelectAsArray(arg => new TypeWithModifiers(arg.Key, CSharpCustomModifier.Convert(arg.Value)))); NamedTypeSymbol constructedType = substitution.SubstituteNamedType(genericType); //if (noPiaIllegalGenericInstantiation) //{ // constructedType = new NoPiaIllegalGenericInstantiationSymbol(moduleSymbol, constructedType); //} return(constructedType); }