Esempio n. 1
0
        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));
        }
Esempio n. 3
0
        /// <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;
        }