private static IMethod RemapMethod(Node node, GenericMappedMethod gmm, IType[] genParams) { var sourceMethod = gmm.SourceMember; if (sourceMethod.GenericInfo != null) { throw new CompilerError(node, "Mapping generic methods in generators is not implemented yet"); } var baseType = sourceMethod.DeclaringType; var genericInfo = baseType.GenericInfo; if (genericInfo == null) { throw new CompilerError(node, "Mapping generic nested types in generators is not implemented yet"); } var genericArgs = ((IGenericArgumentsProvider)gmm.DeclaringType).GenericArguments; var collector = new TypeCollector(type => type is IGenericParameter); foreach (var arg in genericArgs) { collector.Visit(arg); } var mapper = new GeneratorTypeReplacer(); foreach (var genParam in collector.Matches) { var mappedArg = genParams.SingleOrDefault(gp => gp.Name == genParam.Name); if (mappedArg != null) { mapper.Replace(genParam, mappedArg); } } var newType = (IConstructedTypeInfo) new GenericConstructedType( baseType, genericArgs.Select(mapper.MapType).ToArray()); return((IMethod)newType.Map(sourceMethod)); }
private IMethod RemapMethod(Node node, GenericMappedMethod gmm, GenericParameterDeclarationCollection genParams) { var sourceMethod = gmm.SourceMember; if (sourceMethod.GenericInfo != null) { throw new CompilerError(node, "Mapping generic methods in generators is not implemented yet"); } var baseType = sourceMethod.DeclaringType; var genericInfo = baseType.GenericInfo; if (genericInfo == null) { throw new CompilerError(node, "Mapping generic nested types in generators is not implemented yet"); } var genericArgs = ((IGenericArgumentsProvider)gmm.DeclaringType).GenericArguments; var mapList = new List <IType>(); foreach (var arg in genericArgs) { var mappedArg = genParams.SingleOrDefault(gp => gp.Name == arg.Name); if (mappedArg != null) { mapList.Add((IType)mappedArg.Entity); } else { mapList.Add(arg); } } var newType = (IConstructedTypeInfo) new GenericConstructedType(baseType, mapList.ToArray()); return((IMethod)newType.Map(sourceMethod)); }
/// <summary> /// Maps a type member involving generic arguments to its constructed counterpart, after substituting /// concrete types for generic arguments. /// </summary> public IEntity Map(IEntity source) { if (source == null) return null; // Map generic source to the constructed owner of this mapping if (source == _genericSource) { return _constructedOwner; } // Use cache if possible if (_cache.ContainsKey(source)) { return _cache[source]; } // Map entity based on its entity type IEntity mapped = null; switch (source.EntityType) { case EntityType.Ambiguous: mapped = MapAmbiguousEntity((Ambiguous)source); break; case EntityType.Method: mapped = new GenericMappedMethod(_tss, ((IMethod)source), this); break; case EntityType.Constructor: mapped = new GenericMappedConstructor(_tss, ((IConstructor)source), this); break; case EntityType.Field: mapped = new GenericMappedField(_tss, ((IField)source), this); break; case EntityType.Property: mapped = new GenericMappedProperty(_tss, ((IProperty)source), this); break; case EntityType.Event: mapped = new GenericMappedEvent(_tss, ((IEvent)source), this); break; case EntityType.Parameter: mapped = new GenericMappedParameter((IParameter)source, this); break; case EntityType.Array: case EntityType.Type: mapped = MapType((IType)source); break; default: return source; } // Cache mapped result and return it _cache[source] = mapped; return mapped; }