示例#1
0
        /// <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 = SubstituteTypes(oldFieldTypes);
                return((oldFieldTypes == newFieldTypes) ? previous : AnonymousTypeManager.ConstructAnonymousTypeSymbol(previous, newFieldTypes));
            }

            // 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.TypeArgumentsNoUseSiteDiagnostics;
            ImmutableArray <TypeSymbol> newTypeArguments = SubstituteTypes(oldTypeArguments);

            if (ReferenceEquals(oldConstructedFrom, newConstructedFrom) && oldTypeArguments == newTypeArguments)
            {
                return(previous);
            }

            return(newConstructedFrom.ConstructIfGeneric(newTypeArguments));
        }
示例#2
0
        /// <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));
            }

            if (previous.IsTupleType)
            {
                var             previousTuple     = (TupleTypeSymbol)previous;
                NamedTypeSymbol oldUnderlyingType = previousTuple.TupleUnderlyingType;
                NamedTypeSymbol newUnderlyingType = (NamedTypeSymbol)SubstituteType(oldUnderlyingType).Type;

                return(((object)newUnderlyingType == (object)oldUnderlyingType) ? previous : previousTuple.WithUnderlyingType(newUnderlyingType));
            }

            // 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.TypeArgumentsNoUseSiteDiagnostics;
            bool changed          = !ReferenceEquals(oldConstructedFrom, newConstructedFrom);
            bool hasModifiers     = previous.HasTypeArgumentsCustomModifiers;
            var  newTypeArguments = ArrayBuilder <TypeWithModifiers> .GetInstance(oldTypeArguments.Length);

            for (int i = 0; i < oldTypeArguments.Length; i++)
            {
                var oldArgument = hasModifiers ? new TypeWithModifiers(oldTypeArguments[i], previous.GetTypeArgumentCustomModifiers(i)) : new TypeWithModifiers(oldTypeArguments[i]);
                var newArgument = oldArgument.SubstituteTypeWithTupleUnification(this);

                if (!changed && oldArgument != newArgument)
                {
                    changed = true;
                }

                newTypeArguments.Add(newArgument);
            }

            if (!changed)
            {
                newTypeArguments.Free();
                return(previous);
            }

            return(newConstructedFrom.ConstructIfGeneric(newTypeArguments.ToImmutableAndFree()));
        }