Skip to content

Commit a6fc6e3

Browse files
committed
Adding patches improving import module handling.
1 parent 146c442 commit a6fc6e3

File tree

3 files changed

+334
-0
lines changed

3 files changed

+334
-0
lines changed

build.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
patches/8828.diff
7070
patches/8829.diff
7171
patches/8856-draft.diff
72+
patches/8974.diff
73+
patches/8975.diff
7274
patches/disable-error-notification.diff
7375
patches/mvn-sh.diff
7476
patches/project-marker-jdk.diff

patches/8974.diff

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
diff --git a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
2+
index 7ac61fb4370f..31bc75e99a54 100644
3+
--- a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
4+
+++ b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
5+
@@ -731,10 +731,21 @@ private void insideImport(Env env) throws IOException {
6+
ImportTree im = (ImportTree) env.getPath().getLeaf();
7+
SourcePositions sourcePositions = env.getSourcePositions();
8+
CompilationUnitTree root = env.getRoot();
9+
+ if (im.isModule()) {
10+
+ if (offset >= sourcePositions.getStartPosition(root, im.getQualifiedIdentifier())) {
11+
+ addModuleNamesFromGraph(env, null);
12+
+ }
13+
+ } else {
14+
if (offset <= sourcePositions.getStartPosition(root, im.getQualifiedIdentifier())) {
15+
TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(env, im, offset);
16+
- if (last != null && last.token().id() == JavaTokenId.IMPORT && Utilities.startsWith(STATIC_KEYWORD, prefix)) {
17+
- addKeyword(env, STATIC_KEYWORD, SPACE, false);
18+
+ if (last != null && last.token().id() == JavaTokenId.IMPORT) {
19+
+ if (Utilities.startsWith(STATIC_KEYWORD, prefix)) {
20+
+ addKeyword(env, STATIC_KEYWORD, SPACE, false);
21+
+ }
22+
+ if (Utilities.startsWith(MODULE_KEYWORD, prefix) &&
23+
+ env.getController().getSourceVersion().compareTo(SourceVersion.RELEASE_25) >= 0) {
24+
+ addKeyword(env, MODULE_KEYWORD, SPACE, false);
25+
+ }
26+
}
27+
if (options.contains(Options.ALL_COMPLETION) || options.contains(Options.COMBINED_COMPLETION)) {
28+
EnumSet<ElementKind> classKinds = EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE);
29+
@@ -746,6 +757,7 @@ private void insideImport(Env env) throws IOException {
30+
addPackages(env, null, false);
31+
}
32+
}
33+
+ }
34+
}
35+
36+
private void insideClass(Env env) throws IOException {
37+
@@ -1635,7 +1647,13 @@ private void insideMemberSelect(Env env) throws IOException {
38+
}
39+
if (!afterDot) {
40+
if (expEndPos <= offset) {
41+
- insideExpression(env, new TreePath(path, fa.getExpression()));
42+
+ if (fa.getExpression().getKind() == Kind.IDENTIFIER &&
43+
+ ((IdentifierTree) fa.getExpression()).getName().contentEquals(MODULE_KEYWORD)) {
44+
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
45+
+ addModuleNamesFromGraph(env, null);
46+
+ } else {
47+
+ insideExpression(env, new TreePath(path, fa.getExpression()));
48+
+ }
49+
}
50+
return;
51+
}
52+
@@ -1656,10 +1674,15 @@ private void insideMemberSelect(Env env) throws IOException {
53+
}
54+
} else if (lastNonWhitespaceTokenId != JavaTokenId.STAR) {
55+
controller.toPhase(Phase.RESOLVED);
56+
- if (withinModuleName(env)) {
57+
+ boolean inModuleNameInImport = false;
58+
+ if (withinModuleName(env) || (inModuleNameInImport = withinModuleNameInImport(env))) {
59+
String fqnPrefix = fa.getExpression().toString() + '.';
60+
anchorOffset = (int) sourcePositions.getStartPosition(root, fa);
61+
- addModuleNames(env, fqnPrefix, true);
62+
+ if (inModuleNameInImport) {
63+
+ addModuleNamesFromGraph(env, fqnPrefix);
64+
+ } else {
65+
+ addModuleNames(env, fqnPrefix, true);
66+
+ }
67+
return;
68+
}
69+
TreePath parentPath = path.getParentPath();
70+
@@ -4458,12 +4481,20 @@ private void addPackages(Env env, String fqnPrefix, boolean srcOnly) {
71+
}
72+
73+
private void addModuleNames(Env env, String fqnPrefix, boolean srcOnly) {
74+
+ srcOnly = false;
75+
+ addModuleNames(env, fqnPrefix, SourceUtils.getModuleNames(env.getController(), srcOnly ? EnumSet.of(ClassIndex.SearchScope.SOURCE) : EnumSet.allOf(ClassIndex.SearchScope.class)));
76+
+ }
77+
+
78+
+ private void addModuleNamesFromGraph(Env env, String fqnPrefix) {
79+
+ addModuleNames(env, fqnPrefix, env.getController().getElements().getAllModuleElements().stream().map(me -> me.getQualifiedName().toString()).toList());
80+
+ }
81+
+
82+
+ private void addModuleNames(Env env, String fqnPrefix, Iterable<? extends String> modulesNames) {
83+
if (fqnPrefix == null) {
84+
fqnPrefix = EMPTY;
85+
}
86+
- srcOnly = false;
87+
String prefix = env.getPrefix() != null ? fqnPrefix + env.getPrefix() : fqnPrefix;
88+
- for (String name : SourceUtils.getModuleNames(env.getController(), srcOnly ? EnumSet.of(ClassIndex.SearchScope.SOURCE) : EnumSet.allOf(ClassIndex.SearchScope.class))) {
89+
+ for (String name : modulesNames) {
90+
if (startsWith(env, name, prefix) && itemFactory instanceof ModuleItemFactory) {
91+
results.add(((ModuleItemFactory<T>)itemFactory).createModuleItem(name, anchorOffset));
92+
}
93+
@@ -6657,6 +6688,21 @@ private boolean withinModuleName(Env env) {
94+
return false;
95+
}
96+
97+
+ private boolean withinModuleNameInImport(Env env) {
98+
+ TreePath path = env.getPath();
99+
+ Tree last = null;
100+
+ while (path != null) {
101+
+ Tree tree = path.getLeaf();
102+
+ if (last != null
103+
+ && tree.getKind() == Tree.Kind.IMPORT && ((ImportTree) tree).isModule() && ((ImportTree) tree).getQualifiedIdentifier() == last) {
104+
+ return true;
105+
+ }
106+
+ path = path.getParentPath();
107+
+ last = tree;
108+
+ }
109+
+ return false;
110+
+ }
111+
+
112+
private boolean withinProvidesService(Env env) {
113+
TreePath path = env.getPath();
114+
Tree last = null;
115+
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFull.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFull.pass
116+
new file mode 100644
117+
index 000000000000..c7fb77ebcdb5
118+
--- /dev/null
119+
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFull.pass
120+
@@ -0,0 +1,6 @@
121+
+java.base
122+
+java.compiler
123+
+java.xml
124+
+jdk.compiler
125+
+jdk.jartool
126+
+jdk.javadoc
127+
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKJPrefix.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKJPrefix.pass
128+
new file mode 100644
129+
index 000000000000..08f71672206c
130+
--- /dev/null
131+
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKJPrefix.pass
132+
@@ -0,0 +1,2 @@
133+
+jdk.jartool
134+
+jdk.javadoc
135+
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKPrefix.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKPrefix.pass
136+
new file mode 100644
137+
index 000000000000..5e15d03b7041
138+
--- /dev/null
139+
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/importModuleListFullJDKPrefix.pass
140+
@@ -0,0 +1,3 @@
141+
+jdk.compiler
142+
+jdk.jartool
143+
+jdk.javadoc
144+
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/staticAndModuleKeywordAndAllPackages.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/staticAndModuleKeywordAndAllPackages.pass
145+
new file mode 100644
146+
index 000000000000..444f86a32452
147+
--- /dev/null
148+
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/17/staticAndModuleKeywordAndAllPackages.pass
149+
@@ -0,0 +1,7 @@
150+
+module
151+
+static
152+
+com
153+
+java
154+
+javax
155+
+org
156+
+sun
157+
diff --git a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask125FeaturesTest.java b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask125FeaturesTest.java
158+
index d019a4b018e6..18a1e371bd96 100644
159+
--- a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask125FeaturesTest.java
160+
+++ b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask125FeaturesTest.java
161+
@@ -19,7 +19,13 @@
162+
163+
package org.netbeans.modules.java.completion;
164+
165+
+import java.util.ArrayList;
166+
+import java.util.List;
167+
+import javax.swing.event.ChangeListener;
168+
import org.netbeans.modules.java.source.parsing.JavacParser;
169+
+import org.netbeans.spi.java.queries.CompilerOptionsQueryImplementation;
170+
+import org.openide.filesystems.FileObject;
171+
+import org.openide.util.lookup.ServiceProvider;
172+
173+
public class JavaCompletionTask125FeaturesTest extends CompletionTestBase {
174+
175+
@@ -41,7 +47,59 @@ public void testCompactSourceFilesEnd() throws Exception {
176+
performTest("CompactSourceFile", 883, null, "compactSourceFilesInsideClass.pass", SOURCE_LEVEL);
177+
}
178+
179+
+ public void testImportModuleKeyword() throws Exception {
180+
+ performTest("Import", 823, "import ", "staticAndModuleKeywordAndAllPackages.pass", SOURCE_LEVEL);
181+
+ }
182+
+
183+
+ public void testImportModuleNoModuleName() throws Exception {
184+
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--limit-modules=java.base,jdk.compiler,jdk.javadoc,jdk.jartool");
185+
+ performTest("Import", 823, "import module ", "importModuleListFull.pass", SOURCE_LEVEL);
186+
+ }
187+
+
188+
+ public void testImportModulePrefix1() throws Exception {
189+
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--limit-modules=java.base,jdk.compiler,jdk.javadoc,jdk.jartool");
190+
+ performTest("Import", 823, "import module jd", "importModuleListFullJDKPrefix.pass", SOURCE_LEVEL);
191+
+ }
192+
+
193+
+ public void testImportModulePrefix2() throws Exception {
194+
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--limit-modules=java.base,jdk.compiler,jdk.javadoc,jdk.jartool");
195+
+ performTest("Import", 823, "import module jdk.", "importModuleListFullJDKPrefix.pass", SOURCE_LEVEL);
196+
+ }
197+
+
198+
+ public void testImportModulePrefix3() throws Exception {
199+
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--limit-modules=java.base,jdk.compiler,jdk.javadoc,jdk.jartool");
200+
+ performTest("Import", 823, "import module jdk.j", "importModuleListFullJDKJPrefix.pass", SOURCE_LEVEL);
201+
+ }
202+
+
203+
+ @Override
204+
+ protected void tearDown() throws Exception {
205+
+ super.tearDown();
206+
+ TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.clear();
207+
+ }
208+
+
209+
static {
210+
JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true;
211+
}
212+
+
213+
+ @ServiceProvider(service = CompilerOptionsQueryImplementation.class, position = 100)
214+
+ public static class TestCompilerOptionsQueryImplementation implements CompilerOptionsQueryImplementation {
215+
+
216+
+ private static final List<String> EXTRA_OPTIONS = new ArrayList<>();
217+
+
218+
+ @Override
219+
+ public CompilerOptionsQueryImplementation.Result getOptions(FileObject file) {
220+
+ return new CompilerOptionsQueryImplementation.Result() {
221+
+ @Override
222+
+ public List<? extends String> getArguments() {
223+
+ return EXTRA_OPTIONS;
224+
+ }
225+
+
226+
+ @Override
227+
+ public void addChangeListener(ChangeListener listener) {}
228+
+
229+
+ @Override
230+
+ public void removeChangeListener(ChangeListener listener) {}
231+
+ };
232+
+ }
233+
+ }
234+
}
235+
diff --git a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTaskBasicTest.java b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTaskBasicTest.java
236+
index 02a163326ed6..1a57584e5e74 100644
237+
--- a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTaskBasicTest.java
238+
+++ b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTaskBasicTest.java
239+
@@ -140,15 +140,15 @@ public void testAfterImportKeyword() throws Exception {
240+
}
241+
242+
public void testEmptyFileBeforeTypingImportedPackage() throws Exception {
243+
- performTest("Empty", 808, "import ", "staticKeywordAndAllPackages.pass");
244+
+ performTest("Empty", 808, "import ", "staticKeywordAndAllPackages.pass", "24"); //24 - without "import module"
245+
}
246+
247+
public void testBeforeTypingImportedPackage() throws Exception {
248+
- performTest("Simple", 823, "import ", "staticKeywordAndAllPackages.pass");
249+
+ performTest("Simple", 823, "import ", "staticKeywordAndAllPackages.pass", "24"); //24 - without "import module"
250+
}
251+
252+
public void testBeforeImportedPackage() throws Exception {
253+
- performTest("Import", 831, null, "staticKeywordAndAllPackages.pass");
254+
+ performTest("Import", 831, null, "staticKeywordAndAllPackages.pass", "24"); //24 - without "import module"
255+
}
256+
257+
public void testEmptyFileTypingImportedPackage() throws Exception {
258+
@@ -264,7 +264,7 @@ public void testEmptyFileTypingImportedPackageAfterErrorInPackageDeclaration() t
259+
}
260+
261+
public void testTypingStaticImportAfterErrorInPackageDeclaration() throws Exception {
262+
- performTest("SimpleNoPackage", 808, "package \nimport ", "staticKeywordAndAllPackages.pass");
263+
+ performTest("SimpleNoPackage", 808, "package \nimport ", "staticKeywordAndAllPackages.pass", "24"); //24 - without "import module"
264+
}
265+
266+
public void TODO_testTypingStaticImportAfterErrorInPreviousImportDeclaration() throws Exception {
267+
diff --git a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
268+
index 83c9aa8bd5fe..99a60193cb78 100644
269+
--- a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
270+
+++ b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
271+
@@ -373,6 +373,7 @@ public Completion createModuleItem(String moduleName, int substitutionOffset) {
272+
.kind(Completion.Kind.Folder)
273+
.sortText(String.format("%04d%s", 1950, moduleName))
274+
.insertTextFormat(Completion.TextFormat.PlainText)
275+
+ .textEdit(new TextEdit(substitutionOffset, offset, moduleName))
276+
.build();
277+
}
278+

patches/8975.diff

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
diff --git a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
2+
index 104440af8673..1be6ade598af 100644
3+
--- a/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
4+
+++ b/java/java.editor.base/src/org/netbeans/modules/java/editor/base/semantic/SemanticHighlighterBase.java
5+
@@ -25,6 +25,7 @@
6+
import com.sun.source.tree.ExportsTree;
7+
import com.sun.source.tree.ExpressionStatementTree;
8+
import com.sun.source.tree.IdentifierTree;
9+
+import com.sun.source.tree.ImportTree;
10+
import com.sun.source.tree.LiteralTree;
11+
import com.sun.source.tree.MemberReferenceTree;
12+
import com.sun.source.tree.MemberSelectTree;
13+
@@ -1052,6 +1053,20 @@ public Void visitLiteral(LiteralTree node, Void p) {
14+
return super.visitLiteral(node, p);
15+
}
16+
17+
+ @Override
18+
+ public Void visitImport(ImportTree node, Void p) {
19+
+ int startPos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), node);
20+
+
21+
+ if (node.isModule()) {
22+
+ tl.moveToOffset(startPos);
23+
+ Token t = firstIdentifierToken("module");// NOI18N
24+
+ if (tl != null) {
25+
+ contextKeywords.add(t);
26+
+ }
27+
+ }
28+
+ return super.visitImport(node, p);
29+
+ }
30+
+
31+
@Override
32+
public Void scan(Tree tree, Void p) {
33+
if (tree != null && tree.getKind() == Kind.YIELD) {
34+
diff --git a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
35+
index 347fb53f37c6..2e30dd7c2fac 100644
36+
--- a/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
37+
+++ b/java/java.editor.base/test/unit/src/org/netbeans/modules/java/editor/base/semantic/DetectorTest.java
38+
@@ -1091,6 +1091,17 @@ private void t(Object o) {
39+
}
40+
41+
+ public void testImportModule() throws Exception {
42+
+ performTest("ImportModuleTest",
43+
+ """
44+
+ import module java.base
45+
+ public class ImportModuleTest {
46+
+ }
47+
+ """,
48+
+ "[KEYWORD], 0:7-0:13",
49+
+ "[PUBLIC, CLASS, DECLARATION], 1:13-1:29");
50+
+ }
51+
+
52+
private void performTest(String fileName) throws Exception {
53+
performTest(fileName, new Performer() {
54+
public void compute(CompilationController parameter, Document doc, final ErrorDescriptionSetter setter) {

0 commit comments

Comments
 (0)