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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java (-8 / +189 lines)
Lines 44-60 Link Here
44
static {
44
static {
45
//	org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
45
//	org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
46
//	org.eclipse.jdt.internal.codeassist.SelectionEngine.DEBUG = true;
46
//	org.eclipse.jdt.internal.codeassist.SelectionEngine.DEBUG = true;
47
//	TESTS_PREFIX =  "testBug110060";
47
//	TESTS_PREFIX =  "testBug110336";
48
//	TESTS_NAMES = new String[] { "testBug113671" };
48
//	TESTS_NAMES = new String[] { "testBug110336e" };
49
//	TESTS_NUMBERS = new int[] { 114539 };
49
//	TESTS_NUMBERS = new int[] { 79267 };
50
//	TESTS_RANGE = new int[] { 83304, -1 };
50
//	TESTS_RANGE = new int[] { 83304, -1 };
51
	}
51
	}
52
52
53
class TestCollector extends JavaSearchResultCollector {
53
class TestCollector extends JavaSearchResultCollector {
54
	public List matches = new ArrayList();
54
	public List matches = new ArrayList();
55
	public void acceptSearchMatch(SearchMatch match) throws CoreException {
55
	public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
56
		super.acceptSearchMatch(match);
56
		super.acceptSearchMatch(searchMatch);
57
		matches.add(match);
57
		matches.add(searchMatch);
58
	}
59
}
60
class TypeReferencesCollector extends JavaSearchResultCollector {
61
62
	protected IJavaElement getElement(SearchMatch searchMatch) {
63
		IJavaElement element = super.getElement(searchMatch);
64
		IJavaElement localElement = null;
65
		TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) match;
66
		localElement = typeRefMatch.getLocalElement();
67
		if (localElement != null) {
68
			return localElement;
69
		}
70
		return element;
71
	}
72
	protected void writeLine() throws CoreException {
73
		super.writeLine();
74
		TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) this.match;
75
		IJavaElement[] others = typeRefMatch.getOtherElements();
76
		int length = others==null ? 0 : others.length;
77
		if (length > 0) {
78
			line.append("+[");
79
			for (int i=0; i<length; i++) {
80
				IJavaElement other = others[i];
81
				if (i>0) line.append(',');
82
				line.append(other.getElementName());
83
			}
84
			line.append(']');
85
		}
58
	}
86
	}
59
}
87
}
60
88
Lines 5268-5274 Link Here
5268
 * @test Bug 114539: [search] Internal error when refactoring code with errors
5296
 * @test Bug 114539: [search] Internal error when refactoring code with errors
5269
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=114539"
5297
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=114539"
5270
 */
5298
 */
5271
// Types search
5272
public void testBug114539() throws CoreException {
5299
public void testBug114539() throws CoreException {
5273
	workingCopies = new ICompilationUnit[2];
5300
	workingCopies = new ICompilationUnit[2];
5274
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b114539/Foo.java",
5301
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b114539/Foo.java",
Lines 5285-5293 Link Here
5285
	);
5312
	);
5286
	IField field = this.workingCopies[1].getType("Bar").getField("FOO");
5313
	IField field = this.workingCopies[1].getType("Bar").getField("FOO");
5287
	search(field, REFERENCES);
5314
	search(field, REFERENCES);
5288
	this.discard = false;
5289
	assertSearchResults(
5315
	assertSearchResults(
5290
		"src/b114539/Foo.java b114539.Foo.bar [FOO] POTENTIAL_MATCH"
5316
		"src/b114539/Foo.java b114539.Foo.bar [FOO] POTENTIAL_MATCH"
5291
	);
5317
	);
5292
}
5318
}
5319
5320
/**
5321
 * @test Bug 110336: [plan][search] Should optionaly return the local variable for type reference
5322
 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=110336"
5323
 */
5324
public void testBug110336a() throws CoreException {
5325
	workingCopies = new ICompilationUnit[1];
5326
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5327
		"package b110336;\n" + 
5328
		"public class Test {\n" + 
5329
		"	<TP extends Test> void method(Class<Test> clazz) {\n" + 
5330
		"		Test localVar1 = new Test();\n" + 
5331
		"		Class<Test> localVar2 = new Class<Test>();\n" + 
5332
		"		localVar1.method(localVar2);\n" + 
5333
		"	}\n" + 
5334
		"}\n"
5335
	);
5336
	IType type = this.workingCopies[0].getType("Test");
5337
	TypeReferencesCollector collector = new TypeReferencesCollector();
5338
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5339
	assertSearchResults(
5340
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).TP [Test]\n" + 
5341
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).clazz [Test]\n" + 
5342
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).localVar1 [Test]\n" + 
5343
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).localVar1 [Test]\n" + 
5344
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).localVar2 [Test]\n" + 
5345
		"src/b110336/Test.java void b110336.Test.method(Class<Test>).localVar2 [Test]",
5346
		collector
5347
	);
5348
}
5349
public void testBug110336b() throws CoreException {
5350
	workingCopies = new ICompilationUnit[1];
5351
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5352
		"package b110336;\n" + 
5353
		"public class Test {\n" + 
5354
		"	void method1(Test methodParam) {\n" + 
5355
		"		Test localVar1 = new Test(){\n" + 
5356
		"			Class c = Test.class;\n" + 
5357
		"			<TP extends Test> void foo(){\n" + 
5358
		"				Test o = (Test) null;\n" + 
5359
		"			}\n" + 
5360
		"		};\n" + 
5361
		"	}	\n" + 
5362
		"}\n"
5363
	);
5364
	IType type = this.workingCopies[0].getType("Test");
5365
	TypeReferencesCollector collector = new TypeReferencesCollector();
5366
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5367
	assertSearchResults(
5368
		"src/b110336/Test.java void b110336.Test.method1(Test):<anonymous>#1 [Test]\n" + 
5369
		"src/b110336/Test.java void b110336.Test.method1(Test):<anonymous>#1.c [Test]\n" + 
5370
		"src/b110336/Test.java void void b110336.Test.method1(Test):<anonymous>#1.foo().TP [Test]\n" + 
5371
		"src/b110336/Test.java void void b110336.Test.method1(Test):<anonymous>#1.foo().o [Test]\n" + 
5372
		"src/b110336/Test.java void void b110336.Test.method1(Test):<anonymous>#1.foo().o [Test]\n" + 
5373
		"src/b110336/Test.java void b110336.Test.method1(Test).methodParam [Test]\n" + 
5374
		"src/b110336/Test.java void b110336.Test.method1(Test).localVar1 [Test]",
5375
		collector
5376
	);
5377
}
5378
public void testBug110336c() throws CoreException {
5379
	workingCopies = new ICompilationUnit[1];
5380
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5381
		"package b110336;\n" + 
5382
		"public class Test<TP extends X> {\n" + 
5383
		"	X x;\n" + 
5384
		"\n" + 
5385
		"}\n" + 
5386
		"class X {}\n"
5387
	);
5388
	IType type = this.workingCopies[0].getType("X");
5389
	TypeReferencesCollector collector = new TypeReferencesCollector();
5390
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5391
	assertSearchResults(
5392
		"src/b110336/Test.java b110336.Test.TP [X]\n" + 
5393
		"src/b110336/Test.java b110336.Test.x [X]",
5394
		collector
5395
	);
5396
}
5397
public void testBug110336d() throws CoreException {
5398
	workingCopies = new ICompilationUnit[1];
5399
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5400
		"package b110336;\n" + 
5401
		"public class Test {\n" + 
5402
		"	Test a1Test = null, b1Test = new Test(), c1Test;\n" + 
5403
		"	Test a2Test = new Test(), b2Test, c2Test = null;\n" + 
5404
		"	Test a3Test, b3Test = null, c3Test = new Test();\n" + 
5405
		"}\n"
5406
	);
5407
	IType type = this.workingCopies[0].getType("Test");
5408
	TypeReferencesCollector collector = new TypeReferencesCollector();
5409
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5410
	assertSearchResults(
5411
		"src/b110336/Test.java b110336.Test.a1Test [Test]+[b1Test,c1Test]\n" + 
5412
		"src/b110336/Test.java b110336.Test.b1Test [Test]\n" + 
5413
		"src/b110336/Test.java b110336.Test.a2Test [Test]+[b2Test,c2Test]\n" + 
5414
		"src/b110336/Test.java b110336.Test.a2Test [Test]\n" + 
5415
		"src/b110336/Test.java b110336.Test.a3Test [Test]+[b3Test,c3Test]\n" + 
5416
		"src/b110336/Test.java b110336.Test.c3Test [Test]",
5417
		collector
5418
	);
5419
}
5420
public void testBug110336e() throws CoreException {
5421
	workingCopies = new ICompilationUnit[1];
5422
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5423
		"package b110336;\n" + 
5424
		"public class Test {\n" + 
5425
		"	void foo() {\n" + 
5426
		"		Test lv1 = null, lv2 = new Test(), lv3;\n" + 
5427
		"		Test lv4 = new Test(), lv5, lv6 = null;\n" + 
5428
		"		Test lv7, lv8 = null, lv9 = new Test();\n" + 
5429
		"	}\n" + 
5430
		"}\n"
5431
	);
5432
	IType type = this.workingCopies[0].getType("Test");
5433
	TypeReferencesCollector collector = new TypeReferencesCollector();
5434
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5435
	assertSearchResults(
5436
		"src/b110336/Test.java void b110336.Test.foo().lv1 [Test]+[lv2,lv3]\n" + 
5437
		"src/b110336/Test.java void b110336.Test.foo().lv2 [Test]\n" + 
5438
		"src/b110336/Test.java void b110336.Test.foo().lv4 [Test]+[lv5,lv6]\n" + 
5439
		"src/b110336/Test.java void b110336.Test.foo().lv4 [Test]\n" + 
5440
		"src/b110336/Test.java void b110336.Test.foo().lv7 [Test]+[lv8,lv9]\n" + 
5441
		"src/b110336/Test.java void b110336.Test.foo().lv9 [Test]",
5442
		collector
5443
	);
5444
}
5445
public void testBug110336f() throws CoreException {
5446
	workingCopies = new ICompilationUnit[1];
5447
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5448
		"package b110336;\n" + 
5449
		"public class Test extends Exception {\n" + 
5450
		"        void foo(Test test1) { // <- no local element\n" + 
5451
		"                Test test2; // <- local element\n" + 
5452
		"                try {\n" + 
5453
		"                        throw new Test();\n" + 
5454
		"                }\n" + 
5455
		"                catch (Test test4) { // <- no local element\n" + 
5456
		"                }\n" + 
5457
		"                for(Test test3;;) {} // <- local element\n" + 
5458
		"        }\n" + 
5459
		"\n" + 
5460
		"}\n"
5461
	);
5462
	IType type = this.workingCopies[0].getType("Test");
5463
	TypeReferencesCollector collector = new TypeReferencesCollector();
5464
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5465
	assertSearchResults(
5466
		"src/b110336/Test.java void b110336.Test.foo(Test).test1 [Test]\n" + 
5467
		"src/b110336/Test.java void b110336.Test.foo(Test).test2 [Test]\n" + 
5468
		"src/b110336/Test.java void b110336.Test.foo(Test) [Test]\n" + 
5469
		"src/b110336/Test.java void b110336.Test.foo(Test).test4 [Test]\n" + 
5470
		"src/b110336/Test.java void b110336.Test.foo(Test).test3 [Test]",
5471
		collector
5472
	);
5473
}
5293
}
5474
}
(-)src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java (-1 / +1 lines)
Lines 40-46 Link Here
40
static {
40
static {
41
//	org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
41
//	org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
42
//	TESTS_PREFIX =  "testCamelCase";
42
//	TESTS_PREFIX =  "testCamelCase";
43
//	TESTS_NAMES = new String[] { "testMethodDeclaration11" };
43
	TESTS_NAMES = new String[] { "testTypeReference11" };
44
//	TESTS_NUMBERS = new int[] { 113671 };
44
//	TESTS_NUMBERS = new int[] { 113671 };
45
//	TESTS_RANGE = new int[] { 16, -1 };
45
//	TESTS_RANGE = new int[] { 16, -1 };
46
}
46
}
(-)src/org/eclipse/jdt/core/tests/model/AbstractJavaSearchTests.java (-7 / +36 lines)
Lines 45-50 Link Here
45
	 * Collects results as a string.
45
	 * Collects results as a string.
46
	 */
46
	 */
47
	public static class JavaSearchResultCollector extends SearchRequestor {
47
	public static class JavaSearchResultCollector extends SearchRequestor {
48
		protected SearchMatch match;
48
		public StringBuffer results = new StringBuffer(), line;
49
		public StringBuffer results = new StringBuffer(), line;
49
		public boolean showAccuracy;
50
		public boolean showAccuracy;
50
		public boolean showContext;
51
		public boolean showContext;
Lines 54-64 Link Here
54
		public boolean showProject;
55
		public boolean showProject;
55
		public boolean showSynthetic;
56
		public boolean showSynthetic;
56
		public int count = 0;
57
		public int count = 0;
57
		public void acceptSearchMatch(SearchMatch match) throws CoreException {
58
		public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
58
			count++;
59
			count++;
60
			this.match = searchMatch;
61
			writeLine();
62
			writeLineToResult();
63
		}
64
		protected void writeLineToResult() {
65
			if (match.getAccuracy() == SearchMatch.A_ACCURATE || showPotential) {
66
				if (results.length() > 0) results.append("\n");
67
				results.append(line);
68
			}
69
		}
70
		protected void writeLine() throws CoreException {
59
			try {
71
			try {
60
				IResource resource = match.getResource();
72
				IResource resource = match.getResource();
61
				IJavaElement element = (IJavaElement) match.getElement();
73
				IJavaElement element = getElement(match);
62
				line = new StringBuffer(getPathString(resource, element));
74
				line = new StringBuffer(getPathString(resource, element));
63
				if (this.showProject) {
75
				if (this.showProject) {
64
					IProject project = element.getJavaProject().getProject();
76
					IProject project = element.getJavaProject().getProject();
Lines 104-109 Link Here
104
					line.append(".");
116
					line.append(".");
105
					line.append(localVar.getElementName());
117
					line.append(localVar.getElementName());
106
					unit = (ICompilationUnit)localVar.getAncestor(IJavaElement.COMPILATION_UNIT);
118
					unit = (ICompilationUnit)localVar.getAncestor(IJavaElement.COMPILATION_UNIT);
119
				} else if (element instanceof ITypeParameter) {
120
					line.append(" ");
121
					ITypeParameter typeParam = (ITypeParameter)element;
122
					IJavaElement parent = typeParam.getParent();
123
					if (parent instanceof IType) {
124
						IType type = (IType)parent;
125
						append(type);
126
						unit = type.getCompilationUnit();
127
					} else if (parent instanceof IMethod) {
128
						IMethod method = (IMethod)parent;
129
						append(method);
130
						unit = method.getCompilationUnit();
131
					} else {
132
						line.append("<Unexpected kind of parent for type parameter>");
133
						unit = (ICompilationUnit)typeParam.getAncestor(IJavaElement.COMPILATION_UNIT);
134
					}
135
					line.append(".");
136
					line.append(typeParam.getElementName());
107
				} else if (element instanceof IImportDeclaration) {
137
				} else if (element instanceof IImportDeclaration) {
108
					IImportDeclaration importDeclaration = (IImportDeclaration)element;
138
					IImportDeclaration importDeclaration = (IImportDeclaration)element;
109
					unit = (ICompilationUnit)importDeclaration.getAncestor(IJavaElement.COMPILATION_UNIT);
139
					unit = (ICompilationUnit)importDeclaration.getAncestor(IJavaElement.COMPILATION_UNIT);
Lines 180-195 Link Here
180
						}
210
						}
181
					}
211
					}
182
				}
212
				}
183
				if (match.getAccuracy() == SearchMatch.A_ACCURATE || showPotential) {
184
					if (results.length() > 0) results.append("\n");
185
					results.append(line);
186
				}
187
			} catch (JavaModelException e) {
213
			} catch (JavaModelException e) {
188
				results.append("\n");
214
				results.append("\n");
189
				results.append(e.toString());
215
				results.append(e.toString());
190
			}
216
			}
191
		}
217
		}
192
		private void append(IField field) throws JavaModelException {
218
		protected void append(IField field) throws JavaModelException {
193
			append(field.getDeclaringType());
219
			append(field.getDeclaringType());
194
			line.append(".");
220
			line.append(".");
195
			line.append(field.getElementName());
221
			line.append(field.getElementName());
Lines 288-293 Link Here
288
				line.append(((SourceRefElement)type).occurrenceCount);
314
				line.append(((SourceRefElement)type).occurrenceCount);
289
			}
315
			}
290
		}
316
		}
317
		protected IJavaElement getElement(SearchMatch searchMatch) {
318
			return (IJavaElement) searchMatch.getElement();
319
		}
291
		protected String getPathString(IResource resource, IJavaElement element) {
320
		protected String getPathString(IResource resource, IJavaElement element) {
292
			String pathString;
321
			String pathString;
293
			if (resource != null) {
322
			if (resource != null) {
(-)search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java (-44 / +170 lines)
Lines 61-66 Link Here
61
import org.eclipse.jdt.internal.core.JavaElement;
61
import org.eclipse.jdt.internal.core.JavaElement;
62
import org.eclipse.jdt.internal.core.JavaModelManager;
62
import org.eclipse.jdt.internal.core.JavaModelManager;
63
import org.eclipse.jdt.internal.core.JavaProject;
63
import org.eclipse.jdt.internal.core.JavaProject;
64
import org.eclipse.jdt.internal.core.LocalVariable;
64
import org.eclipse.jdt.internal.core.NameLookup;
65
import org.eclipse.jdt.internal.core.NameLookup;
65
import org.eclipse.jdt.internal.core.Openable;
66
import org.eclipse.jdt.internal.core.Openable;
66
import org.eclipse.jdt.internal.core.PackageFragment;
67
import org.eclipse.jdt.internal.core.PackageFragment;
Lines 165-171 Link Here
165
	}
166
	}
166
}
167
}
167
168
168
169
public static class WorkingCopyDocument extends JavaSearchDocument {
169
public static class WorkingCopyDocument extends JavaSearchDocument {
170
	public org.eclipse.jdt.core.ICompilationUnit workingCopy;
170
	public org.eclipse.jdt.core.ICompilationUnit workingCopy;
171
	WorkingCopyDocument(org.eclipse.jdt.core.ICompilationUnit workingCopy, SearchParticipant participant) {
171
	WorkingCopyDocument(org.eclipse.jdt.core.ICompilationUnit workingCopy, SearchParticipant participant) {
Lines 562-567 Link Here
562
	}
562
	}
563
	return ((IType) parent).getInitializer(occurrenceCount);
563
	return ((IType) parent).getInitializer(occurrenceCount);
564
}
564
}
565
/**
566
 * Create an handle for a local variable declartion (may be a local variable or type parameter).
567
 */
568
protected IJavaElement createHandle(AbstractVariableDeclaration variableDeclaration, IJavaElement parent) {
569
	switch (variableDeclaration.getKind()) {
570
		case AbstractVariableDeclaration.LOCAL_VARIABLE:
571
			return new LocalVariable((JavaElement)parent,
572
				new String(variableDeclaration.name),
573
				variableDeclaration.declarationSourceStart,
574
				variableDeclaration.declarationSourceEnd,
575
				variableDeclaration.sourceStart,
576
				variableDeclaration.sourceEnd,
577
				new String(variableDeclaration.type.resolvedType.signature())
578
			);
579
		case AbstractVariableDeclaration.PARAMETER:
580
			return new LocalVariable((JavaElement)parent,
581
				new String(variableDeclaration.name),
582
				variableDeclaration.declarationSourceStart,
583
				variableDeclaration.declarationSourceEnd,
584
				variableDeclaration.sourceStart,
585
				variableDeclaration.sourceEnd,
586
				new String(variableDeclaration.type.resolvedType.signature())
587
			);
588
		case AbstractVariableDeclaration.TYPE_PARAMETER:
589
			return new org.eclipse.jdt.internal.core.TypeParameter((JavaElement)parent, new String(variableDeclaration.name));
590
	}
591
	return null;
592
}
565
/*
593
/*
566
 * Creates hierarchy resolver if needed. 
594
 * Creates hierarchy resolver if needed. 
567
 * Returns whether focus is visible.
595
 * Returns whether focus is visible.
Lines 1364-1370 Link Here
1364
	return new TypeParameterReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
1392
	return new TypeParameterReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
1365
}
1393
}
1366
1394
1367
public SearchMatch newTypeReferenceMatch(
1395
public TypeReferenceMatch newTypeReferenceMatch(
1368
		IJavaElement enclosingElement,
1396
		IJavaElement enclosingElement,
1369
		Binding enclosingBinding,
1397
		Binding enclosingBinding,
1370
		int accuracy,
1398
		int accuracy,
Lines 1379-1385 Link Here
1379
	return new TypeReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
1407
	return new TypeReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
1380
}
1408
}
1381
1409
1382
public SearchMatch newTypeReferenceMatch(
1410
public TypeReferenceMatch newTypeReferenceMatch(
1383
		IJavaElement enclosingElement,
1411
		IJavaElement enclosingElement,
1384
		Binding enclosingBinding,
1412
		Binding enclosingBinding,
1385
		int accuracy,
1413
		int accuracy,
Lines 1541-1546 Link Here
1541
		} catch (Exception e) {
1569
		} catch (Exception e) {
1542
			// it's just for debug purposes... ignore all exceptions in this area
1570
			// it's just for debug purposes... ignore all exceptions in this area
1543
		}
1571
		}
1572
		if (match instanceof TypeReferenceMatch) {
1573
			try {
1574
				TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) match;
1575
				JavaElement local = (JavaElement) typeRefMatch.getLocalElement();
1576
				if (local != null) {
1577
					System.out.println("\tLocal element: "+ local.toStringWithAncestors()); //$NON-NLS-1$
1578
				}
1579
				IJavaElement[] others = typeRefMatch.getOtherElements();
1580
				int length = others==null ? 0 : others.length;
1581
				if (length > 0) {
1582
					System.out.println("\tOther elements:"); //$NON-NLS-1$
1583
					for (int i=0; i<length; i++) {
1584
						JavaElement other = (JavaElement) others[i];
1585
						System.out.println("\t\t- "+ other.toStringWithAncestors()); //$NON-NLS-1$
1586
					}
1587
				}
1588
			} catch (Exception e) {
1589
				// it's just for debug purposes... ignore all exceptions in this area
1590
			}
1591
		}
1544
		System.out.println(match.getAccuracy() == SearchMatch.A_ACCURATE
1592
		System.out.println(match.getAccuracy() == SearchMatch.A_ACCURATE
1545
			? "\tAccuracy: EXACT_MATCH" //$NON-NLS-1$
1593
			? "\tAccuracy: EXACT_MATCH" //$NON-NLS-1$
1546
			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
1594
			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
Lines 1848-1853 Link Here
1848
		}
1896
		}
1849
	}
1897
	}
1850
1898
1899
	// report the type parameters
1900
	TypeParameter[] typeParameters = method.typeParameters();
1901
	if (typeParameters != null) {
1902
		if (enclosingElement == null) {
1903
			enclosingElement = createHandle(method, parent);
1904
		}
1905
		reportMatching(typeParameters, enclosingElement, parent, method.binding, nodeSet);
1906
	}
1907
1851
	// report annotations
1908
	// report annotations
1852
	if (method.annotations != null) {
1909
	if (method.annotations != null) {
1853
		if (enclosingElement == null) {
1910
		if (enclosingElement == null) {
Lines 1867-1873 Link Here
1867
					for (int i = 0, l = nodes.length; i < l; i++) {
1924
					for (int i = 0, l = nodes.length; i < l; i++) {
1868
						ASTNode node = nodes[i];
1925
						ASTNode node = nodes[i];
1869
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
1926
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
1870
						this.patternLocator.matchReportReference(node, enclosingElement, method.binding, level.intValue(), this);
1927
						this.patternLocator.matchReportReference(node, enclosingElement, method.binding, method.scope, level.intValue(), this);
1871
					}
1928
					}
1872
					return;
1929
					return;
1873
				}
1930
				}
Lines 2033-2039 Link Here
2033
 * Visit the given field declaration and report the nodes that match exactly the
2090
 * Visit the given field declaration and report the nodes that match exactly the
2034
 * search pattern (ie. the ones in the matching nodes set)
2091
 * search pattern (ie. the ones in the matching nodes set)
2035
 */
2092
 */
2036
protected void reportMatching(FieldDeclaration field, TypeDeclaration type, IJavaElement parent, int accuracy, boolean typeInHierarchy, MatchingNodeSet nodeSet) throws CoreException {
2093
protected void reportMatching(FieldDeclaration field, TypeDeclaration type, IJavaElement parent, IJavaElement[] otherElements, int accuracy, boolean typeInHierarchy, MatchingNodeSet nodeSet) throws CoreException {
2037
	IJavaElement enclosingElement = null;
2094
	IJavaElement enclosingElement = null;
2038
	if (accuracy > -1) {
2095
	if (accuracy > -1) {
2039
		enclosingElement = createHandle(field, type, parent);
2096
		enclosingElement = createHandle(field, type, parent);
Lines 2065-2081 Link Here
2065
	}
2122
	}
2066
2123
2067
	if (typeInHierarchy) {
2124
	if (typeInHierarchy) {
2068
		// limit scan to end part position for multiple fields declaration (see bug 73112)
2125
		// Look at field declaration
2069
		int end = field.endPart2Position==0 ? field.declarationSourceEnd : field.endPart2Position;
2126
		if (field.endPart1Position != 0) { // not an initializer
2070
		ASTNode[] nodes = nodeSet.matchingNodes(field.declarationSourceStart, end);
2127
			ASTNode[] nodes = nodeSet.matchingNodes(field.declarationSourceStart, field.endPart1Position);
2128
			if (nodes != null) {
2129
				if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) {
2130
					for (int i = 0, l = nodes.length; i < l; i++)
2131
						nodeSet.matchingNodes.removeKey(nodes[i]);
2132
				} else {
2133
					if (enclosingElement == null)
2134
						enclosingElement = createHandle(field, type, parent);
2135
					if (encloses(enclosingElement)) {
2136
						for (int i = 0, l = nodes.length; i < l; i++) {
2137
							ASTNode node = nodes[i];
2138
							Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
2139
							this.patternLocator.matchReportReference(node, enclosingElement, null, otherElements, field.binding, level.intValue(), this);
2140
						}
2141
					}
2142
				}
2143
			}
2144
		}
2145
2146
		// Look in initializers
2147
		int fieldEnd = field.endPart2Position == 0 ? field.declarationSourceEnd : field.endPart2Position;
2148
		ASTNode[] nodes = nodeSet.matchingNodes(field.sourceStart, fieldEnd);
2071
		if (nodes != null) {
2149
		if (nodes != null) {
2072
			if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) {
2150
			if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) {
2073
				for (int i = 0, l = nodes.length; i < l; i++)
2151
				for (int i = 0, l = nodes.length; i < l; i++)
2074
					nodeSet.matchingNodes.removeKey(nodes[i]);
2152
					nodeSet.matchingNodes.removeKey(nodes[i]);
2075
			} else {
2153
			} else {
2076
				if (enclosingElement == null)
2154
				if (enclosingElement == null) {
2077
					enclosingElement = createHandle(field, type, parent);
2155
					enclosingElement = createHandle(field, type, parent);
2078
				if (encloses(enclosingElement))
2156
				}
2157
				if (encloses(enclosingElement)) {
2079
					for (int i = 0, l = nodes.length; i < l; i++) {
2158
					for (int i = 0, l = nodes.length; i < l; i++) {
2080
						ASTNode node = nodes[i];
2159
						ASTNode node = nodes[i];
2081
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
2160
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
Lines 2088-2093 Link Here
2088
						}
2167
						}
2089
						this.patternLocator.matchReportReference(node, enclosingElement, field.binding, level.intValue(), this);
2168
						this.patternLocator.matchReportReference(node, enclosingElement, field.binding, level.intValue(), this);
2090
					}
2169
					}
2170
				}
2091
			}
2171
			}
2092
		}
2172
		}
2093
	}
2173
	}
Lines 2121-2156 Link Here
2121
	}
2201
	}
2122
2202
2123
	boolean matchedClassContainer = (this.matchContainer & PatternLocator.CLASS_CONTAINER) != 0;
2203
	boolean matchedClassContainer = (this.matchContainer & PatternLocator.CLASS_CONTAINER) != 0;
2124
	
2204
2125
	// report the type parameters
2205
	// report the type parameters
2126
	if (type.typeParameters != null) {
2206
	if (type.typeParameters != null) {
2127
		for (int i=0, l=type.typeParameters.length; i<l; i++) {
2207
		reportMatching(type.typeParameters, enclosingElement, parent, type.binding, nodeSet);
2128
			TypeParameter typeParameter = type.typeParameters[i];
2129
			if (typeParameter != null) {
2130
				Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
2131
				if (level != null && matchedClassContainer) {
2132
					if (level.intValue() > -1 && enclosesElement) {
2133
						int offset = typeParameter.sourceStart;
2134
						SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, type.binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
2135
						report(match);
2136
					}
2137
				}
2138
				if (typeParameter.type != null) {
2139
					level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
2140
					if (level != null && matchedClassContainer) {
2141
						this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, type.binding, level.intValue(), this);
2142
					}
2143
				}
2144
				if (typeParameter.bounds != null) {
2145
					for (int j=0, b=typeParameter.bounds.length; j<b; j++) {
2146
						level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.bounds[j]);
2147
						if (level != null && matchedClassContainer) {
2148
							this.patternLocator.matchReportReference(typeParameter.bounds[j], enclosingElement, type.binding, level.intValue(), this);
2149
						}
2150
					}
2151
				}
2152
			}
2153
		}
2154
	}
2208
	}
2155
2209
2156
	// report annotations
2210
	// report annotations
Lines 2202-2221 Link Here
2202
	boolean typeInHierarchy = type.binding == null || typeInHierarchy(type.binding);
2256
	boolean typeInHierarchy = type.binding == null || typeInHierarchy(type.binding);
2203
	matchedClassContainer = matchedClassContainer && typeInHierarchy; 
2257
	matchedClassContainer = matchedClassContainer && typeInHierarchy; 
2204
2258
2259
	// Visit fields
2205
	FieldDeclaration[] fields = type.fields;
2260
	FieldDeclaration[] fields = type.fields;
2206
	if (fields != null) {
2261
	if (fields != null) {
2207
		if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2262
		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2263
		IJavaElement[] otherElements = null;
2264
		int first = -1;
2208
		for (int i = 0, l = fields.length; i < l; i++) {
2265
		for (int i = 0, l = fields.length; i < l; i++) {
2209
			FieldDeclaration field = fields[i];
2266
			FieldDeclaration field = fields[i];
2210
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(field);
2267
			boolean last = field.endPart2Position == 0 || field.declarationEnd == field.endPart2Position;
2211
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2268
			// Store first index of multiple field declaration
2212
			reportMatching(field, type, enclosingElement, value, typeInHierarchy, nodeSet);
2269
			if (!last) {
2270
				if (first == -1) {
2271
					first = i;
2272
				}
2273
			}
2274
			// Mutliple declaration fields
2275
			if (first >= 0) {
2276
				// Create handle for all multiple fields except first one as it would be returned through the match
2277
				if (i > first) {
2278
					if (otherElements == null) {
2279
						otherElements = new IJavaElement[] { createHandle(field, type, enclosingElement) };
2280
					} else {
2281
						int length = otherElements.length;
2282
						System.arraycopy(otherElements, 0, otherElements = new IJavaElement[length+1], 0, length);
2283
						otherElements[length] = createHandle(field, type, enclosingElement);
2284
					}
2285
				}
2286
				// On last field, report match with all other elements
2287
				if (last) {
2288
					for (int j=first; j<=i; j++) {
2289
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(fields[j]);
2290
						int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2291
						reportMatching(fields[j], type, enclosingElement, otherElements, value, typeInHierarchy, nodeSet);
2292
					}
2293
					first = -1;
2294
					otherElements = null;
2295
				}
2296
			} else {
2297
				// Single field, report normally
2298
				Integer level = (Integer) nodeSet.matchingNodes.removeKey(field);
2299
				int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2300
				reportMatching(field, type, enclosingElement, null, value, typeInHierarchy, nodeSet);
2301
			}
2213
		}
2302
		}
2214
	}
2303
	}
2215
2304
2305
	// Visit methods
2216
	AbstractMethodDeclaration[] methods = type.methods;
2306
	AbstractMethodDeclaration[] methods = type.methods;
2217
	if (methods != null) {
2307
	if (methods != null) {
2218
		if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2308
		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2219
		for (int i = 0, l = methods.length; i < l; i++) {
2309
		for (int i = 0, l = methods.length; i < l; i++) {
2220
			AbstractMethodDeclaration method = methods[i];
2310
			AbstractMethodDeclaration method = methods[i];
2221
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(method);
2311
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(method);
Lines 2224-2233 Link Here
2224
		}
2314
		}
2225
	}
2315
	}
2226
2316
2317
	// Visit types
2227
	TypeDeclaration[] memberTypes = type.memberTypes;
2318
	TypeDeclaration[] memberTypes = type.memberTypes;
2228
	if (memberTypes != null) {
2319
	if (memberTypes != null) {
2229
		for (int i = 0, l = memberTypes.length; i < l; i++) {
2320
		for (int i = 0, l = memberTypes.length; i < l; i++) {
2230
			if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2321
			if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2231
			TypeDeclaration memberType = memberTypes[i];
2322
			TypeDeclaration memberType = memberTypes[i];
2232
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(memberType);
2323
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(memberType);
2233
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2324
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
Lines 2235-2240 Link Here
2235
		}
2326
		}
2236
	}
2327
	}
2237
}
2328
}
2329
/**
2330
 * Report matches in type parameters.
2331
 */
2332
protected void reportMatching(TypeParameter[] typeParameters, IJavaElement enclosingElement, IJavaElement parent, Binding binding, MatchingNodeSet nodeSet) throws CoreException {
2333
	if (typeParameters == null) return;
2334
	for (int i=0, l=typeParameters.length; i<l; i++) {
2335
		TypeParameter typeParameter = typeParameters[i];
2336
		if (typeParameter != null) {
2337
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
2338
			if (level != null) {
2339
				if (level.intValue() > -1 && encloses(enclosingElement)) {
2340
					int offset = typeParameter.sourceStart;
2341
					SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
2342
					report(match);
2343
				}
2344
			}
2345
			if (typeParameter.type != null) {
2346
				level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
2347
				if (level != null) {
2348
					IJavaElement localElement = createHandle(typeParameter, enclosingElement);
2349
					this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, localElement, null, binding, level.intValue(), this);
2350
				}
2351
			}
2352
			if (typeParameter.bounds != null) {
2353
				for (int j=0, b=typeParameter.bounds.length; j<b; j++) {
2354
					level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.bounds[j]);
2355
					if (level != null) {
2356
						IJavaElement localElement = createHandle(typeParameter, enclosingElement);
2357
						this.patternLocator.matchReportReference(typeParameter.bounds[j], enclosingElement, localElement, null, binding, level.intValue(), this);
2358
					}
2359
				}
2360
			}
2361
		}
2362
	}
2363
}
2238
protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
2364
protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
2239
	ASTNode[] nodes = null;
2365
	ASTNode[] nodes = null;
2240
	if (superReference instanceof ParameterizedSingleTypeReference || superReference instanceof ParameterizedQualifiedTypeReference) {
2366
	if (superReference instanceof ParameterizedSingleTypeReference || superReference instanceof ParameterizedQualifiedTypeReference) {
(-)search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java (+12 lines)
Lines 391-396 Link Here
391
		locator.report(match);
391
		locator.report(match);
392
	}
392
	}
393
}
393
}
394
/**
395
 * Reports the match of the given reference. Also provide a local element to eventually report in match.
396
 */
397
protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
398
	matchReportReference(reference, element, elementBinding, accuracy, locator);
399
}
400
/**
401
 * Reports the match of the given reference. Also provide a scope to look for potential other elements.
402
 */
403
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException {
404
	matchReportReference(reference, element, elementBinding, accuracy, locator);
405
}
394
public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
406
public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
395
    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
407
    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
396
}
408
}
(-)search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java (-4 / +71 lines)
Lines 255-261 Link Here
255
		// TODO (frederic) need to add a test for this case while searching generic types...
255
		// TODO (frederic) need to add a test for this case while searching generic types...
256
		if (locator.encloses(element)) {
256
		if (locator.encloses(element)) {
257
			int offset = arrayRef.sourceStart;
257
			int offset = arrayRef.sourceStart;
258
			match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, arrayRef.sourceEnd-offset+1, arrayRef);
258
			int length = arrayRef.sourceEnd-offset+1;
259
			if (this.match == null) {
260
				this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, length, arrayRef);
261
			} else {
262
				this.match.setOffset(offset);
263
				this.match.setLength(length);
264
			}
259
			locator.report(match);
265
			locator.report(match);
260
			return;
266
			return;
261
		}
267
		}
Lines 268-273 Link Here
268
	locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName);
274
	locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName);
269
}
275
}
270
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
276
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
277
	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
278
}
279
/**
280
 * Reports the match of the given reference. Also provide a local element to eventually report in match.
281
 */
282
protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
271
	if (this.isDeclarationOfReferencedTypesPattern) {
283
	if (this.isDeclarationOfReferencedTypesPattern) {
272
		if ((element = findElement(element, accuracy)) != null)
284
		if ((element = findElement(element, accuracy)) != null)
273
			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
285
			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
Lines 275-281 Link Here
275
	}
287
	}
276
	
288
	
277
	// Create search match
289
	// Create search match
278
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
290
	TypeReferenceMatch refMatch = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
291
	refMatch.setLocalElement(localElement);
292
	refMatch.setOtherElements(otherElements);
293
	this.match = refMatch;
279
294
280
	// Report match depending on reference type
295
	// Report match depending on reference type
281
	if (reference instanceof QualifiedNameReference)
296
	if (reference instanceof QualifiedNameReference)
Lines 293-298 Link Here
293
		locator.report(match);
308
		locator.report(match);
294
	}
309
	}
295
}
310
}
311
/**
312
 * Reports the match of the given reference. Also provide a scope to look for potential other elements.
313
 */
314
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException {
315
	if (scope == null || (scope.kind != Scope.BLOCK_SCOPE && scope.kind != Scope.METHOD_SCOPE)) {
316
		matchReportReference(reference, element, elementBinding, accuracy, locator);
317
		return;
318
	}
319
	BlockScope blockScope = (BlockScope) scope;
320
	LocalDeclaration[] localDeclarations = blockScope.findLocalVariableDeclarations(reference.sourceStart);
321
	int length = localDeclarations == null ? 0 : localDeclarations.length;
322
	IJavaElement localElement = null;
323
	IJavaElement[] otherElements = null;
324
	if (length > 0) {
325
		// Set other elements to  as it's different from enclosing one
326
		int idx = 0;
327
		for (; idx<length; idx++) {
328
			if (localDeclarations[idx] == null) break;
329
			if (reference.sourceStart == localDeclarations[idx].declarationSourceStart) {
330
				localElement = locator.createHandle(localDeclarations[idx], element);
331
				break;
332
			}
333
			if (idx>0 && localDeclarations[idx].sourceStart > reference.sourceStart) {
334
				localElement = locator.createHandle(localDeclarations[idx-1], element);
335
				break;
336
			}
337
		}
338
		if (localElement == null && idx > 0) {
339
			if (reference.sourceEnd < localDeclarations[idx-1].declarationEnd) {
340
				localElement = locator.createHandle(localDeclarations[idx-1], element);
341
			}
342
		}
343
		int size = 0;
344
		for (int j=1; j<length; j++) {
345
			if (localDeclarations[j] == null) break;
346
			if (reference.sourceStart == localDeclarations[j].declarationSourceStart) {
347
				if (otherElements == null) {
348
					otherElements = new IJavaElement[length-j];
349
				}
350
				otherElements[size++] = locator.createHandle(localDeclarations[j], element);
351
			}
352
		}
353
		if (size > 0 && size != (length-1)) {
354
			System.arraycopy(otherElements, 0, otherElements = new IJavaElement[size], 0, size);
355
		}
356
	}
357
	matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator);
358
}
296
protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
359
protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
297
	Binding binding = qNameRef.binding;
360
	Binding binding = qNameRef.binding;
298
	TypeBinding typeBinding = null;
361
	TypeBinding typeBinding = null;
Lines 325-331 Link Here
325
	}
388
	}
326
389
327
	// Create search match to report
390
	// Create search match to report
328
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
391
	if (this.match == null) {
392
		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
393
	}
329
394
330
	// try to match all enclosing types for which the token matches as well.
395
	// try to match all enclosing types for which the token matches as well.
331
	if (typeBinding instanceof ReferenceBinding) {
396
	if (typeBinding instanceof ReferenceBinding) {
Lines 368-374 Link Here
368
	}
433
	}
369
434
370
	// Create search match to report
435
	// Create search match to report
371
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
436
	if (this.match == null) {
437
		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
438
	}
372
439
373
	// try to match all enclosing types for which the token matches as well
440
	// try to match all enclosing types for which the token matches as well
374
	if (typeBinding instanceof ReferenceBinding) {
441
	if (typeBinding instanceof ReferenceBinding) {
(-)search/org/eclipse/jdt/core/search/TypeReferenceMatch.java (+44 lines)
Lines 24-29 Link Here
24
 */
24
 */
25
public class TypeReferenceMatch extends SearchMatch {
25
public class TypeReferenceMatch extends SearchMatch {
26
26
27
	private IJavaElement[] otherElements;
28
	private IJavaElement localElement;
29
27
	/**
30
	/**
28
	 * Creates a new type reference match.
31
	 * Creates a new type reference match.
29
	 * 
32
	 * 
Lines 40-43 Link Here
40
		super(enclosingElement, accuracy, offset, length, participant, resource);
43
		super(enclosingElement, accuracy, offset, length, participant, resource);
41
		setInsideDocComment(insideDocComment);
44
		setInsideDocComment(insideDocComment);
42
	}
45
	}
46
47
	/**
48
	 * Returns the local element of this search match.
49
	 * This may be a local variable or a type parameter.
50
	 * 
51
	 * @return the element of the search match, or <code>null</code> if none or there's
52
	 * 	no more inner-most enclosing than the element itself ({@link SearchMatch#getElement()}).
53
	 */
54
	public final IJavaElement getLocalElement() {
55
		return this.localElement;
56
	}
57
58
	/**
59
	 * Returns other elements of this search match.
60
	 * These may be other fields of a multiple fields declaration.
61
	 * 
62
	 * @return the other elements of the search match, or <code>null</code> if none.
63
	 */
64
	public final IJavaElement[] getOtherElements() {
65
		return this.otherElements;
66
	}
67
68
	/**
69
	 * Sets the local element of this search match.
70
	 * 
71
	 * @param element the local element that encloses or corresponds to the match,
72
	 * or <code>null</code> if none
73
	 */
74
	public final void setLocalElement(IJavaElement element) {
75
		this.localElement = element;
76
	}
77
78
	/**
79
	 * Sets the other elements of this search match.
80
	 * 
81
	 * @param elements the other elements of the match,
82
	 * 	or <code>null</code> if none
83
	 */
84
	public final void setOtherElements(IJavaElement[] elements) {
85
		this.otherElements = elements;
86
	}
43
}
87
}
(-)compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (+57 lines)
Lines 299-304 Link Here
299
		}
299
		}
300
	}
300
	}
301
301
302
	/**
303
	 * Returns all declarations of most specific locals containing a given position in their source range.
304
	 * This code does not recurse in nested types.
305
	 * Returned array may have null values at trailing indexes.
306
	 */
307
	public LocalDeclaration[] findLocalVariableDeclarations(int position) {
308
309
		// local variable init
310
		int ilocal = 0, maxLocals = this.localIndex;
311
		boolean hasMoreVariables = maxLocals > 0;
312
		LocalDeclaration[] localDeclarations = null;
313
		int declPtr = 0;
314
315
		// scope init
316
		int iscope = 0, maxScopes = this.subscopeCount;
317
		boolean hasMoreScopes = maxScopes > 0;
318
319
		// iterate scopes and variables in parallel
320
		while (hasMoreVariables || hasMoreScopes) {
321
			if (hasMoreScopes
322
				&& (!hasMoreVariables || (subscopes[iscope].startIndex() <= ilocal))) {
323
				// consider subscope first
324
				Scope subscope = subscopes[iscope];
325
				if (subscope.kind == Scope.BLOCK_SCOPE) { // do not dive in nested types
326
					localDeclarations = ((BlockScope)subscope).findLocalVariableDeclarations(position);
327
					if (localDeclarations != null) {
328
						return localDeclarations;
329
					}
330
				}
331
				hasMoreScopes = ++iscope < maxScopes;
332
			} else {
333
				// consider variable first
334
				LocalVariableBinding local = locals[ilocal]; // if no local at all, will be locals[ilocal]==null
335
				if (local != null) {
336
					LocalDeclaration localDecl = local.declaration;
337
					if (localDecl != null) {
338
						if (localDecl.declarationSourceStart <= position) {
339
							if (position <= localDecl.declarationSourceEnd) {
340
								if (localDeclarations == null) {
341
									localDeclarations = new LocalDeclaration[maxLocals];
342
								}
343
								localDeclarations[declPtr++] = localDecl;
344
							}
345
						} else {
346
							return localDeclarations;
347
						}
348
					}
349
				}
350
				hasMoreVariables = ++ilocal < maxLocals;
351
				if (!hasMoreVariables && localDeclarations != null) {
352
					return localDeclarations;
353
				}
354
			}
355
		}
356
		return null;
357
	}
358
302
	/* Note that it must never produce a direct access to the targetEnclosingType,
359
	/* Note that it must never produce a direct access to the targetEnclosingType,
303
	 * but instead a field sequence (this$2.this$1.this$0) so as to handle such a test case:
360
	 * but instead a field sequence (this$2.this$1.this$0) so as to handle such a test case:
304
	 *
361
	 *

Return to bug 110336