'Find references' implementation.
This class is thread-safe. The intended multi-threaded usage is to call GetSearchScopes() once, and then call FindReferencesInFile() concurrently on multiple threads (parallel foreach over all interesting files).
예제 #1
0
		void Init(string code)
		{
			compilationUnit = new CSharpParser().Parse(new StringReader(code), "test.cs");
			parsedFile = compilationUnit.ToTypeSystem();
			compilation = TypeSystemHelper.CreateCompilation(parsedFile);
			findReferences = new FindReferences();
		}
예제 #2
0
 void Init(string code)
 {
     syntaxTree     = SyntaxTree.Parse(code, "test.cs");
     unresolvedFile = syntaxTree.ToTypeSystem();
     compilation    = TypeSystemHelper.CreateCompilation(unresolvedFile);
     findReferences = new FindReferences();
 }
예제 #3
0
 void Init(string code)
 {
     compilationUnit = new CSharpParser().Parse(new StringReader(code), "test.cs");
     parsedFile      = compilationUnit.ToTypeSystem();
     compilation     = TypeSystemHelper.CreateCompilation(parsedFile);
     findReferences  = new FindReferences();
 }
예제 #4
0
        public FindUsagesResponse FindUsages(FindUsagesRequest request)
        {
            var res = _parser.ParsedContent(request.Buffer, request.FileName);
            var loc = new TextLocation(request.Line, request.Column);
            var result = new ConcurrentBag<AstNode>();
            var findReferences = new FindReferences();
            ResolveResult resolveResult = ResolveAtLocation.Resolve(res.Compilation, res.UnresolvedFile, res.SyntaxTree, loc);
            if (resolveResult is LocalResolveResult)
            {
                var variable = (resolveResult as LocalResolveResult).Variable;
                findReferences.FindLocalReferences(variable, res.UnresolvedFile, res.SyntaxTree, res.Compilation, (node, rr) => result.Add(node), CancellationToken.None);
            }
            else
            {
                IEntity entity = null;
                if (resolveResult is TypeResolveResult)
                {
                    entity = (resolveResult as TypeResolveResult).Type.GetDefinition();
                }

                if (resolveResult is MemberResolveResult)
                {
                    entity = (resolveResult as MemberResolveResult).Member;
                }

                if (entity == null)
                {
                    return new FindUsagesResponse {Usages = new List<Usage>()};
                }
                var searchScopes = findReferences.GetSearchScopes(entity);

                var interesting = new List<CSharpUnresolvedFile>();

                foreach (var scope in searchScopes)
                {
                    var scopeInteresting = findReferences.GetInterestingFiles(scope, res.Compilation);
                    interesting.AddRange(scopeInteresting);
                }

                Parallel.ForEach(interesting, file =>
                    {
                        ParsedResult parsedResult = _parser.ParsedContent(
                            _solution.GetFile(file.FileName).Content.Text, file.FileName);
                        findReferences.FindReferencesInFile(searchScopes, file, parsedResult.SyntaxTree,
                                                            parsedResult.Compilation,
                                                            (node, rr) => result.Add(node), CancellationToken.None);
                    });

            }

            var usages = result.Select(node => new Usage
            {
                FileName = node.GetRegion().FileName,
                Text = node.Preview(_solution.GetFile(node.GetRegion().FileName)).Replace("'", "''"),
                Line = node.StartLocation.Line,
                Column = node.StartLocation.Column,
            });

            return new FindUsagesResponse { Usages = usages };
        }
예제 #5
0
		void Init(string code)
		{
			syntaxTree = SyntaxTree.Parse(code, "test.cs");
			unresolvedFile = syntaxTree.ToTypeSystem();
			compilation = TypeSystemHelper.CreateCompilation(unresolvedFile);
			findReferences = new FindReferences();
		}
예제 #6
0
		AstNode[] FindReferences(IEntity entity)
		{
			var result = new List<AstNode>();
			var findReferences = new FindReferences();
			var searchScopes = findReferences.GetSearchScopes(entity);
			findReferences.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, compilation,
			                                    (node, rr) => result.Add(node), CancellationToken.None);
			return result.OrderBy(n => n.StartLocation).ToArray();
		}
예제 #7
0
        AstNode[] FindReferences(IEntity entity)
        {
            var result         = new List <AstNode>();
            var findReferences = new FindReferences();
            var searchScopes   = findReferences.GetSearchScopes(entity);

            findReferences.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, compilation,
                                                (node, rr) => result.Add(node), CancellationToken.None);
            return(result.OrderBy(n => n.StartLocation).ToArray());
        }
        bool IsReferenced(IVariable variable, AstNode node, SyntaxTree syntaxTree, RefactoringContext context)
        {
            int referencesFound = 0;
            var findRef = new FindReferences();
            findRef.FindLocalReferences(variable, context.UnresolvedFile, syntaxTree, context.Compilation, (n, entity) => {
                referencesFound++;
            }, CancellationToken.None);

            // One reference is the declaration, and that does not count
            return referencesFound > 1;
        }
	    private static List<AstNode> ComputeMatchNodes(RefactoringContext context, VariableInitializer firstOrNullObject)
	    {
	        var referenceFinder = new FindReferences();
	        var matchedNodes = new List<AstNode>();

	        var resolveResult = context.Resolver.Resolve(firstOrNullObject);
	        var member = resolveResult as MemberResolveResult;
            if (member == null)//not a member is unexpected case, so is better to return no match than to break the code
                return matchedNodes;

	        FoundReferenceCallback callback = (matchNode, result) => matchedNodes.Add(matchNode);

	        var searchScopes = referenceFinder.GetSearchScopes(member.Member);
	        referenceFinder.FindReferencesInFile(searchScopes,
	                                             context.UnresolvedFile,
	                                             context.RootNode as SyntaxTree,
	                                             context.Compilation, callback,
	                                             context.CancellationToken);
	        return matchedNodes;
	    }
			void FindIssuesInNode(AstNode anchor, AstNode node, string accessorName = "setter")
			{
				if (node == null || node.IsNull)
					return;
				var localResolveResult = context.GetResolverStateBefore(node)
					.LookupSimpleNameOrTypeName("value", new List<IType>(), NameLookupMode.Expression) as LocalResolveResult; 
				if (localResolveResult == null)
					return;

				var variable = localResolveResult.Variable;
				bool referenceFound = false;
				var findRef = new FindReferences();
				var syntaxTree = (SyntaxTree)context.RootNode;
				findRef.FindLocalReferences(variable, context.UnresolvedFile, syntaxTree, context.Compilation, (n, entity) => {
					if (n.StartLocation >= node.StartLocation && n.EndLocation <= node.EndLocation) {
						referenceFound = true;
					}
				}, CancellationToken.None);

				if(!referenceFound)
					AddIssue(anchor, context.TranslateString("The " + accessorName + " does not use the 'value' parameter"));
			}
		bool HasDependency(FindReferences referenceFinder, Expression expression)
		{
			if (HasDependencyCheck(referenceFinder, expression))
				return true;
			var queue = new Queue<ResolveResult>();
			queue.Enqueue(context.Resolve(expression));
			do {
				var result = queue.Dequeue();
				if (result is LocalResolveResult && HasDependencyCheck(referenceFinder, (LocalResolveResult)result)) {
					return true;
				}
				foreach (var childResult in result.GetChildResults()) {
					queue.Enqueue(childResult);
				}
			} while (queue.Count > 0);
			return false;
		}
		bool HasDependency(Expression expression)
		{
			var referenceFinder = new FindReferences();
			return HasDependency(referenceFinder, expression);
		}
예제 #13
0
		bool HasDependency(RefactoringContext context, AstNode firstSearchNode, AstNode targetNode)
		{
			var referenceFinder = new FindReferences();
			var identifiers = targetNode.Descendants
				.Where(n => n is IdentifierExpression)
					.Select<AstNode, IdentifierExpression>(node => (IdentifierExpression)node);
			foreach (var identifier in identifiers) {
				var resolveResult = context.Resolve(identifier);
				var localResolveResult = resolveResult as LocalResolveResult;
				if (localResolveResult == null)
					continue;
				bool referenceFound = false;
				var variable = localResolveResult.Variable;
				var syntaxTree = context.RootNode as SyntaxTree;
				referenceFinder.FindLocalReferences(localResolveResult.Variable, context.UnresolvedFile, syntaxTree,
				                                    context.Compilation, (node, nodeResolveResult) => {
					if (node.StartLocation > firstSearchNode.StartLocation && node.EndLocation < targetNode.StartLocation)
						referenceFound = true;
				}, CancellationToken.None);
				if (referenceFound)
					return true;
			}
			return false;
		}
예제 #14
0
        public static void Main(string[] args)
        {
            if (args.Length != 4)
            {
                Console.WriteLine("use: RenameClass.exe <SolutionPath> <ClassNamespace> <CurrentClassName> <NewClassName>");
                return;
            }

            var solutionFile = args[0]; // "C:\\Users\\v-ezeqs\\Documents\\Visual Studio 2010\\Projects\\Application36\\Application36.sln"
            var classNamespace = args[1]; // "Application36.WebHost"
            var className = args[2]; // "SiteMaster"
            var classNewName = args[3]; // "SiteMaster2"

            if (!File.Exists(solutionFile))
            {
                Console.WriteLine("Solution not found at {0}", solutionFile);
                return;
            }

            Console.WriteLine("Loading solution...");

            // Loading Solution in Memory
            Solution solution = new Solution(solutionFile);

            Console.WriteLine("Finding references...");

            // Define which Type I'm looking for
            var typeReference = new GetClassTypeReference(classNamespace, className) as ITypeReference;

            // Try to find the Type definition in solution's projects
            foreach (var proj in solution.Projects)
            {
                var type = typeReference.Resolve(proj.Compilation);
                if (type.Kind != TypeKind.Unknown)
                {
                    SetSearchedMembers(new List<object>() { type });
                }
            }

            if (searchedMembers == null)
            {
                Console.WriteLine("Not References found. Refactoring Done.");
                return;
            }

            // Find all related members related with the Type (like Members, Methods, etc)
            ICSharpCode.NRefactory.CSharp.Resolver.FindReferences refFinder = new ICSharpCode.NRefactory.CSharp.Resolver.FindReferences();
            var scopes = searchedMembers.Select (e => refFinder.GetSearchScopes (e as IEntity));

            // Finding references to the Type on the one of the different Solution files
            refs = new List<dynamic>();
            foreach (var file in solution.AllFiles.Distinct (new CSharpFileEqualityComparer())) {
                foreach (var scope in scopes)
                {
                    refFinder.FindReferencesInFile(
                        scope,
                        file.UnresolvedTypeSystemForFile,
                        file.SyntaxTree,
                        file.Project.Compilation,
                        (astNode, result) =>
                        {
                            var newRef = GetReference(result, astNode, file);
                            if (newRef == null || refs.Any(r => r.File.FileName == newRef.File.FileName && r.Region == newRef.Region))
                                return;
                            refs.Add(newRef);
                        },
                        CancellationToken.None
                    );
                }
            }

            Console.WriteLine("Refactoring {0} places in {1} files...",
                              refs.Count(),
                              refs.Select(x => x.File.FileName).Distinct().Count());

            // Perform replace for each of the References found
            foreach (var r in refs) {
                // DocumentScript expects the the AST to stay unmodified (so that it fits
                // to the document state at the time of the DocumentScript constructor call),
                // so we call Freeze() to prevent accidental modifications (e.g. forgetting a Clone() call).
                r.File.SyntaxTree.Freeze();

                // Create a document containing the file content:
                var fileText = File.ReadAllText(r.File.FileName);
                var document = new StringBuilderDocument(fileText);
                using (var script = new DocumentScript(document, FormattingOptionsFactory.CreateAllman(), new TextEditorOptions())) {
                    // Alternative 1: clone a portion of the AST and modify it
                    //var copy = (InvocationExpression)expr.Clone();
                    //copy.Arguments.Add(stringComparisonAst.Member("Ordinal"));
                    //script.Replace(expr, copy);

                    // Alternative 2: perform direct text insertion / replace
                    int offset = script.GetCurrentOffset(r.Region.Begin);
                    var length = r.Region.End.Column - r.Region.Begin.Column;

                    script.Replace(offset, length, classNewName);
                }
                File.WriteAllText(r.File.FileName, document.Text);
            }

            Console.WriteLine("Refactoring Done.");
        }
예제 #15
0
		void FindReferencesButtonClick(object sender, EventArgs e)
		{
			if (csharpTreeView.SelectedNode == null)
				return;
			
			IProjectContent project = new CSharpProjectContent();
			var unresolvedFile = syntaxTree.ToTypeSystem();
			project = project.AddOrUpdateFiles(unresolvedFile);
			project = project.AddAssemblyReferences(builtInLibs.Value);
			
			ICompilation compilation = project.CreateCompilation();
			CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
			
			AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
			IEntity entity;
			MemberResolveResult mrr = resolver.Resolve(node) as MemberResolveResult;
			TypeResolveResult trr = resolver.Resolve(node) as TypeResolveResult;
			if (mrr != null) {
				entity = mrr.Member;
			} else if (trr != null) {
				entity = trr.Type.GetDefinition();
			} else {
				return;
			}
			
			FindReferences fr = new FindReferences();
			int referenceCount = 0;
			FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
				Debug.WriteLine(matchNode.StartLocation + " - " + matchNode + " - " + result);
				referenceCount++;
			};
			
			var searchScopes = fr.GetSearchScopes(entity);
			Debug.WriteLine("Find references to " + entity.ReflectionName);
			fr.FindReferencesInFile(searchScopes, unresolvedFile, syntaxTree, compilation, callback, CancellationToken.None);
			
			MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
		}
예제 #16
0
		public override void Rename(ISymbol symbol, string name = null)
        {
            FindReferences refFinder = new FindReferences();
            refFinder.FindReferencesInFile(refFinder.GetSearchScopes(symbol),
                                           _context.UnresolvedFile,
                                           _context.RootNode as SyntaxTree,
                                           _context.Compilation, (n, r) => Rename(n, name),
                                           _context.CancellationToken);
        }
예제 #17
0
 public override void Rename(IEntity entity, string name)
 {
     FindReferences refFinder = new FindReferences ();
     refFinder.FindReferencesInFile (refFinder.GetSearchScopes (entity),
                                    context.UnresolvedFile,
                                    context.RootNode as SyntaxTree,
                                    context.Compilation, (n, r) => Rename (n, name),
                                    context.CancellationToken);
 }
예제 #18
0
        private List<AstNode> GetResolvedNodes(ResolveResultType type, AstNode node)
        {
            var resolvedNodes = new List<AstNode>();
            ResolveResult resolveResult = _resolver.Resolve(node);
            if (resolveResult != null)
            {
                var findReferences = new FindReferences();
                FoundReferenceCallback callback = delegate (AstNode matchNode, ResolveResult result)
                {
                    resolvedNodes.Add(matchNode);
                };

                if (type == ResolveResultType.Local)
                {
                    var localResolveResult = resolveResult as LocalResolveResult;
                    if (localResolveResult != null)
                        findReferences.FindLocalReferences(localResolveResult.Variable, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None);
                }
                else if (type == ResolveResultType.Member)
                {
                    var memberResolveResult = resolveResult as MemberResolveResult;
                    if (memberResolveResult != null)
                    {
                        var searchScopes = findReferences.GetSearchScopes(memberResolveResult.Member);
                        findReferences.FindReferencesInFile(searchScopes, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None);
                    }
                }
                else if (type == ResolveResultType.Type)
                {
                    var typeResolveResult = resolveResult as TypeResolveResult;
                    if (typeResolveResult != null)
                    {
                        var searchScopes = findReferences.GetSearchScopes(typeResolveResult.Type.GetDefinition());
                        findReferences.FindReferencesInFile(searchScopes, _unresolvedFile, SyntaxTree, _compilation, callback, CancellationToken.None);
                    }
                }
            }
            else
            {
            }
            return resolvedNodes;
        }
 public override void Rename(ISymbol symbol, string name)
 {
     if (symbol.SymbolKind == SymbolKind.Variable || symbol.SymbolKind == SymbolKind.Parameter) {
         Rename(symbol as IVariable, name);
         return;
     }
     FindReferences refFinder = new FindReferences ();
     refFinder.FindReferencesInFile (refFinder.GetSearchScopes (symbol),
                                    context.UnresolvedFile,
                                    context.RootNode as SyntaxTree,
                                    context.Compilation, (n, r) => Rename (n, name),
                                    context.CancellationToken);
 }
예제 #20
0
파일: CSDemo.cs 프로젝트: jiguixin/ILSpy
		void FindReferencesButtonClick(object sender, EventArgs e)
		{
			if (csharpTreeView.SelectedNode == null)
				return;
			
			SimpleProjectContent project = new SimpleProjectContent();
			var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert(compilationUnit);
			project.UpdateProjectContent(null, parsedFile);
			
			List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
			projects.Add(project);
			projects.AddRange(builtInLibs.Value);
			
			using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
				CSharpResolver resolver = new CSharpResolver(context);
				
				AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
				IResolveVisitorNavigator navigator = new NodeListResolveVisitorNavigator(new[] { node });
				ResolveVisitor visitor = new ResolveVisitor(resolver, parsedFile, navigator);
				visitor.Scan(compilationUnit);
				IEntity entity;
				MemberResolveResult mrr = visitor.GetResolveResult(node) as MemberResolveResult;
				TypeResolveResult trr = visitor.GetResolveResult(node) as TypeResolveResult;
				if (mrr != null) {
					entity = mrr.Member;
				} else if (trr != null) {
					entity = trr.Type.GetDefinition();
				} else {
					return;
				}
				
				FindReferences fr = new FindReferences();
				int referenceCount = 0;
				FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
					referenceCount++;
				};
				
				var searchScopes = fr.GetSearchScopes(entity);
				navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray());
				visitor = new ResolveVisitor(resolver, parsedFile, navigator);
				visitor.Scan(compilationUnit);
				
				csharpTreeView.BeginUpdate();
				ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
				csharpTreeView.EndUpdate();
				
				MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
			}
		}
			public override void Rename (ISymbol symbol, string name)
			{
				if (symbol.SymbolKind == SymbolKind.Variable || symbol.SymbolKind == SymbolKind.Parameter) {
					Rename(symbol as IVariable, name);
					return;
				}

				FindReferences refFinder = new FindReferences ();

				foreach (var fileContext in context.projectContexts)
				{
					using (var newScript = (TestScript) fileContext.StartScript()) {
						refFinder.FindReferencesInFile(refFinder.GetSearchScopes(symbol), 
						                               fileContext.UnresolvedFile, 
						                               fileContext.RootNode as SyntaxTree, 
						                               fileContext.Compilation,
						                               (n, r) => newScript.Rename(n, name), 
						                               context.CancellationToken);
					}
				}
			}
			void DoLocalOperationOn(TestRefactoringContext localContext, IEnumerable<IEntity> entities, Action<RefactoringContext, Script, IEnumerable<AstNode>> callback)
			{
				List<AstNode> nodes = new List<AstNode>();
				FindReferences refFinder = new FindReferences();
				refFinder.FindCallsThroughInterface = true;
				refFinder.FindReferencesInFile(refFinder.GetSearchScopes(entities),
				                               localContext.UnresolvedFile,
				                               localContext.RootNode as SyntaxTree,
				                               localContext.Compilation,
				                               (node, result) => {
					                               nodes.Add(node);
				                               },
				                               CancellationToken.None);

				using (var script = localContext.StartScript()) {
					callback(localContext, script, nodes);
				}
			}
		bool HasDependencyCheck(FindReferences referenceFinder, LocalResolveResult localResolveResult)
		{
			bool result = false;
			referenceFinder.FindLocalReferences(localResolveResult.Variable, context.UnresolvedFile,
			                                    (SyntaxTree)context.RootNode, context.Compilation,
			                                    (node, resolveResult) => {
				result |= VariableHasBeenConverted(localResolveResult.Variable);
			}, CancellationToken.None);
			return result;
		}
예제 #24
0
 public override void Rename(IVariable variable, string name)
 {
     FindReferences refFinder = new FindReferences ();
     refFinder.FindLocalReferences (variable,
                                    context.UnresolvedFile,
                                    context.RootNode as SyntaxTree,
                                    context.Compilation, (n, r) => Rename (n, name),
                                    context.CancellationToken);
 }
		bool HasDependencyCheck(FindReferences referenceFinder, Expression expression)
		{
			var memberReferences = from exp in expression.DescendantsAndSelf
				let memberReference = exp as MemberReferenceExpression
				where memberReference != null
				select memberReference;
			foreach (var memberReference in memberReferences) {
				var resolveResult = context.Resolve(memberReference) as MemberResolveResult;
				if (resolveResult == null)
					continue;
				var initializerPath = AccessPath.FromResolveResult(resolveResult);
				if (initializerPath != null && accessPaths.ContainsKey(initializerPath))
					return true;
			}
			return false;
		}
예제 #26
0
 public override void RenameTypeParameter(IType type, string name = null)
 {
     FindReferences refFinder = new FindReferences ();
     refFinder.FindTypeParameterReferences (type,
                                    context.UnresolvedFile,
                                    context.RootNode as SyntaxTree,
                                    context.Compilation, (n, r) => Rename (n, name),
                                    context.CancellationToken);
 }
        void TestFindReferences(IEntity entity)
        {
            if (IgnoreEntity(entity))
                return;
            FindReferences fr = new FindReferences();
            fr.FindTypeReferencesEvenIfAliased = true;

            Stopwatch w = new Stopwatch();
            var searchScopes = fr.GetSearchScopes(entity);
            foreach (var project in solution.Projects) {
                w.Restart();
                HashSet<AstNode> foundReferences = new HashSet<AstNode>();
                var interestingFiles = new HashSet<CSharpFile>();
                foreach (var searchScope in searchScopes) {
                    foreach (var unresolvedFile in fr.GetInterestingFiles(searchScope, project.Compilation)) {
                        var file = project.Files.Single(f => f.FileName == unresolvedFile.FileName);
                        Debug.Assert(file.UnresolvedTypeSystemForFile == unresolvedFile);

                        // Skip file if it doesn't contain the search term
                        if (searchScope.SearchTerm != null && file.OriginalText.IndexOf(searchScope.SearchTerm, StringComparison.Ordinal) < 0)
                            continue;

                        interestingFiles.Add(file);
                    }
                }
                foreach (var file in interestingFiles) {
                    fr.FindReferencesInFile(searchScopes, file.UnresolvedTypeSystemForFile, file.SyntaxTree, project.Compilation,
                                            delegate(AstNode node, ResolveResult result) {
                                                foundReferences.Add(node);
                                            }, CancellationToken.None);
                }
                w.Stop();
                if (timings.ContainsKey(entity.EntityType)) {
                    timings[entity.EntityType] += w.Elapsed;
                } else {
                    timings[entity.EntityType] = w.Elapsed;
                }

                IEntity importedEntity = project.Compilation.Import(entity);

                HashSet<AstNode> expectedReferences;
                if (importedEntity == null || !referenceDict.TryGetValue(importedEntity, out expectedReferences)) {
                    if (foundReferences.Any()) {
                        // There aren't any expected references stored, but we found some references anyways:
                        Console.WriteLine();
                        Console.WriteLine("Entity not in reference dictionary: " + entity);
                    }
                    return;
                }
                if (foundReferences.Except(expectedReferences).Any()) {
                    Console.WriteLine();
                    Console.WriteLine("Reference mismatch for " + entity + ":");
                    var n = foundReferences.Except(expectedReferences).First();
                    Console.WriteLine("Found unexpected reference " + n + " (" + n.GetRegion() + ")");
                }
                if (expectedReferences.Except(foundReferences).Any()) {
                    Console.WriteLine();
                    Console.WriteLine("Reference mismatch for " + entity + ":");
                    var n = expectedReferences.Except(foundReferences).First();
                    Console.WriteLine("Did not find expected reference " + n + " (" + n.GetRegion() + ")");
                }
            }

            if (entityCount.ContainsKey(entity.EntityType)) {
                entityCount[entity.EntityType]++;
            } else {
                entityCount[entity.EntityType] = 1;
            }
        }
		IResolveVisitorNavigator InitNavigator(ICompilation compilation)
		{
			if (currentSymbolReference == null || compilation == null)
				return null;
			var symbol = currentSymbolReference.Resolve(compilation.TypeResolveContext);
			FindReferences findReferences = new FindReferences();
			if (symbol == null) return null;
			var searchScopes = findReferences.GetSearchScopes(symbol);
			if (searchScopes.Count == 0)
				return null;
			var navigators = new IResolveVisitorNavigator[searchScopes.Count];
			for (int i = 0; i < navigators.Length; i++) {
				navigators[i] = searchScopes[i].GetNavigator(compilation, ColorizeMatch);
			}
			IResolveVisitorNavigator combinedNavigator;
			if (searchScopes.Count == 1) {
				combinedNavigator = navigators[0];
			}
			else {
				combinedNavigator = new CompositeResolveVisitorNavigator(navigators);
			}
			return combinedNavigator;
		}