protected ResolveResult Resolve(string code) { CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", ""))); TextLocation[] dollars = FindDollarSigns(code).ToArray(); Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node"); SetUp(); CSharpParsedFile parsedFile = new CSharpParsedFile("test.cs", resolver.CurrentUsingScope); TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(parsedFile, resolver.CurrentUsingScope, null); cu.AcceptVisitor(convertVisitor, null); project.UpdateProjectContent(null, convertVisitor.ParsedFile); FindNodeVisitor fnv = new FindNodeVisitor(dollars[0], dollars[1]); cu.AcceptVisitor(fnv, null); Assert.IsNotNull(fnv.ResultNode, "Did not find DOM node at the specified location"); Debug.WriteLine(new string('=', 70)); Debug.WriteLine("Starting new resolver for " + fnv.ResultNode); var navigator = new NodeListResolveVisitorNavigator(new[] { fnv.ResultNode }); ResolveResult rr; using (var context = this.context.Synchronize()) { ResolveVisitor rv = new ResolveVisitor(new CSharpResolver(context), convertVisitor.ParsedFile, navigator); rv.Scan(cu); rr = rv.GetResolveResult(fnv.ResultNode); } Assert.IsNotNull(rr, "ResolveResult is null - did something go wrong while navigating to the target node?"); Debug.WriteLine("ResolveResult is " + rr); return(rr); }
void InitResolver(AstNode firstNodeToResolve) { if (resolveVisitor == null) { resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, new NodeListResolveVisitorNavigator(firstNodeToResolve)); resolveVisitor.Scan(rootNode); } }
/// <summary> /// Applies a resolver navigator. This will resolve the nodes requested by the navigator, and will inform the /// navigator of the results. /// This method must be called as the first operation on the CSharpAstResolver, it is invalid to apply a navigator /// after a portion of the file was already resolved. /// </summary> public void ApplyNavigator(IResolveVisitorNavigator navigator, CancellationToken cancellationToken = default(CancellationToken)) { if (navigator == null) { throw new ArgumentNullException("navigator"); } if (resolverInitialized) { throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver."); } resolverInitialized = true; resolveVisitor.cancellationToken = cancellationToken; resolveVisitor.SetNavigator(navigator); try { resolveVisitor.Scan(rootNode); } finally { resolveVisitor.SetNavigator(null); resolveVisitor.cancellationToken = CancellationToken.None; } }
/// <summary> /// Applies a resolver navigator. This will resolve the nodes requested by the navigator, and will inform the /// navigator of the results. /// This method must be called as the first operation on the CSharpAstResolver, it is invalid to apply a navigator /// after a portion of the file was already resolved. /// </summary> public void ApplyNavigator(IResolveVisitorNavigator navigator, CancellationToken cancellationToken = default(CancellationToken)) { if (navigator == null) { throw new ArgumentNullException("navigator"); } if (resolveVisitor != null) { throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver."); } resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, navigator); lock (resolveVisitor) resolveVisitor.Scan(rootNode); }
/// <summary> /// Finds all references in the given file. /// </summary> /// <param name="searchScopes">The search scopes for which to look.</param> /// <param name="parsedFile">The type system representation of the file being searched.</param> /// <param name="compilationUnit">The compilation unit of the file being searched.</param> /// <param name="context">The type resolve context to use for resolving the file.</param> /// <param name="callback">Callback used to report the references that were found.</param> public void FindReferencesInFile(IList <IFindReferenceSearchScope> searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit, ITypeResolveContext context, FoundReferenceCallback callback) { if (searchScopes == null) { throw new ArgumentNullException("searchScopes"); } if (parsedFile == null) { throw new ArgumentNullException("parsedFile"); } if (compilationUnit == null) { throw new ArgumentNullException("compilationUnit"); } if (context == null) { throw new ArgumentNullException("context"); } this.CancellationToken.ThrowIfCancellationRequested(); if (searchScopes.Count == 0) { return; } using (var ctx = context.Synchronize()) { IResolveVisitorNavigator navigator; if (searchScopes.Count == 1) { navigator = searchScopes[0].GetNavigator(callback); } else { navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray()); } navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); CSharpResolver resolver = new CSharpResolver(ctx, this.CancellationToken); ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator); v.Scan(compilationUnit); } }
public static ResolveResult Resolve(ITypeResolveContext context, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location, CancellationToken cancellationToken = default(CancellationToken)) { AstNode node = cu.GetNodeAt(location); if (node == null) { return(null); } AstNode resolvableNode; if (node is AstType) { resolvableNode = node; if (resolvableNode.Parent is ComposedType) { while (resolvableNode.Parent is ComposedType) { resolvableNode = resolvableNode.Parent; } //node is preffered over the resolvable node. Which shouldn't be done in the case of nullables, arrays etc. node = resolvableNode; } } else if (node is Identifier) { resolvableNode = node.Parent; } else if (node.NodeType == NodeType.Token) { if (node.Parent is ConstructorInitializer) { resolvableNode = node.Parent; } else { return(null); } } else { // don't resolve arbitrary nodes - we don't want to show tooltips for everything return(null); } InvocationExpression parentInvocation = null; if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression)) { // we also need to resolve the invocation parentInvocation = resolvableNode.Parent as InvocationExpression; } IResolveVisitorNavigator navigator; if (parentInvocation != null) { navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode, parentInvocation }); } else { navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode }); } using (var ctx = context.Synchronize()) { CSharpResolver resolver = new CSharpResolver(ctx, cancellationToken); ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator); v.Scan(cu); // Prefer the RR from the token itself, if it was assigned a ResolveResult // (this can happen with the identifiers in various nodes such as catch clauses or foreach statements) ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode); if (rr is MethodGroupResolveResult && parentInvocation != null) { return(v.GetResolveResult(parentInvocation)); } else { return(rr); } } }