private static IMethodSymbol Resolve( SymbolKeyReader reader, string metadataName, int arity, bool isPartialMethodImplementationPart, ImmutableArray <RefKind> parameterRefKinds, int beforeParametersPosition, IMethodSymbol method) { if (method.Arity == arity && method.MetadataName == metadataName && ParameterRefKindsMatch(method.Parameters, parameterRefKinds)) { // Method looks like a potential match. It has the right arity, name and // refkinds match. We now need to do the more complicated work of checking // the parameters (and possibly the return type). This is more complicated // because those symbols might refer to method type parameters. In order // for resolution to work on those type parameters, we have to keep track // in the reader that we're resolving this method. // Restore our position to right before the list of parameters. Also, push // this method into our method-resolution-stack so that we can properly resolve // method type parameter ordinals. reader.Position = beforeParametersPosition; reader.PushMethod(method); var result = Resolve(reader, isPartialMethodImplementationPart, method); reader.PopMethod(method); if (result != null) { return(result); } } return(null); }
public static SymbolKeyResolution Resolve(SymbolKeyReader reader) { var metadataName = reader.ReadString(); var containingSymbolResolution = reader.ReadSymbolKey(); var arity = reader.ReadInteger(); var isPartialMethodImplementationPart = reader.ReadBoolean(); var parameterRefKinds = reader.ReadRefKindArray(); // For each method that we look at, we'll have to resolve the parameter list and // return type in the context of that method. i.e. if we have Foo<T>(IList<T> list) // then we'll need to have marked that we're on the Foo<T> method so that we know // 'T' in IList<T> resolves to. // // Because of this, we keep track of where we are in the reader. Before resolving // every parameter list, we'll mark which method we're on and we'll rewind to this // point. var beforeParametersPosition = reader.Position; var result = new List <IMethodSymbol>(); var namedTypes = containingSymbolResolution.GetAllSymbols().OfType <INamedTypeSymbol>(); foreach (var namedType in namedTypes) { var method = Resolve(reader, metadataName, arity, isPartialMethodImplementationPart, parameterRefKinds, beforeParametersPosition, namedType); // Note: after finding the first method that matches we stop. That's necessary // as we cache results while searching. We don't want to override these positive // matches with a negative ones if we were to continue searching. if (method != null) { result.Add(method); break; } } if (reader.Position == beforeParametersPosition) { // We didn't find any candidates. We still need to stream through this // method signature so the reader is in a proper position. // Push an null-method to our stack so that any method-type-parameters // can at least be read (if not resolved) properly. reader.PushMethod(methodOpt: null); var parameterTypeResolutions = reader.ReadSymbolKeyArray(); var returnType = GetFirstSymbol <ITypeSymbol>(reader.ReadSymbolKey()); reader.PopMethod(methodOpt: null); } return(CreateSymbolInfo(result)); }