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); }
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); } }