diff options
author | Manoj Palat | 2017-11-30 15:48:29 +0000 |
---|---|---|
committer | Manoj Palat | 2017-11-30 15:48:29 +0000 |
commit | 8e405848a1fdb3ab38dabe1577508bb26c74fc36 (patch) | |
tree | 4561d40d90273b8e328d19189071205ac650e424 | |
parent | 08f8bd434eb6a8c62f1730632f400aa60c1711cf (diff) | |
download | eclipse.jdt.core-I20171201-0600.tar.gz eclipse.jdt.core-I20171201-0600.tar.xz eclipse.jdt.core-I20171201-0600.zip |
Module Graph part of Bug 519151 - [9][search] Need a way to use modulesI20171201-0600I20171201-0345
as a search scope
Change-Id: Iea393498831dc4c4b6986d35a7f3e34c8f959d41
7 files changed, 702 insertions, 23 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java index d629ab8215..d266fccd43 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs9Tests.java @@ -31,6 +31,8 @@ import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.TypeReferenceMatch; +import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; + import junit.framework.Test; /** @@ -38,9 +40,11 @@ import junit.framework.Test; */ public class JavaSearchBugs9Tests extends AbstractJavaSearchTests { + private final String module_separator = String.valueOf(IIndexConstants.SEPARATOR); // "/" + private final String explicit_unnamed = new String(IJavaSearchConstants.ALL_UNNAMED); // "ALL-UNNAMED" static { // org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true; -// TESTS_NAMES = new String[] {"testBug519151_012"}; +// TESTS_NAMES = new String[] {"testBug519151"}; } public JavaSearchBugs9Tests(String name) { @@ -2423,7 +2427,8 @@ public void testBug519151_001() throws CoreException { this.workingCopies[1] = getWorkingCopy("/JavaSearchBugs/src/module-info.java", "import pack.*;\n" + "module mod.one {}"); - SearchPattern pattern = SearchPattern.createPattern("mod.one:pack.X", IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); + String needle = "mod.one" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); new SearchEngine(this.workingCopies).search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, getJavaSearchWorkingCopiesScope(), @@ -2457,7 +2462,8 @@ public void testBug519151_003() throws CoreException { this.workingCopies[1] = getWorkingCopy("/JavaSearchBugs/src/module-info.java", "import pack.*;\n" + "module mod.one {}"); - SearchPattern pattern = SearchPattern.createPattern(":pack.X", IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); + String needle = this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); new SearchEngine(this.workingCopies).search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, getJavaSearchWorkingCopiesScope(), @@ -2499,7 +2505,8 @@ public void testBug519151_004() throws Exception { project2.open(null); project1.open(null); - SearchPattern pattern = SearchPattern.createPattern("first:pack.X", IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); + String needle = "first" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); search(pattern, scope, this.resultCollector); @@ -2596,7 +2603,8 @@ public void testBug519151_006() throws Exception { project2.open(null); project1.open(null); - SearchPattern pattern = SearchPattern.createPattern(":pack.X", IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); + String needle = this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); search(pattern, scope, this.resultCollector); @@ -2727,7 +2735,8 @@ public void testBug519151_009() throws Exception { project2.open(null); project1.open(null); - SearchPattern pattern = SearchPattern.createPattern("first,second:pack.X", IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); + String needle = "first,second" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); search(pattern, scope, this.resultCollector); @@ -2775,7 +2784,7 @@ public void testBug519151_010() throws Exception { project2.open(null); project1.open(null); - String needle = " first, second:pack.X"; // with white space + String needle = " first, second"+ this.module_separator +"pack.X"; // with white space SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -2824,7 +2833,7 @@ public void testBug519151_011() throws Exception { project2.open(null); project1.open(null); - String needle = "mod.:pack.X"; + String needle = "mod."+ this.module_separator +"pack.X"; SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, SearchPattern.R_PREFIX_MATCH); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -2874,7 +2883,7 @@ public void testBug519151_012() throws Exception { project2.open(null); project1.open(null); - String needle = "mod.*:pack.X"; + String needle = "mod.*" + this.module_separator + "pack.X"; SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, SearchPattern.R_PATTERN_MATCH); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -2889,7 +2898,539 @@ public void testBug519151_012() throws Exception { deleteProject("second"); } } +public void testBug519151_013() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module first {\n" + + " requires second;\n" + + "}\n"; + createFile("/JavaSearchBugs9/src/module-info.java", fileContent); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module second {\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/Y.java", + "package pack;\n" + + "public class Y {}\n"); + + + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + project1.close(); // sync + project2.close(); + project2.open(null); + project1.open(null); + + String needle = "first" + this.module_separator + "pack.Y"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/Y.java pack.Y [Y] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + } +} +public void testBug519151_014() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module mod.first {\n" + + " requires mod.second {\n" + + "}\n"; + createFile("/JavaSearchBugs9/src/module-info.java", fileContent); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + " requires third;\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String thirdFile = + "module third {\n" + + "}\n"; + createFile("/third/src/module-info.java", thirdFile); + createFolder("/third/src/pack"); + createFile("/third/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = "third" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} + +public void testBug519151_015() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module mod.first {\n" + + " requires mod.second {\n" + + "}\n"; + createFile("/JavaSearchBugs9/src/module-info.java", fileContent); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + " requires third;\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String thirdFile = + "module third {\n" + + "}\n"; + createFile("/third/src/module-info.java", thirdFile); + createFolder("/third/src/pack"); + createFile("/third/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = "mod.second,third" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH\n" + + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} + +public void testBug519151_016() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module mod.first {\n" + + " requires mod.second {\n" + + "}\n"; + createFile("/JavaSearchBugs9/src/module-info.java", fileContent); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + " requires third;\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String thirdFile = + "module third {\n" + + "}\n"; + createFile("/third/src/module-info.java", thirdFile); + createFolder("/third/src/pack"); + createFile("/third/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = "non.existant.module" + this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults("", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} +public void testBug519151_017() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module mod.first {\n" + + " requires mod.second {\n" + + "}\n"; + createFile("/JavaSearchBugs9/src/module-info.java", fileContent); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + " requires third;\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String thirdFile = + "module third {\n" + + "}\n"; + createFile("/third/src/module-info.java", thirdFile); + createFolder("/third/src/pack"); + createFile("/third/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults("", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} +public void testBug519151_018() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + createFile("/third/src/X.java", + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = this.module_separator + "pack.X"; + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} +public void testBug519151_019() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + createFile("/third/src/X.java", + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String needle = this.explicit_unnamed + this.module_separator + "pack.X"; // "ALL-UNNAMED/pack.X" + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} +public void testBug519151_020() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + createFile("/third/src/X.java", + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String module1 = this.explicit_unnamed; // "ALL-UNNAMED/pack.X" + String module2 = "mod.second"; + String needle = module1 + "," + module2 + this.module_separator + "pack.X"; // "ALL-UNNAMED,second/pack.X" + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH\n" + + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} +public void testBug519151_021() throws Exception { + try { + + IJavaProject project1 = createJavaProject("JavaSearchBugs9", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + createFolder("/JavaSearchBugs9/src/pack"); + createFile("/JavaSearchBugs9/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module mod.second {\n" + + " requires third;\n"+ + "}\n"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack"); + createFile("/second/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + + IJavaProject project3 = createJavaProject("third", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project3.open(null); + addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String thirdFile = + "module third {\n" + + "}\n"; + createFile("/third/src/module-info.java", thirdFile); + createFolder("/third/src/pack"); + createFile("/third/src/pack/X.java", + "package pack;\n" + + "public class X {}\n"); + addClasspathEntry(project1, JavaCore.newProjectEntry(project3.getPath())); + + project1.close(); // sync + project2.close(); + project3.close(); + project3.open(null); + project2.open(null); + project1.open(null); + + String module1 = this.explicit_unnamed; // "ALL-UNNAMED/pack.X" + String module2 = "mod.second"; + String needle = module1 + "," + module2 + this.module_separator + "pack.X"; // "ALL-UNNAMED,second/pack.X" + SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, IJavaSearchConstants.MODULE_GRAPH, + SearchPattern.R_PATTERN_MATCH); + IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] + {getJavaProject("JavaSearchBugs9")}); + search(pattern, scope, this.resultCollector); + assertSearchResults( + "src/pack/X.java pack.X [X] EXACT_MATCH\n" + + "src/pack/X.java pack.X [X] EXACT_MATCH\n" + + "src/pack/X.java pack.X [X] EXACT_MATCH", + this.resultCollector); + } + finally { + deleteProject("JavaSearchBugs9"); + deleteProject("second"); + deleteProject("third"); + } +} public void _testBug519151_0X1() throws Exception { try { @@ -2924,7 +3465,7 @@ public void _testBug519151_0X1() throws Exception { project2.open(null); project1.open(null); - String needle = "0mod.*:pack.X"; // Pattern + String needle = "0mod.*" + this.module_separator + "pack.X"; // Pattern SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -2974,7 +3515,7 @@ public void _testBug519151_0X2() throws Exception { project2.open(null); project1.open(null); - String needle = "0mod\\.s.*:pack.X"; // Pattern + String needle = "0mod\\.s.*" + this.module_separator + "pack.X"; // Pattern SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -3037,7 +3578,7 @@ public void _testBug519151_0X3() throws Exception { project2.open(null); project1.open(null); - String needle = "0mod\\.f.*,mod\\.s.*:pack.X"; // Pattern + String needle = "0mod\\.f.*,mod\\.s.*" + this.module_separator + "pack.X"; // Pattern SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); @@ -3102,7 +3643,7 @@ public void _testBug519151_0X4() throws Exception { project2.open(null); project1.open(null); - String needle = "0mod\\.f.*,mod\\.s.*:pack.X"; // Pattern + String needle = "0mod\\.f.*,mod\\.s.*" + this.module_separator + "pack.X"; // Pattern SearchPattern pattern = SearchPattern.createPattern(needle, IJavaSearchConstants.CLASS, DECLARATIONS, ERASURE_RULE); IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs9")}); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java index 1e9fa81b6e..baf6c77e8e 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java @@ -198,6 +198,16 @@ public interface IJavaSearchConstants { int WRITE_ACCESSES = 5; /** + * When searching for Type Declaration matches, and if a module is given, this + * will find type declaration matches in this module as well as the dependent + * module graph of the given module. + * + * @since 3.14 + * @category limitTo + */ + int MODULE_GRAPH = 6; + + /** * Ignore declaring type while searching result. * Can be used in conjunction with any of the nature of match. * @@ -550,5 +560,13 @@ public interface IJavaSearchConstants { */ int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady; + /* Special Constant for module search */ + + /** + * The unnamed module is represented by this constant for making the intent explicit + * in searches involving modules + * @since 3.14 + */ + char[] ALL_UNNAMED = "ALL-UNNAMED".toCharArray(); ////$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java index c7ad4ec42a..67acd62108 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java @@ -1441,12 +1441,25 @@ private static SearchPattern createPackagePattern(String patternString, int limi * </ul> * </div> * Since 3.14 for Java 9, Type Declaration Patterns can have module names also embedded with the following syntax - * <p><b><code>[moduleName1[,moduleName2,..]]:[qualification '.']typeName ['<' typeArguments '>']</code></b></p> + * <p><b><code>[moduleName1[,moduleName2,..]]/[qualification '.']typeName ['<' typeArguments '>']</code></b> + * </p> + * <p> + * Unnamed modules can also be included and are represented either by an absence of module name implicitly + * or explicitly by specifying ALL-UNNAMED for module name. + * Module graph search is also supported with the limitTo option set to <code>IJavaSearchConstants.MODULE_GRAPH</code>. + * In the module graph case, the given type is searched in all the modules required directly as well + * as indirectly by the given module(s). + * </p> + * <p> + * Note that whitespaces are ignored in between module names. It is an error to give multiple module separators - in such + * cases a null pattern will be returned. + * </p> * <p>Examples:</p> * <ul> - * <li><code>java.base:java.lang.Object</code></li> - * <li><code>mod.one, mod.two:pack.X</code> find declaration in the list of given modules.</li> - * <li><code>:pack.X</code> find in the unnamed module.</li> + * <li><code>java.base/java.lang.Object</code></li> + * <li><code>mod.one, mod.two/pack.X</code> find declaration in the list of given modules.</li> + * <li><code>/pack.X</code> find in the unnamed module.</li> + * <li><code>ALL-UNNAMED/pack.X</code> find in the unnamed module.</li> * </ul> * <p> * </li> @@ -1502,6 +1515,7 @@ private static SearchPattern createPackagePattern(String patternString, int limi * <li>{@link IJavaSearchConstants#METHOD}: look for methods</li> * <li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li> * <li>{@link IJavaSearchConstants#PACKAGE}: look for packages</li> + * <li>{@link IJavaSearchConstants#MODULE}: look for modules</li> * </ul> * @param limitTo determines the nature of the expected matches * <ul> @@ -1521,6 +1535,10 @@ private static SearchPattern createPackagePattern(String patternString, int limi * Note that types may be only classes or only interfaces if {@link IJavaSearchConstants#CLASS CLASS} or * {@link IJavaSearchConstants#INTERFACE INTERFACE} is respectively used instead of {@link IJavaSearchConstants#TYPE TYPE}. * </li> + * <li>{@link IJavaSearchConstants#MODULE_GRAPH MODULE_GRAPH}: for types with a module prefix, + * will find all types present in required modules (directly or indirectly required) ie + * in any module present in the module graph of the given module. + * </li> * <li>All other fine grain constants defined in the <b>limitTo</b> category * of the {@link IJavaSearchConstants} are also accepted nature: * <table border=0> @@ -2198,7 +2216,7 @@ private static SearchPattern createTypePattern(char[] simpleName, char[] package return null; } private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule, char indexSuffix) { - String[] arr = patternString.split(String.valueOf(IIndexConstants.MODULE_SEPARATOR)); + String[] arr = patternString.split(String.valueOf(IIndexConstants.SEPARATOR)); String moduleName = null; if (arr.length == 2) { moduleName = arr[0]; @@ -2283,9 +2301,15 @@ private static SearchPattern createTypePattern(String patternString, int limitTo if (typeChars.length == 1 && typeChars[0] == '*') { typeChars = null; } + boolean modGraph = false; switch (limitTo) { + case IJavaSearchConstants.MODULE_GRAPH : + modGraph = true; + //$FALL-THROUGH$ case IJavaSearchConstants.DECLARATIONS : // cannot search for explicit member types - return new QualifiedTypeDeclarationPattern(patModName, qualificationChars, typeChars, indexSuffix, matchRule); + TypeDeclarationPattern typeDeclarationPattern = new QualifiedTypeDeclarationPattern(patModName, qualificationChars, typeChars, indexSuffix, matchRule); + typeDeclarationPattern.moduleGraph = modGraph; + return typeDeclarationPattern; case IJavaSearchConstants.REFERENCES : return new TypeReferencePattern(qualificationChars, typeChars, typeSignature, indexSuffix, matchRule); case IJavaSearchConstants.IMPLEMENTORS : diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java index 43e2e83e8d..44b2e9ccbf 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java @@ -45,7 +45,6 @@ public interface IIndexConstants { char SEPARATOR= '/'; char PARAMETER_SEPARATOR= ','; char SECONDARY_SUFFIX = 'S'; - char MODULE_SEPARATOR= ':'; char[] ONE_STAR = new char[] {'*'}; char[][] ONE_STAR_CHAR = new char[][] {ONE_STAR}; diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java index c03e0d1d8b..aa2d3d8950 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java @@ -145,6 +145,7 @@ public int numberOfMatches; // (numberOfMatches - 1) is the last unit in matches public PossibleMatch[] matchesToProcess; public PossibleMatch currentPossibleMatch; +/* package */HashMap<SearchMatch, Binding> matchBinding = new HashMap<>(); /* * Time spent in the IJavaSearchResultCollector */ @@ -1671,7 +1672,9 @@ public SearchMatch newDeclarationMatch( case IJavaElement.TYPE_PARAMETER: return new TypeParameterDeclarationMatch(element, accuracy, offset, length, participant, resource); case IJavaElement.JAVA_MODULE: - return new ModuleDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource); + ModuleDeclarationMatch match = new ModuleDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource); + this.matchBinding.put(match, binding); + return match; default: return null; } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java index 9fc2530685..4a8d41d2f7 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java @@ -10,13 +10,29 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core.search.matching; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchDocument; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchParticipant; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.core.search.SearchRequestor; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.lookup.*; +import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.search.JavaSearchParticipant; public class TypeDeclarationLocator extends PatternLocator { @@ -109,17 +125,89 @@ protected int resolveLevelForType(char[] simpleNamePattern, char[] qualification return resolveLevelForType(simpleNamePattern, fullQualificationPattern, type); return IMPOSSIBLE_MATCH; } +private HashSet<String> getModuleGraph(String mName, TypeDeclarationPattern typePattern, HashSet<String> mGraph) { + mGraph.add(mName); + SearchPattern modulePattern = SearchPattern.createPattern(mName, + IJavaSearchConstants.MODULE, IJavaSearchConstants.DECLARATIONS, typePattern.getMatchRule()); + if (modulePattern == null) return mGraph; + final HashSet<String> tmpGraph = new HashSet<>(); + final SearchParticipant participant = new JavaSearchParticipant() { + public void locateMatches(SearchDocument[] indexMatches, SearchPattern mPattern, + IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { + MatchLocator matchLocator = new MatchLocator(mPattern, requestor, scope, monitor); + /* eliminating false matches and locating them */ + if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); + matchLocator.locateMatches(indexMatches); + addRequiredModules(matchLocator); + } + private void addRequiredModules(MatchLocator matchLocator) { + if (matchLocator.matchBinding == null) return; + for (Binding b :matchLocator.matchBinding.values()) { + if (b instanceof ModuleBinding && ((ModuleBinding) b).moduleName != null) { + ModuleBinding m = (ModuleBinding) b; + tmpGraph.add(new String(m.moduleName)); + for (ModuleBinding r : m.getAllRequiredModules()) { + char[] name = r.moduleName; + if (name == null || CharOperation.equals(name, CharOperation.NO_CHAR)) continue; + tmpGraph.add(new String(name)); + } + } + } + } + }; + final SearchRequestor requestor = new SearchRequestor() { + @Override + public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException { + System.out.println(searchMatch.toString()); + // do nothing + } + }; + try { + new SearchEngine().search(modulePattern, new SearchParticipant[] {participant}, + JavaModelManager.getJavaModelManager().getWorkspaceScope(), + requestor, null); + } catch (CoreException e) { + // do nothing + } + mGraph.addAll(tmpGraph); + return mGraph; +} +private char[][] getModuleList(TypeDeclarationPattern typePattern) { + if (!typePattern.moduleGraph) + return typePattern.moduleNames; + if (typePattern.moduleGraphElements != null) // already computed + return typePattern.moduleGraphElements; + typePattern.moduleGraphElements = CharOperation.NO_CHAR_CHAR; // signal processing done. + // compute (lazy) + List<String> moduleList = Arrays.asList(CharOperation.toStrings(typePattern.moduleNames)); + int sz = moduleList.size(); + HashSet<String> mGraph = new HashSet<>(); + for (int i = 0; i < sz; ++i) { + mGraph = getModuleGraph(moduleList.get(i), typePattern, mGraph); + } + sz = mGraph.size(); + if (sz > 0) { + String[] ar = mGraph.toArray(new String[0]); + char[][] tmp = new char[sz][]; + for (int i = 0; i < sz; ++i) { + tmp[i] = ar[i].toCharArray(); + } + typePattern.moduleGraphElements = tmp; + } + return typePattern.moduleGraphElements; +} private int matchModule(TypeDeclarationPattern typePattern, TypeBinding type) { if (!(type instanceof ReferenceBinding)) return INACCURATE_MATCH; // a safety net, should not come here for error free code. ReferenceBinding reference = (ReferenceBinding) type; - ModuleBinding module = reference.module(); + ModuleBinding module = reference.module(); if (module == null || module.moduleName == null || typePattern.moduleNames == null) return POSSIBLE_MATCH; //can't determine, say possible to all. String bindModName = new String(module.moduleName); if (typePattern.modulePatterns == null) {// use 'normal' matching - for (char[] m : typePattern.moduleNames) { // match any in the list + char[][] moduleList = getModuleList(typePattern); + for (char[] m : moduleList) { // match any in the list int ret = matchNameValue(m, module.moduleName); if (ret != IMPOSSIBLE_MATCH) return ret; } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java index c6b08837bd..1131790116 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.util.regex.Pattern; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.core.index.*; @@ -27,6 +28,8 @@ public char[][] enclosingTypeNames; public char[][] moduleNames = null; private boolean allowModuleRegex = false; // enable to try experimental Module Regex Match /* package */ Pattern[] modulePatterns = null; +public boolean moduleGraph = false; +/* package */ char[][] moduleGraphElements = null; // set to CLASS_SUFFIX for only matching classes // set to INTERFACE_SUFFIX for only matching interfaces @@ -177,6 +180,7 @@ protected void addModuleNames(char[] modNames) { if (modNames == null) { return; } + final String explicit_unnamed = new String(IJavaSearchConstants.ALL_UNNAMED); String[] names = new String(modNames).split(String.valueOf(CharOperation.COMMA_SEPARATOR)); int len = names.length; if (this.allowModuleRegex && len > 0 && names[0] != null && names[0].length() > 0 @@ -189,6 +193,8 @@ protected void addModuleNames(char[] modNames) { } else { // 'normal' matching - flag if don't care conditions are passed for (int i = 0; i < len; ++i) { names[i] = names[i].trim(); + if (explicit_unnamed.equals(names[i])) + names[i] = ""; //$NON-NLS-1$ } } this.moduleNames = new char[len][]; |