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); } }
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; }
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))); } }
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)); }
private FieldSymbol VisitFieldSymbol(FieldSymbol field) { // Property of a regular type return(((FieldSymbol)field.OriginalDefinition) .AsMember((NamedTypeSymbol)TypeMap.SubstituteType(field.ContainingType).AsTypeSymbolOnly())); }
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))); } }
private static TypeSymbol SubstituteType(TypeMap typeMap, TypeSymbol typeSymbol) { return(typeMap == null ? typeSymbol : typeMap.SubstituteType(typeSymbol)); }
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()); }
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); } } } } }
internal override TypeSymbol GetDeducedBaseType(ConsList <TypeParameterSymbol> inProgress) { return(_map.SubstituteType(_substitutedFrom.GetDeducedBaseType(inProgress))); }
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); }
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); }