View | Details | Raw Unified | Return to bug 100772 | Differences between
and this patch

Collapse All | Expand All

(-)search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java (-6 / +15 lines)
Lines 790-796 Link Here
790
				boolean found = false;
790
				boolean found = false;
791
				if (paramLength == paramTypeslength) {
791
				if (paramLength == paramTypeslength) {
792
					for (int p=0; p<paramLength; p++) {
792
					for (int p=0; p<paramLength; p++) {
793
						if (CharOperation.equals(methodParameters[p].erasure().shortReadableName(), parameterTypes[p])) {
793
						if (CharOperation.equals(methodParameters[p].sourceName(), parameterTypes[p])) {
794
							// param erasure match
794
							// param erasure match
795
							found = true;
795
							found = true;
796
						} else {
796
						} else {
Lines 1912-1924 Link Here
1912
 */
1912
 */
1913
protected void reportMatching(CompilationUnitDeclaration unit, boolean mustResolve) throws CoreException {
1913
protected void reportMatching(CompilationUnitDeclaration unit, boolean mustResolve) throws CoreException {
1914
	MatchingNodeSet nodeSet = this.currentPossibleMatch.nodeSet;
1914
	MatchingNodeSet nodeSet = this.currentPossibleMatch.nodeSet;
1915
	boolean locatorMustResolve = this.patternLocator.mustResolve;
1916
	if (nodeSet.mustResolve) this.patternLocator.mustResolve = true;
1915
	if (BasicSearchEngine.VERBOSE) {
1917
	if (BasicSearchEngine.VERBOSE) {
1916
		System.out.println("Report matching: "); //$NON-NLS-1$
1918
		System.out.println("Report matching: "); //$NON-NLS-1$
1917
		System.out.println("	- node set:\n"+nodeSet); //$NON-NLS-1$
1919
		int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
1918
		System.out.println("	- must resolve: "+mustResolve); //$NON-NLS-1$
1920
		System.out.print("	- node set: accurate="+ size); //$NON-NLS-1$
1921
		size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
1922
		System.out.println(", possible="+size); //$NON-NLS-1$
1923
		System.out.print("	- must resolve: "+mustResolve); //$NON-NLS-1$
1924
		System.out.print(" (locator: "+this.patternLocator.mustResolve); //$NON-NLS-1$
1925
		System.out.println(", nodeSet: "+nodeSet.mustResolve+')'); //$NON-NLS-1$
1919
	}
1926
	}
1920
	boolean locatorMustResolve = this.patternLocator.mustResolve;
1921
	if (nodeSet.mustResolve) this.patternLocator.mustResolve = true;
1922
	if (mustResolve) {
1927
	if (mustResolve) {
1923
		this.unitScope= unit.scope.compilationUnitScope();
1928
		this.unitScope= unit.scope.compilationUnitScope();
1924
		// move the possible matching nodes that exactly match the search pattern to the matching nodes set
1929
		// move the possible matching nodes that exactly match the search pattern to the matching nodes set
Lines 1941-1947 Link Here
1941
		}
1946
		}
1942
		nodeSet.possibleMatchingNodesSet = new SimpleSet(3);
1947
		nodeSet.possibleMatchingNodesSet = new SimpleSet(3);
1943
		if (BasicSearchEngine.VERBOSE) {
1948
		if (BasicSearchEngine.VERBOSE) {
1944
			System.out.println("	- resolved node set:\n"+nodeSet); //$NON-NLS-1$
1949
			int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
1950
			System.out.print("	- node set: accurate="+size); //$NON-NLS-1$
1951
			size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
1952
			System.out.println(", possible="+size); //$NON-NLS-1$
1945
		}
1953
		}
1946
	} else {
1954
	} else {
1947
		this.unitScope = null;
1955
		this.unitScope = null;
Lines 2006-2011 Link Here
2006
	this.methodHandles = null;
2014
	this.methodHandles = null;
2007
	this.bindings.removeKey(this.pattern);
2015
	this.bindings.removeKey(this.pattern);
2008
	this.patternLocator.mustResolve = locatorMustResolve;
2016
	this.patternLocator.mustResolve = locatorMustResolve;
2017
	this.patternLocator.clear();
2009
}
2018
}
2010
/**
2019
/**
2011
 * Visit the given field declaration and report the nodes that match exactly the
2020
 * Visit the given field declaration and report the nodes that match exactly the
(-)search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java (-60 / +94 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.core.search.matching;
11
package org.eclipse.jdt.internal.core.search.matching;
12
12
13
import java.util.HashMap;
14
13
import org.eclipse.core.resources.IResource;
15
import org.eclipse.core.resources.IResource;
14
import org.eclipse.core.runtime.*;
16
import org.eclipse.core.runtime.*;
15
import org.eclipse.jdt.core.*;
17
import org.eclipse.jdt.core.*;
Lines 29-40 Link Here
29
//extra reference info
31
//extra reference info
30
public char[][][] allSuperDeclaringTypeNames;
32
public char[][][] allSuperDeclaringTypeNames;
31
33
34
//method declarations which parameters verification fail
35
private HashMap methodDeclarationsWithInvalidParam = new HashMap();
36
32
public MethodLocator(MethodPattern pattern) {
37
public MethodLocator(MethodPattern pattern) {
33
	super(pattern);
38
	super(pattern);
34
39
35
	this.pattern = pattern;
40
	this.pattern = pattern;
36
	this.isDeclarationOfReferencedMethodsPattern = this.pattern instanceof DeclarationOfReferencedMethodsPattern;
41
	this.isDeclarationOfReferencedMethodsPattern = this.pattern instanceof DeclarationOfReferencedMethodsPattern;
37
}
42
}
43
/*
44
 * Clear caches
45
 */
46
protected void clear() {
47
	this.methodDeclarationsWithInvalidParam = new HashMap();
48
}
38
public void initializePolymorphicSearch(MatchLocator locator) {
49
public void initializePolymorphicSearch(MatchLocator locator) {
39
	try {
50
	try {
40
		this.allSuperDeclaringTypeNames =
51
		this.allSuperDeclaringTypeNames =
Lines 50-100 Link Here
50
	}
61
	}
51
}
62
}
52
/*
63
/*
53
 * Return whether a method may override a method in super classes erasures or not.
54
 */
55
private boolean isErasureMethodOverride(ReferenceBinding type, MethodBinding method) {
56
	if (type == null) return false;
57
58
	// matches superclass
59
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
60
		ReferenceBinding superClass = type.superclass();
61
		if (superClass.isParameterizedType()) {
62
			TypeBinding erasure = ((ParameterizedTypeBinding)superClass).erasure();
63
			if (erasure instanceof ReferenceBinding) {
64
				MethodBinding[] methods = superClass.getMethods(this.pattern.selector);
65
				int length = methods.length;
66
				for (int i = 0; i<length; i++) {
67
					if (methods[i].areParametersEqual(method)) return true;
68
				}
69
			}
70
		}
71
		if (isErasureMethodOverride(superClass, method)) {
72
			return true;
73
		}
74
	}
75
76
	// matches interfaces
77
	ReferenceBinding[] interfaces = type.superInterfaces();
78
	if (interfaces == null) return false;
79
	int iLength = interfaces.length;
80
	for (int i = 0; i<iLength; i++) {
81
		if (interfaces[i].isParameterizedType()) {
82
			TypeBinding erasure = ((ParameterizedTypeBinding)interfaces[i]).erasure();
83
			if (erasure instanceof ReferenceBinding) {
84
				MethodBinding[] methods = ((ReferenceBinding)erasure).getMethods(this.pattern.selector);
85
				int length = methods.length;
86
				for (int j = 0; j<length; j++) {
87
					if (methods[i].areParametersEqual(method)) return true;
88
				}
89
			}
90
		}
91
		if (isErasureMethodOverride(interfaces[i], method)) {
92
			return true;
93
		}
94
	}
95
	return false;
96
}
97
/*
98
 * Return whether a type name is in pattern all super declaring types names.
64
 * Return whether a type name is in pattern all super declaring types names.
99
 */
65
 */
100
private boolean isTypeInSuperDeclaringTypeNames(char[][] typeName) {
66
private boolean isTypeInSuperDeclaringTypeNames(char[][] typeName) {
Lines 159-164 Link Here
159
						nodeSet.mustResolve = true;
125
						nodeSet.mustResolve = true;
160
						resolve = true;
126
						resolve = true;
161
					}
127
					}
128
					this.methodDeclarationsWithInvalidParam.put(node, null);
162
				} else {
129
				} else {
163
					return IMPOSSIBLE_MATCH;
130
					return IMPOSSIBLE_MATCH;
164
				}
131
				}
Lines 287-292 Link Here
287
254
288
	return level;
255
	return level;
289
}
256
}
257
private boolean matchOverriddenMethod(ReferenceBinding type, MethodBinding method, MethodBinding matchMethod) {
258
	if (type == null) return false;
259
260
	// matches superclass
261
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
262
		ReferenceBinding superClass = type.superclass();
263
		if (superClass.isParameterizedType()) {
264
			MethodBinding[] methods = superClass.getMethods(this.pattern.selector);
265
			int length = methods.length;
266
			for (int i = 0; i<length; i++) {
267
				if (methods[i].areParametersEqual(method)) {
268
					if (matchMethod == null) {
269
						if (methodParametersEqualsPattern(methods[i].original())) return true;
270
					} else {
271
						if (methods[i].original().areParametersEqual(matchMethod)) return true;
272
					}
273
				}
274
			}
275
		}
276
		if (matchOverriddenMethod(superClass, method, matchMethod)) {
277
			return true;
278
		}
279
	}
280
281
	// matches interfaces
282
	ReferenceBinding[] interfaces = type.superInterfaces();
283
	if (interfaces == null) return false;
284
	int iLength = interfaces.length;
285
	for (int i = 0; i<iLength; i++) {
286
		if (interfaces[i].isParameterizedType()) {
287
			MethodBinding[] methods = interfaces[i].getMethods(this.pattern.selector);
288
			int length = methods.length;
289
			for (int j = 0; j<length; j++) {
290
				if (methods[i].areParametersEqual(method)) {
291
					if (matchMethod == null) {
292
						if (methodParametersEqualsPattern(methods[i].original())) return true;
293
					} else {
294
						if (methods[i].original().areParametersEqual(matchMethod)) return true;
295
					}
296
				}
297
			}
298
		}
299
		if (matchOverriddenMethod(interfaces[i], method, matchMethod)) {
300
			return true;
301
		}
302
	}
303
	return false;
304
}
290
/**
305
/**
291
 * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
306
 * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
292
 */
307
 */
Lines 406-446 Link Here
406
		locator.report(match);
421
		locator.report(match);
407
	}
422
	}
408
}
423
}
409
protected int referenceType() {
424
/*
410
	return IJavaElement.METHOD;
425
 * Return whether method parameters are equals to pattern ones.
426
 */
427
private boolean methodParametersEqualsPattern(MethodBinding method) {
428
	TypeBinding[] methodParameters = method.parameters;
429
430
	int length = methodParameters.length;
431
	if (length != this.pattern.parameterSimpleNames.length) return false;
432
433
	for (int i = 0; i < length; i++) {
434
		char[] paramQualifiedName = qualifiedPattern(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i]);
435
		if (!CharOperation.match(paramQualifiedName, methodParameters[i].readableName(), this.isCaseSensitive)) {
436
			return false;
437
		}
438
	}
439
	return true;
411
}
440
}
412
public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
441
public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
413
	if (elementBinding != null) {
442
	if (elementBinding != null) {
414
		MethodBinding methodBinding = (MethodBinding) elementBinding;
443
		MethodBinding methodBinding = (MethodBinding) elementBinding;
415
		// Redo arguments verif as in this case previous filter may accept different ones
444
		// If method parameters verification was not valid, then try to see if method arguments can match a method in hierarchy
416
		boolean equals = true;
445
		if (this.methodDeclarationsWithInvalidParam.containsKey(reference)) {
417
		if (this.pattern.parameterSimpleNames != null) {
446
			// First see if this reference has already been resolved => report match if validated
418
			int paramLength = this.pattern.parameterSimpleNames.length;
447
			Boolean report = (Boolean) this.methodDeclarationsWithInvalidParam.get(reference);
419
			for (int i=0; equals && i<paramLength; i++) {
448
			if (report != null) {
420
				int level = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], methodBinding.parameters[i]);
449
				if (report.booleanValue()) {
421
				if (level == IMPOSSIBLE_MATCH) equals = false;
450
					return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
451
				}
452
				return null;
422
			}
453
			}
423
		}
454
			if (matchOverriddenMethod(methodBinding.declaringClass, methodBinding, null)) {
424
		// If arguments are not equals then try to see if method arguments can match erasures in hierarchy
455
				this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
425
		if (!equals && this.pattern.findDeclarations && this.mayBeGeneric) {
426
			if (isErasureMethodOverride(methodBinding.declaringClass, methodBinding)) {
427
				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
456
				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
428
			}
457
			}
429
			if (isTypeInSuperDeclaringTypeNames(methodBinding.declaringClass.compoundName)) {
458
			if (isTypeInSuperDeclaringTypeNames(methodBinding.declaringClass.compoundName)) {
430
				MethodBinding patternBinding = locator.getMethodBinding(this.pattern);
459
				MethodBinding patternBinding = locator.getMethodBinding(this.pattern);
431
				if (patternBinding != null) {
460
				if (patternBinding != null) {
432
					patternBinding = patternBinding.original();
461
					if (!matchOverriddenMethod(patternBinding.declaringClass, patternBinding, methodBinding)) {
433
					if (!isErasureMethodOverride(patternBinding.declaringClass, patternBinding)) {
462
						this.methodDeclarationsWithInvalidParam.put(reference, Boolean.FALSE);
434
						return null;
463
						return null;
435
					}
464
					}
436
				}
465
				}
466
				this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
437
				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
467
				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
438
			}
468
			}
469
			this.methodDeclarationsWithInvalidParam.put(reference, Boolean.FALSE);
439
			return null;
470
			return null;
440
		}
471
		}
441
	}
472
	}
442
	return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
473
	return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
443
}
474
}
475
protected int referenceType() {
476
	return IJavaElement.METHOD;
477
}
444
protected void reportDeclaration(MethodBinding methodBinding, MatchLocator locator, SimpleSet knownMethods) throws CoreException {
478
protected void reportDeclaration(MethodBinding methodBinding, MatchLocator locator, SimpleSet knownMethods) throws CoreException {
445
	ReferenceBinding declaringClass = methodBinding.declaringClass;
479
	ReferenceBinding declaringClass = methodBinding.declaringClass;
446
	IType type = locator.lookupType(declaringClass);
480
	IType type = locator.lookupType(declaringClass);
(-)search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java (-29 / +26 lines)
Lines 107-112 Link Here
107
	this.matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
107
	this.matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
108
	this.mustResolve = ((InternalSearchPattern)pattern).mustResolve;
108
	this.mustResolve = ((InternalSearchPattern)pattern).mustResolve;
109
}
109
}
110
/*
111
 * Clear caches
112
 */
113
protected void clear() {
114
	// nothing to clear by default
115
}
110
/* (non-Javadoc)
116
/* (non-Javadoc)
111
 * Modify PatternLocator.qualifiedPattern behavior:
117
 * Modify PatternLocator.qualifiedPattern behavior:
112
 * do not add star before simple name pattern when qualification pattern is null.
118
 * do not add star before simple name pattern when qualification pattern is null.
Lines 651-657 Link Here
651
	int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;
657
	int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;
652
658
653
	// pattern has type parameter(s) or type argument(s)
659
	// pattern has type parameter(s) or type argument(s)
654
	boolean isRawType = type.isRawType();
655
	if (type.isGenericType()) {
660
	if (type.isGenericType()) {
656
		// Binding is generic, get its type variable(s)
661
		// Binding is generic, get its type variable(s)
657
		TypeVariableBinding[] typeVariables = null;
662
		TypeVariableBinding[] typeVariables = null;
Lines 669-682 Link Here
669
		}
674
		}
670
		// TODO (frederic) do we need to verify each parameter?
675
		// TODO (frederic) do we need to verify each parameter?
671
		return level; // we can't do better
676
		return level; // we can't do better
672
	} else if (isRawType) {
677
	} else if (type.isRawType()) {
673
		return level; // raw type always match
678
		return level; // raw type always match
674
	} else if (!type.isParameterizedType()) {
675
		// Standard types (ie. neither generic nor parameterized nor raw types)
676
		// cannot match pattern with type parameters or arguments
677
		return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
678
	} else {
679
	} else {
679
		ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) type;
680
		TypeBinding leafType = type.leafComponentType();
681
		if (!leafType.isParameterizedType()) {
682
			// Standard types (ie. neither generic nor parameterized nor raw types)
683
			// cannot match pattern with type parameters or arguments
684
			return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
685
		}
686
		ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType;
680
687
681
		// Compare arguments only if there ones on both sides
688
		// Compare arguments only if there ones on both sides
682
		if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
689
		if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
Lines 765-795 Link Here
765
				// If pattern is not exact then match fails
772
				// If pattern is not exact then match fails
766
				if (patternTypeArgHasAnyChars) return impossible;
773
				if (patternTypeArgHasAnyChars) return impossible;
767
774
768
				// Get reference binding
769
				ReferenceBinding refBinding = null;
770
				if (argTypeBinding.isArrayType()) {
771
					TypeBinding leafBinding = ((ArrayBinding) argTypeBinding).leafComponentType;
772
					if (!leafBinding.isBaseType()) {
773
						refBinding = (ReferenceBinding) leafBinding;
774
					}
775
				} else if (!argTypeBinding.isBaseType()) {
776
					refBinding = (ReferenceBinding) argTypeBinding;
777
				}
778
				// Scan hierarchy
775
				// Scan hierarchy
779
				if (refBinding != null) {
776
				TypeBinding leafTypeBinding = argTypeBinding.leafComponentType();
780
					refBinding = refBinding.superclass();
777
				if (leafTypeBinding.isBaseType()) return impossible;
781
					while (refBinding != null) {
778
				ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass();
782
						if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) ||
779
				while (refBinding != null) {
783
							CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) {
780
					if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) ||
784
							// found name in hierarchy => match
781
						CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) {
782
						// found name in hierarchy => match
783
						continue nextTypeArgument;
784
					} else if (refBinding.isLocalType() || refBinding.isMemberType()) {
785
						// for local or member type, verify also source name (bug 81084)
786
						if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
785
							continue nextTypeArgument;
787
							continue nextTypeArgument;
786
						} else if (refBinding.isLocalType() || refBinding.isMemberType()) {
787
							// for local or member type, verify also source name (bug 81084)
788
							if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
789
								continue nextTypeArgument;
790
						}
791
						refBinding = refBinding.superclass();
792
					}
788
					}
789
					refBinding = refBinding.superclass();
793
				}
790
				}
794
				return impossible;
791
				return impossible;
795
			}
792
			}

Return to bug 100772