Beispiel #1
0
        private NamedTypeSymbol TransformNamedType(NamedTypeSymbol namedType, bool isContaining = false)
        {
            if (namedType.IsTupleType)
            {
                return(TransformTupleType(namedType, isContaining));
            }

            // Native compiler encodes a bool for the given namedType, but none for its containing types.
            if (!isContaining)
            {
                var flag = ConsumeFlag();
                Debug.Assert(!flag);
            }

            NamedTypeSymbol containingType = namedType.ContainingType;
            NamedTypeSymbol newContainingType;

            if ((object)containingType != null && containingType.IsGenericType)
            {
                newContainingType = TransformNamedType(namedType.ContainingType, isContaining: true);
                if ((object)newContainingType == null)
                {
                    return(null);
                }

                Debug.Assert(newContainingType.IsGenericType);
            }
            else
            {
                newContainingType = containingType;
            }

            // Native compiler encodes bools for each type argument, starting from type arguments for the outermost containing type to those for the given namedType.
            ImmutableArray <TypeSymbolWithAnnotations> typeArguments = namedType.TypeArgumentsNoUseSiteDiagnostics;

            ImmutableArray <TypeSymbolWithAnnotations> transformedTypeArguments = TransformTypeArguments(typeArguments); // Note, modifiers are not involved, this is behavior of the native compiler.

            if (transformedTypeArguments.IsDefault)
            {
                return(null);
            }

            // Construct a new namedType, if required.
            bool containerIsChanged = (!TypeSymbol.Equals(newContainingType, containingType, TypeCompareKind.ConsiderEverything2));

            if (containerIsChanged || transformedTypeArguments != typeArguments)
            {
                if (containerIsChanged)
                {
                    namedType = namedType.OriginalDefinition.AsMember(newContainingType);
                    return(namedType.ConstructIfGeneric(transformedTypeArguments));
                }

                return(namedType.ConstructedFrom.Construct(transformedTypeArguments, unbound: false));
            }
            else
            {
                return(namedType);
            }
        }
        private NamedTypeSymbol TransformNamedType(NamedTypeSymbol namedType, bool isContaining = false)
        {
            // Native compiler encodes a bool for the given namedType, but none for its containing types.
            if (!isContaining)
            {
                var flag = ConsumeFlag();
                Debug.Assert(!flag);
            }

            NamedTypeSymbol containingType = namedType.ContainingType;
            NamedTypeSymbol newContainingType;

            if ((object)containingType != null && containingType.IsGenericType)
            {
                newContainingType = TransformNamedType(namedType.ContainingType, isContaining: true);
                if ((object)newContainingType == null)
                {
                    return(null);
                }

                Debug.Assert(newContainingType.IsGenericType);
            }
            else
            {
                newContainingType = containingType;
            }

            // Native compiler encodes bools for each type argument, starting from type arguments for the outermost containing type to those for the given namedType.
            ImmutableArray <TypeSymbol> typeArguments = namedType.TypeArgumentsNoUseSiteDiagnostics;
            var customModifiers = namedType.HasTypeArgumentsCustomModifiers ? namedType.TypeArgumentsCustomModifiers : default(ImmutableArray <ImmutableArray <CustomModifier> >);

            ImmutableArray <TypeSymbol> transformedTypeArguments = TransformTypeArguments(typeArguments); // Note, modifiers are not involved, this is behavior of the native compiler.

            if (transformedTypeArguments.IsDefault)
            {
                return(null);
            }

            // Construct a new namedType, if required.
            bool containerIsChanged = (newContainingType != containingType);

            if (containerIsChanged || transformedTypeArguments != typeArguments)
            {
                var newTypeArguments = customModifiers.IsDefault ?
                                       transformedTypeArguments.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers) :
                                       transformedTypeArguments.Zip(customModifiers, (t, m) => new TypeWithModifiers(t, m)).AsImmutable();

                if (containerIsChanged)
                {
                    namedType = namedType.OriginalDefinition.AsMember(newContainingType);
                    return(namedType.ConstructIfGeneric(newTypeArguments));
                }

                return(namedType.ConstructedFrom.Construct(newTypeArguments, unbound: false));
            }
            else
            {
                return(namedType);
            }
        }
        private NamedTypeSymbol DecodeNamedType(NamedTypeSymbol type)
        {
            // First decode the type arguments
            var typeArgs    = type.TypeArgumentsNoUseSiteDiagnostics;
            var decodedArgs = DecodeTypeArguments(typeArgs);

            NamedTypeSymbol decodedType = type;

            // Now check the container
            NamedTypeSymbol containingType = type.ContainingType;
            NamedTypeSymbol decodedContainingType;

            if ((object)containingType != null && containingType.IsGenericType)
            {
                decodedContainingType = DecodeNamedType(containingType);
                Debug.Assert(decodedContainingType.IsGenericType);
            }
            else
            {
                decodedContainingType = containingType;
            }

            // Replace the type if necessary
            var containerChanged = !ReferenceEquals(decodedContainingType, containingType);
            var typeArgsChanged  = typeArgs != decodedArgs;

            if (typeArgsChanged || containerChanged)
            {
                var newTypeArgs = type.HasTypeArgumentsCustomModifiers
                    ? decodedArgs.SelectAsArray((t, i, m) => new TypeWithModifiers(t, m.GetTypeArgumentCustomModifiers(i)), type)
                    : decodedArgs.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers);

                if (containerChanged)
                {
                    decodedType = decodedType.OriginalDefinition.AsMember(decodedContainingType);
                    // If the type is nested, e.g. Outer<T>.Inner<V>, then Inner is definitely
                    // not a tuple, since we know all tuple-compatible types (System.ValueTuple)
                    // are not nested types. Thus, it is safe to return without checking if
                    // Inner is a tuple.
                    return(decodedType.ConstructIfGeneric(newTypeArgs));
                }

                decodedType = type.ConstructedFrom.Construct(newTypeArgs, unbound: false);
            }

            // Now decode into a tuple, if it is one
            int tupleCardinality;

            if (decodedType.IsTupleCompatible(out tupleCardinality))
            {
                var elementNames = EatElementNamesIfAvailable(tupleCardinality);

                Debug.Assert(elementNames.IsDefault || elementNames.Length == tupleCardinality);

                decodedType = TupleTypeSymbol.Create(decodedType, elementNames);
            }

            return(decodedType);
        }
Beispiel #4
0
        private NamedTypeSymbol DecodeNamedType(NamedTypeSymbol type)
        {
            // First decode the type arguments
            var typeArgs    = type.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics;
            var decodedArgs = DecodeTypeArguments(typeArgs);

            NamedTypeSymbol decodedType = type;

            // Now check the container
            NamedTypeSymbol containingType = type.ContainingType;
            NamedTypeSymbol?decodedContainingType;

            if (containingType is object && containingType.IsGenericType)
            {
                decodedContainingType = DecodeNamedType(containingType);
                Debug.Assert(decodedContainingType.IsGenericType);
            }
            else
            {
                decodedContainingType = containingType;
            }

            // Replace the type if necessary
            var containerChanged = !ReferenceEquals(decodedContainingType, containingType);
            var typeArgsChanged  = typeArgs != decodedArgs;

            if (typeArgsChanged || containerChanged)
            {
                if (containerChanged)
                {
                    decodedType = decodedType.OriginalDefinition.AsMember(decodedContainingType);
                    // If the type is nested, e.g. Outer<T>.Inner<V>, then Inner is definitely
                    // not a tuple, since we know all tuple-compatible types (System.ValueTuple)
                    // are not nested types. Thus, it is safe to return without checking if
                    // Inner is a tuple.
                    return(decodedType.ConstructIfGeneric(decodedArgs));
                }

                decodedType = type.ConstructedFrom.Construct(decodedArgs, unbound: false);
            }

            // Now decode into a tuple, if it is one
            if (decodedType.IsTupleType)
            {
                int tupleCardinality = decodedType.TupleElementTypesWithAnnotations.Length;
                if (tupleCardinality > 0)
                {
                    var elementNames = EatElementNamesIfAvailable(tupleCardinality);

                    Debug.Assert(elementNames.IsDefault || elementNames.Length == tupleCardinality);

                    decodedType = NamedTypeSymbol.CreateTuple(decodedType, elementNames);
                }
            }

            return(decodedType);
        }
        private NamedTypeSymbol TransformNamedType(NamedTypeSymbol namedType, bool isContaining = false)
        {
            Debug.Assert(!dynamicTransformFlags[index] || isContaining);

            // Native compiler encodes a bool for the given namedType, but none for its containing types.
            if (!isContaining)
            {
                index++;
            }

            NamedTypeSymbol containingType = namedType.ContainingType;
            NamedTypeSymbol newContainingType;

            if ((object)containingType != null && containingType.IsGenericType)
            {
                newContainingType = TransformNamedType(namedType.ContainingType, isContaining: true);
                if ((object)newContainingType == null)
                {
                    return(null);
                }

                Debug.Assert(newContainingType.IsGenericType);
            }
            else
            {
                newContainingType = containingType;
            }

            // Native compiler encodes bools for each type argument, starting from type arguments for the outermost containing type to those for the given namedType.
            ImmutableArray <TypeSymbol> typeArguments            = namedType.TypeArgumentsNoUseSiteDiagnostics;
            ImmutableArray <TypeSymbol> transformedTypeArguments = TransformTypeArguments(typeArguments);

            if (transformedTypeArguments.IsDefault)
            {
                return(null);
            }

            // Construct a new namedType, if required.
            if (newContainingType != containingType)
            {
                namedType = namedType.OriginalDefinition.AsMember(newContainingType);
                return(namedType.ConstructIfGeneric(transformedTypeArguments));
            }
            else if (transformedTypeArguments != typeArguments)
            {
                return(namedType.ConstructedFrom.Construct(transformedTypeArguments));
            }
            else
            {
                return(namedType);
            }
        }