Beispiel #1
0
        public static async Task <List <IMethodSymbol> > FindExtensionMethodsAsync(this ITypeSymbol type, Project project, CancellationToken cancellationToken = default)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var members     = new List <IMethodSymbol>(10);
            var isValueType = type.IsValueType;

            foreach (var typeSymbol in compilation.GlobalNamespace.GetAllTypes(cancellationToken))
            {
                if (typeSymbol.IsStatic == false || typeSymbol.MightContainExtensionMethods == false)
                {
                    continue;
                }
                foreach (var member in typeSymbol.GetMembers())
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(members);
                    }
                    if (member.IsStatic == false || member.Kind != SymbolKind.Method)
                    {
                        continue;
                    }
                    var m = (IMethodSymbol)member;
                    if (m.IsExtensionMethod == false || m.CanBeReferencedByName == false)
                    {
                        continue;
                    }
                    var p = m.Parameters[0];
                    if (type.CanConvertTo(p.Type))
                    {
                        members.Add(m);
                        continue;
                    }
                    if (m.IsGenericMethod == false || p.Type.TypeKind != TypeKind.TypeParameter)
                    {
                        continue;
                    }
                    foreach (var item in m.TypeParameters)
                    {
                        if (item != p.Type ||
                            item.HasValueTypeConstraint && isValueType == false ||
                            item.HasReferenceTypeConstraint && isValueType)
                        {
                            continue;
                        }
                        if (item.HasConstructorConstraint)
                        {
                        }
                        if (item.ConstraintTypes.Length > 0 &&
                            item.ConstraintTypes.Any(i => i == type || type.CanConvertTo(i)) == false)
                        {
                            continue;
                        }
                        members.Add(m);
                    }
                }
            }
            return(members);
        }
Beispiel #2
0
        /// <summary>
        /// Finds all members defined or referenced in <paramref name="project"/> which may have a parameter that is of or derived from <paramref name="type"/>.
        /// </summary>
        public static async Task <List <ISymbol> > FindInstanceAsParameterAsync(this ITypeSymbol type, Project project, CancellationToken cancellationToken = default)
        {
            var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var members = new List <ISymbol>(10);
            ImmutableArray <IParameterSymbol> parameters;
            var assembly = compilation.Assembly;

            foreach (var typeSymbol in compilation.GlobalNamespace.GetAllTypes(cancellationToken))
            {
                foreach (var member in typeSymbol.GetMembers())
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(members);
                    }
                    if (member.Kind != SymbolKind.Field &&
                        member.CanBeReferencedByName &&
                        (parameters = member.GetParameters()).IsDefaultOrEmpty == false)
                    {
                        if (parameters.Any(p => type.CanConvertTo(p.Type) && p.Type.IsCommonClass() == false) &&
                            type.CanAccess(member, assembly))
                        {
                            members.Add(member);
                        }
                    }
                }
            }
            return(members);
        }
Beispiel #3
0
        /// <summary>Checks whether the given symbol has the given <paramref name="kind"/>, <paramref name="returnType"/> and <paramref name="parameters"/>.</summary>
        /// <param name="symbol">The symbol to be checked.</param>
        /// <param name="kind">The <see cref="SymbolKind"/> the symbol should have.</param>
        /// <param name="returnType">The type that the symbol should return.</param>
        /// <param name="parameters">The parameters the symbol should take.</param>
        public static bool MatchSignature(this ISymbol symbol, SymbolKind kind, ITypeSymbol returnType, ImmutableArray <IParameterSymbol> parameters)
        {
            if (symbol.Kind != kind)
            {
                return(false);
            }
            if (returnType == null && symbol.GetReturnType() != null ||
                returnType != null && returnType.CanConvertTo(symbol.GetReturnType()) == false)
            {
                return(false);
            }
            var method = kind == SymbolKind.Method ? symbol as IMethodSymbol
                                : kind == SymbolKind.Event ? (symbol as IEventSymbol).RaiseMethod
                                : null;

            if (method != null && parameters.IsDefault == false)
            {
                var memberParameters = method.Parameters;
                if (memberParameters.Length != parameters.Length)
                {
                    return(false);
                }
                for (var i = parameters.Length - 1; i >= 0; i--)
                {
                    var pi = parameters[i];
                    var mi = memberParameters[i];
                    if (pi.Type.Equals(mi.Type) == false ||
                        pi.RefKind != mi.RefKind)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #4
0
 public static bool CanConvertTo(this ITypeSymbol symbol, ITypeSymbol target)
 {
     if (symbol.Equals(target))
     {
         return(true);
     }
     if (target.TypeKind == TypeKind.TypeParameter)
     {
         var param = target as ITypeParameterSymbol;
         foreach (var item in param.ConstraintTypes)
         {
             if (item.CanConvertTo(symbol))
             {
                 return(true);
             }
         }
         return(false);
     }
     if (symbol.TypeKind == TypeKind.TypeParameter)
     {
         var param = symbol as ITypeParameterSymbol;
         foreach (var item in param.ConstraintTypes)
         {
             if (item.CanConvertTo(target))
             {
                 return(true);
             }
         }
         return(false);
     }
     foreach (var item in symbol.Interfaces)
     {
         if (item.CanConvertTo(target))
         {
             return(true);
         }
     }
     while ((symbol = symbol.BaseType) != null)
     {
         if (symbol.CanConvertTo(target))
         {
             return(true);
         }
     }
     return(false);
 }