diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java index 88206c70777..37fed89d522 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java @@ -1376,27 +1376,34 @@ protected void locateMatchesWithASTParser(JavaProject javaProject, PossibleMatch map.put(CompilerOptions.OPTION_TaskTags, org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING); this.options = new CompilerOptions(map); - List unitCollector = new ArrayList<>(); - Map matchToCU = new HashMap<>(); + // Original implementation used Map throughout, however, + // PossibleMatch was determined to be a bad / non-unique key where the + // hashCode and equals methods would let two different matches overlap. + // So we have to use Arrays and Lists, like a bunch of barbarians. + org.eclipse.jdt.core.ICompilationUnit[] unitArray = new org.eclipse.jdt.core.ICompilationUnit[possibleMatches.length]; + Map cuToMatch = new HashMap<>(); for( int i = 0; i < possibleMatches.length; i++ ) { if( !skipMatch(javaProject, possibleMatches[i])) { org.eclipse.jdt.core.ICompilationUnit u = findUnitForPossibleMatch(javaProject, possibleMatches[i]); - unitCollector.add(u); - matchToCU.put(possibleMatches[i], u); + unitArray[i] = u; cuToMatch.put(u, possibleMatches[i]); } } - org.eclipse.jdt.core.ICompilationUnit[] units = unitCollector.toArray(new org.eclipse.jdt.core.ICompilationUnit[unitCollector.size()]); + org.eclipse.jdt.core.ICompilationUnit[] nonNullUnits = + Arrays.asList(unitArray).stream().filter(x -> x != null).toArray(org.eclipse.jdt.core.ICompilationUnit[]::new); +// debugMethodOne(javaProject, possibleMatches[0], new org.eclipse.jdt.core.ICompilationUnit[] {units[0]}); +// debugMethodTwo(javaProject, possibleMatches[0], new org.eclipse.jdt.core.ICompilationUnit[] {units[0]}); +// debugMethodThree(javaProject, possibleMatches[0], units); - if (units.length == 0) { + if (nonNullUnits.length == 0) { return; } Set ownerSet = new HashSet<>(); - for( int i = 0; i < units.length; i++ ) { - if( units[i].getOwner() != null ) { - ownerSet.add(units[i].getOwner()); + for( int i = 0; i < nonNullUnits.length; i++ ) { + if( nonNullUnits[i].getOwner() != null ) { + ownerSet.add(nonNullUnits[i].getOwner()); } } WorkingCopyOwner owner = null; @@ -1412,36 +1419,45 @@ protected void locateMatchesWithASTParser(JavaProject javaProject, PossibleMatch if( owner != null ) astParser.setWorkingCopyOwner(owner); - Map asts = new HashMap<>(); - astParser.createASTs(units, new String[0], new ASTRequestor() { + org.eclipse.jdt.core.dom.CompilationUnit[] domUnits = new org.eclipse.jdt.core.dom.CompilationUnit[possibleMatches.length]; + List nonNullDomIndexes = new ArrayList<>(); + astParser.createASTs(nonNullUnits, new String[0], new ASTRequestor() { @Override public void acceptAST(org.eclipse.jdt.core.ICompilationUnit source, org.eclipse.jdt.core.dom.CompilationUnit ast) { PossibleMatch pm = cuToMatch.get(source); if( pm != null ) { - asts.put(pm, ast); + for( int i = 0; i < possibleMatches.length; i++ ) { + if( possibleMatches[i] == pm ) { + domUnits[i] = ast; + nonNullDomIndexes.add(i); + return; + } + } } - -// Arrays.stream(possibleMatches, start, start + length) .filter(match -> match.openable.equals(source)) -// .findAny() .ifPresent(match -> asts.put(match, ast)); } - }, this.progressMonitor); // todo, use a subprogressmonitor or slice it - asts.forEach((possibleMatch, ast) -> { + // todo, use a subprogressmonitor or slice it + }, this.progressMonitor); + + + nonNullDomIndexes.forEach(x -> { + PossibleMatch possibleMatch = possibleMatches[x]; + org.eclipse.jdt.core.dom.CompilationUnit ast = domUnits[x]; ast.accept(new PatternLocatorVisitor(this.patternLocator, possibleMatch.nodeSet, this)); }); - asts.keySet().forEach(possibleMatch -> { + + for( int x : nonNullDomIndexes ) { + PossibleMatch possibleMatch = possibleMatches[x]; this.currentPossibleMatch = possibleMatch; - possibleMatch.nodeSet.trustedASTNodeLevels.forEach((node, level) -> { + for( org.eclipse.jdt.core.dom.ASTNode node : possibleMatch.nodeSet.trustedASTNodeLevels.keySet()) { + int level = possibleMatch.nodeSet.trustedASTNodeLevels.get(node); SearchMatch match = toMatch(node, level, possibleMatch); if( match != null && match.getElement() != null ) { - try { - this.report(match); - } catch (CoreException ex) { - ILog.get().error(ex.getMessage(), ex); - } + this.report(match); } - }); - }); + } + } } + private SearchMatch toMatch(org.eclipse.jdt.core.dom.ASTNode node, int accuracy, PossibleMatch possibleMatch) { IResource resource = possibleMatch.resource; if (node instanceof MethodDeclaration || node instanceof AbstractTypeDeclaration || node instanceof VariableDeclaration) {