diff --git a/java/java.source.base/src/org/netbeans/api/java/source/TreeUtilities.java b/java/java.source.base/src/org/netbeans/api/java/source/TreeUtilities.java index cb4ab8b2833a..1bce54979aa4 100644 --- a/java/java.source.base/src/org/netbeans/api/java/source/TreeUtilities.java +++ b/java/java.source.base/src/org/netbeans/api/java/source/TreeUtilities.java @@ -79,7 +79,6 @@ import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCLambda; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.JCTree.Tag; import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.Log; import java.lang.reflect.Method; @@ -89,6 +88,7 @@ import org.netbeans.api.java.lexer.JavaTokenId; import org.netbeans.api.java.lexer.JavadocTokenId; import org.netbeans.api.java.source.JavaSource.Phase; +import org.netbeans.api.lexer.Token; import org.netbeans.api.lexer.TokenSequence; import org.netbeans.lib.nbjavac.services.NBAttr; import org.netbeans.lib.nbjavac.services.NBResolve; @@ -108,11 +108,42 @@ public final class TreeUtilities { private static final Logger LOG = Logger.getLogger(TreeUtilities.class.getName()); - /**{@link Kind}s that are represented by {@link ClassTree}. + /** + * {@link Kind}s that are represented by {@link ClassTree}. * * @since 0.67 */ - public static final Set CLASS_TREE_KINDS = EnumSet.of(Kind.ANNOTATION_TYPE, Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.RECORD); + public static final Set CLASS_TREE_KINDS = Collections.unmodifiableSet(EnumSet.of( + Kind.ANNOTATION_TYPE, + Kind.CLASS, + Kind.ENUM, + Kind.INTERFACE, + Kind.RECORD + )); + + private static final Set SPAN_COMMENT_TOKENS = EnumSet.of( + JavaTokenId.DOT, + JavaTokenId.WHITESPACE, + JavaTokenId.BLOCK_COMMENT, + JavaTokenId.LINE_COMMENT, + JavaTokenId.JAVADOC_COMMENT + ); + + private static final Set SPAN_CLASS_TOKENS = EnumSet.of( + JavaTokenId.CLASS, + JavaTokenId.INTERFACE, + JavaTokenId.ENUM, + JavaTokenId.AT, + JavaTokenId.WHITESPACE, + JavaTokenId.BLOCK_COMMENT, + JavaTokenId.LINE_COMMENT, + JavaTokenId.JAVADOC_COMMENT + ); + + private static final Set SPAN_CLASS_IDENTIFIERS = Set.of( + "record" + ); + private final CompilationInfo info; private final CommentHandlerService handler; @@ -379,6 +410,7 @@ public TreePath pathFor(TreePath path, int pos) { return pathFor(path, pos, info.getTrees().getSourcePositions()); } + @SuppressWarnings("AssignmentToMethodParameter") public TreePath pathFor(TreePath path, int pos, SourcePositions sourcePositions) { if (info == null || path == null || sourcePositions == null) throw new IllegalArgumentException(); @@ -392,13 +424,14 @@ class Result extends Error { class PathFinder extends ErrorAwareTreePathScanner { private int pos; - private SourcePositions sourcePositions; + private final SourcePositions sourcePositions; private PathFinder(int pos, SourcePositions sourcePositions) { this.pos = pos; this.sourcePositions = sourcePositions; } + @Override public Void scan(Tree tree, Void p) { if (tree != null) { CompilationUnitTree cut = getCurrentPath().getCompilationUnit(); @@ -585,14 +618,15 @@ class Result extends Error { } class PathFinder extends DocTreePathScanner { - private int pos; - private DocSourcePositions sourcePositions; + private final int pos; + private final DocSourcePositions sourcePositions; private PathFinder(int pos, DocSourcePositions sourcePositions) { this.pos = pos; this.sourcePositions = sourcePositions; } + @Override public Void scan(DocTree tree, TreePath p) { if (tree != null) { if (sourcePositions.getStartPosition(p.getCompilationUnit(), getCurrentPath().getDocComment(), tree) < pos && sourcePositions.getEndPosition(p.getCompilationUnit(), getCurrentPath().getDocComment(), tree) >= pos) { @@ -748,9 +782,9 @@ private static T doParse(JavacTaskImpl task, String text, Sourc CharBuffer buf = CharBuffer.wrap((text+"\u0000").toCharArray(), 0, text.length()); ParserFactory factory = ParserFactory.instance(context); Parser parser = factory.newParser(buf, false, true, false, false); - if (parser instanceof JavacParser) { + if (parser instanceof JavacParser javacParser) { if (sourcePositions != null) - sourcePositions[0] = new ParserSourcePositions((JavacParser)parser, offset); + sourcePositions[0] = new ParserSourcePositions(javacParser, offset); return actualParse.apply(parser); } return null; @@ -785,10 +819,12 @@ private ParserSourcePositions(JavacParser parser, int offset) { this.offset = offset; } + @Override public long getStartPosition(CompilationUnitTree file, Tree tree) { return parser.getStartPos((JCTree)tree) - offset; } + @Override public long getEndPosition(CompilationUnitTree file, Tree tree) { return parser.getEndPos((JCTree)tree) - offset; } @@ -864,12 +900,12 @@ public Scope toScopeWithDisabledAccessibilityChecks(Scope scope) { } private static Env getEnv(Scope scope) { - if (scope instanceof NBScope) { - scope = ((NBScope) scope).delegate; + if (scope instanceof NBScope nbScope) { + scope = nbScope.delegate; } - if (scope instanceof HackScope) { - return ((HackScope) scope).getEnv(); + if (scope instanceof HackScope hackScope) { + return hackScope.getEnv(); } return ((JavacScope) scope).getEnv(); @@ -1142,7 +1178,7 @@ public int[] findBodySpan(ClassTree clazz) { * @since 0.25 */ public int[] findNameSpan(ClassTree clazz) { - return findNameSpan(clazz.getSimpleName().toString(), clazz, JavaTokenId.CLASS, JavaTokenId.INTERFACE, JavaTokenId.ENUM, JavaTokenId.AT, JavaTokenId.WHITESPACE, JavaTokenId.BLOCK_COMMENT, JavaTokenId.LINE_COMMENT, JavaTokenId.JAVADOC_COMMENT); + return findNameSpan(clazz.getSimpleName().toString(), clazz, SPAN_CLASS_TOKENS, SPAN_CLASS_IDENTIFIERS); } /**Find span of the {@link MethodTree#getName()} identifier in the source. @@ -1297,7 +1333,7 @@ public int[] findNameSpan(ContinueTree cont) { * @since 0.25 */ public int[] findNameSpan(MemberSelectTree mst) { - return findNameSpan(mst.getIdentifier().toString(), mst, JavaTokenId.DOT, JavaTokenId.WHITESPACE, JavaTokenId.BLOCK_COMMENT, JavaTokenId.LINE_COMMENT, JavaTokenId.JAVADOC_COMMENT); + return findNameSpan(mst.getIdentifier().toString(), mst, SPAN_COMMENT_TOKENS, Set.of()); } /**Find span of the {@link MemberReferenceTree#getName()} identifier in the source. @@ -1310,7 +1346,7 @@ public int[] findNameSpan(MemberSelectTree mst) { * @since 0.124 */ public int[] findNameSpan(MemberReferenceTree mst) { - return findNameSpan(mst.getName().toString(), mst, JavaTokenId.DOT, JavaTokenId.WHITESPACE, JavaTokenId.BLOCK_COMMENT, JavaTokenId.LINE_COMMENT, JavaTokenId.JAVADOC_COMMENT); + return findNameSpan(mst.getName().toString(), mst, SPAN_COMMENT_TOKENS, Set.of()); } /**Find span of the name in the DocTree's reference tree (see {@link #getReferenceName(com.sun.source.util.DocTreePath)} @@ -1366,32 +1402,38 @@ public int[] findNameSpan(DocCommentTree docTree, ReferenceTree ref) { return null; } - - private int[] findNameSpan(String name, Tree t, JavaTokenId... allowedTokens) { + + private int[] findNameSpan(String name, Tree tree) { + return findNameSpan(name, tree, Set.of(), Set.of()); + } + + @SuppressWarnings("NestedAssignment") + private int[] findNameSpan(String name, Tree tree, Set allowedTokens, Set allowedIdentifiers) { if (!SourceVersion.isIdentifier(name)) { //names like "", etc. return null; } - JCTree jcTree = (JCTree) t; + JCTree jcTree = (JCTree) tree; int pos = jcTree.pos; if (pos < 0) return null; - Set allowedTokensSet = EnumSet.noneOf(JavaTokenId.class); - - allowedTokensSet.addAll(Arrays.asList(allowedTokens)); - TokenSequence tokenSequence = info.getTokenHierarchy().tokenSequence(JavaTokenId.language()); - tokenSequence.move(pos); boolean wasNext; - while ((wasNext = tokenSequence.moveNext()) && allowedTokensSet.contains(tokenSequence.token().id())) - ; - + while (wasNext = tokenSequence.moveNext()) { + Token t = tokenSequence.token(); + if (!allowedTokens.contains(t.id()) + && ((allowedIdentifiers.isEmpty() || t.id() != JavaTokenId.IDENTIFIER) + || !allowedIdentifiers.contains(t.text().toString()))) { + break; + } + } + if (wasNext) { if (tokenSequence.token().id() == JavaTokenId.IDENTIFIER) { boolean nameMatches; @@ -1620,33 +1662,24 @@ public StatementTree getBreakContinueTarget(TreePath breakOrContinue) throws Ill } } - static Set EXOTIC_ESCAPE = new HashSet( - Arrays.asList('!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', - ':', '=', '?', '@', '^', '_', '`', '{', '|', '}') + static final Set EXOTIC_ESCAPE = Set.of( + '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', + ':', '=', '?', '@', '^', '_', '`', '{', '|', '}' ); - private static final Map ESCAPE_UNENCODE; - private static final Map ESCAPE_ENCODE; - - static { - Map unencode = new HashMap(); - - unencode.put('n', '\n'); - unencode.put('t', '\t'); - unencode.put('b', '\b'); - unencode.put('r', '\r'); - - ESCAPE_UNENCODE = Collections.unmodifiableMap(unencode); - - Map encode = new HashMap(); - - encode.put('\n', 'n'); - encode.put('\t', 't'); - encode.put('\b', 'b'); - encode.put('\r', 'r'); + private static final Map ESCAPE_UNENCODE = Map.of( + 'n', '\n', + 't', '\t', + 'b', '\b', + 'r', '\r' + ); - ESCAPE_ENCODE = Collections.unmodifiableMap(encode); - } + private static final Map ESCAPE_ENCODE = Map.of( + '\n', 'n', + '\t', 't', + '\b', 'b', + '\r', 'r' + ); /**Returns new tree based on {@code original}, such that each visited subtree * that occurs as a key in {@code original2Translated} is replaced by the corresponding @@ -1795,6 +1828,7 @@ private UncaughtExceptionsVisitor(final CompilationInfo info) { this.info = info; } + @Override public Void visitMethodInvocation(MethodInvocationTree node, Set p) { super.visitMethodInvocation(node, p); Element el = info.getTrees().getElement(getCurrentPath()); @@ -1803,6 +1837,7 @@ public Void visitMethodInvocation(MethodInvocationTree node, Set p) return null; } + @Override public Void visitNewClass(NewClassTree node, Set p) { super.visitNewClass(node, p); Element el = info.getTrees().getElement(getCurrentPath()); @@ -1811,6 +1846,7 @@ public Void visitNewClass(NewClassTree node, Set p) { return null; } + @Override public Void visitThrow(ThrowTree node, Set p) { super.visitThrow(node, p); TypeMirror tm = info.getTrees().getTypeMirror(new TreePath(getCurrentPath(), node.getExpression())); @@ -1823,6 +1859,7 @@ else if (tm.getKind() == TypeKind.UNION) return null; } + @Override public Void visitTry(TryTree node, Set p) { Set s = new LinkedHashSet(); Trees trees = info.getTrees(); @@ -1867,6 +1904,7 @@ public Void visitTry(TryTree node, Set p) { return null; } + @Override public Void visitMethod(MethodTree node, Set p) { Set s = new LinkedHashSet(); scan(node.getBody(), s); @@ -1895,8 +1933,8 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Set p) private static class UnrelatedTypeMirrorSet extends AbstractSet { - private Types types; - private LinkedList list = new LinkedList(); + private final Types types; + private final LinkedList list = new LinkedList<>(); public UnrelatedTypeMirrorSet(Types types) { this.types = types; diff --git a/java/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java b/java/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java index 721432b57d5e..517bb856c12b 100644 --- a/java/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java +++ b/java/spi.java.hints/src/org/netbeans/spi/java/hints/ErrorDescriptionFactory.java @@ -49,8 +49,6 @@ import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.java.source.CompilationInfo; import org.netbeans.api.java.source.GeneratorUtilities; -import org.netbeans.api.java.source.JavaSource; -import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.TreePathHandle; import org.netbeans.api.java.source.WorkingCopy; import org.netbeans.api.lexer.TokenSequence; @@ -172,7 +170,7 @@ private static int[] computeNameSpan(Tree tree, HintContext context) { case METHOD -> { return info.getTreeUtilities().findNameSpan((MethodTree) tree); } - case ANNOTATION_TYPE, CLASS, ENUM, INTERFACE -> { + case ANNOTATION_TYPE, CLASS, ENUM, RECORD, INTERFACE -> { return info.getTreeUtilities().findNameSpan((ClassTree) tree); } case VARIABLE -> { @@ -488,6 +486,7 @@ public String getText() { return NbBundle.getMessage(ErrorDescriptionFactory.class, "LBL_FIX_Suppress_Waning", keyNames.toString() ); // NOI18N } + @Override public void performRewrite(TransformationContext ctx) throws IOException { WorkingCopy copy = ctx.getWorkingCopy(); TreePath path = ctx.getPath();