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 / +239 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
}
5474
public void testBug110336g() throws CoreException {
5475
	workingCopies = new ICompilationUnit[1];
5476
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5477
		"package b110336;\n" + 
5478
		"public class Test {\n" + 
5479
		"	{\n" + 
5480
		"		Test lv1 = null, lv2 = new Test(), lv3;\n" + 
5481
		"		Test lv4 = new Test(), lv5, lv6 = null;\n" + 
5482
		"		Test lv7, lv8 = null, lv9 = new Test();\n" + 
5483
		"	}\n" + 
5484
		"}\n"
5485
	);
5486
	IType type = this.workingCopies[0].getType("Test");
5487
	TypeReferencesCollector collector = new TypeReferencesCollector();
5488
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5489
	assertSearchResults(
5490
		"src/b110336/Test.java b110336.Test.{}.lv1 [Test]+[lv2,lv3]\n" + 
5491
		"src/b110336/Test.java b110336.Test.{}.lv2 [Test]\n" + 
5492
		"src/b110336/Test.java b110336.Test.{}.lv4 [Test]+[lv5,lv6]\n" + 
5493
		"src/b110336/Test.java b110336.Test.{}.lv4 [Test]\n" + 
5494
		"src/b110336/Test.java b110336.Test.{}.lv7 [Test]+[lv8,lv9]\n" + 
5495
		"src/b110336/Test.java b110336.Test.{}.lv9 [Test]",
5496
		collector
5497
	);
5498
}
5499
public void testBug110336h() throws CoreException {
5500
	workingCopies = new ICompilationUnit[1];
5501
	workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/b110336/Test.java",
5502
		"package b110336;\n" + 
5503
		"public class Test {\n" + 
5504
		"	static {\n" + 
5505
		"		Test lv1 = null, lv2 = new Test(), lv3;\n" + 
5506
		"		Test lv4 = new Test(), lv5, lv6 = null;\n" + 
5507
		"		Test lv7, lv8 = null, lv9 = new Test();\n" + 
5508
		"	}\n" + 
5509
		"}\n"
5510
	);
5511
	IType type = this.workingCopies[0].getType("Test");
5512
	TypeReferencesCollector collector = new TypeReferencesCollector();
5513
	search(type, REFERENCES, EXACT_RULE, getJavaSearchScopeBugs(), collector);
5514
	assertSearchResults(
5515
		"src/b110336/Test.java b110336.Test.static {}.lv1 [Test]+[lv2,lv3]\n" + 
5516
		"src/b110336/Test.java b110336.Test.static {}.lv2 [Test]\n" + 
5517
		"src/b110336/Test.java b110336.Test.static {}.lv4 [Test]+[lv5,lv6]\n" + 
5518
		"src/b110336/Test.java b110336.Test.static {}.lv4 [Test]\n" + 
5519
		"src/b110336/Test.java b110336.Test.static {}.lv7 [Test]+[lv8,lv9]\n" + 
5520
		"src/b110336/Test.java b110336.Test.static {}.lv9 [Test]",
5521
		collector
5522
	);
5523
}
5293
}
5524
}
(-)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 (-45 / +177 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 necessary if field is 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 initializer
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 2086-2093 Link Here
2086
								node = field;
2165
								node = field;
2087
							}
2166
							}
2088
						}
2167
						}
2089
						this.patternLocator.matchReportReference(node, enclosingElement, field.binding, level.intValue(), this);
2168
						// Set block scope for initializer in case there would have other local and other elements to report
2169
						BlockScope blockScope = null;
2170
						if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
2171
							Block block = ((Initializer)field).block;
2172
							if (block != null) blockScope = block.scope;
2173
						}
2174
						this.patternLocator.matchReportReference(node, enclosingElement, field.binding, blockScope, level.intValue(), this);
2090
					}
2175
					}
2176
				}
2091
			}
2177
			}
2092
		}
2178
		}
2093
	}
2179
	}
Lines 2121-2156 Link Here
2121
	}
2207
	}
2122
2208
2123
	boolean matchedClassContainer = (this.matchContainer & PatternLocator.CLASS_CONTAINER) != 0;
2209
	boolean matchedClassContainer = (this.matchContainer & PatternLocator.CLASS_CONTAINER) != 0;
2124
	
2210
2125
	// report the type parameters
2211
	// report the type parameters
2126
	if (type.typeParameters != null) {
2212
	if (type.typeParameters != null) {
2127
		for (int i=0, l=type.typeParameters.length; i<l; i++) {
2213
		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
	}
2214
	}
2155
2215
2156
	// report annotations
2216
	// report annotations
Lines 2202-2221 Link Here
2202
	boolean typeInHierarchy = type.binding == null || typeInHierarchy(type.binding);
2262
	boolean typeInHierarchy = type.binding == null || typeInHierarchy(type.binding);
2203
	matchedClassContainer = matchedClassContainer && typeInHierarchy; 
2263
	matchedClassContainer = matchedClassContainer && typeInHierarchy; 
2204
2264
2265
	// Visit fields
2205
	FieldDeclaration[] fields = type.fields;
2266
	FieldDeclaration[] fields = type.fields;
2206
	if (fields != null) {
2267
	if (fields != null) {
2207
		if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2268
		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2269
		IJavaElement[] otherElements = null;
2270
		int first = -1;
2208
		for (int i = 0, l = fields.length; i < l; i++) {
2271
		for (int i = 0, l = fields.length; i < l; i++) {
2209
			FieldDeclaration field = fields[i];
2272
			FieldDeclaration field = fields[i];
2210
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(field);
2273
			boolean last = field.endPart2Position == 0 || field.declarationEnd == field.endPart2Position;
2211
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2274
			// Store first index of multiple field declaration
2212
			reportMatching(field, type, enclosingElement, value, typeInHierarchy, nodeSet);
2275
			if (!last) {
2276
				if (first == -1) {
2277
					first = i;
2278
				}
2279
			}
2280
			// Mutliple declaration fields
2281
			if (first >= 0) {
2282
				// Create handle for all multiple fields except first one as it would be returned through the match
2283
				if (i > first) {
2284
					if (otherElements == null) {
2285
						otherElements = new IJavaElement[] { createHandle(field, type, enclosingElement) };
2286
					} else {
2287
						int length = otherElements.length;
2288
						System.arraycopy(otherElements, 0, otherElements = new IJavaElement[length+1], 0, length);
2289
						otherElements[length] = createHandle(field, type, enclosingElement);
2290
					}
2291
				}
2292
				// On last field, report match with all other elements
2293
				if (last) {
2294
					for (int j=first; j<=i; j++) {
2295
						Integer level = (Integer) nodeSet.matchingNodes.removeKey(fields[j]);
2296
						int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2297
						reportMatching(fields[j], type, enclosingElement, otherElements, value, typeInHierarchy, nodeSet);
2298
					}
2299
					first = -1;
2300
					otherElements = null;
2301
				}
2302
			} else {
2303
				// Single field, report normally
2304
				Integer level = (Integer) nodeSet.matchingNodes.removeKey(field);
2305
				int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2306
				reportMatching(field, type, enclosingElement, null, value, typeInHierarchy, nodeSet);
2307
			}
2213
		}
2308
		}
2214
	}
2309
	}
2215
2310
2311
	// Visit methods
2216
	AbstractMethodDeclaration[] methods = type.methods;
2312
	AbstractMethodDeclaration[] methods = type.methods;
2217
	if (methods != null) {
2313
	if (methods != null) {
2218
		if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2314
		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2219
		for (int i = 0, l = methods.length; i < l; i++) {
2315
		for (int i = 0, l = methods.length; i < l; i++) {
2220
			AbstractMethodDeclaration method = methods[i];
2316
			AbstractMethodDeclaration method = methods[i];
2221
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(method);
2317
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(method);
Lines 2224-2233 Link Here
2224
		}
2320
		}
2225
	}
2321
	}
2226
2322
2323
	// Visit types
2227
	TypeDeclaration[] memberTypes = type.memberTypes;
2324
	TypeDeclaration[] memberTypes = type.memberTypes;
2228
	if (memberTypes != null) {
2325
	if (memberTypes != null) {
2229
		for (int i = 0, l = memberTypes.length; i < l; i++) {
2326
		for (int i = 0, l = memberTypes.length; i < l; i++) {
2230
			if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
2327
			if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
2231
			TypeDeclaration memberType = memberTypes[i];
2328
			TypeDeclaration memberType = memberTypes[i];
2232
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(memberType);
2329
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(memberType);
2233
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
2330
			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
Lines 2235-2240 Link Here
2235
		}
2332
		}
2236
	}
2333
	}
2237
}
2334
}
2335
/**
2336
 * Report matches in type parameters.
2337
 */
2338
protected void reportMatching(TypeParameter[] typeParameters, IJavaElement enclosingElement, IJavaElement parent, Binding binding, MatchingNodeSet nodeSet) throws CoreException {
2339
	if (typeParameters == null) return;
2340
	for (int i=0, l=typeParameters.length; i<l; i++) {
2341
		TypeParameter typeParameter = typeParameters[i];
2342
		if (typeParameter != null) {
2343
			Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
2344
			if (level != null) {
2345
				if (level.intValue() > -1 && encloses(enclosingElement)) {
2346
					int offset = typeParameter.sourceStart;
2347
					SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
2348
					report(match);
2349
				}
2350
			}
2351
			if (typeParameter.type != null) {
2352
				level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
2353
				if (level != null) {
2354
					IJavaElement localElement = createHandle(typeParameter, enclosingElement);
2355
					this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, localElement, null, binding, level.intValue(), this);
2356
				}
2357
			}
2358
			if (typeParameter.bounds != null) {
2359
				for (int j=0, b=typeParameter.bounds.length; j<b; j++) {
2360
					level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.bounds[j]);
2361
					if (level != null) {
2362
						IJavaElement localElement = createHandle(typeParameter, enclosingElement);
2363
						this.patternLocator.matchReportReference(typeParameter.bounds[j], enclosingElement, localElement, null, binding, level.intValue(), this);
2364
					}
2365
				}
2366
			}
2367
		}
2368
	}
2369
}
2238
protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
2370
protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
2239
	ASTNode[] nodes = null;
2371
	ASTNode[] nodes = null;
2240
	if (superReference instanceof ParameterizedSingleTypeReference || superReference instanceof ParameterizedQualifiedTypeReference) {
2372
	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 / +83 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 267-273 Link Here
267
	}
273
	}
268
	locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName);
274
	locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName);
269
}
275
}
276
/**
277
 * Reports the match of the given reference.
278
 */
270
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
279
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
280
	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
281
}
282
/**
283
 * Reports the match of the given reference. Also provide a local and other elements to eventually report in match.
284
 */
285
protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
271
	if (this.isDeclarationOfReferencedTypesPattern) {
286
	if (this.isDeclarationOfReferencedTypesPattern) {
272
		if ((element = findElement(element, accuracy)) != null)
287
		if ((element = findElement(element, accuracy)) != null)
273
			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
288
			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
Lines 275-281 Link Here
275
	}
290
	}
276
	
291
	
277
	// Create search match
292
	// Create search match
278
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
293
	TypeReferenceMatch refMatch = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
294
	refMatch.setLocalElement(localElement);
295
	refMatch.setOtherElements(otherElements);
296
	this.match = refMatch;
279
297
280
	// Report match depending on reference type
298
	// Report match depending on reference type
281
	if (reference instanceof QualifiedNameReference)
299
	if (reference instanceof QualifiedNameReference)
Lines 293-298 Link Here
293
		locator.report(match);
311
		locator.report(match);
294
	}
312
	}
295
}
313
}
314
/**
315
 * Reports the match of the given reference. Also provide a scope to look for possible local and other elements.
316
 */
317
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException {
318
	if (scope == null || (scope.kind != Scope.BLOCK_SCOPE && scope.kind != Scope.METHOD_SCOPE)) {
319
		matchReportReference(reference, element, elementBinding, accuracy, locator);
320
		return;
321
	}
322
	
323
	// Look if some block scope local variable declarations include reference start position
324
	BlockScope blockScope = (BlockScope) scope;
325
	LocalDeclaration[] localDeclarations = blockScope.findLocalVariableDeclarations(reference.sourceStart);
326
	int length = localDeclarations == null ? 0 : localDeclarations.length;
327
	IJavaElement localElement = null;
328
	IJavaElement[] otherElements = null;
329
330
	// Some local variable declaration are matching
331
	if (length > 0) {
332
333
		// Set local element to first matching local declaration
334
		int idx = 0;
335
		for (; idx<length; idx++) {
336
			if (localDeclarations[idx] == null) break;
337
			if (reference.sourceStart == localDeclarations[idx].declarationSourceStart) {
338
				localElement = locator.createHandle(localDeclarations[idx], element);
339
				break;
340
			}
341
			if (idx>0 && localDeclarations[idx].sourceStart > reference.sourceStart) {
342
				localElement = locator.createHandle(localDeclarations[idx-1], element);
343
				break;
344
			}
345
		}
346
		if (localElement == null && idx > 0) {
347
			if (reference.sourceEnd < localDeclarations[idx-1].declarationEnd) {
348
				localElement = locator.createHandle(localDeclarations[idx-1], element);
349
			}
350
		}
351
		
352
		// Store other local variable declarations in other elements
353
		int size = 0;
354
		for (int j=1; j<length; j++) {
355
			if (localDeclarations[j] == null) break;
356
			if (reference.sourceStart == localDeclarations[j].declarationSourceStart) {
357
				if (otherElements == null) {
358
					otherElements = new IJavaElement[length-j];
359
				}
360
				otherElements[size++] = locator.createHandle(localDeclarations[j], element);
361
			}
362
		}
363
		if (size > 0 && size != (length-1)) {
364
			System.arraycopy(otherElements, 0, otherElements = new IJavaElement[size], 0, size);
365
		}
366
	}
367
	
368
	// Report match with local and other elements if any
369
	matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator);
370
}
296
protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
371
protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
297
	Binding binding = qNameRef.binding;
372
	Binding binding = qNameRef.binding;
298
	TypeBinding typeBinding = null;
373
	TypeBinding typeBinding = null;
Lines 325-331 Link Here
325
	}
400
	}
326
401
327
	// Create search match to report
402
	// Create search match to report
328
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
403
	if (this.match == null) {
404
		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
405
	}
329
406
330
	// try to match all enclosing types for which the token matches as well.
407
	// try to match all enclosing types for which the token matches as well.
331
	if (typeBinding instanceof ReferenceBinding) {
408
	if (typeBinding instanceof ReferenceBinding) {
Lines 368-374 Link Here
368
	}
445
	}
369
446
370
	// Create search match to report
447
	// Create search match to report
371
	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
448
	if (this.match == null) {
449
		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
450
	}
372
451
373
	// try to match all enclosing types for which the token matches as well
452
	// try to match all enclosing types for which the token matches as well
374
	if (typeBinding instanceof ReferenceBinding) {
453
	if (typeBinding instanceof ReferenceBinding) {
(-)search/org/eclipse/jdt/core/search/TypeReferenceMatch.java (+49 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 localElement;
28
	private IJavaElement[] otherElements;
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 which declaring type is the referenced one
50
	 * or a type parameter which extends it.
51
	 * 
52
	 * @return the element of the search match, or <code>null</code> if none or there's
53
	 * 	no more specific local element than the element itself ({@link SearchMatch#getElement()}).
54
	 */
55
	public final IJavaElement getLocalElement() {
56
		return this.localElement;
57
	}
58
59
	/**
60
	 * Returns other enclosing elements of this search match.
61
	 *
62
	 * If {@link #getLocalElement()} is not <code>null</code>, these may be other
63
	 * local elements such as additional local variables of a multiple local
64
	 * variables declaration. Otherwise, these may be other elements such as
65
	 * additional fields of a multiple fields declaration.
66
	 * 
67
	 * @return the other elements of the search match, or <code>null</code> if none
68
	 */
69
	public final IJavaElement[] getOtherElements() {
70
		return this.otherElements;
71
	}
72
73
	/**
74
	 * Sets the local element of this search match.
75
	 * 
76
	 * @param localElement A more specific local element that corresponds to the match,
77
	 * 	or <code>null</code> if none
78
	 */
79
	public final void setLocalElement(IJavaElement localElement) {
80
		this.localElement = localElement;
81
	}
82
83
	/**
84
	 * Sets the other elements of this search match.
85
	 * 
86
	 * @param otherElements the other elements of the match,
87
	 * 	or <code>null</code> if none
88
	 */
89
	public final void setOtherElements(IJavaElement[] otherElements) {
90
		this.otherElements = otherElements;
91
	}
43
}
92
}
(-)buildnotes_jdt-core.html (-1 / +40 lines)
Lines 54-63 Link Here
54
<li>Added API <code>IMember#getOccurrenceCount()</code> to return the relative position of the member in the source.</li>
54
<li>Added API <code>IMember#getOccurrenceCount()</code> to return the relative position of the member in the source.</li>
55
<li>Added API <code>WorkingCopyOwner#newWorkingCopy(String,IProgressMonitor)</code> to create a new working copy 
55
<li>Added API <code>WorkingCopyOwner#newWorkingCopy(String,IProgressMonitor)</code> to create a new working copy 
56
     without an underlying resource.</li>
56
     without an underlying resource.</li>
57
<li>Added API on TypeReferenceMatch to report local element and other elements while
58
searching for type references (see bug (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110336">110336</a>):
59
	/**
60
	 * Returns the local element of this search match.
61
	 * This may be a local variable which declaring type is the referenced one
62
	 * or a type parameter which extends it.
63
	 * 
64
	 * @return the element of the search match, or <code>null</code> if none or there's
65
	 * 	no more specific local element than the element itself ({@link SearchMatch#getElement()}).
66
	 */
67
	public final IJavaElement getLocalElement()
68
	/**
69
	 * Returns other enclosing elements of this search match.
70
	 *
71
	 * If {@link #getLocalElement()} is not <code>null</code>, these may be other
72
	 * local elements such as additional local variables of a multiple local
73
	 * variables declaration. Otherwise, these may be other elements such as
74
	 * additional fields of a multiple fields declaration.
75
	 * 
76
	 * @return the other elements of the search match, or <code>null</code> if none
77
	 */
78
	public final IJavaElement[] getOtherElements()
79
	/**
80
	 * Sets the local element of this search match.
81
	 * 
82
	 * @param localElement A more specific local element that corresponds to the match,
83
	 * 	or <code>null</code> if none
84
	 */
85
	public final void setLocalElement(IJavaElement localElement)
86
	/**
87
	 * Sets the other elements of this search match.
88
	 * 
89
	 * @param otherElements the other elements of the match,
90
	 * 	or <code>null</code> if none
91
	 */
92
	public final void setOtherElements(IJavaElement[] otherElements)
93
</li>
57
</ul>
94
</ul>
58
95
59
<h3>Problem Reports Fixed</h3>
96
<h3>Problem Reports Fixed</h3>
60
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117890">117890</a>
97
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110336">110336</a>
98
[plan][search] Should optionaly return the local variable for type reference
99
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117890">117890</a>
61
JavaElement.getURLContents(...) leaves file open
100
JavaElement.getURLContents(...) leaves file open
62
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117589">117589</a>
101
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117589">117589</a>
63
Completion dialog shows html file name
102
Completion dialog shows html file name
(-)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