private ReducedExtensionMethodSymbol(MethodSymbol reducedFrom)
        {
            Debug.Assert((object)reducedFrom != null);
            Debug.Assert(reducedFrom.IsExtensionMethod);
            Debug.Assert((object)reducedFrom.ReducedFrom == null);
            Debug.Assert(reducedFrom.ConstructedFrom == reducedFrom);
            Debug.Assert(reducedFrom.ParameterCount > 0);

            _reducedFrom   = reducedFrom;
            _typeMap       = TypeMap.Empty.WithAlphaRename(reducedFrom, this, out _typeParameters);
            _typeArguments = _typeMap.SubstituteTypes(reducedFrom.TypeArguments);
        }
Example #2
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.SubstituteTypes(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.SubstituteTypes(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.SubstituteTypes(method.TypeArguments)));
            }
        }