View | Details | Raw Unified | Return to bug 250454
Collapse All | Expand All

(-)search/org/eclipse/jdt/internal/core/search/IndexSelector.java (-36 / +67 lines)
Lines 12-22 Link Here
12
12
13
import org.eclipse.core.resources.IFolder;
13
import org.eclipse.core.resources.IFolder;
14
import org.eclipse.core.runtime.IPath;
14
import org.eclipse.core.runtime.IPath;
15
import org.eclipse.jdt.core.IClasspathEntry;
15
import org.eclipse.jdt.core.*;
16
import org.eclipse.jdt.core.IJavaElement;
17
import org.eclipse.jdt.core.IJavaModel;
18
import org.eclipse.jdt.core.IJavaProject;
19
import org.eclipse.jdt.core.JavaModelException;
20
import org.eclipse.jdt.core.search.IJavaSearchScope;
16
import org.eclipse.jdt.core.search.IJavaSearchScope;
21
import org.eclipse.jdt.core.search.SearchPattern;
17
import org.eclipse.jdt.core.search.SearchPattern;
22
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
18
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
Lines 49-65 Link Here
49
 * a JarPackageFragmentRot) either because the focus is part of the project or the jar, or because it is
45
 * a JarPackageFragmentRot) either because the focus is part of the project or the jar, or because it is
50
 * accessible throught the project's classpath
46
 * accessible throught the project's classpath
51
 */
47
 */
52
public static boolean canSeeFocus(IJavaElement focus, boolean isPolymorphicSearch, IPath projectOrJarPath) {
48
public static boolean canSeeFocus(SearchPattern pattern, IPath projectOrJarPath) {
53
	try {
49
	try {
54
		IClasspathEntry[] focusEntries = null;
50
		IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
55
		if (isPolymorphicSearch) {
56
			JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
57
			focusEntries = focusProject.getExpandedClasspath();
58
		}
59
		IJavaModel model = focus.getJavaModel();
60
		IJavaProject project = getJavaProject(projectOrJarPath, model);
51
		IJavaProject project = getJavaProject(projectOrJarPath, model);
61
		if (project != null)
52
		IJavaElement[] focuses = getFocusedElements(pattern, project);
62
			return canSeeFocus(focus, (JavaProject) project, focusEntries);
53
		if (project != null) {
54
			return canSeeFocus(focuses, (JavaProject) project);
55
		}
63
56
64
		// projectOrJarPath is a jar
57
		// projectOrJarPath is a jar
65
		// it can see the focus only if it is on the classpath of a project that can see the focus
58
		// it can see the focus only if it is on the classpath of a project that can see the focus
Lines 67-96 Link Here
67
		for (int i = 0, length = allProjects.length; i < length; i++) {
60
		for (int i = 0, length = allProjects.length; i < length; i++) {
68
			JavaProject otherProject = (JavaProject) allProjects[i];
61
			JavaProject otherProject = (JavaProject) allProjects[i];
69
			IClasspathEntry entry = otherProject.getClasspathEntryFor(projectOrJarPath);
62
			IClasspathEntry entry = otherProject.getClasspathEntryFor(projectOrJarPath);
70
			if (entry != null
63
			if (entry != null && entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
71
					&& entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
64
				if (canSeeFocus(focuses, otherProject)) {
72
					&& canSeeFocus(focus, otherProject, focusEntries))
65
					return true;
73
				return true;
66
				}
67
			}
74
		}
68
		}
75
		return false;
69
		return false;
76
	} catch (JavaModelException e) {
70
	} catch (JavaModelException e) {
77
		return false;
71
		return false;
78
	}
72
	}
79
}
73
}
80
public static boolean canSeeFocus(IJavaElement focus, JavaProject javaProject, IClasspathEntry[] focusEntriesForPolymorphicSearch) {
74
private static boolean canSeeFocus(IJavaElement[] focuses, JavaProject javaProject) {
75
	int length = focuses.length;
76
	for (int i=0; i<length; i++) {
77
		if (canSeeFocus(focuses[i], javaProject)) return true;
78
	}
79
	return false;
80
}
81
private static boolean canSeeFocus(IJavaElement focus, JavaProject javaProject) {
81
	try {
82
	try {
82
		if (focus.equals(javaProject))
83
		if (focus == null) return false;
83
			return true;
84
		if (focus.equals(javaProject)) return true;
84
85
85
		if (focusEntriesForPolymorphicSearch != null) {
86
			// look for refering project
87
			IPath projectPath = javaProject.getProject().getFullPath();
88
			for (int i = 0, length = focusEntriesForPolymorphicSearch.length; i < length; i++) {
89
				IClasspathEntry entry = focusEntriesForPolymorphicSearch[i];
90
				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(projectPath))
91
					return true;
92
			}
93
		}
94
		if (focus instanceof JarPackageFragmentRoot) {
86
		if (focus instanceof JarPackageFragmentRoot) {
95
			// focus is part of a jar
87
			// focus is part of a jar
96
			IPath focusPath = focus.getPath();
88
			IPath focusPath = focus.getPath();
Lines 115-120 Link Here
115
		return false;
107
		return false;
116
	}
108
	}
117
}
109
}
110
111
/*
112
 * Create the list of focused jars or projects.
113
 */
114
private static IJavaElement[] getFocusedElements(SearchPattern pattern, IJavaElement focusElement) throws JavaModelException {
115
	if (pattern instanceof MethodPattern) {
116
		// For method pattern, it needs to walk along the focus type super hierarchy
117
		// and add jars/projects of all the encountered types.
118
		IType type = (IType) pattern.focus.getAncestor(IJavaElement.TYPE);
119
		MethodPattern methodPattern = (MethodPattern) pattern;
120
		String selector = new String(methodPattern.selector);
121
		int parameterCount = methodPattern.parameterCount;
122
		ITypeHierarchy superHierarchy = type.newSupertypeHierarchy(null);
123
		IType[] allTypes = superHierarchy.getAllSupertypes(type);
124
		int length = allTypes.length;
125
		SimpleSet focusSet = new SimpleSet(length+1);
126
		focusSet.add(focusElement);
127
		for (int i=0; i<length; i++) {
128
			IMethod[] methods = allTypes[i].getMethods();
129
			int mLength = methods.length;
130
			for (int m=0; m<mLength; m++) {
131
				if (parameterCount == methods[m].getNumberOfParameters() && methods[m].getElementName().equals(selector)) {
132
					IPackageFragmentRoot root = (IPackageFragmentRoot) allTypes[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
133
					IJavaElement element = root.isArchive() ? root : root.getParent();
134
					focusSet.add(element);
135
				}
136
			}
137
		}
138
		// Rebuilt a contiguous array
139
		IJavaElement[] focuses = new IJavaElement[focusSet.elementSize];
140
		Object[] values = focusSet.values;
141
		int count = 0;
142
		for (int i = values.length; --i >= 0;) {
143
			if (values[i] != null) {
144
				focuses[count++] = (IJavaElement) values[i];
145
			}
146
		}
147
		return focuses;
148
	}
149
	return new IJavaElement[] { focusElement };
150
}
151
118
/*
152
/*
119
 *  Compute the list of paths which are keying index files.
153
 *  Compute the list of paths which are keying index files.
120
 */
154
 */
Lines 139-156 Link Here
139
			SimpleSet visitedProjects = new SimpleSet(length);
173
			SimpleSet visitedProjects = new SimpleSet(length);
140
			int projectIndex = 0;
174
			int projectIndex = 0;
141
			SimpleSet externalLibsToCheck = new SimpleSet(length);
175
			SimpleSet externalLibsToCheck = new SimpleSet(length);
142
			IClasspathEntry[] focusEntries = null;
176
			IJavaElement[] focuses = getFocusedElements(this.pattern, focus);
143
			if (this.pattern instanceof MethodPattern) { // should consider polymorphic search for method patterns
144
				JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
145
				focusEntries = focusProject.getExpandedClasspath();
146
			}
147
			IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
177
			IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
148
			for (int i = 0; i < length; i++) {
178
			for (int i = 0; i < length; i++) {
149
				IPath path = projectsAndJars[i];
179
				IPath path = projectsAndJars[i];
150
				JavaProject project = (JavaProject) getJavaProject(path, model);
180
				JavaProject project = (JavaProject) getJavaProject(path, model);
151
				if (project != null) {
181
				if (project != null) {
152
					visitedProjects.add(project);
182
					visitedProjects.add(project);
153
					if (canSeeFocus(focus, project, focusEntries)) {
183
					if (canSeeFocus(focuses, project)) {
154
						locations.add(manager.computeIndexLocation(path));
184
						locations.add(manager.computeIndexLocation(path));
155
						projectsCanSeeFocus[projectIndex++] = project;
185
						projectsCanSeeFocus[projectIndex++] = project;
156
					}
186
					}
Lines 207-212 Link Here
207
		if (values[i] != null)
237
		if (values[i] != null)
208
			this.indexLocations[count++] = (IPath) values[i];
238
			this.indexLocations[count++] = (IPath) values[i];
209
}
239
}
240
210
public IPath[] getIndexLocations() {
241
public IPath[] getIndexLocations() {
211
	if (this.indexLocations == null) {
242
	if (this.indexLocations == null) {
212
		initializeIndexLocations();
243
		initializeIndexLocations();
(-)search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java (-9 / +4 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 169-175 Link Here
169
public static SearchDocument[] addWorkingCopies(SearchPattern pattern, SearchDocument[] indexMatches, org.eclipse.jdt.core.ICompilationUnit[] copies, SearchParticipant participant) {
169
public static SearchDocument[] addWorkingCopies(SearchPattern pattern, SearchDocument[] indexMatches, org.eclipse.jdt.core.ICompilationUnit[] copies, SearchParticipant participant) {
170
	if (copies == null) return indexMatches;
170
	if (copies == null) return indexMatches;
171
	// working copies take precedence over corresponding compilation units
171
	// working copies take precedence over corresponding compilation units
172
	HashMap workingCopyDocuments = workingCopiesThatCanSeeFocus(copies, pattern.focus, pattern.isPolymorphicSearch(), participant);
172
	HashMap workingCopyDocuments = workingCopiesThatCanSeeFocus(copies, pattern, participant);
173
	if (workingCopyDocuments.size() == 0) return indexMatches;
173
	if (workingCopyDocuments.size() == 0) return indexMatches;
174
	SearchDocument[] matches = null;
174
	SearchDocument[] matches = null;
175
	int length = indexMatches.length;
175
	int length = indexMatches.length;
Lines 207-224 Link Here
207
/*
207
/*
208
 * Returns the working copies that can see the given focus.
208
 * Returns the working copies that can see the given focus.
209
 */
209
 */
210
private static HashMap workingCopiesThatCanSeeFocus(org.eclipse.jdt.core.ICompilationUnit[] copies, IJavaElement focus, boolean isPolymorphicSearch, SearchParticipant participant) {
210
private static HashMap workingCopiesThatCanSeeFocus(org.eclipse.jdt.core.ICompilationUnit[] copies, SearchPattern pattern, SearchParticipant participant) {
211
	if (copies == null) return new HashMap();
211
	if (copies == null) return new HashMap();
212
	if (focus != null) {
213
		while (!(focus instanceof IJavaProject) && !(focus instanceof JarPackageFragmentRoot)) {
214
			focus = focus.getParent();
215
		}
216
	}
217
	HashMap result = new HashMap();
212
	HashMap result = new HashMap();
218
	for (int i=0, length = copies.length; i<length; i++) {
213
	for (int i=0, length = copies.length; i<length; i++) {
219
		org.eclipse.jdt.core.ICompilationUnit workingCopy = copies[i];
214
		org.eclipse.jdt.core.ICompilationUnit workingCopy = copies[i];
220
		IPath projectOrJar = MatchLocator.getProjectOrJar(workingCopy).getPath();
215
		IPath projectOrJar = MatchLocator.getProjectOrJar(workingCopy).getPath();
221
		if (focus == null || IndexSelector.canSeeFocus(focus, isPolymorphicSearch, projectOrJar)) {
216
		if (pattern.focus == null || IndexSelector.canSeeFocus(pattern, projectOrJar)) {
222
			result.put(
217
			result.put(
223
				workingCopy.getPath().toString(),
218
				workingCopy.getPath().toString(),
224
				new WorkingCopyDocument(workingCopy, participant)
219
				new WorkingCopyDocument(workingCopy, participant)
(-)src/org/eclipse/jdt/core/tests/model/JavaSearchMultipleProjectsTests.java (-3 / +129 lines)
Lines 1210-1218 Link Here
1210
}
1210
}
1211
1211
1212
/**
1212
/**
1213
 * @bug 48534: [search] Java Search for OR-pattern finds too much in strange project setup
1213
 * @bug 210689: [search] Import references not found on working copies not written on disk
1214
 * @test Ensure that search does not find illegal references with given projects setup
1214
 * @test Ensure that import references are found when searching on working copies not written on disk
1215
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=48534"
1215
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=210689"
1216
 */
1216
 */
1217
public void testBug210689() throws CoreException {
1217
public void testBug210689() throws CoreException {
1218
	try {
1218
	try {
Lines 1429-1432 Link Here
1429
		deleteProjects(new String[] {"P1", "P2", "P3"});
1429
		deleteProjects(new String[] {"P1", "P2", "P3"});
1430
	}
1430
	}
1431
}
1431
}
1432
1433
/**
1434
 * @bug 250454: [search] Cannot find method references between projects
1435
 * @test Ensure that search does not find illegal references with given projects setup
1436
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=250454"
1437
 */
1438
public void testBug250454() throws CoreException {
1439
	try {
1440
		// setup project P0
1441
		createJavaProject("P0");
1442
		createFolder("/P0/p");
1443
		createFile(
1444
			"/P0/p/Shape.java",
1445
			"package p;\n" +
1446
			"public interface Shape {\n" + 
1447
			"	public void f();\n" + 
1448
			"}\n"
1449
		);
1450
1451
		// setup project P1
1452
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P0" }, "");
1453
		createFolder("/P1/p");
1454
		createFile(
1455
			"/P1/p/Square.java",
1456
			"package p;\n" +
1457
			"public class Square implements Shape {\n" + 
1458
			"	public void f() {}\n" + 
1459
			"}\n"
1460
		);
1461
1462
		// setup project P2
1463
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB"}, new String[] { "/P0" }, "");
1464
		createFolder("/P2/p");
1465
		createFile(
1466
			"/P2/p/ShapeUser.java",
1467
			"package p;\n" +
1468
			"public class ShapeUser {\n" + 
1469
			"	public void useShape(Shape p_shape) {\n" + 
1470
			"		p_shape.f();\n" + 
1471
			"	}\n"
1472
		);
1473
1474
		// Perform search
1475
		IType type = getCompilationUnit("/P1/p/Square.java").getType("Square");
1476
		IMethod method = type.getMethod("f", new String[0]);
1477
		SearchPattern pattern = SearchPattern.createPattern(method, REFERENCES);
1478
		JavaSearchResultCollector resultCollector = new JavaSearchResultCollector();
1479
		resultCollector.showProject();
1480
		resultCollector.showAccuracy(true);
1481
		new SearchEngine().search(
1482
			pattern,
1483
			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
1484
			SearchEngine.createWorkspaceScope(),
1485
			resultCollector,
1486
			null
1487
		);
1488
		assertSearchResults(
1489
			"Unexpected references to "+method,
1490
			"p/ShapeUser.java [in P2] void p.ShapeUser.useShape(Shape) [f()] EXACT_MATCH",
1491
			resultCollector);
1492
	} finally {
1493
		deleteProject("P0");
1494
		deleteProject("P1");
1495
		deleteProject("P2");
1496
	}
1497
}
1498
public void testBug250454_jars() throws CoreException, IOException {
1499
	String jarPath = getExternalPath()+"b250454.jar";
1500
	try {
1501
		// setup jar
1502
		String[] pathsAndContents= new String[] {
1503
			"p/Shape.java",
1504
			"package p;\n" +
1505
			"public interface Shape {\n" + 
1506
			"	public void f();\n" + 
1507
			"}\n"
1508
		};
1509
		createJar(pathsAndContents, jarPath);
1510
1511
		// setup project P1
1512
		createJavaProject("P1", new String[] {""}, new String[] {"JCL_LIB", jarPath}, "");
1513
		createFolder("/P1/p");
1514
		createFile(
1515
			"/P1/p/Square.java",
1516
			"package p;\n" +
1517
			"public class Square implements Shape {\n" + 
1518
			"	public void f() {}\n" + 
1519
			"}\n"
1520
		);
1521
1522
		// setup project P2
1523
		createJavaProject("P2", new String[] {""}, new String[] {"JCL_LIB", jarPath}, "");
1524
		createFolder("/P2/p");
1525
		createFile(
1526
			"/P2/p/ShapeUser.java",
1527
			"package p;\n" +
1528
			"public class ShapeUser {\n" + 
1529
			"	public void useShape(Shape p_shape) {\n" + 
1530
			"		p_shape.f();\n" + 
1531
			"	}\n"
1532
		);
1533
1534
		// Perform search
1535
		IType type = getCompilationUnit("/P1/p/Square.java").getType("Square");
1536
		IMethod method = type.getMethod("f", new String[0]);
1537
		SearchPattern pattern = SearchPattern.createPattern(method, REFERENCES);
1538
		JavaSearchResultCollector resultCollector = new JavaSearchResultCollector();
1539
		resultCollector.showProject();
1540
		resultCollector.showAccuracy(true);
1541
		new SearchEngine().search(
1542
			pattern,
1543
			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
1544
			SearchEngine.createWorkspaceScope(),
1545
			resultCollector,
1546
			null
1547
		);
1548
		assertSearchResults(
1549
			"Unexpected references to "+method,
1550
			"p/ShapeUser.java [in P2] void p.ShapeUser.useShape(Shape) [f()] EXACT_MATCH",
1551
			resultCollector);
1552
	} finally {
1553
		deleteExternalFile(jarPath);
1554
		deleteProject("P1");
1555
		deleteProject("P2");
1556
	}
1557
}
1432
}
1558
}

Return to bug 250454