You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ne...@apache.org on 2020/07/30 09:11:02 UTC
[netbeans] branch master updated: [NETBEANS-4311]: Added support
for auto-completion of Java Record
This is an automated email from the ASF dual-hosted git repository.
neilcsmith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 84ed378 [NETBEANS-4311]: Added support for auto-completion of Java Record
new 277ab58 Merge pull request #2222 from arusinha/netbeans-4311
84ed378 is described below
commit 84ed378465d5ece29d5ff47b6f716a1209cedb5f
Author: Arunava Sinha <ar...@oracle.com>
AuthorDate: Mon Jun 29 19:53:29 2020 +0530
[NETBEANS-4311]: Added support for auto-completion of Java Record
---
.../modules/editor/resources/completion/record.png | Bin 0 -> 785 bytes
.../java/completion/JavaCompletionTask.java | 273 +++++++++++++++++++--
.../JavaCompletionTaskTest/1.8/override.pass | 1 +
.../JavaCompletionTaskTest/1.8/record.pass | 1 +
.../1.8/typesRecordLocalMembersAndVars.pass | 8 +
.../1.8/typesRecordStaticMembersAndVars.pass | 8 +
.../14/typesRecordLocalMembersAndVars.pass | 7 +
.../14/typesRecordStaticMembersAndVars.pass | 7 +
.../modules/java/completion/data/Records.java | 34 +++
.../JavaCompletionTask114FeaturesTest.java | 29 +++
.../modules/editor/java/JavaCompletionItem.java | 22 +-
.../netbeans/modules/java/source/TreeShims.java | 9 +
.../refactoring/java/ui/WhereUsedPanel.java | 5 +-
13 files changed, 375 insertions(+), 29 deletions(-)
diff --git a/ide/editor/src/org/netbeans/modules/editor/resources/completion/record.png b/ide/editor/src/org/netbeans/modules/editor/resources/completion/record.png
new file mode 100644
index 0000000..220e6f3
Binary files /dev/null and b/ide/editor/src/org/netbeans/modules/editor/resources/completion/record.png differ
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
index b6bbb7f..ef40212 100644
--- a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
+++ b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java
@@ -199,7 +199,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
private static final String WHILE_KEYWORD = "while"; //NOI18N
private static final String WITH_KEYWORD = "with"; //NOI18N
private static final String YIELD_KEYWORD = "yield"; //NOI18N
-
+ private static final String RECORD_KEYWORD = "record"; //NOI18N
private static final String JAVA_LANG_CLASS = "java.lang.Class"; //NOI18N
private static final String JAVA_LANG_OBJECT = "java.lang.Object"; //NOI18N
private static final String JAVA_LANG_ITERABLE = "java.lang.Iterable"; //NOI18N
@@ -237,9 +237,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
private static final SourceVersion SOURCE_VERSION_RELEASE_10;
private static final SourceVersion SOURCE_VERSION_RELEASE_11;
private static final SourceVersion SOURCE_VERSION_RELEASE_13;
-
+ private static final SourceVersion SOURCE_VERSION_RELEASE_14;
static {
- SourceVersion r10, r11, r13;
+ SourceVersion r10, r11, r13, r14;
try {
r10 = SourceVersion.valueOf("RELEASE_10");
@@ -256,10 +256,16 @@ public final class JavaCompletionTask<T> extends BaseTask {
} catch (IllegalArgumentException ex) {
r13 = null;
}
+ try {
+ r14 = SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ r14 = null;
+ }
SOURCE_VERSION_RELEASE_10 = r10;
SOURCE_VERSION_RELEASE_11 = r11;
SOURCE_VERSION_RELEASE_13 = r13;
+ SOURCE_VERSION_RELEASE_14 = r14;
}
private final ItemFactory<T> itemFactory;
@@ -502,6 +508,8 @@ public final class JavaCompletionTask<T> extends BaseTask {
default:
if (path.getLeaf().getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
insideSwitch(env);
+ } else if (TreeShims.isRecord(path.getLeaf())) {
+ insideRecord(env);
}
break;
}
@@ -726,7 +734,11 @@ public final class JavaCompletionTask<T> extends BaseTask {
addPackages(env, null, false);
}
if (options.contains(Options.ALL_COMPLETION)) {
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE), null);
+ EnumSet<ElementKind> classKinds = EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE);
+ if (isRecordSupported(env)) {
+ classKinds.add(TreeShims.getRecordKind());
+ }
+ addTypes(env, classKinds, null);
} else {
hasAdditionalClasses = true;
}
@@ -748,7 +760,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
int idx = headerText.indexOf('{'); //NOI18N
if (idx >= 0) {
addKeywordsForClassBody(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
addElementCreators(env);
return;
}
@@ -866,7 +878,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
addClassModifiers(env, cls.getModifiers().getFlags());
} else {
addMemberModifiers(env, cls.getModifiers().getFlags(), false);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
}
}
@@ -919,7 +931,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
boolean isLocal = !TreeUtilities.CLASS_TREE_KINDS.contains(parent.getKind());
addMemberModifiers(env, var.getModifiers().getFlags(), isLocal);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
ModifiersTree mods = var.getModifiers();
if (mods.getFlags().isEmpty() && mods.getAnnotations().isEmpty()) {
addElementCreators(env);
@@ -1023,7 +1035,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
switch (lastToken.token().id()) {
case LPAREN:
addMemberModifiers(env, Collections.<Modifier>emptySet(), true);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
case RPAREN:
Tree mthParent = path.getParentPath().getLeaf();
@@ -1062,13 +1074,13 @@ public final class JavaCompletionTask<T> extends BaseTask {
case GTGTGT:
addPrimitiveTypeKeywords(env);
addKeyword(env, VOID_KEYWORD, SPACE, false);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
case COMMA:
switch (state) {
case 3:
addMemberModifiers(env, Collections.<Modifier>emptySet(), true);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
case 4:
if (!options.contains(Options.ALL_COMPLETION) && mth.getBody() != null) {
@@ -1110,7 +1122,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
switch (state) {
case 0:
addMemberModifiers(env, mth.getModifiers().getFlags(), false);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
case 1:
if (((TypeParameterTree) lastTree).getBounds().isEmpty()) {
@@ -1183,10 +1195,10 @@ public final class JavaCompletionTask<T> extends BaseTask {
addClassModifiers(env, m);
} else if (parent.getKind() != Tree.Kind.VARIABLE || grandParent == null || TreeUtilities.CLASS_TREE_KINDS.contains(grandParent.getKind())) {
addMemberModifiers(env, m, false);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
} else if (parent.getKind() == Tree.Kind.VARIABLE && grandParent.getKind() == Tree.Kind.METHOD) {
addMemberModifiers(env, m, true);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
} else {
localResult(env);
addKeywordsForBlock(env);
@@ -1296,7 +1308,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
if (pos >= 0 && pos < offset) {
insideExpression(env, new TreePath(env.getPath(), att.getUnderlyingType()));
} else {
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
}
}
@@ -1452,7 +1464,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
}
}
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
case QUESTION:
addKeyword(env, EXTENDS_KEYWORD, SPACE, false);
@@ -1471,7 +1483,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
String text = env.getController().getText().substring(blockPos, offset);
if (text.indexOf('{') < 0) { //NOI18N
addMemberModifiers(env, Collections.singleton(STATIC), false);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
return;
}
StatementTree last = null;
@@ -1592,9 +1604,11 @@ public final class JavaCompletionTask<T> extends BaseTask {
break;
case LT:
case COMMA:
+ addClassTypes(env, null);
+ break;
case EXTENDS:
case SUPER:
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
}
} else if (lastNonWhitespaceTokenId != JavaTokenId.STAR) {
@@ -1922,7 +1936,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
break;
case LT:
case COMMA:
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
break;
}
}
@@ -1941,7 +1955,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
case COMMA:
if (let.getParameters().isEmpty()
|| env.getController().getTrees().getSourcePositions().getStartPosition(path.getCompilationUnit(), let.getParameters().get(0).getType()) >= 0) {
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
addPrimitiveTypeKeywords(env);
addKeyword(env, FINAL_KEYWORD, SPACE, false);
}
@@ -1984,7 +1998,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
addLocalMembersAndVars(env);
addValueKeywords(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env,null);
addPrimitiveTypeKeywords(env);
}
@@ -2057,7 +2071,11 @@ public final class JavaCompletionTask<T> extends BaseTask {
env.insideNew();
}
if (encl == null) {
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE), base);
+ EnumSet<ElementKind> classKinds = EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE);
+ if (isRecordSupported(env)) {
+ classKinds.add(TreeShims.getRecordKind());
+ }
+ addTypes(env, classKinds, base);
} else {
TypeMirror enclType = controller.getTrees().getTypeMirror(new TreePath(path, nc.getEnclosingExpression()));
if (enclType != null && enclType.getKind() == TypeKind.DECLARED) {
@@ -2074,7 +2092,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
addLocalMembersAndVars(env);
addValueKeywords(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env,null);
addPrimitiveTypeKeywords(env);
break;
case GT:
@@ -2241,7 +2259,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(env, fl, offset);
if (last != null && last.token().id() == JavaTokenId.LPAREN) {
addLocalFieldsAndVars(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env,null);
addPrimitiveTypeKeywords(env);
}
} else {
@@ -2471,7 +2489,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
}
addLocalMembersAndVars(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env,null);
addPrimitiveTypeKeywords(env);
addValueKeywords(env);
} else {
@@ -2483,7 +2501,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
InstanceOfTree iot = (InstanceOfTree) env.getPath().getLeaf();
TokenSequence<JavaTokenId> ts = findLastNonWhitespaceToken(env, iot, env.getOffset());
if (ts != null && ts.token().id() == JavaTokenId.INSTANCEOF) {
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
}
}
@@ -3008,10 +3026,193 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
}
}
+
+ private void addClassTypes(final Env env, DeclaredType baseType) throws IOException{
+ EnumSet<ElementKind> classKinds = EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER);
+ if (isRecordSupported(env)) {
+ classKinds.add(TreeShims.getRecordKind());
+ }
+ addTypes(env, classKinds, baseType);
+ }
+
+ private boolean isRecordSupported(final Env env) {
+ return (SOURCE_VERSION_RELEASE_14 != null && env.getController().getSourceVersion().compareTo(SOURCE_VERSION_RELEASE_14) >= 0);
+ }
+
+ private void insideRecord(Env env) throws IOException {
+ int offset = env.getOffset();
+ env.insideClass();
+ TreePath path = env.getPath();
+ ClassTree cls = (ClassTree) path.getLeaf();
+ CompilationController controller = env.getController();
+ SourcePositions sourcePositions = env.getSourcePositions();
+ CompilationUnitTree root = env.getRoot();
+ int startPos = (int) sourcePositions.getEndPosition(root, cls.getModifiers());
+ if (startPos <= 0) {
+ startPos = (int) sourcePositions.getStartPosition(root, cls);
+ }
+ String headerText = controller.getText().substring(startPos, offset);
+ int idx = headerText.indexOf('{'); //NOI18N
+ if (idx >= 0) {
+ addKeywordsForClassBody(env);
+ addClassTypes(env, null);
+ addElementCreators(env);
+ return;
+ }
+ TreeUtilities tu = controller.getTreeUtilities();
+ Tree lastImpl = null;
+ for (Tree impl : cls.getImplementsClause()) {
+ int implPos = (int) sourcePositions.getEndPosition(root, impl);
+ if (implPos == Diagnostic.NOPOS || offset <= implPos) {
+ break;
+ }
+ lastImpl = impl;
+ startPos = implPos;
+ }
+ if (lastImpl != null) {
+ TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(env, startPos, offset);
+ if (last != null && last.token().id() == JavaTokenId.COMMA) {
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, EnumSet.of(INTERFACE, ANNOTATION_TYPE), null);
+ }
+ return;
+ }
+ List<? extends Tree> members = cls.getMembers();
+
+ Tree lastParam = null;
+ for (Tree member : members) {
+ if (member.getKind() == Tree.Kind.VARIABLE) {
+ ModifiersTree modifiers = ((VariableTree) member).getModifiers();
+ Set<Modifier> modifierSet = modifiers.getFlags();
+
+ if (!modifierSet.contains(Modifier.STATIC)) {
+ int paramPos = (int) sourcePositions.getEndPosition(root, member);
+ if (paramPos == Diagnostic.NOPOS || offset <= paramPos) {
+ break;
+ }
+ lastParam = member;
+ startPos = paramPos;
+ }
+ }
+
+ if (lastParam != null) {
+ TokenSequence<JavaTokenId> first = findFirstNonWhitespaceToken(env, startPos, offset);
+ if (first != null && first.token().id() == JavaTokenId.COMMA) {
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, EnumSet.of(INTERFACE, ANNOTATION_TYPE), null);
+ return;
+ }
+ if (first != null && first.token().id() == JavaTokenId.RPAREN) {
+ first = nextNonWhitespaceToken(first);
+ if (!tu.isInterface(cls) && first.token().id() == JavaTokenId.LBRACE) {
+ addKeyword(env, IMPLEMENTS_KEYWORD, SPACE, false);
+ }
+
+ }
+ return;
+ }
+
+ }
+
+ TypeParameterTree lastTypeParam = null;
+ for (TypeParameterTree tp : cls.getTypeParameters()) {
+ int tpPos = (int) sourcePositions.getEndPosition(root, tp);
+ if (tpPos == Diagnostic.NOPOS || offset <= tpPos) {
+ break;
+ }
+ lastTypeParam = tp;
+ startPos = tpPos;
+ }
+
+ TokenSequence<JavaTokenId> lastNonWhitespaceToken = findLastNonWhitespaceToken(env, startPos, offset);
+ if (lastNonWhitespaceToken != null) {
+ switch (lastNonWhitespaceToken.token().id()) {
+ case LPAREN:
+ addMemberModifiers(env, Collections.<Modifier>emptySet(), true);
+ addClassTypes(env, null);
+ break;
+ case IMPLEMENTS:
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, EnumSet.of(INTERFACE, ANNOTATION_TYPE), null);
+ break;
+ case RPAREN:
+ if (!tu.isAnnotation(cls)) {
+ if (!tu.isInterface(cls)) {
+ addKeyword(env, IMPLEMENTS_KEYWORD, SPACE, false);
+ }
+ }
+ break;
+ }
+ return;
+ }
+
+ if (lastTypeParam != null) {
+ TokenSequence<JavaTokenId> first = findFirstNonWhitespaceToken(env, startPos, offset);
+
+ if (first != null && (first.token().id() == JavaTokenId.GT
+ || first.token().id() == JavaTokenId.GTGT
+ || first.token().id() == JavaTokenId.GTGTGT)) {
+ first = nextNonWhitespaceToken(first);
+
+ TokenSequence<JavaTokenId> last = findLastNonWhitespaceToken(env, first.offset(), offset);
+ TokenSequence<JavaTokenId> old = first;
+ first = nextNonWhitespaceToken(first);
+ if (last != null && first.token().id() == last.token().id()) {
+ first = nextNonWhitespaceToken(first);
+ } else {
+ first = old;
+ }
+
+ if (first != null && first.offset() < offset) {
+ if (first.token().id() == JavaTokenId.EXTENDS) {
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.afterExtends();
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, tu.isInterface(cls) ? EnumSet.of(INTERFACE, ANNOTATION_TYPE) : EnumSet.of(CLASS), null);
+ return;
+ }
+ if (first.token().id() == JavaTokenId.IMPLEMENTS) {
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, EnumSet.of(INTERFACE, ANNOTATION_TYPE), null);
+ return;
+ }
+ } else if (!tu.isAnnotation(cls)) {
+
+ if (!tu.isInterface(cls) && first.token().id() == JavaTokenId.LBRACE) {
+ addKeyword(env, IMPLEMENTS_KEYWORD, SPACE, false);
+ } else if (!tu.isInterface(cls) && first.token().id() == JavaTokenId.RPAREN) {
+ controller.toPhase(Phase.ELEMENTS_RESOLVED);
+ env.addToExcludes(controller.getTrees().getElement(path));
+ addTypes(env, EnumSet.of(INTERFACE, ANNOTATION_TYPE), null);
+ }
+ return;
+ }
+ } else if (lastTypeParam.getBounds().isEmpty()) {
+ addKeyword(env, EXTENDS_KEYWORD, SPACE, false);
+ }
+ return;
+ }
+
+ lastNonWhitespaceToken = findLastNonWhitespaceToken(env, (int) sourcePositions.getStartPosition(root, cls), offset);
+ if (lastNonWhitespaceToken != null && lastNonWhitespaceToken.token().id() == JavaTokenId.AT) {
+ addKeyword(env, INTERFACE_KEYWORD, SPACE, false);
+ addTypes(env, EnumSet.of(ANNOTATION_TYPE), null);
+ } else if (path.getParentPath().getLeaf().getKind() == Tree.Kind.COMPILATION_UNIT) {
+ addClassModifiers(env, cls.getModifiers().getFlags());
+ } else {
+ addMemberModifiers(env, cls.getModifiers().getFlags(), false);
+ addClassTypes(env, null);
+ }
+
+ }
private void localResult(Env env) throws IOException {
addLocalMembersAndVars(env);
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
addPrimitiveTypeKeywords(env);
}
@@ -3092,7 +3293,7 @@ public final class JavaCompletionTask<T> extends BaseTask {
break;
}
}
- addTypes(env, EnumSet.of(CLASS, INTERFACE, ENUM, ANNOTATION_TYPE, TYPE_PARAMETER), null);
+ addClassTypes(env, null);
}
private void addLocalMembersAndVars(final Env env) throws IOException {
@@ -3793,6 +3994,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
}
private void addPackageContent(final Env env, PackageElement pe, EnumSet<ElementKind> kinds, DeclaredType baseType, boolean insideNew, boolean srcOnly) throws IOException {
+ if (isRecordSupported(env)) {
+ kinds.add(TreeShims.getRecordKind());
+ }
Set<? extends TypeMirror> smartTypes = options.contains(Options.ALL_COMPLETION) ? null : getSmartTypes(env);
CompilationController controller = env.getController();
Elements elements = controller.getElements();
@@ -4306,6 +4510,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
kws.add(ENUM_KEYWORD);
kws.add(FINAL_KEYWORD);
kws.add(INTERFACE_KEYWORD);
+ if (isRecordSupported(env)) {
+ kws.add(RECORD_KEYWORD);
+ }
}
boolean beforeAnyClass = true;
boolean beforePublicClass = true;
@@ -4374,6 +4581,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
&& env.getController().getTreeUtilities().getPathElementOfKind(Tree.Kind.INTERFACE, env.getPath()) != null) {
results.add(itemFactory.createKeywordItem(DEFAULT_KEYWORD, SPACE, anchorOffset, false));
}
+ if (isRecordSupported(env)) {
+ results.add(itemFactory.createKeywordItem(RECORD_KEYWORD, SPACE, anchorOffset, false));
+ }
addPrimitiveTypeKeywords(env);
}
@@ -4389,6 +4599,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
results.add(itemFactory.createKeywordItem(kw, SPACE, anchorOffset, false));
}
}
+ if (isRecordSupported(env)) {
+ results.add(itemFactory.createKeywordItem(RECORD_KEYWORD, SPACE, anchorOffset, false));
+ }
if (Utilities.startsWith(RETURN_KEYWORD, prefix)) {
TreePath tp = env.getController().getTreeUtilities().getPathElementOfKind(EnumSet.of(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION), env.getPath());
String postfix = SPACE;
@@ -4573,6 +4786,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
kws.add(CLASS_KEYWORD);
kws.add(INTERFACE_KEYWORD);
kws.add(ENUM_KEYWORD);
+ if (isRecordSupported(env)) {
+ kws.add(RECORD_KEYWORD);
+ }
for (String kw : kws) {
if (Utilities.startsWith(kw, prefix)) {
results.add(itemFactory.createKeywordItem(kw, SPACE, anchorOffset, false));
@@ -4627,6 +4843,9 @@ public final class JavaCompletionTask<T> extends BaseTask {
kws.add(CLASS_KEYWORD);
kws.add(INTERFACE_KEYWORD);
kws.add(ENUM_KEYWORD);
+ if (isRecordSupported(env)) {
+ kws.add(RECORD_KEYWORD);
+ }
}
for (String kw : kws) {
if (Utilities.startsWith(kw, prefix)) {
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/override.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/override.pass
new file mode 100644
index 0000000..be68102
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/override.pass
@@ -0,0 +1 @@
+Override
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/record.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/record.pass
new file mode 100644
index 0000000..d4141f0
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/record.pass
@@ -0,0 +1 @@
+record
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordLocalMembersAndVars.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordLocalMembersAndVars.pass
new file mode 100644
index 0000000..7bc4924
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordLocalMembersAndVars.pass
@@ -0,0 +1,8 @@
+R
+R1
+Readable
+ReflectiveOperationException
+Runnable
+Runtime
+RuntimeException
+RuntimePermission
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordStaticMembersAndVars.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordStaticMembersAndVars.pass
new file mode 100644
index 0000000..7bc4924
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/typesRecordStaticMembersAndVars.pass
@@ -0,0 +1,8 @@
+R
+R1
+Readable
+ReflectiveOperationException
+Runnable
+Runtime
+RuntimeException
+RuntimePermission
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordLocalMembersAndVars.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordLocalMembersAndVars.pass
new file mode 100644
index 0000000..6acc0ac
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordLocalMembersAndVars.pass
@@ -0,0 +1,7 @@
+Readable
+Record
+ReflectiveOperationException
+Runnable
+Runtime
+RuntimeException
+RuntimePermission
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordStaticMembersAndVars.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordStaticMembersAndVars.pass
new file mode 100644
index 0000000..6acc0ac
--- /dev/null
+++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/14/typesRecordStaticMembersAndVars.pass
@@ -0,0 +1,7 @@
+Readable
+Record
+ReflectiveOperationException
+Runnable
+Runtime
+RuntimeException
+RuntimePermission
\ No newline at end of file
diff --git a/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Records.java b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Records.java
new file mode 100644
index 0000000..e1cb7ae
--- /dev/null
+++ b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Records.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package test;
+
+public class Test {
+
+ public record Records <R extends Number, R1 > ( ) {
+
+ public static
+}
+
+ public static void main(String args )
+ {
+ record Record1(@Ov ) {}
+
+ record Rec( ) {}
+ }
+ }
diff --git a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask114FeaturesTest.java b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask114FeaturesTest.java
index 1f4b212..4cdfe27 100644
--- a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask114FeaturesTest.java
+++ b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask114FeaturesTest.java
@@ -48,7 +48,36 @@ public class JavaCompletionTask114FeaturesTest extends CompletionTestBase {
public void testBindingUse() throws Exception {
performTest("GenericMethodInvocation", 1231, "boolean b = argO instanceof String str && st", "BindingUse.pass", SOURCE_LEVEL);
}
+
+ public void testBeforeLeftRecordBraces() throws Exception {
+ performTest("Records", 896, null, "implementsKeyword.pass", SOURCE_LEVEL);
+ }
+
+ public void testBeforeRecParamsLeftParen() throws Exception {
+ performTest("Records", 892, null, "empty.pass", SOURCE_LEVEL);
+ }
+
+ public void testInsideRecParams() throws Exception {
+ performTest("Records", 894, "R", "typesRecordLocalMembersAndVars.pass", SOURCE_LEVEL);
+ }
+
+ public void testAfterTypeParamInRecParam() throws Exception {
+ performTest("Records", 890, null, "extendsKeyword.pass", SOURCE_LEVEL);
+ }
+
+ public void testInsideRecAfterStaticKeyWord() throws Exception {
+ performTest("Records", 918, "R", "typesRecordStaticMembersAndVars.pass", SOURCE_LEVEL);
+ }
+
+ public void testAnnotationInRecordParam() throws Exception {
+ performTest("Records", 999, null, "override.pass", SOURCE_LEVEL);
+ }
+
+ public void testRecordKeywordInsideClass() throws Exception {
+ performTest("Records", 1014, "rec", "record.pass", SOURCE_LEVEL);
+ }
+
public void noop() {
}
diff --git a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
index 39c1387..181e5e0 100644
--- a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
+++ b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionItem.java
@@ -120,7 +120,9 @@ public abstract class JavaCompletionItem implements CompletionItem {
case ANNOTATION_TYPE:
return new AnnotationTypeItem(info, elem, type, 0, substitutionOffset, referencesCount, isDeprecated, insideNew, addSimpleName, smartType, autoImportEnclosingType, whiteList);
default:
- throw new IllegalArgumentException("kind=" + elem.getKind());
+ if(elem.getKind().name().equals(TreeShims.RECORD))
+ return new RecordItem(info, elem, type, 0, substitutionOffset, referencesCount, isDeprecated, insideNew, addSimpleName, smartType, autoImportEnclosingType, whiteList);
+ else throw new IllegalArgumentException("kind=" + elem.getKind());
}
}
@@ -1313,7 +1315,25 @@ public abstract class JavaCompletionItem implements CompletionItem {
return icon;
}
}
+
+ static class RecordItem extends ClassItem {
+
+ private static final String RECORD = "org/netbeans/modules/editor/resources/completion/record.png"; // NOI18N
+ private static ImageIcon icon;
+ private RecordItem(CompilationInfo info, TypeElement elem, DeclaredType type, int dim, int substitutionOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean insideNew, boolean addSimpleName, boolean smartType, boolean autoImport, WhiteListQuery.WhiteList whiteList) {
+ super(info, elem, type, dim, substitutionOffset, referencesCount, isDeprecated, insideNew, false, addSimpleName, smartType, autoImport, whiteList);
+ }
+
+ @Override
+ protected ImageIcon getBaseIcon() {
+ if (icon == null) {
+ icon = ImageUtilities.loadImageIcon(RECORD, false);
+ }
+ return icon;
+ }
+ }
+
static class AnnotationTypeItem extends ClassItem {
private static final String ANNOTATION = "org/netbeans/modules/editor/resources/completion/annotation_type.png"; // NOI18N
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
index 5e7b042..88504aa 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
@@ -228,4 +228,13 @@ public class TreeShims {
public static boolean isRecordComponent(ElementKind kind) {
return "RECORD_COMPONENT".equals(kind.name());
}
+
+ public static ElementKind getRecordKind() {
+ try {
+ return ElementKind.valueOf(RECORD); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ return null;
+ }
+ }
+
}
diff --git a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/WhereUsedPanel.java b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/WhereUsedPanel.java
index 2540b8e..583ac8d 100644
--- a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/WhereUsedPanel.java
+++ b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/WhereUsedPanel.java
@@ -86,7 +86,10 @@ public class WhereUsedPanel extends JPanel implements CustomRefactoringPanel {
case FIELD:
case ENUM_CONSTANT:
default: {
- panel = new WhereUsedPanelVariable(parent);
+ if (kind.name().equals("RECORD")) // NOI18N
+ panel = new WhereUsedPanelClass(parent);
+ else
+ panel = new WhereUsedPanelVariable(parent);
break;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists