private static MethodSymbol ConstructMethodSymbol(MethodSymbol methodSymbol, AbstractTypeParameterMap methodTypeSubstitution, IGenericContext genericContext) { var metadataGenericContext = genericContext as MetadataGenericContext; if (metadataGenericContext != null) { var customTypeSubstitution = metadataGenericContext.CustomTypeSubstitution; if (customTypeSubstitution != null) { return new ConstructedMethodSymbol(methodSymbol, GetTypeArguments(methodSymbol.OriginalDefinition.TypeParameters, customTypeSubstitution, null)); } } var metadataMethodAdapter = genericContext.MethodSpecialization as MetadataMethodAdapter; if (metadataMethodAdapter != null) { var methodSymbolContext = metadataMethodAdapter.MethodDef; var constructedFrom = methodSymbol.ConstructedFrom; return new ConstructedMethodSymbol(constructedFrom.ConstructedFrom, GetTypeArguments(constructedFrom.TypeParameters, methodSymbolContext, methodTypeSubstitution)); } var metadataTypeAdapter = genericContext.TypeSpecialization as MetadataTypeAdapter; if (metadataTypeAdapter != null) { var namedTypeSymbolContext = metadataTypeAdapter.TypeDef as NamedTypeSymbol; var constructedFrom = methodSymbol.ConstructedFrom; return new ConstructedMethodSymbol(constructedFrom.ConstructedFrom, GetTypeArguments(constructedFrom.TypeParameters, namedTypeSymbolContext, methodTypeSubstitution)); } return null; }
private static ImmutableArray<TypeSymbol> GetTypeArguments(ImmutableArray<TypeParameterSymbol> definitionTypeParameters, AbstractTypeParameterMap currentTypeMap, AbstractTypeParameterMap typeSubstitutionOpt) { var typeArguments = ImmutableArray.CreateBuilder<TypeSymbol>(definitionTypeParameters.Length); foreach (var typeParameterSymbol in definitionTypeParameters) { if (typeSubstitutionOpt != null) { var substitutedType = currentTypeMap.SubstituteType(typeParameterSymbol); if (!object.ReferenceEquals(substitutedType, typeParameterSymbol)) { typeArguments.Add(currentTypeMap.SubstituteType(substitutedType)); } else { var substitutedTypeOpt = typeSubstitutionOpt.SubstituteType(typeParameterSymbol.OriginalDefinition); typeArguments.Add(currentTypeMap.SubstituteType(substitutedTypeOpt)); } } else { typeArguments.Add(currentTypeMap.SubstituteType(typeParameterSymbol)); } } return typeArguments.ToImmutableArray(); }
private static ImmutableArray<TypeSymbol> GetTypeArguments(ImmutableArray<TypeParameterSymbol> definitionTypeParameters, MethodSymbol methodSymbol, AbstractTypeParameterMap typeSubstitution) { var current = methodSymbol; if (current == null) { throw new Exception("Could not find TypeArguments in Generic Context"); } return GetTypeArguments(definitionTypeParameters, current.TypeSubstitution, typeSubstitution); }
private static ImmutableArray<TypeSymbol> GetTypeArguments(ImmutableArray<TypeParameterSymbol> definitionTypeParameters, NamedTypeSymbol namedTypeSymbol, AbstractTypeParameterMap typeSubstitution) { var current = namedTypeSymbol; while (current != null && current.TypeArguments.Length == 0) { current = namedTypeSymbol.ContainingType; } if (current == null) { throw new Exception("Could not find TypeArguments in Generic Context"); } return GetTypeArguments(definitionTypeParameters, current.TypeSubstitution, typeSubstitution); }