private static void SubstituteTypes(ImmutableArray <TypeSymbol> types, TypeMap typeMap, HashSet <TypeSymbol> result)
 {
     foreach (var type in types)
     {
         result.Add(typeMap.SubstituteType(type));
     }
 }
        protected MethodSymbol VisitMethodSymbol(MethodSymbol method)
        {
            if ((object)method == null)
            {
                return(null);
            }

            if (!method.ContainingType.IsAnonymousType)
            {
                //  Method of a regular type
                return(((MethodSymbol)method.OriginalDefinition)
                       .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType))
                       .ConstructIfGeneric(TypeMap.SubstituteTypes(method.TypeArguments)));
            }

            //  Method of an anonymous type
            var newType = (NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType);

            if (ReferenceEquals(newType, method.ContainingType))
            {
                //  Anonymous type symbol was not rewritten
                return(method);
            }

            //  get a new method by name
            foreach (var member in newType.GetMembers(method.Name))
            {
                if (member.Kind == SymbolKind.Method)
                {
                    return((MethodSymbol)member);
                }
            }

            throw ExceptionUtilities.Unreachable;
        }
 private static void SubstituteConstraintTypes(ImmutableArray <TypeWithAnnotations> types, TypeMap typeMap, HashSet <TypeSymbol> result)
 {
     foreach (var type in types)
     {
         result.Add(typeMap.SubstituteType(type).Type);
     }
 }
Beispiel #4
0
        private PropertySymbol VisitPropertySymbol(PropertySymbol property)
        {
            if ((object)property == null)
            {
                return(null);
            }

            if (!property.ContainingType.IsAnonymousType)
            {
                //  Property of a regular type
                return(((PropertySymbol)property.OriginalDefinition)
                       .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(property.ContainingType).AsTypeSymbolOnly()));
            }

            //  Method of an anonymous type
            var newType = (NamedTypeSymbol)TypeMap.SubstituteType(property.ContainingType).AsTypeSymbolOnly();

            if (ReferenceEquals(newType, property.ContainingType))
            {
                //  Anonymous type symbol was not rewritten
                return(property);
            }

            //  get a new property by name
            foreach (var member in newType.GetMembers(property.Name))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    return((PropertySymbol)member);
                }
            }

            throw ExceptionUtilities.Unreachable;
        }
Beispiel #5
0
 internal static LocalSymbol ToOtherMethod(this LocalSymbol local, MethodSymbol method, TypeMap typeMap)
 {
     var l = local as EELocalSymbolBase;
     if ((object)l != null)
     {
         return l.ToOtherMethod(method, typeMap);
     }
     var type = typeMap.SubstituteType(local.Type);
     return new EELocalSymbol(method, local.Locations, local.Name, -1, local.DeclarationKind, type.Type, local.RefKind, local.IsPinned, local.IsCompilerGenerated, local.CanScheduleToStack);
 }
        protected MethodSymbol?VisitMethodSymbol(MethodSymbol?method)
        {
            if (method is null)
            {
                return(null);
            }

            if (method.ContainingType is null)
            {
                Debug.Assert(method is SynthesizedGlobalMethodSymbol);
                return(method);
            }
            else if (method.ContainingType.IsAnonymousType)
            {
                //  Method of an anonymous type
                var newType = (NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType).AsTypeSymbolOnly();
                if (ReferenceEquals(newType, method.ContainingType))
                {
                    //  Anonymous type symbol was not rewritten
                    return(method);
                }

                //  get a new method by name
                foreach (var member in newType.GetMembers(method.Name))
                {
                    if (member.Kind == SymbolKind.Method)
                    {
                        return((MethodSymbol)member);
                    }
                }

                throw ExceptionUtilities.Unreachable;
            }
            else
            {
                //  Method of a regular type
                return(((MethodSymbol)method.OriginalDefinition)
                       .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType).AsTypeSymbolOnly())
                       .ConstructIfGeneric(TypeMap.SubstituteTypes(method.TypeArgumentsWithAnnotations)));
            }
        }
Beispiel #7
0
 internal override EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap)
 {
     var type = typeMap.SubstituteType(_type);
     return new EELocalSymbol(method, _locations, _nameOpt, _ordinal, _declarationKind, type.Type, _refKind, _isPinned, _isCompilerGenerated, _canScheduleToStack);
 }
 private static FieldSymbol SubstituteField(FieldSymbol field, TypeMap typeMap)
 {
     Debug.Assert(!field.IsStatic);
     Debug.Assert(!field.IsReadOnly);
     Debug.Assert(field.CustomModifiers.Length == 0);
     // CONSIDER: Instead of digging fields out of the unsubstituted type and then performing substitution
     // on each one individually, we could dig fields out of the substituted type.
     return new EEDisplayClassFieldSymbol(typeMap.SubstituteNamedType(field.ContainingType), field.Name, typeMap.SubstituteType(field.Type));
 }
Beispiel #9
0
 private FieldSymbol VisitFieldSymbol(FieldSymbol field)
 {
     //  Property of a regular type
     return(((FieldSymbol)field.OriginalDefinition)
            .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(field.ContainingType).AsTypeSymbolOnly()));
 }
Beispiel #10
0
        protected MethodSymbol VisitMethodSymbol(MethodSymbol method)
        {
            if ((object)method == null)
            {
                return(null);
            }

            if (method.IsTupleMethod)
            {
                //  Method of a tuple type
                var oldType         = method.ContainingType;
                var constructedFrom = method.ConstructedFrom;
                Debug.Assert(oldType.IsTupleType);

                var newType = (NamedTypeSymbol)TypeMap.SubstituteType(oldType).AsTypeSymbolOnly();
                if ((object)newType == oldType)
                {
                    //  tuple type symbol was not rewritten
                    return(constructedFrom.ConstructIfGeneric(TypeMap.SubstituteTypesWithoutModifiers(method.TypeArguments)));
                }

                Debug.Assert(newType.IsTupleType);
                Debug.Assert(oldType.TupleElementTypes.Length == newType.TupleElementTypes.Length);

                //  get a new method by position
                var oldMembers = oldType.GetMembers();
                var newMembers = newType.GetMembers();
                Debug.Assert(oldMembers.Length == newMembers.Length);

                for (int i = 0; i < oldMembers.Length; i++)
                {
                    if ((object)constructedFrom == oldMembers[i])
                    {
                        return(((MethodSymbol)newMembers[i]).ConstructIfGeneric(TypeMap.SubstituteTypesWithoutModifiers(method.TypeArguments)));
                    }
                }

                throw ExceptionUtilities.Unreachable;
            }
            else if (method.ContainingType.IsAnonymousType)
            {
                //  Method of an anonymous type
                var newType = (NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType).AsTypeSymbolOnly();
                if (ReferenceEquals(newType, method.ContainingType))
                {
                    //  Anonymous type symbol was not rewritten
                    return(method);
                }

                //  get a new method by name
                foreach (var member in newType.GetMembers(method.Name))
                {
                    if (member.Kind == SymbolKind.Method)
                    {
                        return((MethodSymbol)member);
                    }
                }

                throw ExceptionUtilities.Unreachable;
            }
            else
            {
                //  Method of a regular type
                return(((MethodSymbol)method.OriginalDefinition)
                       .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(method.ContainingType).AsTypeSymbolOnly())
                       .ConstructIfGeneric(TypeMap.SubstituteTypesWithoutModifiers(method.TypeArguments)));
            }
        }
Beispiel #11
0
 private static TypeSymbol SubstituteType(TypeMap typeMap, TypeSymbol typeSymbol)
 {
     return(typeMap == null ? typeSymbol : typeMap.SubstituteType(typeSymbol));
 }
Beispiel #12
0
        private SynthesizedFieldSymbolBase MakeHoistedField(TypeMap TypeMap, LocalSymbol local, TypeSymbol type)
        {
            Debug.Assert(local.DeclarationKind != LocalDeclarationKind.CompilerGenerated);
            int index = nextLocalNumber++;

            // Special Case: There's logic in the EE to recognize locals that have been captured by a lambda
            // and would have been hoisted for the state machine.  Basically, we just hoist the local containing
            // the instance of the lambda display class and retain its original name (rather than using an
            // iterator local name).  See FUNCBRECEE::ImportIteratorMethodInheritedLocals.
            string fieldName = local.DeclarationKind == LocalDeclarationKind.CompilerGeneratedLambdaDisplayClassLocal
                ? local.Name
                : GeneratedNames.MakeIteratorLocalName(local.Name, index);
            return F.SynthesizeField(TypeMap.SubstituteType(type), fieldName, index, isPublic: true);
        }
 internal override TypeSymbol GetDeducedBaseType(ConsList <TypeParameterSymbol> inProgress)
 {
     return(_map.SubstituteType(_underlyingTypeParameter.GetDeducedBaseType(inProgress)).AsTypeSymbolOnly());
 }
Beispiel #14
0
        private void CreateInitialProxies(
           TypeMap TypeMap,
           IOrderedEnumerable<Symbol> captured,
           MultiDictionary<Symbol, CSharpSyntaxNode> locations)
        {
            foreach (var sym in captured)
            {
                var local = sym as LocalSymbol;
                if ((object)local != null && local.DeclarationKind != LocalDeclarationKind.CompilerGenerated)
                {
                    Debug.Assert(local.RefKind == RefKind.None); // there are no user-declared ref variables
                    MakeInitialProxy(TypeMap, locations, local);
                    continue;
                }

                var parameter = sym as ParameterSymbol;
                if ((object)parameter != null)
                {
                    if (parameter.IsThis)
                    {
                        var proxyField = F.StateMachineField(method.ContainingType, GeneratedNames.IteratorThisProxyName(), isPublic: true);
                        variableProxies.Add(parameter, new CapturedToFrameSymbolReplacement(proxyField));

                        if (PreserveInitialLocals)
                        {
                            var initialThis = method.ContainingType.IsStructType() ? 
                                F.StateMachineField(method.ContainingType, GeneratedNames.IteratorThisProxyProxyName(), isPublic: true) : proxyField;

                            initialParameters.Add(parameter, new CapturedToFrameSymbolReplacement(initialThis));
                        }
                    }
                    else
                    {
                        var proxyField = F.StateMachineField(TypeMap.SubstituteType(parameter.Type), parameter.Name, isPublic: true);
                        variableProxies.Add(parameter, new CapturedToFrameSymbolReplacement(proxyField));

                        if (PreserveInitialLocals)
                        {
                            string proxyName = GeneratedNames.IteratorParameterProxyName(parameter.Name);
                            initialParameters.Add(parameter, new CapturedToFrameSymbolReplacement(
                                F.StateMachineField(TypeMap.SubstituteType(parameter.Type), proxyName, isPublic: true)));
                        }
                        if (parameter.Type.IsRestrictedType())
                        {
                            // CS4013: Instance of type '{0}' cannot be used inside an anonymous function, query expression, iterator block or async method
                            diagnostics.Add(ErrorCode.ERR_SpecialByRefInLambda, parameter.Locations[0], parameter.Type);
                        }
                    }
                }
            }
        }
Beispiel #15
0
 internal override TypeSymbol GetDeducedBaseType(ConsList <TypeParameterSymbol> inProgress)
 {
     return(_map.SubstituteType(_substitutedFrom.GetDeducedBaseType(inProgress)));
 }
Beispiel #16
0
        private SynthesizedFieldSymbolBase MakeHoistedLocalField(TypeMap TypeMap, LocalSymbol local, TypeSymbol type)
        {
            Debug.Assert(local.SynthesizedLocalKind == SynthesizedLocalKind.None ||
                         local.SynthesizedLocalKind == SynthesizedLocalKind.LambdaDisplayClass);

            int index = nextLocalNumber++;

            // Special Case: There's logic in the EE to recognize locals that have been captured by a lambda
            // and would have been hoisted for the state machine.  Basically, we just hoist the local containing
            // the instance of the lambda display class and retain its original name (rather than using an
            // iterator local name).  See FUNCBRECEE::ImportIteratorMethodInheritedLocals.
            string fieldName = (local.SynthesizedLocalKind == SynthesizedLocalKind.LambdaDisplayClass)
                ? GeneratedNames.MakeLambdaDisplayClassStorageName(index)
                : GeneratedNames.MakeHoistedLocalFieldName(local.Name, index);

            return F.StateMachineField(TypeMap.SubstituteType(type), fieldName, index);
        }
        public void TypeMap()
        {
            var source = @"
struct S<T> where T : struct
{
}
";

            var comp = CreateCompilationWithMscorlib(source);
            comp.VerifyDiagnostics();

            var intType = comp.GetSpecialType(SpecialType.System_Int32);
            var customModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateOptional(intType));

            var structType = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("S");
            var typeParamType = structType.TypeParameters.Single();

            var pointerType = new PointerTypeSymbol(typeParamType, customModifiers); // NOTE: We're constructing this manually, since it's illegal.
            var arrayType = new ArrayTypeSymbol(comp.Assembly, typeParamType, customModifiers); // This is legal, but we're already manually constructing types.

            var typeMap = new TypeMap(ImmutableArray.Create(typeParamType), ImmutableArray.Create<TypeSymbol>(intType));

            var substitutedPointerType = (PointerTypeSymbol)typeMap.SubstituteType(pointerType);
            var substitutedArrayType = (ArrayTypeSymbol)typeMap.SubstituteType(arrayType);

            // The map changed the types.
            Assert.Equal(intType, substitutedPointerType.PointedAtType);
            Assert.Equal(intType, substitutedArrayType.ElementType);

            // The map preserved the custom modifiers.
            Assert.Equal(customModifiers, substitutedPointerType.CustomModifiers);
            Assert.Equal(customModifiers, substitutedArrayType.CustomModifiers);
        }
 internal override EELocalSymbolBase ToOtherMethod(MethodSymbol method, TypeMap typeMap)
 {
     var type = typeMap.SubstituteType(_type);
     return new EELocalConstantSymbol(method, _name, type, _value);
 }
Beispiel #19
0
 public sealed override TypeSymbol VisitType(TypeSymbol type)
 {
     return(TypeMap.SubstituteType(type));
 }
        internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection)
        {
            if (method.IsVoidReturningAsync())
            {
                return TryCreate(
                    F: F,

                    builderType: F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncVoidMethodBuilder),
                    resultType: F.SpecialType(SpecialType.System_Void),

                    setException: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetException,
                    setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetResult,
                    awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitOnCompleted,
                    awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitUnsafeOnCompleted,
                    start: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Start_T,
                    setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetStateMachine,
                    task: null,
                    collection: out collection);
            }

            if (method.IsTaskReturningAsync(F.Compilation))
            {
                NamedTypeSymbol builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder);

                PropertySymbol task;
                if (!TryGetWellKnownPropertyAsMember(F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Task, builderType, out task))
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return false;
                }

                return TryCreate(
                    F: F,

                    builderType: F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder),
                    resultType: F.SpecialType(SpecialType.System_Void),

                    setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetException,
                    setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetResult,
                    awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitOnCompleted,
                    awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitUnsafeOnCompleted,
                    start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Start_T,
                    setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetStateMachine,
                    task: task,
                    collection: out collection);
            }

            if (method.IsGenericTaskReturningAsync(F.Compilation))
            {
                TypeSymbol resultType = method.ReturnType.GetMemberTypeArgumentsNoUseSiteDiagnostics().Single();

                if (resultType.IsDynamic())
                {
                    resultType = F.SpecialType(SpecialType.System_Object);
                }

                if (typeMap != null)
                {
                    resultType = typeMap.SubstituteType(resultType).Type;
                }

                NamedTypeSymbol builderType = F.WellKnownType(WellKnownType.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T).Construct(resultType);

                PropertySymbol task;
                if (!TryGetWellKnownPropertyAsMember(F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Task, builderType, out task))
                {
                    collection = default(AsyncMethodBuilderMemberCollection);
                    return false;
                }

                return TryCreate(
                    F: F,

                    builderType: builderType,
                    resultType: resultType,

                    setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetException,
                    setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetResult,
                    awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitOnCompleted,
                    awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitUnsafeOnCompleted,
                    start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Start_T,
                    setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetStateMachine,
                    task: task,
                    collection: out collection);
            }

            throw ExceptionUtilities.UnexpectedValue(method);
        }