Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 357547 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java (+291 lines)
Lines 604-607 Link Here
604
		deleteProject("P");
604
		deleteProject("P");
605
	}
605
	}
606
	}
606
	}
607
	/**
608
	 * @bug 357547: [search] Search for method references is returning methods as overriden even if the superclass's method is only package-visible
609
	 * @test Search for a non-overriden method because of package visibility should not be found
610
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=357547"
611
	 */
612
	public void testBug357547a() throws CoreException {
613
		IJavaProject project = null;
614
		try
615
		{
616
			project = createJavaProject("P");
617
			createFolder("/P/p1");
618
			createFile("/P/p1/B.java",
619
					"package p1;\n" +
620
					"import p2.*;\n" +
621
					"public class B extends A {\n" +
622
					"long k(){\n" +
623
					"return 0;\n" +
624
			  		"}\n" +
625
					"}\n");
626
			createFolder("/P/p2");
627
			createFile("/P/p2/A.java",
628
					"package p2;\n" +
629
					"public class A {\n" +
630
					"long k(){\n" +
631
					"return 0;\n" +
632
			  		"}\n" +
633
			  		"public long m(){\n"+
634
			  		"return new A().k();\n" +
635
			  		"}\n"+
636
					"}\n");
637
			IType type = getCompilationUnit("/P/p1/B.java").getType("B");
638
			IMethod method = type.getMethod("k", new String[]{});
639
			search(method, REFERENCES, EXACT_RULE, SearchEngine.createWorkspaceScope(), this.resultCollector);
640
			assertSearchResults("Should not get any results", "", this.resultCollector);
641
		} finally {
642
			deleteProject(project);
643
		}
644
	}
645
	
646
	// search for the method name should also not return matches if not-overriden because of package-visible
647
	public void testBug357547b() throws CoreException {
648
		IJavaProject project = null;
649
		try
650
		{
651
			project = createJavaProject("P");
652
			createFolder("/P/p1");
653
			createFile("/P/p1/B.java",
654
					"package p1;\n" +
655
					"import p2.*;\n" +
656
					"public class B extends A {\n" +
657
					"long k(){\n" +
658
					"return 0;\n" +
659
			  		"}\n" +
660
					"}\n");
661
			createFolder("/P/p2");
662
			createFile("/P/p2/A.java",
663
					"package p2;\n" +
664
					"public class A {\n" +
665
					"long k(){\n" +
666
					"return 0;\n" +
667
			  		"}\n" +
668
			  		"public long m(){\n"+
669
			  		"return new A().k();\n" +
670
			  		"}\n"+
671
					"}\n");
672
			waitUntilIndexesReady();
673
			// search
674
			SearchPattern pattern = SearchPattern.createPattern("p*.B.k()", METHOD, REFERENCES , 0 );
675
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }), this.resultCollector);
676
			assertSearchResults("Should not get any results", "", this.resultCollector);
677
		} finally {
678
			deleteProject(project);
679
		}
680
	}
681
	
682
	// search for the method name should return the match if same package 
683
	public void testBug357547c() throws CoreException {
684
		IJavaProject project = null;
685
		try
686
		{
687
			project = createJavaProject("P");
688
			createFolder("/P/p2");
689
			createFile("/P/p2/B.java",
690
					"package p2;\n" +
691
					"public class B extends A {\n" +
692
					"long k(){\n" +
693
					"return 0;\n" +
694
			  		"}\n" +
695
					"}\n");
696
			createFile("/P/p2/A.java",
697
					"package p2;\n" +
698
					"public class A {\n" +
699
					"long k(){\n" +
700
					"return 0;\n" +
701
			  		"}\n" +
702
			  		"public long m(){\n"+
703
			  		"return new A().k();\n" +
704
			  		"}\n"+
705
					"}\n");
706
			waitUntilIndexesReady();
707
			// search
708
			SearchPattern pattern = SearchPattern.createPattern("B.k()", METHOD, REFERENCES, EXACT_RULE);
709
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }), this.resultCollector);
710
			assertSearchResults("Wrong results", "p2/A.java long p2.A.m() [k()] EXACT_MATCH", this.resultCollector);
711
		} finally {
712
			deleteProject(project);
713
		}
714
	}
715
	
716
	
717
	public void testBug357547d() throws CoreException {
718
		IJavaProject project = null;
719
		try
720
		{
721
			project = createJavaProject("P");
722
			createFolder("/P/p1");
723
			createFile("/P/p1/B.java",
724
					"package p1;\n" +
725
					"import p2.*;\n" +
726
					"public class B extends A {\n" +
727
					"long k(){\n" +
728
					"return 0;\n" +
729
			  		"}\n" +
730
					"}\n");
731
			createFolder("/P/p2");
732
			createFile("/P/p2/A.java",
733
					"package p2;\n" +
734
					"public class A{ \n" +
735
					"long k(){\n" +
736
					"return 0;\n" +
737
			  		"}\n" +
738
			  		"public long m(){\n"+
739
			  		"return new A().k();\n" +
740
			  		"}\n"+
741
					"}\n");
742
			createFile("/P/p2/B.java",
743
					"package p2;\n" +
744
					"public class B {\n" +
745
					"}\n");
746
			waitUntilIndexesReady();
747
			// search
748
			SearchPattern pattern = SearchPattern.createPattern("B.k()", METHOD, REFERENCES, EXACT_RULE);
749
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }), this.resultCollector);
750
			assertSearchResults("Should not get any results", "", this.resultCollector);
751
		} finally {
752
			deleteProject(project);
753
		}
754
	}
755
	// search for the method name should also not return matches if not-overriden because of package-visible
756
	// even if they are in jars
757
	public void testBug357547e() throws CoreException, IOException {
758
		IJavaProject project = null;
759
		try
760
		{
761
			project = createJavaProject("P", new String[] {""}, new String[] { "/P/lib357547.jar", "JCL15_LIB" }, "", "1.5");
762
			org.eclipse.jdt.core.tests.util.Util.createJar(new String[] {
763
					"p2/A.java",
764
					"package p2;\n" + 
765
					"public class A{}\n" }, 
766
					project.getProject().getLocation().append("libStuff.jar").toOSString(), "1.5");
767
			
768
			org.eclipse.jdt.core.tests.util.Util.createJar(
769
					new String[] {
770
						"p1/B.java",
771
						"package p1;\n"+
772
						"import p2.*;\n"+
773
						"public class B extends A {\n" +
774
						"long k(){\n" +
775
						"return 0;\n" +
776
						"}\n" + 
777
						"}\n"},
778
					null,
779
					project.getProject().getLocation().append("lib357547.jar").toOSString(),
780
					new String[] { project.getProject().getLocation().append("libStuff.jar").toOSString() },
781
					"1.5");
782
			refresh(project);
783
			createFolder("/P/p2");
784
			createFile("/P/p2/A.java",
785
					"package p2;\n" +
786
					"public class A {\n" +
787
					"long k(){\n" +
788
					"return 0;\n" +
789
			  		"}\n" +
790
			  		"public long m(){\n"+
791
			  		"return new A().k();\n" +
792
			  		"}\n"+
793
					"}\n");
794
			waitUntilIndexesReady();
795
			// search
796
			SearchPattern pattern = SearchPattern.createPattern("B.k()", METHOD, REFERENCES, EXACT_RULE);
797
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }, IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES), this.resultCollector);
798
			assertSearchResults("Wrong results", "", this.resultCollector);
799
		} finally {
800
			deleteProject(project);
801
		}
802
	}
803
	// search for the method name should also not return matches if not-overriden because of package-visible
804
	// even if they are in jars
805
	public void testBug357547f() throws CoreException, IOException {
806
		IJavaProject project = null;
807
		try
808
		{
809
			project = createJavaProject("P", new String[] {""}, new String[] { "/P/lib357547.jar", "JCL15_LIB" }, "", "1.5");
810
			org.eclipse.jdt.core.tests.util.Util.createJar(new String[] {
811
					"p2/A.java",
812
					"package p2;\n" + 
813
					"public class A{}\n" }, 
814
					project.getProject().getLocation().append("libStuff.jar").toOSString(), "1.5");
815
			
816
			org.eclipse.jdt.core.tests.util.Util.createJar(
817
					new String[] {
818
						"p2/B.java",
819
						"package p2;\n" +
820
						"import p2.*;\n" +
821
						"public class B extends A {\n" +
822
						"long k(){\n" +
823
						"return 0;\n" +
824
						"}\n" + 
825
						"}\n"},
826
					null,
827
					project.getProject().getLocation().append("lib357547.jar").toOSString(),
828
					new String[] { project.getProject().getLocation().append("libStuff.jar").toOSString() },
829
					"1.5");
830
			refresh(project);
831
			createFolder("/P/p2");
832
			createFile("/P/p2/A.java",
833
					"package p2;\n" +
834
					"public class A {\n" +
835
					"long k(){\n" +
836
					"return 0;\n" +
837
			  		"}\n" +
838
			  		"public long m(){\n"+
839
			  		"return new A().k();\n" +
840
			  		"}\n"+
841
					"}\n");
842
			waitUntilIndexesReady();
843
			// search
844
			SearchPattern pattern = SearchPattern.createPattern("B.k()", METHOD, REFERENCES, EXACT_RULE);
845
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }, IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SOURCES), this.resultCollector);
846
			assertSearchResults("Wrong results", "p2/A.java long p2.A.m() [k()] EXACT_MATCH", this.resultCollector);
847
		} finally {
848
			deleteProject(project);
849
		}
850
	}
851
	
852
	// search for declarations also should take care of default
853
	public void testBug357547g() throws CoreException {
854
		IJavaProject project = null;
855
		try
856
		{
857
			project = createJavaProject("P");
858
			createFolder("/P/p1");
859
			createFile("/P/p1/B.java",
860
					"package p1;\n" +
861
					"import p2.*;\n" +
862
					"public class B extends A {\n" +
863
					"long k(int a){\n" +
864
					"return 0;\n" +
865
			  		"}\n" +
866
					"}\n");
867
			createFile("/P/p1/C.java",
868
					"package p1;\n" +
869
					"public class C extends B {\n" +
870
					"long k(int a){\n" +
871
					"return 0;\n" +
872
			  		"}\n" +
873
					"}\n");
874
			createFolder("/P/p2");
875
			createFile("/P/p2/A.java",
876
					"package p2;\n" +
877
					"public class A{ \n" +
878
					"long k(int a){\n" +
879
					"return 0;\n" +
880
			  		"}\n" +
881
			  		"public long m(){\n"+
882
			  		"return new A().k(0);\n" +
883
			  		"}\n"+
884
					"}\n");
885
			createFile("/P/p2/B.java",
886
					"package p2;\n" +
887
					"public class B {\n" +
888
					"}\n");
889
			waitUntilIndexesReady();
890
			// search
891
			SearchPattern pattern = SearchPattern.createPattern("A.k(int)", METHOD, DECLARATIONS, EXACT_RULE);
892
			search(pattern, SearchEngine.createJavaSearchScope(new IJavaElement[] { project }), this.resultCollector);
893
			assertSearchResults("Wrong results", "p2/A.java long p2.A.k(int) [k] EXACT_MATCH", this.resultCollector);
894
		} finally {
895
			deleteProject(project);
896
		}
897
	}
607
}
898
}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java (-15 / +31 lines)
Lines 31-39 Link Here
31
//extra reference info
31
//extra reference info
32
public char[][][] allSuperDeclaringTypeNames;
32
public char[][][] allSuperDeclaringTypeNames;
33
33
34
// This is set only if focus is null. In these cases
35
// it will be hard to determine if the super class is of the same package
36
// at a latter point. Hence, this array is created with all the super class 
37
// names of the same package name as of the matching class name.
38
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=357547
39
private char[][][] samePkgSuperDeclaringTypeNames;
40
34
private MatchLocator matchLocator;
41
private MatchLocator matchLocator;
35
//method declarations which parameters verification fail
42
//method declarations which parameters verification fail
36
private HashMap methodDeclarationsWithInvalidParam = new HashMap();
43
private HashMap methodDeclarationsWithInvalidParam = new HashMap();
44
37
45
38
public MethodLocator(MethodPattern pattern) {
46
public MethodLocator(MethodPattern pattern) {
39
	super(pattern);
47
	super(pattern);
Lines 75-88 Link Here
75
		start = System.currentTimeMillis();
83
		start = System.currentTimeMillis();
76
	}
84
	}
77
	try {
85
	try {
78
		this.allSuperDeclaringTypeNames =
86
		SuperTypeNamesCollector namesCollector = 
79
			new SuperTypeNamesCollector(
87
			new SuperTypeNamesCollector(
80
				this.pattern,
88
				this.pattern,
81
				this.pattern.declaringSimpleName,
89
				this.pattern.declaringSimpleName,
82
				this.pattern.declaringQualification,
90
				this.pattern.declaringQualification,
83
				locator,
91
				locator,
84
				this.pattern.declaringType,
92
				this.pattern.declaringType,
85
				locator.progressMonitor).collect();
93
				locator.progressMonitor);
94
		this.allSuperDeclaringTypeNames = namesCollector.collect();
95
		this.samePkgSuperDeclaringTypeNames = namesCollector.getSamePackageSuperTypeNames();
86
		this.matchLocator = locator;	
96
		this.matchLocator = locator;	
87
	} catch (JavaModelException e) {
97
	} catch (JavaModelException e) {
88
		// inaccurate matches will be found
98
		// inaccurate matches will be found
Lines 109-115 Link Here
109
 * this message send or not.
119
 * this message send or not.
110
 */
120
 */
111
protected boolean isVirtualInvoke(MethodBinding method, MessageSend messageSend) {
121
protected boolean isVirtualInvoke(MethodBinding method, MessageSend messageSend) {
112
	return !method.isStatic() && !method.isPrivate() && !messageSend.isSuperAccess();
122
		return !method.isStatic() && !method.isPrivate() && !messageSend.isSuperAccess()
123
				&& !(method.isDefault() && this.pattern.focus != null && 
124
				!CharOperation.equals(this.pattern.declaringQualification, method.declaringClass.qualifiedPackageName()));
113
}
125
}
114
public int match(ASTNode node, MatchingNodeSet nodeSet) {
126
public int match(ASTNode node, MatchingNodeSet nodeSet) {
115
	int declarationsLevel = IMPOSSIBLE_MATCH;
127
	int declarationsLevel = IMPOSSIBLE_MATCH;
Lines 631-637 Link Here
631
		subType = CharOperation.compareWith(this.pattern.declaringQualification, method.declaringClass.fPackage.shortReadableName()) == 0;
643
		subType = CharOperation.compareWith(this.pattern.declaringQualification, method.declaringClass.fPackage.shortReadableName()) == 0;
632
	}
644
	}
633
	int declaringLevel = subType
645
	int declaringLevel = subType
634
		? resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass, method.selector, null)
646
		? resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass, method.selector, null, method.declaringClass.qualifiedPackageName(), method.isDefault())
635
		: resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass);
647
		: resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass);
636
	return (methodLevel & MATCH_LEVEL_MASK) > (declaringLevel & MATCH_LEVEL_MASK) ? declaringLevel : methodLevel; // return the weaker match
648
	return (methodLevel & MATCH_LEVEL_MASK) > (declaringLevel & MATCH_LEVEL_MASK) ? declaringLevel : methodLevel; // return the weaker match
637
}
649
}
Lines 664-677 Link Here
664
	int declaringLevel;
676
	int declaringLevel;
665
	if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) {
677
	if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) {
666
		ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
678
		ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
667
		declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.selector, method.parameters);
679
		declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.selector, method.parameters, methodReceiverType.qualifiedPackageName(), method.isDefault());
668
		if (declaringLevel == IMPOSSIBLE_MATCH) {
680
		if (declaringLevel == IMPOSSIBLE_MATCH) {
669
			if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) {
681
			if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) {
670
				declaringLevel = INACCURATE_MATCH;
682
				declaringLevel = INACCURATE_MATCH;
671
			} else {
683
			} else {
672
				if (resolveLevelAsSuperInvocation(methodReceiverType, method.parameters, true)) {
684
				char[][][] superTypeNames = (method.isDefault() && this.pattern.focus == null) ? this.samePkgSuperDeclaringTypeNames: this.allSuperDeclaringTypeNames;
673
					declaringLevel = methodLevel // since this is an ACCURATE_MATCH so return the possibly weaker match
685
				if (superTypeNames != null && resolveLevelAsSuperInvocation(methodReceiverType, method.parameters, superTypeNames, true)) {
674
						| SUPER_INVOCATION_FLAVOR; // this is an overridden method => add flavor to returned level
686
						declaringLevel = methodLevel // since this is an ACCURATE_MATCH so return the possibly weaker match
687
							| SUPER_INVOCATION_FLAVOR; // this is an overridden method => add flavor to returned level
675
				}
688
				}
676
			}
689
			}
677
		}
690
		}
Lines 692-702 Link Here
692
 * Returns INACCURATE_MATCH if resolve fails
705
 * Returns INACCURATE_MATCH if resolve fails
693
 * Returns IMPOSSIBLE_MATCH if it doesn't.
706
 * Returns IMPOSSIBLE_MATCH if it doesn't.
694
 */
707
 */
695
protected int resolveLevelAsSubtype(char[] simplePattern, char[] qualifiedPattern, ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes) {
708
protected int resolveLevelAsSubtype(char[] simplePattern, char[] qualifiedPattern, ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes, char[] packageName, boolean isDefault) {
696
	if (type == null) return INACCURATE_MATCH;
709
	if (type == null) return INACCURATE_MATCH;
697
710
698
	int level = resolveLevelForType(simplePattern, qualifiedPattern, type);
711
	int level = resolveLevelForType(simplePattern, qualifiedPattern, type);
699
	if (level != IMPOSSIBLE_MATCH) {
712
	if (level != IMPOSSIBLE_MATCH) {
713
		if (isDefault && !CharOperation.equals(packageName, type.qualifiedPackageName())) {
714
			return IMPOSSIBLE_MATCH;
715
		}
700
		MethodBinding method = argumentTypes == null ? null : getMethodBinding(type, methodName, argumentTypes);
716
		MethodBinding method = argumentTypes == null ? null : getMethodBinding(type, methodName, argumentTypes);
701
		if (((method != null && !method.isAbstract()) || !type.isAbstract()) && !type.isInterface()) { // if concrete, then method is overridden
717
		if (((method != null && !method.isAbstract()) || !type.isAbstract()) && !type.isInterface()) { // if concrete, then method is overridden
702
			level |= OVERRIDDEN_METHOD_FLAVOR;
718
			level |= OVERRIDDEN_METHOD_FLAVOR;
Lines 706-712 Link Here
706
722
707
	// matches superclass
723
	// matches superclass
708
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
724
	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
709
		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, type.superclass(), methodName, argumentTypes);
725
		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, type.superclass(), methodName, argumentTypes, packageName, isDefault);
710
		if (level != IMPOSSIBLE_MATCH) {
726
		if (level != IMPOSSIBLE_MATCH) {
711
			if (argumentTypes != null) {
727
			if (argumentTypes != null) {
712
				// need to verify if method may be overridden
728
				// need to verify if method may be overridden
Lines 730-736 Link Here
730
	ReferenceBinding[] interfaces = type.superInterfaces();
746
	ReferenceBinding[] interfaces = type.superInterfaces();
731
	if (interfaces == null) return INACCURATE_MATCH;
747
	if (interfaces == null) return INACCURATE_MATCH;
732
	for (int i = 0; i < interfaces.length; i++) {
748
	for (int i = 0; i < interfaces.length; i++) {
733
		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, interfaces[i], methodName, null);
749
		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, interfaces[i], methodName, null, packageName, isDefault);
734
		if (level != IMPOSSIBLE_MATCH) {
750
		if (level != IMPOSSIBLE_MATCH) {
735
			if (!type.isAbstract() && !type.isInterface()) { // if concrete class, then method is overridden
751
			if (!type.isAbstract() && !type.isInterface()) { // if concrete class, then method is overridden
736
				level |= OVERRIDDEN_METHOD_FLAVOR;
752
				level |= OVERRIDDEN_METHOD_FLAVOR;
Lines 745-754 Link Here
745
 * Return whether the given type binding or one of its possible super interfaces
761
 * Return whether the given type binding or one of its possible super interfaces
746
 * matches a type in the declaring type names hierarchy.
762
 * matches a type in the declaring type names hierarchy.
747
 */
763
 */
748
private boolean resolveLevelAsSuperInvocation(ReferenceBinding type, TypeBinding[] argumentTypes, boolean methodAlreadyVerified) {
764
private boolean resolveLevelAsSuperInvocation(ReferenceBinding type, TypeBinding[] argumentTypes, char[][][] superTypeNames, boolean methodAlreadyVerified) {
749
	char[][] compoundName = type.compoundName;
765
	char[][] compoundName = type.compoundName;
750
	for (int i = 0, max = this.allSuperDeclaringTypeNames.length; i < max; i++) {
766
	for (int i = 0, max = superTypeNames.length; i < max; i++) {
751
		if (CharOperation.equals(this.allSuperDeclaringTypeNames[i], compoundName)) {
767
		if (CharOperation.equals(superTypeNames[i], compoundName)) {
752
			// need to verify if the type implements the pattern method
768
			// need to verify if the type implements the pattern method
753
			if (methodAlreadyVerified) return true; // already verified before enter into this method (see resolveLevel(MessageSend))
769
			if (methodAlreadyVerified) return true; // already verified before enter into this method (see resolveLevel(MessageSend))
754
			MethodBinding[] methods = type.getMethods(this.pattern.selector);
770
			MethodBinding[] methods = type.getMethods(this.pattern.selector);
Lines 780-786 Link Here
780
		ReferenceBinding[] interfaces = type.superInterfaces();
796
		ReferenceBinding[] interfaces = type.superInterfaces();
781
		if (interfaces == null) return false;
797
		if (interfaces == null) return false;
782
		for (int i = 0; i < interfaces.length; i++) {
798
		for (int i = 0; i < interfaces.length; i++) {
783
			if (resolveLevelAsSuperInvocation(interfaces[i], argumentTypes, false)) {
799
			if (resolveLevelAsSuperInvocation(interfaces[i], argumentTypes, superTypeNames, false)) {
784
				return true;
800
				return true;
785
			}
801
			}
786
		}
802
		}
(-)a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java (-11 / +37 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2012 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 13-19 Link Here
13
import org.eclipse.core.runtime.IProgressMonitor;
13
import org.eclipse.core.runtime.IProgressMonitor;
14
import org.eclipse.core.runtime.SubProgressMonitor;
14
import org.eclipse.core.runtime.SubProgressMonitor;
15
import org.eclipse.jdt.core.*;
15
import org.eclipse.jdt.core.*;
16
import org.eclipse.jdt.core.ICompilationUnit;
17
import org.eclipse.jdt.core.compiler.CharOperation;
16
import org.eclipse.jdt.core.compiler.CharOperation;
18
import org.eclipse.jdt.core.search.*;
17
import org.eclipse.jdt.core.search.*;
19
import org.eclipse.jdt.internal.compiler.ASTVisitor;
18
import org.eclipse.jdt.internal.compiler.ASTVisitor;
Lines 45-63 Link Here
45
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
44
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
46
			ReferenceBinding binding = typeDeclaration.binding;
45
			ReferenceBinding binding = typeDeclaration.binding;
47
			if (SuperTypeNamesCollector.this.matches(binding))
46
			if (SuperTypeNamesCollector.this.matches(binding))
48
				collectSuperTypeNames(binding);
47
				collectSuperTypeNames(binding, binding.compoundName);
49
			return true;
48
			return true;
50
		}
49
		}
51
		public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
50
		public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
52
			ReferenceBinding binding = typeDeclaration.binding;
51
			ReferenceBinding binding = typeDeclaration.binding;
53
			if (SuperTypeNamesCollector.this.matches(binding))
52
			if (SuperTypeNamesCollector.this.matches(binding))
54
				collectSuperTypeNames(binding);
53
				collectSuperTypeNames(binding, binding.compoundName);
55
			return true;
54
			return true;
56
		}
55
		}
57
		public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
56
		public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
58
			ReferenceBinding binding = memberTypeDeclaration.binding;
57
			ReferenceBinding binding = memberTypeDeclaration.binding;
59
			if (SuperTypeNamesCollector.this.matches(binding))
58
			if (SuperTypeNamesCollector.this.matches(binding))
60
				collectSuperTypeNames(binding);
59
				collectSuperTypeNames(binding, binding.compoundName);
61
			return true;
60
			return true;
62
		}
61
		}
63
		public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
62
		public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
Lines 82-87 Link Here
82
char[][][] result;
81
char[][][] result;
83
int resultIndex;
82
int resultIndex;
84
83
84
char[][][] samePackageSuperTypeName; // set only if focus is null
85
int samePackageIndex;
86
85
public SuperTypeNamesCollector(
87
public SuperTypeNamesCollector(
86
	SearchPattern pattern,
88
	SearchPattern pattern,
87
	char[] typeSimpleName,
89
	char[] typeSimpleName,
Lines 98-103 Link Here
98
	this.progressMonitor = progressMonitor;
100
	this.progressMonitor = progressMonitor;
99
}
101
}
100
102
103
private boolean addIfSamePackage(char[][] compoundName, char[][] path) {
104
	if (compoundName.length != path.length) return false;
105
	int resultLength = this.samePackageSuperTypeName.length;
106
	for (int i = 0; i < resultLength; i++)
107
		if (CharOperation.equals(this.samePackageSuperTypeName[i], compoundName)) return false; // already known
108
	
109
	for (int i = 0, length = compoundName.length - 1; i < length; i ++) {
110
		if (!CharOperation.equals(compoundName[i], path[i])) return false;
111
	}
112
	if (resultLength == this.samePackageIndex)
113
		System.arraycopy(this.samePackageSuperTypeName, 0, this.samePackageSuperTypeName = new char[resultLength*2][][], 0, resultLength);
114
	this.samePackageSuperTypeName[this.samePackageIndex++] = compoundName;
115
	return true;
116
}
117
101
protected void addToResult(char[][] compoundName) {
118
protected void addToResult(char[][] compoundName) {
102
	int resultLength = this.result.length;
119
	int resultLength = this.result.length;
103
	for (int i = 0; i < resultLength; i++)
120
	for (int i = 0; i < resultLength; i++)
Lines 107-112 Link Here
107
		System.arraycopy(this.result, 0, this.result = new char[resultLength*2][][], 0, resultLength);
124
		System.arraycopy(this.result, 0, this.result = new char[resultLength*2][][], 0, resultLength);
108
	this.result[this.resultIndex++] = compoundName;
125
	this.result[this.resultIndex++] = compoundName;
109
}
126
}
127
110
/*
128
/*
111
 * Parse the given compiation unit and build its type bindings.
129
 * Parse the given compiation unit and build its type bindings.
112
 */
130
 */
Lines 141-147 Link Here
141
			if (this.type.isBinary()) {
159
			if (this.type.isBinary()) {
142
				BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null);
160
				BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null);
143
				if (binding != null)
161
				if (binding != null)
144
					collectSuperTypeNames(binding);
162
					collectSuperTypeNames(binding, null);
145
			} else {
163
			} else {
146
				ICompilationUnit unit = this.type.getCompilationUnit();
164
				ICompilationUnit unit = this.type.getCompilationUnit();
147
				SourceType sourceType = (SourceType) this.type;
165
				SourceType sourceType = (SourceType) this.type;
Lines 150-156 Link Here
150
				if (parsedUnit != null) {
168
				if (parsedUnit != null) {
151
					TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type);
169
					TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type);
152
					if (typeDecl != null && typeDecl.binding != null)
170
					if (typeDecl != null && typeDecl.binding != null)
153
						collectSuperTypeNames(typeDecl.binding);
171
						collectSuperTypeNames(typeDecl.binding, null);
154
				}
172
				}
155
			}
173
			}
156
		} catch (AbortCompilation e) {
174
		} catch (AbortCompilation e) {
Lines 171-176 Link Here
171
	Util.sort(paths); // sort by projects
189
	Util.sort(paths); // sort by projects
172
	JavaProject previousProject = null;
190
	JavaProject previousProject = null;
173
	this.result = new char[1][][];
191
	this.result = new char[1][][];
192
	this.samePackageSuperTypeName = new char[1][][];
174
	this.resultIndex = 0;
193
	this.resultIndex = 0;
175
	for (int i = 0, length = paths.length; i < length; i++) {
194
	for (int i = 0, length = paths.length; i < length; i++) {
176
		try {
195
		try {
Lines 191-197 Link Here
191
				IClassFile classFile = (IClassFile) openable;
210
				IClassFile classFile = (IClassFile) openable;
192
				BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null);
211
				BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null);
193
				if (matches(binding))
212
				if (matches(binding))
194
					collectSuperTypeNames(binding);
213
					collectSuperTypeNames(binding, binding.compoundName);
195
			}
214
			}
196
		} catch (AbortCompilation e) {
215
		} catch (AbortCompilation e) {
197
			// ignore: continue with next element
216
			// ignore: continue with next element
Lines 206-216 Link Here
206
/**
225
/**
207
 * Collects the names of all the supertypes of the given type.
226
 * Collects the names of all the supertypes of the given type.
208
 */
227
 */
209
protected void collectSuperTypeNames(ReferenceBinding binding) {
228
protected void collectSuperTypeNames(ReferenceBinding binding, char[][] path) {
210
	ReferenceBinding superclass = binding.superclass();
229
	ReferenceBinding superclass = binding.superclass();
230
	if (path != null) {
231
		boolean samePackage = addIfSamePackage(superclass.compoundName, path);
232
		if (!samePackage) path = null;
233
	}
211
	if (superclass != null) {
234
	if (superclass != null) {
212
		addToResult(superclass.compoundName);
235
		addToResult(superclass.compoundName);
213
		collectSuperTypeNames(superclass);
236
		collectSuperTypeNames(superclass, null);
214
	}
237
	}
215
238
216
	ReferenceBinding[] interfaces = binding.superInterfaces();
239
	ReferenceBinding[] interfaces = binding.superInterfaces();
Lines 218-224 Link Here
218
		for (int i = 0; i < interfaces.length; i++) {
241
		for (int i = 0; i < interfaces.length; i++) {
219
			ReferenceBinding interfaceBinding = interfaces[i];
242
			ReferenceBinding interfaceBinding = interfaces[i];
220
			addToResult(interfaceBinding.compoundName);
243
			addToResult(interfaceBinding.compoundName);
221
			collectSuperTypeNames(interfaceBinding);
244
			collectSuperTypeNames(interfaceBinding, null);
222
		}
245
		}
223
	}
246
	}
224
}
247
}
Lines 254-259 Link Here
254
		this.progressMonitor == null ? null : new SubProgressMonitor(this.progressMonitor, 100));
277
		this.progressMonitor == null ? null : new SubProgressMonitor(this.progressMonitor, 100));
255
	return pathCollector.getPaths();
278
	return pathCollector.getPaths();
256
}
279
}
280
public char[][][] getSamePackageSuperTypeNames() {
281
	return this.samePackageSuperTypeName;
282
}
257
protected boolean matches(char[][] compoundName) {
283
protected boolean matches(char[][] compoundName) {
258
	int length = compoundName.length;
284
	int length = compoundName.length;
259
	if (length == 0) return false;
285
	if (length == 0) return false;

Return to bug 357547