コード例 #1
0
        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);
        }