Example #1
0
            private IEnumerable <IMethodSymbol> Resolve(Compilation compilation, INamedTypeSymbol container, bool ignoreAssemblyKey, CancellationToken cancellationToken)
            {
                var comparisonOptions = new ComparisonOptions(compilation.IsCaseSensitive, ignoreAssemblyKey, compareMethodTypeParametersByName: true);

                ITypeSymbol[] typeArguments = null;

                if (typeArgumentKeysOpt != null)
                {
                    typeArguments = typeArgumentKeysOpt.Select(a => a.Resolve(compilation).Symbol as ITypeSymbol).ToArray();

                    if (typeArguments.Any(a => a == null))
                    {
                        yield break;
                    }
                }

                foreach (var method in container.GetMembers().OfType <IMethodSymbol>())
                {
                    // Quick checks first
                    if (method.MetadataName != this.metadataName || method.Arity != this.arity || method.Parameters.Length != this.originalParameterTypeKeys.Length)
                    {
                        continue;
                    }

                    // Is this a conversion operator? If so, we must also compare the return type.
                    if (this.returnType != null)
                    {
                        if (!this.returnType.Equals(SymbolKey.Create(method.ReturnType, compilation, cancellationToken), comparisonOptions))
                        {
                            continue;
                        }
                    }

                    if (!ParametersMatch(comparisonOptions, compilation, method.OriginalDefinition.Parameters, refKinds, originalParameterTypeKeys, cancellationToken))
                    {
                        continue;
                    }

                    // It matches, so let's return it, but we might have to do some construction first
                    var methodToReturn = method;

                    if (isPartialMethodImplementationPart)
                    {
                        methodToReturn = methodToReturn.PartialImplementationPart ?? methodToReturn;
                    }

                    if (typeArguments != null)
                    {
                        methodToReturn = methodToReturn.Construct(typeArguments);
                    }

                    yield return(methodToReturn);
                }
            }
Example #2
0
        private static bool ParametersMatch(
            ComparisonOptions options,
            Compilation compilation,
            ImmutableArray <IParameterSymbol> parameters,
            RefKind[] refKinds,
            SymbolKey[] typeKeys,
            CancellationToken cancellationToken)
        {
            if (parameters.Length != refKinds.Length)
            {
                return(false);
            }

            for (int i = 0; i < refKinds.Length; i++)
            {
                // The ref-out distinction is not interesting for SymbolKey because you can't overload
                // based on the difference.
                var parameter = parameters[i];
                if (!SymbolEquivalenceComparer.AreRefKindsEquivalent(refKinds[i], parameter.RefKind, distinguishRefFromOut: false))
                {
                    return(false);
                }

                // We are checking parameters for equality, if they refer to method type parameters,
                // then we don't want to recurse through the method (which would then recurse right
                // back into the parameters).  So we ask that type parameters only be checked by
                // metadataName to prevent that.
                var newOptions = new ComparisonOptions(
                    options.IgnoreCase,
                    options.IgnoreAssemblyKey,
                    compareMethodTypeParametersByName: true);

                if (!typeKeys[i].Equals(SymbolKey.Create(parameter.Type, compilation, cancellationToken), newOptions))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #3
0
        private static bool ParametersMatch(
            ComparisonOptions options,
            Compilation compilation,
            ImmutableArray <IParameterSymbol> parameters,
            RefKind[] refKinds,
            SymbolKey[] typeKeys,
            CancellationToken cancellationToken)
        {
            if (parameters.Length != refKinds.Length)
            {
                return(false);
            }

            for (int i = 0; i < refKinds.Length; i++)
            {
                var parameter = parameters[i];
                if (refKinds[i] != parameters[i].RefKind)
                {
                    return(false);
                }

                // We are checking parameters for equality, if they refer to method type parameters,
                // then we don't want to recurse through the method (which would then recurse right
                // back into the parameters).  So we ask that type parameters only be checked by
                // metadataName to prevent that.
                var newOptions = new ComparisonOptions(
                    options.IgnoreCase,
                    options.IgnoreAssemblyKey,
                    compareMethodTypeParametersByName: true);

                if (!typeKeys[i].Equals(SymbolKey.Create(parameter.Type, compilation, cancellationToken), newOptions))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #4
0
 public static SymbolKey GetSymbolKey(this ISymbol symbol, CancellationToken cancellationToken = default)
 => SymbolKey.Create(symbol, cancellationToken);
Example #5
0
 public static SymbolKey GetSymbolKey(this ISymbol symbol)
 {
     return(SymbolKey.Create(symbol, null, CancellationToken.None));
 }
Example #6
0
 internal static SymbolKey GetSymbolKey(this ISymbol symbol, Compilation compilation, CancellationToken cancellationToken)
 {
     return(SymbolKey.Create(symbol, compilation, cancellationToken));
 }