Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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<Kind> CLASS_TREE_KINDS = EnumSet.of(Kind.ANNOTATION_TYPE, Kind.CLASS, Kind.ENUM, Kind.INTERFACE, Kind.RECORD);
public static final Set<Kind> CLASS_TREE_KINDS = Collections.unmodifiableSet(EnumSet.of(
Kind.ANNOTATION_TYPE,
Kind.CLASS,
Kind.ENUM,
Kind.INTERFACE,
Kind.RECORD
));

private static final Set<JavaTokenId> SPAN_COMMENT_TOKENS = EnumSet.of(
JavaTokenId.DOT,
JavaTokenId.WHITESPACE,
JavaTokenId.BLOCK_COMMENT,
JavaTokenId.LINE_COMMENT,
JavaTokenId.JAVADOC_COMMENT
);

private static final Set<JavaTokenId> 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<String> SPAN_CLASS_IDENTIFIERS = Set.of(
"record"
);

private final CompilationInfo info;
private final CommentHandlerService handler;

Expand Down Expand Up @@ -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();
Expand All @@ -392,13 +424,14 @@ class Result extends Error {

class PathFinder extends ErrorAwareTreePathScanner<Void,Void> {
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();
Expand Down Expand Up @@ -585,14 +618,15 @@ class Result extends Error {
}

class PathFinder extends DocTreePathScanner<Void,TreePath> {
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) {
Expand Down Expand Up @@ -748,9 +782,9 @@ private static <T extends Tree> 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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -864,12 +900,12 @@ public Scope toScopeWithDisabledAccessibilityChecks(Scope scope) {
}

private static Env<AttrContext> 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();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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)}
Expand Down Expand Up @@ -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<JavaTokenId> allowedTokens, Set<String> allowedIdentifiers) {
if (!SourceVersion.isIdentifier(name)) {
//names like "<error>", etc.
return null;
}

JCTree jcTree = (JCTree) t;
JCTree jcTree = (JCTree) tree;
int pos = jcTree.pos;

if (pos < 0)
return null;

Set<JavaTokenId> allowedTokensSet = EnumSet.noneOf(JavaTokenId.class);

allowedTokensSet.addAll(Arrays.asList(allowedTokens));

TokenSequence<JavaTokenId> 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<JavaTokenId> 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;
Expand Down Expand Up @@ -1620,33 +1662,24 @@ public StatementTree getBreakContinueTarget(TreePath breakOrContinue) throws Ill
}
}

static Set<Character> EXOTIC_ESCAPE = new HashSet<Character>(
Arrays.<Character>asList('!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-',
':', '=', '?', '@', '^', '_', '`', '{', '|', '}')
static final Set<Character> EXOTIC_ESCAPE = Set.of(
'!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-',
':', '=', '?', '@', '^', '_', '`', '{', '|', '}'
);

private static final Map<Character, Character> ESCAPE_UNENCODE;
private static final Map<Character, Character> ESCAPE_ENCODE;

static {
Map<Character, Character> unencode = new HashMap<Character, Character>();

unencode.put('n', '\n');
unencode.put('t', '\t');
unencode.put('b', '\b');
unencode.put('r', '\r');

ESCAPE_UNENCODE = Collections.unmodifiableMap(unencode);

Map<Character, Character> encode = new HashMap<Character, Character>();

encode.put('\n', 'n');
encode.put('\t', 't');
encode.put('\b', 'b');
encode.put('\r', 'r');
private static final Map<Character, Character> ESCAPE_UNENCODE = Map.of(
'n', '\n',
't', '\t',
'b', '\b',
'r', '\r'
);

ESCAPE_ENCODE = Collections.unmodifiableMap(encode);
}
private static final Map<Character, Character> 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
Expand Down Expand Up @@ -1795,6 +1828,7 @@ private UncaughtExceptionsVisitor(final CompilationInfo info) {
this.info = info;
}

@Override
public Void visitMethodInvocation(MethodInvocationTree node, Set<TypeMirror> p) {
super.visitMethodInvocation(node, p);
Element el = info.getTrees().getElement(getCurrentPath());
Expand All @@ -1803,6 +1837,7 @@ public Void visitMethodInvocation(MethodInvocationTree node, Set<TypeMirror> p)
return null;
}

@Override
public Void visitNewClass(NewClassTree node, Set<TypeMirror> p) {
super.visitNewClass(node, p);
Element el = info.getTrees().getElement(getCurrentPath());
Expand All @@ -1811,6 +1846,7 @@ public Void visitNewClass(NewClassTree node, Set<TypeMirror> p) {
return null;
}

@Override
public Void visitThrow(ThrowTree node, Set<TypeMirror> p) {
super.visitThrow(node, p);
TypeMirror tm = info.getTrees().getTypeMirror(new TreePath(getCurrentPath(), node.getExpression()));
Expand All @@ -1823,6 +1859,7 @@ else if (tm.getKind() == TypeKind.UNION)
return null;
}

@Override
public Void visitTry(TryTree node, Set<TypeMirror> p) {
Set<TypeMirror> s = new LinkedHashSet<TypeMirror>();
Trees trees = info.getTrees();
Expand Down Expand Up @@ -1867,6 +1904,7 @@ public Void visitTry(TryTree node, Set<TypeMirror> p) {
return null;
}

@Override
public Void visitMethod(MethodTree node, Set<TypeMirror> p) {
Set<TypeMirror> s = new LinkedHashSet<TypeMirror>();
scan(node.getBody(), s);
Expand Down Expand Up @@ -1895,8 +1933,8 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Set<TypeMirror> p)

private static class UnrelatedTypeMirrorSet extends AbstractSet<TypeMirror> {

private Types types;
private LinkedList<TypeMirror> list = new LinkedList<TypeMirror>();
private final Types types;
private final LinkedList<TypeMirror> list = new LinkedList<>();

public UnrelatedTypeMirrorSet(Types types) {
this.types = types;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 -> {
Expand Down Expand Up @@ -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();
Expand Down
Loading