/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. // NOTE: ref is irrelevant here since we are just encoding/decoding the type out of the signature context ImmutableArray <bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, RefKind.None); TypeSymbol typeWithDynamic = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, RefKind.None, flags); TypeSymbol resultType; if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreDynamic)) { // We also preserve tuple names, if present and different ImmutableArray <string> names = CSharpCompilation.TupleNamesEncoder.Encode(destinationType); resultType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithDynamic, names); } else { resultType = typeWithDynamic; } Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames)); // Same custom modifiers as source type. Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic and tuple names as destination type. return(resultType); }
internal static LocalSymbol Create( TypeNameDecoder <PEModuleSymbol, TypeSymbol> typeNameDecoder, MethodSymbol containingMethod, AssemblySymbol sourceAssembly, Alias alias) { var typeName = alias.Type; Debug.Assert(typeName.Length > 0); var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName); Debug.Assert((object)type != null); ReadOnlyCollection <byte> dynamicFlags; ReadOnlyCollection <string> tupleElementNames; CustomTypeInfo.Decode(alias.CustomTypeInfoId, alias.CustomTypeInfo, out dynamicFlags, out tupleElementNames); if (dynamicFlags != null) { type = DecodeDynamicTypes(type, sourceAssembly, dynamicFlags); } if (tupleElementNames != null) { type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, sourceAssembly, tupleElementNames.AsImmutable()); } var name = alias.FullName; var displayName = alias.Name; switch (alias.Kind) { case DkmClrAliasKind.Exception: return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetExceptionMethodName)); case DkmClrAliasKind.StowedException: return(new ExceptionLocalSymbol(containingMethod, name, displayName, type, ExpressionCompilerConstants.GetStowedExceptionMethodName)); case DkmClrAliasKind.ReturnValue: { int index; PseudoVariableUtilities.TryParseReturnValueIndex(name, out index); Debug.Assert(index >= 0); return(new ReturnValueLocalSymbol(containingMethod, name, displayName, type, index)); } case DkmClrAliasKind.ObjectId: return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: false)); case DkmClrAliasKind.Variable: return(new ObjectIdLocalSymbol(containingMethod, type, name, displayName, isWritable: true)); default: throw ExceptionUtilities.UnexpectedValue(alias.Kind); } }
private TypeSymbol IncludeDynamicAndTupleElementNamesIfAny( TypeSymbol type, RefKind refKind, ImmutableArray <bool> dynamicFlagsOpt, ImmutableArray <string?> tupleElementNamesOpt) { if (!dynamicFlagsOpt.IsDefault) { type = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(type, _sourceAssembly, refKind, dynamicFlagsOpt, checkLength: false); } return(TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, tupleElementNamesOpt)); }
/// <param name="sourceType">Type that already has custom modifiers.</param> /// <param name="destinationType">Same as <paramref name="sourceType"/>, but without custom modifiers. May differ in object/dynamic.</param> /// <param name="containingAssembly">The assembly containing the signature referring to the destination type.</param> /// <param name="nonNullTypesContext">The NonNullTypes context at the destination.</param> /// <returns><paramref name="destinationType"/> with custom modifiers copied from <paramref name="sourceType"/>.</returns> internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly, INonNullTypesContext nonNullTypesContext) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); Debug.Assert(nonNullTypesContext != null); const RefKind refKind = RefKind.None; // NOTE: overrides can differ by object/dynamic. If they do, we'll need to tweak newType before // we can use it in place of this.Type. We do so by computing the dynamic transform flags that // code gen uses and then passing them to the dynamic type decoder that metadata reading uses. // NOTE: ref is irrelevant here since we are just encoding/decoding the type out of the signature context ImmutableArray <bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol typeWithDynamic = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); TypeSymbol resultType; if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreDynamic)) { // We also preserve tuple names, if present and different ImmutableArray <string> names = CSharpCompilation.TupleNamesEncoder.Encode(destinationType); resultType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithDynamic, names); } else { resultType = typeWithDynamic; } // Preserve nullable modifiers as well. // https://github.com/dotnet/roslyn/issues/30077: Is it reasonable to copy annotations from the source? // If the destination had some of those annotations but not all, then clearly the destination // was incorrect. Or if the destination is C#7, then the destination will advertise annotations // that the author did not write and did not validate. var flagsBuilder = ArrayBuilder <bool> .GetInstance(); destinationType.AddNullableTransforms(flagsBuilder); int position = 0; int length = flagsBuilder.Count; bool transformResult = resultType.ApplyNullableTransforms(flagsBuilder.ToImmutableAndFree(), nonNullTypesContext, ref position, out resultType); Debug.Assert(transformResult && position == length); Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames)); // Same custom modifiers as source type. // Note: We would want to check nullability, but that would pull on NonNullTypes too early (ie. cause cycles). Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); // Same object/dynamic and tuple names as destination type. return(resultType); }
internal static TypeSymbol CopyTypeCustomModifiers(TypeSymbol sourceType, TypeSymbol destinationType, AssemblySymbol containingAssembly) { Debug.Assert(sourceType.Equals(destinationType, TypeCompareKind.AllIgnoreOptions)); const RefKind refKind = RefKind.None; // NOTE: overrides can differ by object/dynamic, tuple element names, etc. // If they do, we'll need to tweak destinationType before we can use it in place of sourceType. // NOTE: refKind is irrelevant here since we are just encoding/decoding the type. ImmutableArray <bool> flags = CSharpCompilation.DynamicTransformsEncoder.EncodeWithoutCustomModifierFlags(destinationType, refKind); TypeSymbol resultType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags(sourceType, containingAssembly, refKind, flags); if (!containingAssembly.RuntimeSupportsNumericIntPtr) { var builder = ArrayBuilder <bool> .GetInstance(); CSharpCompilation.NativeIntegerTransformsEncoder.Encode(builder, destinationType); resultType = NativeIntegerTypeDecoder.TransformType(resultType, builder.ToImmutableAndFree()); } if (destinationType.ContainsTuple() && !sourceType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreDynamic)) { // We also preserve tuple names, if present and different ImmutableArray <string> names = CSharpCompilation.TupleNamesEncoder.Encode(destinationType); resultType = TupleTypeDecoder.DecodeTupleTypesIfApplicable(resultType, names); } // Preserve nullable modifiers as well. // https://github.com/dotnet/roslyn/issues/30077: Is it reasonable to copy annotations from the source? // If the destination had some of those annotations but not all, then clearly the destination // was incorrect. Or if the destination is C#7, then the destination will advertise annotations // that the author did not write and did not validate. var flagsBuilder = ArrayBuilder <byte> .GetInstance(); destinationType.AddNullableTransforms(flagsBuilder); int position = 0; int length = flagsBuilder.Count; bool transformResult = resultType.ApplyNullableTransforms(defaultTransformFlag: 0, flagsBuilder.ToImmutableAndFree(), ref position, out resultType); Debug.Assert(transformResult && position == length); Debug.Assert(resultType.Equals(sourceType, TypeCompareKind.IgnoreDynamicAndTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes | TypeCompareKind.IgnoreNativeIntegers)); // Same custom modifiers as source type. // Same object/dynamic, nullability, native integers, and tuple names as destination type. Debug.Assert(resultType.Equals(destinationType, TypeCompareKind.IgnoreCustomModifiersAndArraySizesAndLowerBounds)); return(resultType); }
private TypeSymbol IncludeTupleElementNames(TypeSymbol type, ImmutableArray <string> tupleElementNames) { return(TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, _sourceAssembly, tupleElementNames)); }