Пример #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, cancellationToken: cancellationToken).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 != _metadataName || method.Arity != _arity || method.Parameters.Length != _originalParameterTypeKeys.Length)
                    {
                        continue;
                    }

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

                    if (!ParametersMatch(comparisonOptions, 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);
                }
            }
 private static void Resolve(
     PooledArrayBuilder <IParameterSymbol> result, SymbolKeyReader reader,
     string metadataName, ImmutableArray <IParameterSymbol> parameters)
 {
     foreach (var parameter in parameters)
     {
         if (SymbolKey.Equals(reader.Compilation, parameter.MetadataName, metadataName))
         {
             result.AddIfNotNull(parameter);
         }
     }
 }
Пример #3
0
            private static IEnumerable <(ISymbol symbol, int ordinal)> EnumerateSymbols(
                Compilation compilation, ISymbol containingSymbol,
                SymbolKind kind, string localName,
                CancellationToken cancellationToken)
            {
                var ordinal = 0;

                foreach (var declaringLocation in containingSymbol.DeclaringSyntaxReferences)
                {
                    // This operation can potentially fail. If containingSymbol came from
                    // a SpeculativeSemanticModel, containingSymbol.ContainingAssembly.Compilation
                    // may not have been rebuilt to reflect the trees used by the
                    // SpeculativeSemanticModel to produce containingSymbol. In that case,
                    // asking the ContainingAssembly's compilation for a SemanticModel based
                    // on trees for containingSymbol with throw an ArgumentException.
                    // Unfortunately, the best way to avoid this (currently) is to see if
                    // we're asking for a model for a tree that's part of the compilation.
                    // (There's no way to get back to a SemanticModel from a symbol).

                    // TODO (rchande): It might be better to call compilation.GetSemanticModel
                    // and catch the ArgumentException. The compilation internally has a
                    // Dictionary<SyntaxTree, ...> that it uses to check if the SyntaxTree
                    // is applicable wheras the public interface requires us to enumerate
                    // the entire IEnumerable of trees in the Compilation.
                    if (!Contains(compilation.SyntaxTrees, declaringLocation.SyntaxTree))
                    {
                        continue;
                    }

                    var node = declaringLocation.GetSyntax(cancellationToken);
                    if (node.Language == LanguageNames.VisualBasic)
                    {
                        node = node.Parent;
                    }

                    var semanticModel = compilation.GetSemanticModel(node.SyntaxTree);

                    foreach (var token in node.DescendantNodes())
                    {
                        var symbol = semanticModel.GetDeclaredSymbol(token, cancellationToken);

                        if (symbol != null &&
                            symbol.Kind == kind &&
                            SymbolKey.Equals(compilation, symbol.Name, localName))
                        {
                            yield return(symbol, ordinal++);
                        }
                    }
                }
            }
 private static IEnumerable <IParameterSymbol> Resolve(
     SymbolKeyReader reader, ISymbol container, string metadataName)
 {
     if (container is IMethodSymbol)
     {
         return(((IMethodSymbol)container).Parameters.Where(
                    p => SymbolKey.Equals(reader.Compilation, p.MetadataName, metadataName)));
     }
     else if (container is IPropertySymbol)
     {
         return(((IPropertySymbol)container).Parameters.Where(
                    p => SymbolKey.Equals(reader.Compilation, p.MetadataName, metadataName)));
     }
     else
     {
         return(SpecializedCollections.EmptyEnumerable <IParameterSymbol>());
     }
 }
            public static SymbolKeyResolution Resolve(SymbolKeyReader reader)
            {
                var cancellationToken = reader.CancellationToken;

                var name      = reader.ReadString();
                var kind      = (SymbolKind)reader.ReadInteger();
                var locations = reader.ReadLocationArray();
                var ordinal   = reader.ReadInteger();

                // First check if we can recover the symbol just through the original location.
                foreach (var loc in locations)
                {
                    var resolutionOpt = reader.ResolveLocation(loc);
                    if (resolutionOpt.HasValue)
                    {
                        var resolution = resolutionOpt.Value;
                        var symbol     = resolution.GetAnySymbol();
                        if (symbol?.Kind == kind &&
                            SymbolKey.Equals(reader.Compilation, name, symbol.Name))
                        {
                            return(resolution);
                        }
                    }
                }

                // Couldn't recover.  See if we can still find a match across the textual drift.
                if (ordinal != int.MaxValue &&
                    TryGetSemanticModel(reader.Compilation, locations[0].SourceTree, out var semanticModel))
                {
                    foreach (var symbol in EnumerateSymbols(semanticModel, kind, name, cancellationToken))
                    {
                        if (symbol.ordinal == ordinal)
                        {
                            return(new SymbolKeyResolution(symbol.symbol));
                        }
                    }
                }

                return(default);
Пример #6
0
            private static IEnumerable <IParameterSymbol> Resolve(
                SymbolKeyReader reader, ISymbol container, string metadataName)
            {
                if (container is IMethodSymbol)
                {
                    return(((IMethodSymbol)container).Parameters.Where(
                               p => SymbolKey.Equals(reader.Compilation, p.MetadataName, metadataName)));
                }
                else if (container is IPropertySymbol)
                {
                    return(((IPropertySymbol)container).Parameters.Where(
                               p => SymbolKey.Equals(reader.Compilation, p.MetadataName, metadataName)));
                }
                else if (container is IEventSymbol)
                {
                    // Parameters can be owned by events in VB.  i.e. it's legal in VB to have:
                    //
                    //      Public Event E(a As Integer, b As Integer);
                    //
                    // In this case it's equivalent to:
                    //
                    //      Public Delegate UnutterableCompilerName(a As Integer, b As Integer)
                    //      public Event E As UnutterableCompilerName
                    //
                    // So, in this case, to resolve the parameter, we go have to map the event,
                    // then find the delegate it returns, then find the parameter in the delegate's
                    // 'Invoke' method.
                    var eventSymbol    = (IEventSymbol)container;
                    var delegateInvoke = (eventSymbol.Type as INamedTypeSymbol)?.DelegateInvokeMethod;

                    if (delegateInvoke != null)
                    {
                        return(delegateInvoke.Parameters.Where(
                                   p => SymbolKey.Equals(reader.Compilation, p.MetadataName, metadataName)));
                    }
                }

                return(SpecializedCollections.EmptyEnumerable <IParameterSymbol>());
            }