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

(-)src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java (-1 / +63 lines)
Lines 55-61 Link Here
55
	}
55
	}
56
}
56
}
57
class TypeReferencesCollector extends JavaSearchResultCollector {
57
class TypeReferencesCollector extends JavaSearchResultCollector {
58
59
	protected IJavaElement getElement(SearchMatch searchMatch) {
58
	protected IJavaElement getElement(SearchMatch searchMatch) {
60
		IJavaElement element = super.getElement(searchMatch);
59
		IJavaElement element = super.getElement(searchMatch);
61
		IJavaElement localElement = null;
60
		IJavaElement localElement = null;
Lines 6896-6899 Link Here
6896
		"b156177.B156177_I",
6895
		"b156177.B156177_I",
6897
		requestor);
6896
		requestor);
6898
}
6897
}
6898
6899
/**
6900
 * Bug 156491: [1.5][search] interfaces and annotations could be found with only one requets of searchAllTypeName
6901
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=156491"
6902
 */
6903
public void testBug156491() throws CoreException {
6904
	resultCollector.showRule = true;
6905
	workingCopies = new ICompilationUnit[5];
6906
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/pack/I.java",
6907
		"package pack;\n" + 
6908
		"public interface I {}\n"
6909
	);
6910
	workingCopies[1] = getWorkingCopy("/JavaSearchBugs/src/pack/X.java",
6911
		"package pack;\n" + 
6912
		"public class X {\n" + 
6913
		"	public String toString() {\n" + 
6914
		"		return \"X\";\n" + 
6915
		"	}\n" + 
6916
		"}\n"
6917
	);
6918
	workingCopies[2] = getWorkingCopy("/JavaSearchBugs/src/pack/Sub.java",
6919
		"package pack;\n" + 
6920
		"public class Sub extends X {}\n"
6921
	);
6922
	workingCopies[3] = getWorkingCopy("/JavaSearchBugs/src/pack/Y.java",
6923
		"package pack;\n" + 
6924
		"public class Y {\n" + 
6925
		"	public String toString() {\n" + 
6926
		"		return \"Y\";\n" + 
6927
		"	}\n" + 
6928
		"}\n"
6929
	);
6930
	workingCopies[4] = getWorkingCopy("/JavaSearchBugs/src/pack/Test.java",
6931
		"package pack;\n" + 
6932
		"public class Test {\n" + 
6933
		"	void noMatch(Y y) {\n" + 
6934
		"		y.toString();\n" + 
6935
		"		toString();\n" + 
6936
		"	}\n" + 
6937
		"	void validMatches(X x) {\n" + 
6938
		"		x.toString();\n" + 
6939
		"	}\n" + 
6940
		"	void polymorphicSuper(Object o) {\n" + 
6941
		"		o.toString();\n" + 
6942
		"	}\n" + 
6943
		"	void polymorphicPotential(I i) {\n" + 
6944
		"		i.toString();\n" + 
6945
		"	}\n" + 
6946
		"	void polymorphicSub(Sub s) {\n" + 
6947
		"		s.toString();\n" + 
6948
		"	}\n" + 
6949
		"}\n"
6950
	);
6951
	IMethod method = workingCopies[1].getType("X").getMethod("toString", new String[0]);
6952
	this.resultCollector.showPolymorphic = 2;
6953
	search(method, REFERENCES);
6954
	assertSearchResults(
6955
		"src/pack/Test.java void pack.Test.validMatches(X) [toString()] EXACT_MATCH\n" + 
6956
		"src/pack/Test.java void pack.Test.polymorphicSuper(Object) [toString()] EXACT_MATCH POLYMORPHIC\n" + 
6957
		"src/pack/Test.java void pack.Test.polymorphicPotential(I) [toString()] POTENTIAL_MATCH POLYMORPHIC\n" + 
6958
		"src/pack/Test.java void pack.Test.polymorphicSub(Sub) [toString()] EXACT_MATCH POLYMORPHIC"
6959
	);
6960
}
6899
}
6961
}
(-)src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java (-1 / +20 lines)
Lines 55-66 Link Here
55
		public boolean showPotential = true;
55
		public boolean showPotential = true;
56
		public boolean showProject;
56
		public boolean showProject;
57
		public boolean showSynthetic;
57
		public boolean showSynthetic;
58
		public int showPolymorphic = 0;
58
		public int count = 0;
59
		public int count = 0;
59
		public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
60
		public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
60
			count++;
61
			count++;
61
			this.match = searchMatch;
62
			this.match = searchMatch;
62
			writeLine();
63
			writeLine();
63
			writeLineToResult();
64
			if (line != null) {
65
				writeLineToResult();
66
			}
64
		}
67
		}
65
		protected void writeLineToResult() {
68
		protected void writeLineToResult() {
66
			if (match.getAccuracy() == SearchMatch.A_ACCURATE || showPotential) {
69
			if (match.getAccuracy() == SearchMatch.A_ACCURATE || showPotential) {
Lines 211-216 Link Here
211
						}
214
						}
212
					}
215
					}
213
				}
216
				}
217
				if (match instanceof MethodReferenceMatch) {
218
					MethodReferenceMatch methRef = (MethodReferenceMatch) match;
219
					if (methRef.isPolymorphic()) {
220
						if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
221
							if (this.showPolymorphic > 0) {
222
								line.append(" POLYMORPHIC");
223
							}
224
						} else {
225
							if (this.showPolymorphic <= 1) {
226
								line = null; // do not show potential polymorphic matches
227
							} else {
228
								line.append(" POLYMORPHIC");
229
							}
230
						}
231
					}
232
				}
214
			} catch (JavaModelException e) {
233
			} catch (JavaModelException e) {
215
				results.append("\n");
234
				results.append("\n");
216
				results.append(e.toString());
235
				results.append(e.toString());
(-)search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java (-4 / +18 lines)
Lines 54-71 Link Here
54
}
54
}
55
55
56
public int addMatch(ASTNode node, int matchLevel) {
56
public int addMatch(ASTNode node, int matchLevel) {
57
	switch (matchLevel & PatternLocator.NODE_SET_MASK) {
57
	int maskedLevel = matchLevel & PatternLocator.MATCH_LEVEL_MASK;
58
	switch (maskedLevel) {
58
		case PatternLocator.INACCURATE_MATCH:
59
		case PatternLocator.INACCURATE_MATCH:
59
			addTrustedMatch(node, POTENTIAL_MATCH);
60
			if (matchLevel != maskedLevel) {
61
				addTrustedMatch(node, new Integer(SearchMatch.A_INACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
62
			} else {
63
				addTrustedMatch(node, POTENTIAL_MATCH);
64
			}
60
			break;
65
			break;
61
		case PatternLocator.POSSIBLE_MATCH:
66
		case PatternLocator.POSSIBLE_MATCH:
62
			addPossibleMatch(node);
67
			addPossibleMatch(node);
63
			break;
68
			break;
64
		case PatternLocator.ERASURE_MATCH:
69
		case PatternLocator.ERASURE_MATCH:
65
			addTrustedMatch(node, ERASURE_MATCH);
70
			if (matchLevel != maskedLevel) {
71
				addTrustedMatch(node, new Integer(SearchPattern.R_ERASURE_MATCH+(matchLevel & PatternLocator.FLAVORS_MASK)));
72
			} else {
73
				addTrustedMatch(node, ERASURE_MATCH);
74
			}
66
			break;
75
			break;
67
		case PatternLocator.ACCURATE_MATCH:
76
		case PatternLocator.ACCURATE_MATCH:
68
			addTrustedMatch(node, EXACT_MATCH);
77
			if (matchLevel != maskedLevel) {
78
				addTrustedMatch(node, new Integer(SearchMatch.A_ACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
79
			} else {
80
				addTrustedMatch(node, EXACT_MATCH);
81
			}
82
			break;
69
	}
83
	}
70
	return matchLevel;
84
	return matchLevel;
71
}
85
}
(-)search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java (-6 / +19 lines)
Lines 1401-1407 Link Here
1401
	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
1401
	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
1402
	if (enclosingBinding != null)
1402
	if (enclosingBinding != null)
1403
		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
1403
		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
1404
	return new MethodReferenceMatch(enclosingElement, accuracy, offset, length, isConstructor, isSynthetic, insideDocComment, participant, resource);
1404
	boolean isPolymorphic = (accuracy & PatternLocator.POLYMORPHIC_FLAVOR) != 0;
1405
	return new MethodReferenceMatch(enclosingElement, accuracy, offset, length, isConstructor, isSynthetic, isPolymorphic, insideDocComment, participant, resource);
1405
}
1406
}
1406
1407
1407
public SearchMatch newPackageReferenceMatch(
1408
public SearchMatch newPackageReferenceMatch(
Lines 1641-1655 Link Here
1641
			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
1642
			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
1642
		System.out.print("\tRule: "); //$NON-NLS-1$
1643
		System.out.print("\tRule: "); //$NON-NLS-1$
1643
		if (match.isExact()) {
1644
		if (match.isExact()) {
1644
			System.out.println("EXACT"); //$NON-NLS-1$
1645
			System.out.print("EXACT"); //$NON-NLS-1$
1645
		} else if (match.isEquivalent()) {
1646
		} else if (match.isEquivalent()) {
1646
			System.out.println("EQUIVALENT"); //$NON-NLS-1$
1647
			System.out.print("EQUIVALENT"); //$NON-NLS-1$
1647
		} else if (match.isErasure()) {
1648
		} else if (match.isErasure()) {
1648
			System.out.println("ERASURE"); //$NON-NLS-1$
1649
			System.out.print("ERASURE"); //$NON-NLS-1$
1649
		} else {
1650
		} else {
1650
			System.out.println("INVALID RULE"); //$NON-NLS-1$
1651
			System.out.print("INVALID RULE"); //$NON-NLS-1$
1651
		}
1652
		}
1652
		System.out.println("\tRaw: "+match.isRaw()); //$NON-NLS-1$
1653
		if (match instanceof MethodReferenceMatch) {
1654
			MethodReferenceMatch methodReferenceMatch = (MethodReferenceMatch) match;
1655
			if (methodReferenceMatch.isPolymorphic()) {
1656
				System.out.print("+POLYMORPHIC"); //$NON-NLS-1$
1657
			}
1658
			if (methodReferenceMatch.isImplicit()) {
1659
				System.out.print("+IMPLICIT"); //$NON-NLS-1$
1660
			}
1661
			if (methodReferenceMatch.isSynthetic()) {
1662
				System.out.print("+SYNTHETIC"); //$NON-NLS-1$
1663
			}
1664
		}
1665
		System.out.println("\n\tRaw: "+match.isRaw()); //$NON-NLS-1$
1653
	}
1666
	}
1654
	this.requestor.acceptSearchMatch(match);
1667
	this.requestor.acceptSearchMatch(match);
1655
	if (BasicSearchEngine.VERBOSE)
1668
	if (BasicSearchEngine.VERBOSE)
(-)search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java (-14 / +21 lines)
Lines 41-53 Link Here
41
41
42
// Possible rule match flavors
42
// Possible rule match flavors
43
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866
43
// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866
44
protected static final int POSSIBLE_FULL_MATCH = POSSIBLE_MATCH | (SearchPattern.R_FULL_MATCH<<16);
44
protected static final int EXACT_FLAVOR = 0x0010;
45
protected static final int POSSIBLE_PREFIX_MATCH = POSSIBLE_MATCH | (SearchPattern.R_PREFIX_MATCH<<16);
45
protected static final int PREFIX_FLAVOR = 0x0020;
46
protected static final int POSSIBLE_PATTERN_MATCH = POSSIBLE_MATCH | (SearchPattern.R_PATTERN_MATCH<<16);
46
protected static final int PATTERN_FLAVOR = 0x0040;
47
protected static final int POSSIBLE_REGEXP_MATCH = POSSIBLE_MATCH | (SearchPattern.R_REGEXP_MATCH<<16);
47
protected static final int REGEXP_FLAVOR = 0x0080;
48
protected static final int POSSIBLE_CAMELCASE_MATCH = POSSIBLE_MATCH | (SearchPattern.R_CAMELCASE_MATCH<<16);
48
protected static final int CAMELCASE_FLAVOR = 0x0100;
49
protected static final int NODE_SET_MASK = 0xFF;
49
protected static final int POLYMORPHIC_FLAVOR = 0x0200;
50
protected static final int POSSIBLE_MATCH_MASK = ~NODE_SET_MASK;
50
protected static final int MATCH_LEVEL_MASK = 0x0F;
51
protected static final int FLAVORS_MASK = ~MATCH_LEVEL_MASK;
51
52
52
/* match container */
53
/* match container */
53
public static final int COMPILATION_UNIT_CONTAINER = 1;
54
public static final int COMPILATION_UNIT_CONTAINER = 1;
Lines 251-260 Link Here
251
 * @param name
252
 * @param name
252
 * @return Possible values are:
253
 * @return Possible values are:
253
 * <ul>
254
 * <ul>
254
 * 	<li>{@link #POSSIBLE_FULL_MATCH}: Given name is equals to pattern</li>
255
 * 	<li> {@link #ACCURATE_MATCH}</li>
255
 * 	<li>{@link #POSSIBLE_PREFIX_MATCH}: Given name prefix equals to pattern</li>
256
 * 	<li> {@link #IMPOSSIBLE_MATCH}</li>
256
 * 	<li>{@link #POSSIBLE_CAMELCASE_MATCH}: Given name matches pattern as Camel Case</li>
257
 * 	<li> {@link #POSSIBLE_MATCH} which may be flavored with following values:
257
 * 	<li>{@link #POSSIBLE_PATTERN_MATCH}: Given name matches pattern as Pattern (ie. using '*' and '?' characters)</li>
258
 * 		<ul>
259
 * 		<li>{@link #EXACT_FLAVOR}: Given name is equals to pattern</li>
260
 * 		<li>{@link #PREFIX_FLAVOR}: Given name prefix equals to pattern</li>
261
 * 		<li>{@link #CAMELCASE_FLAVOR}: Given name matches pattern as Camel Case</li>
262
 * 		<li>{@link #PATTERN_FLAVOR}: Given name matches pattern as Pattern (ie. using '*' and '?' characters)</li>
263
 * 		</ul>
264
 * 	</li>
258
 * </ul>
265
 * </ul>
259
 */
266
 */
260
protected int matchNameValue(char[] pattern, char[] name) {
267
protected int matchNameValue(char[] pattern, char[] name) {
Lines 272-291 Link Here
272
	boolean sameLength = pattern.length == name.length;
279
	boolean sameLength = pattern.length == name.length;
273
	boolean canBePrefix = name.length >= pattern.length;
280
	boolean canBePrefix = name.length >= pattern.length;
274
	if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) {
281
	if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) {
275
		return POSSIBLE_CAMELCASE_MATCH;
282
		return POSSIBLE_MATCH;
276
	}
283
	}
277
	switch (this.matchMode) {
284
	switch (this.matchMode) {
278
		case SearchPattern.R_EXACT_MATCH:
285
		case SearchPattern.R_EXACT_MATCH:
279
			if (!this.isCamelCase) {
286
			if (!this.isCamelCase) {
280
				if (sameLength && matchFirstChar && CharOperation.equals(pattern, name, this.isCaseSensitive)) {
287
				if (sameLength && matchFirstChar && CharOperation.equals(pattern, name, this.isCaseSensitive)) {
281
					return POSSIBLE_FULL_MATCH;
288
					return POSSIBLE_MATCH | EXACT_FLAVOR;
282
				}
289
				}
283
				break;
290
				break;
284
			}
291
			}
285
			// fall through next case to match as prefix if camel case failed
292
			// fall through next case to match as prefix if camel case failed
286
		case SearchPattern.R_PREFIX_MATCH:
293
		case SearchPattern.R_PREFIX_MATCH:
287
			if (canBePrefix && matchFirstChar && CharOperation.prefixEquals(pattern, name, this.isCaseSensitive)) {
294
			if (canBePrefix && matchFirstChar && CharOperation.prefixEquals(pattern, name, this.isCaseSensitive)) {
288
				return POSSIBLE_PREFIX_MATCH;
295
				return POSSIBLE_MATCH;
289
			}
296
			}
290
			break;
297
			break;
291
		case SearchPattern.R_PATTERN_MATCH:
298
		case SearchPattern.R_PATTERN_MATCH:
(-)search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java (-2 / +2 lines)
Lines 99-105 Link Here
99
	if (this.isCamelCase) {
99
	if (this.isCamelCase) {
100
		packageName = CharOperation.concatWith(tokens, '.');
100
		packageName = CharOperation.concatWith(tokens, '.');
101
		if (CharOperation.camelCaseMatch(this.pattern.pkgName, packageName)) {
101
		if (CharOperation.camelCaseMatch(this.pattern.pkgName, packageName)) {
102
			return POSSIBLE_CAMELCASE_MATCH;
102
			return POSSIBLE_MATCH;
103
		}
103
		}
104
	}
104
	}
105
	switch (this.matchMode) {
105
	switch (this.matchMode) {
Lines 107-113 Link Here
107
		case SearchPattern.R_PREFIX_MATCH:
107
		case SearchPattern.R_PREFIX_MATCH:
108
			if (packageName==null) packageName = CharOperation.concatWith(tokens, '.');
108
			if (packageName==null) packageName = CharOperation.concatWith(tokens, '.');
109
			if (CharOperation.prefixEquals(this.pattern.pkgName, packageName, this.isCaseSensitive)) {
109
			if (CharOperation.prefixEquals(this.pattern.pkgName, packageName, this.isCaseSensitive)) {
110
				return POSSIBLE_PREFIX_MATCH;
110
				return POSSIBLE_MATCH;
111
			}
111
			}
112
			break;
112
			break;
113
		case SearchPattern.R_PATTERN_MATCH:
113
		case SearchPattern.R_PATTERN_MATCH:
(-)search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java (-2 / +2 lines)
Lines 113-125 Link Here
113
		}
113
		}
114
		boolean matchFirstChar = !this.isCaseSensitive || (qualifiedPattern[0] == qualifiedTypeName[0]);
114
		boolean matchFirstChar = !this.isCaseSensitive || (qualifiedPattern[0] == qualifiedTypeName[0]);
115
		if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(qualifiedPattern, qualifiedTypeName)) {
115
		if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(qualifiedPattern, qualifiedTypeName)) {
116
			return POSSIBLE_CAMELCASE_MATCH;
116
			return POSSIBLE_MATCH;
117
		}
117
		}
118
		switch (this.matchMode) {
118
		switch (this.matchMode) {
119
			case SearchPattern.R_EXACT_MATCH:
119
			case SearchPattern.R_EXACT_MATCH:
120
			case SearchPattern.R_PREFIX_MATCH:
120
			case SearchPattern.R_PREFIX_MATCH:
121
				if (CharOperation.prefixEquals(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) {
121
				if (CharOperation.prefixEquals(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) {
122
					return POSSIBLE_PREFIX_MATCH;
122
					return POSSIBLE_MATCH;
123
				}
123
				}
124
				break;
124
				break;
125
125
(-)search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java (-8 / +29 lines)
Lines 22-27 Link Here
22
import org.eclipse.jdt.internal.compiler.lookup.*;
22
import org.eclipse.jdt.internal.compiler.lookup.*;
23
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
23
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
24
import org.eclipse.jdt.internal.core.JavaElement;
24
import org.eclipse.jdt.internal.core.JavaElement;
25
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
25
26
26
public class MethodLocator extends PatternLocator {
27
public class MethodLocator extends PatternLocator {
27
28
Lines 47-52 Link Here
47
	this.methodDeclarationsWithInvalidParam = new HashMap();
48
	this.methodDeclarationsWithInvalidParam = new HashMap();
48
}
49
}
49
public void initializePolymorphicSearch(MatchLocator locator) {
50
public void initializePolymorphicSearch(MatchLocator locator) {
51
	long start = 0;
52
	if (BasicSearchEngine.VERBOSE) {
53
		start = System.currentTimeMillis();
54
	}
50
	try {
55
	try {
51
		this.allSuperDeclaringTypeNames =
56
		this.allSuperDeclaringTypeNames =
52
			new SuperTypeNamesCollector(
57
			new SuperTypeNamesCollector(
Lines 59-64 Link Here
59
	} catch (JavaModelException e) {
64
	} catch (JavaModelException e) {
60
		// inaccurate matches will be found
65
		// inaccurate matches will be found
61
	}
66
	}
67
	if (BasicSearchEngine.VERBOSE) {
68
		System.out.println("Time to initialize polymorphic search: "+(System.currentTimeMillis()-start)); //$NON-NLS-1$
69
	}
62
}
70
}
63
/*
71
/*
64
 * Return whether a type name is in pattern all super declaring types names.
72
 * Return whether a type name is in pattern all super declaring types names.
Lines 621-638 Link Here
621
	if (qualifiedPattern == null) return methodLevel; // since any declaring class will do
629
	if (qualifiedPattern == null) return methodLevel; // since any declaring class will do
622
630
623
	int declaringLevel;
631
	int declaringLevel;
624
	if (isVirtualInvoke(method, messageSend) && !(messageSend.actualReceiverType instanceof ArrayBinding)) {
632
	if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) {
625
		declaringLevel = resolveLevelAsSubtype(qualifiedPattern, method.declaringClass);
633
		ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
634
		declaringLevel = resolveLevelAsSubtype(qualifiedPattern, methodReceiverType);
626
		if (declaringLevel == IMPOSSIBLE_MATCH) {
635
		if (declaringLevel == IMPOSSIBLE_MATCH) {
627
			if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) {
636
			if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) {
628
				declaringLevel = INACCURATE_MATCH;
637
				declaringLevel = INACCURATE_MATCH;
629
			} else {
638
			} else {
630
				char[][] compoundName = method.declaringClass.compoundName;
639
				char[][] compoundName = methodReceiverType.compoundName;
631
				for (int i = 0, max = this.allSuperDeclaringTypeNames.length; i < max; i++)
640
				for (int i = 0, max = this.allSuperDeclaringTypeNames.length; i < max; i++) {
632
					if (CharOperation.equals(this.allSuperDeclaringTypeNames[i], compoundName))
641
					if (CharOperation.equals(this.allSuperDeclaringTypeNames[i], compoundName)) {
633
						return methodLevel; // since this is an ACCURATE_MATCH so return the possibly weaker match
642
						return methodLevel // since this is an ACCURATE_MATCH so return the possibly weaker match
643
							| POLYMORPHIC_FLAVOR; // this is a polymorphic method => add flavor to returned level
644
					}
645
				}
646
				if (methodReceiverType.isInterface()) {
647
					// all methods interface with same name and parameters are potential matches
648
					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=156491
649
					return INACCURATE_MATCH | POLYMORPHIC_FLAVOR;
650
				}
634
			}
651
			}
635
		}
652
		}
653
		if ((declaringLevel & FLAVORS_MASK) != 0) {
654
			// level got some flavors => return it
655
			return declaringLevel;
656
		}
636
	} else {
657
	} else {
637
		declaringLevel = resolveLevelForType(qualifiedPattern, method.declaringClass);
658
		declaringLevel = resolveLevelForType(qualifiedPattern, method.declaringClass);
638
	}
659
	}
Lines 654-660 Link Here
654
	// matches superclass
675
	// matches superclass
655
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
676
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
656
		level = resolveLevelAsSubtype(qualifiedPattern, type.superclass());
677
		level = resolveLevelAsSubtype(qualifiedPattern, type.superclass());
657
		if (level != IMPOSSIBLE_MATCH) return level;
678
		if (level != IMPOSSIBLE_MATCH) return level | POLYMORPHIC_FLAVOR; // this is a polymorphic method => add flavor to returned level
658
	}
679
	}
659
680
660
	// matches interfaces
681
	// matches interfaces
Lines 662-668 Link Here
662
	if (interfaces == null) return INACCURATE_MATCH;
683
	if (interfaces == null) return INACCURATE_MATCH;
663
	for (int i = 0; i < interfaces.length; i++) {
684
	for (int i = 0; i < interfaces.length; i++) {
664
		level = resolveLevelAsSubtype(qualifiedPattern, interfaces[i]);
685
		level = resolveLevelAsSubtype(qualifiedPattern, interfaces[i]);
665
		if (level != IMPOSSIBLE_MATCH) return level;
686
		if (level != IMPOSSIBLE_MATCH) return level | POLYMORPHIC_FLAVOR; // this is a polymorphic method => add flavor to returned level
666
	}
687
	}
667
	return IMPOSSIBLE_MATCH;
688
	return IMPOSSIBLE_MATCH;
668
}
689
}
(-)search/org/eclipse/jdt/core/search/MethodReferenceMatch.java (+37 lines)
Lines 25-30 Link Here
25
public class MethodReferenceMatch extends SearchMatch {
25
public class MethodReferenceMatch extends SearchMatch {
26
	private boolean constructor;
26
	private boolean constructor;
27
	private boolean synthetic;
27
	private boolean synthetic;
28
	private boolean polymorphic;
28
29
29
	/**
30
	/**
30
	 * Creates a new method reference match.
31
	 * Creates a new method reference match.
Lines 67-72 Link Here
67
	}
68
	}
68
69
69
	/**
70
	/**
71
	 * Creates a new method reference match.
72
	 * 
73
	 * @param enclosingElement the inner-most enclosing member that references this method
74
	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
75
	 * @param offset the offset the match starts at, or -1 if unknown
76
	 * @param length the length of the match, or -1 if unknown
77
	 * @param constructor <code>true</code> if this search matches a constructor
78
	 * <code>false</code> otherwise
79
	 * @param synthetic <code>true</code> if this search matches a synthetic element
80
	 * <code>false</code> otherwise
81
	 * @param polymorphic <code>true</code> if this search matches a polymorphic element
82
	 * <code>false</code> otherwise
83
	 * @param insideDocComment <code>true</code> if this search match is inside a doc
84
	 * comment, and <code>false</code> otherwise
85
	 * @param participant the search participant that created the match
86
	 * @param resource the resource of the element
87
	 * @since 3.3
88
	 */
89
	public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean polymorphic, boolean insideDocComment, SearchParticipant participant, IResource resource) {
90
		this(enclosingElement, accuracy, offset, length, constructor, synthetic, insideDocComment, participant, resource);
91
		this.polymorphic = polymorphic;
92
	}
93
94
	/**
70
	 * Returns whether the reference is on a constructor.
95
	 * Returns whether the reference is on a constructor.
71
	 *
96
	 *
72
	 * @return Returns whether the reference is on a constructor or not.
97
	 * @return Returns whether the reference is on a constructor or not.
Lines 87-90 Link Here
87
	public final boolean isSynthetic() {
112
	public final boolean isSynthetic() {
88
		return this.synthetic;
113
		return this.synthetic;
89
	}
114
	}
115
116
	/**
117
	 * Returns whether the reference is on a polymorphic method or not.
118
	 * Note that this field is only used for method reference. This happens when the reference
119
	 * is not implemented on the declaring class pattern but only on one of its superclass or subclass.
120
	 * 
121
	 * @return <code>true</code> if the reference is a polymorphic method or not,
122
	 * <code>false </code> otherwise
123
	 */
124
	public boolean isPolymorphic() {
125
		return this.polymorphic;
126
	}
90
}
127
}
(-)search/org/eclipse/jdt/core/search/SearchMatch.java (-2 / +7 lines)
Lines 57-65 Link Here
57
	private boolean insideDocComment = false;
57
	private boolean insideDocComment = false;
58
	
58
	
59
	// store the rule used while reporting the match
59
	// store the rule used while reporting the match
60
	private int rule = SearchPattern.R_FULL_MATCH |
60
	private final static int ALL_GENERIC_FLAVORS = SearchPattern.R_FULL_MATCH |
61
								SearchPattern.R_EQUIVALENT_MATCH |
61
								SearchPattern.R_EQUIVALENT_MATCH |
62
								SearchPattern.R_ERASURE_MATCH;
62
								SearchPattern.R_ERASURE_MATCH;
63
	private int rule = ALL_GENERIC_FLAVORS;
63
	
64
	
64
	// store other necessary information
65
	// store other necessary information
65
	private boolean raw = false;
66
	private boolean raw = false;
Lines 91-97 Link Here
91
		this.length = length;
92
		this.length = length;
92
		this.accuracy = accuracy & A_INACCURATE;
93
		this.accuracy = accuracy & A_INACCURATE;
93
		if (accuracy > A_INACCURATE) {
94
		if (accuracy > A_INACCURATE) {
94
			this.rule = accuracy & ~A_INACCURATE; // accuracy may have also some rule information
95
			int genericFlavors = accuracy & ALL_GENERIC_FLAVORS;
96
			if (genericFlavors > 0) {
97
				this.rule &= ~ALL_GENERIC_FLAVORS; // reset generic flavors
98
			}
99
			this.rule |= accuracy & ~A_INACCURATE; // accuracy may have also some rule information
95
		}
100
		}
96
		this.participant = participant;
101
		this.participant = participant;
97
		this.resource = resource;
102
		this.resource = resource;
(-)buildnotes_jdt-core.html (-1 / +24 lines)
Lines 52-61 Link Here
52
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_713">cvs</a>).
52
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_713">cvs</a>).
53
<h2>What's new in this drop</h2>
53
<h2>What's new in this drop</h2>
54
<ul>
54
<ul>
55
<li>Added <code>isPolymorphic()</code> getters to MethodReferenceMatch.
56
<br>
57
When a search requestor (<code>SearchRequestor</code>) accepts this kind of match,
58
it knows if a method reference match is a polymorphic method (ie. implemented in a superclass or a subclass) or not.
59
<br>
60
In example below:
61
<pre>
62
public class X {
63
	public String toString() {}
64
}
65
public class Test {
66
	void foo(Object o) {
67
		o.toString();
68
	}
69
}
70
</pre>
71
Searching for reference to <code>X.toString()</code> method will get a polymorphic MethodReferenceMatch 
72
as the reference is the Object.toString() method (found in a superclass of X)...
73
</li>
55
</ul>
74
</ul>
56
75
57
<h3>Problem Reports Fixed</h3>
76
<h3>Problem Reports Fixed</h3>
58
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157247">157247</a>
77
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156491">156491</a>
78
[search] Reference search unusable in some situations
79
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73401">73401</a>
80
[search] Unable to search just for references to overridden method
81
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157247">157247</a>
59
[1.6] [compiler] VerifyError with StackMap frames when no local variable attributes are generated
82
[1.6] [compiler] VerifyError with StackMap frames when no local variable attributes are generated
60
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157086">157086</a>
83
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157086">157086</a>
61
should adopt ICU Collator and use new APIs on StructuredViewer
84
should adopt ICU Collator and use new APIs on StructuredViewer

Return to bug 73401