/// <summary>
            /// Walks the given ResolvedType and returns all of the type parameters referenced.
            /// </summary>
            public static HashSet <TypeParameterName> Apply(ResolvedType res)
            {
                var walker = new GetTypeParameters();

                walker.OnType(res);
                return(walker.SharedState.TypeParams);
            }
 /// <summary>
 /// Reverses the dependencies of type parameters resolving to other type parameters in the given
 /// dictionary to create a lookup whose keys are type parameters and whose values are all the type
 /// parameters that can be updated by knowing the resolution of the lookup's associated key.
 /// </summary>
 private static ILookup <TypeParameterName, TypeParameterName> GetReplaceable(TypeParameterResolutions.Builder typeParamResolutions)
 {
     return(typeParamResolutions
            .Select(kvp => (kvp.Key, GetTypeParameters.Apply(kvp.Value)))   // Get any type parameters in the resolution type.
            .SelectMany(tup => tup.Item2.Select(value => (tup.Key, value))) // For each type parameter found, match it to the dictionary key.
            .ToLookup(                                                      // Reverse the keys and resulting type parameters to make the lookup.
                kvp => kvp.value,
                kvp => kvp.Key));
 }
 internal PlaceholderMethodSymbol(
     NamedTypeSymbol container,
     string name,
     GetTypeParameters getTypeParameters,
     GetReturnType getReturnType,
     GetParameters getParameters)
 {
     _container      = container;
     _name           = name;
     _typeParameters = getTypeParameters(this);
     _returnType     = getReturnType(this);
     _parameters     = getParameters(this);
 }
示例#4
0
 internal PlaceholderMethodSymbol(
     NamedTypeSymbol container,
     string name,
     GetTypeParameters getTypeParameters,
     GetReturnType getReturnType,
     GetParameters getParameters)
 {
     _container = container;
     _name = name;
     _typeParameters = getTypeParameters(this);
     _returnType = getReturnType(this);
     _parameters = getParameters(this);
 }
 internal PlaceholderMethodSymbol(
     NamedTypeSymbol container,
     CSharpSyntaxNode syntax,
     string name,
     GetTypeParameters getTypeParameters,
     GetReturnType getReturnType,
     GetParameters getParameters,
     bool returnValueIsByRef) :
     this(container, syntax, name)
 {
     _typeParameters = getTypeParameters(this);
     _returnType = getReturnType(this);
     _parameters = getParameters(this);
     _returnValueIsByRef = returnValueIsByRef;
 }
 internal PlaceholderMethodSymbol(
     NamedTypeSymbol container,
     CSharpSyntaxNode syntax,
     string name,
     GetTypeParameters getTypeParameters,
     GetReturnType getReturnType,
     GetParameters getParameters,
     bool returnValueIsByRef) :
     this(container, syntax, name)
 {
     _typeParameters     = getTypeParameters(this);
     _returnType         = getReturnType(this);
     _parameters         = getParameters(this);
     _returnValueIsByRef = returnValueIsByRef;
 }
        private static IReadOnlyList <T> GetPossibleTs <T>(
            SourceSymbolContext context,
            QualifiedName name,
            ImmutableArray <IType> typeArguments,
            TryGetT <T> tryGetT,
            GetLocalTs <T> getLocalTs,
            GetFullyQualifiedName <T> getFullyQualifiedName,
            GetTypeParameters <T> getTypeParameters) where T : class
        {
            List <T> possibleTs;

            if (name.Parent is null)
            {
                // local ts have priority over top level ts,
                // and an inner local t hides an outer local t

                // local ts can only have simple names, so we can skip this check if the name is not simple

                var scope = context.Scope;
                while (scope != null)
                {
                    possibleTs = getLocalTs(scope)
                                 .Where(
                        x => getFullyQualifiedName(x) == name &&
                        getTypeParameters(x).Length == typeArguments.Length)
                                 .ToList();
                    if (possibleTs.Count > 0)
                    {
                        return(possibleTs);
                    }

                    scope = scope.DeclaringMethod;
                }
            }

            var assemblies = context.Assembly.ReferencedAssembliesAndSelf;

            // types in the innermost namespace have priority over types in its parent namespace,
            // which have priority over types in its parent etc.
            var @namespace = context.NameSpace;

            while (@namespace != null)
            {
                var possibleName = name.Prepend(@namespace);

                possibleTs = LookupPossibleName(possibleName).ToList();

                if (possibleTs.Count > 0)
                {
                    return(possibleTs);
                }

                @namespace = @namespace?.Parent;
            }

            // Types in the global namespace have priority over types defined in imports
            possibleTs = LookupPossibleName(name).ToList();

            if (possibleTs.Count > 0)
            {
                return(possibleTs);
            }

            // look for types in imports
            if (name.Parent is null)
            {
                // imports only bring the top level types into scope, so they are only relevant if the name is simple;

                var possibleNames = context.Imports.Select(x => x.Append(name)).ToList();

                return
                    (possibleNames
                     .SelectMany(LookupPossibleName)
                     .ToList());
            }

            return(Array.Empty <T>());

            IEnumerable <T> LookupPossibleName(QualifiedName possibleName)
            {
                return(assemblies.Select(x =>
                {
                    tryGetT(x, possibleName, out var t);
                    return t;
                }).Where(x => x != null && getTypeParameters(x).Length == typeArguments.Length) !);
            }
        }