mirror of
https://github.com/tiennm99/lombok.git
synced 2026-08-13 12:23:00 +00:00
Add unit test and cover missing cases
This commit is contained in:
@@ -38,6 +38,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sun.source.tree.TreeVisitor;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.BoundKind;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
@@ -75,6 +76,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCWildcard;
|
||||
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
|
||||
import com.sun.tools.javac.tree.TreeCopier;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
@@ -2117,9 +2119,10 @@ public class JavacHandlerUtil {
|
||||
}
|
||||
return out.toList();
|
||||
}
|
||||
|
||||
|
||||
static JCAnnotation copyAnnotation(JCAnnotation annotation, JavacTreeMaker maker) {
|
||||
return maker.Annotation(annotation.annotationType, annotation.args);
|
||||
TreeVisitor<JCTree, Void> visitor = new TreeCopier<Void>(maker.getUnderlyingTreeMaker());
|
||||
return (JCAnnotation) visitor.visitAnnotation(annotation, null);
|
||||
}
|
||||
|
||||
static List<JCAnnotation> mergeAnnotations(List<JCAnnotation> a, List<JCAnnotation> b) {
|
||||
|
||||
@@ -103,6 +103,7 @@ public class Delombok {
|
||||
private LinkedHashMap<File, File> fileToBase = new LinkedHashMap<File, File>();
|
||||
private List<File> filesToParse = new ArrayList<File>();
|
||||
private Map<String, String> formatPrefs = new HashMap<String, String>();
|
||||
private List<AbstractProcessor> preLombokProcessors = new ArrayList<AbstractProcessor>();
|
||||
private List<AbstractProcessor> additionalAnnotationProcessors = new ArrayList<AbstractProcessor>();
|
||||
|
||||
/** If null, output to standard out. */
|
||||
@@ -653,6 +654,10 @@ public class Delombok {
|
||||
fileToBase.put(f, base);
|
||||
}
|
||||
|
||||
public void addPreLombokProcessors(AbstractProcessor processor) {
|
||||
preLombokProcessors.add(processor);
|
||||
}
|
||||
|
||||
public void addAdditionalAnnotationProcessor(AbstractProcessor processor) {
|
||||
additionalAnnotationProcessors.add(processor);
|
||||
}
|
||||
@@ -735,6 +740,7 @@ public class Delombok {
|
||||
Map<JCCompilationUnit, File> baseMap = new IdentityHashMap<JCCompilationUnit, File>();
|
||||
|
||||
Set<AbstractProcessor> processors = new LinkedHashSet<AbstractProcessor>();
|
||||
processors.addAll(preLombokProcessors);
|
||||
processors.add(new lombok.javac.apt.LombokProcessor());
|
||||
processors.addAll(additionalAnnotationProcessors);
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -83,7 +85,11 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
|
||||
delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, result.getMessages()));
|
||||
|
||||
if (parameters.isCheckPositions()) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion()));
|
||||
if (parameters.isCheckPositions()) {
|
||||
NodePositionMapper nodePositionMapper = new NodePositionMapper();
|
||||
delombok.addPreLombokProcessors(nodePositionMapper);
|
||||
delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion(), nodePositionMapper));
|
||||
}
|
||||
delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor());
|
||||
delombok.addAdditionalAnnotationProcessor(new ValidateNoDuplicateTreeNodeProcessor());
|
||||
|
||||
@@ -105,15 +111,35 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static class NodePositionMapper extends TreeProcessor {
|
||||
Map<JCTree, Integer> nodePositions = new HashMap<>();
|
||||
|
||||
@Override void processCompilationUnit(final JCCompilationUnit unit) {
|
||||
unit.accept(new TreeScanner() {
|
||||
@Override public void scan(JCTree tree) {
|
||||
if (tree == null) return;
|
||||
if (tree.pos >= 0) {
|
||||
nodePositions.put(tree, tree.pos);
|
||||
}
|
||||
super.scan(tree);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ValidatePositionProcessor extends TreeProcessor {
|
||||
private final int version;
|
||||
private final NodePositionMapper nodePositionMapper;
|
||||
|
||||
public ValidatePositionProcessor(int version) {
|
||||
public ValidatePositionProcessor(int version, NodePositionMapper nodePositionMapper) {
|
||||
this.version = version;
|
||||
this.nodePositionMapper = nodePositionMapper;
|
||||
}
|
||||
|
||||
private String craftFailMsg(String problematicNode, Deque<JCTree> astContext) {
|
||||
StringBuilder msg = new StringBuilder(problematicNode).append(" position of node not set: ");
|
||||
StringBuilder msg = new StringBuilder(problematicNode);
|
||||
for (JCTree t : astContext) {
|
||||
msg.append("\n ").append(t.getClass().getSimpleName());
|
||||
String asStr = t.toString();
|
||||
@@ -125,12 +151,30 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
return msg.append("\n-------").toString();
|
||||
}
|
||||
|
||||
private boolean isLombokGenerated(JCTree tree) {
|
||||
List<JCAnnotation> annotations = com.sun.tools.javac.util.List.nil();
|
||||
if (tree instanceof JCMethodDecl) {
|
||||
annotations = ((JCMethodDecl) tree).mods.annotations;
|
||||
}
|
||||
if (tree instanceof JCVariableDecl) {
|
||||
annotations = ((JCVariableDecl) tree).mods.annotations;
|
||||
}
|
||||
for (JCAnnotation annotation: annotations) {
|
||||
if ("lombok.Generated".equals(annotation.getAnnotationType().toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override void processCompilationUnit(final JCCompilationUnit unit) {
|
||||
final Deque<JCTree> astContext = new ArrayDeque<JCTree>();
|
||||
final Deque<JCTree> lombokGeneratedNodes = new ArrayDeque<JCTree>();
|
||||
unit.accept(new TreeScanner() {
|
||||
@Override public void scan(JCTree tree) {
|
||||
if (tree == null) return;
|
||||
if (tree instanceof JCMethodDecl && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) return;
|
||||
if (isLombokGenerated(tree)) lombokGeneratedNodes.add(tree);
|
||||
astContext.push(tree);
|
||||
try {
|
||||
if (tree instanceof JCModifiers) return;
|
||||
@@ -153,16 +197,26 @@ public class RunTestsViaDelombok extends AbstractRunTests {
|
||||
|
||||
if (tree instanceof JCVariableDecl && (((JCVariableDecl) tree).mods.flags & Javac.GENERATED_MEMBER) != 0) return;
|
||||
|
||||
if (check && tree.pos == -1) fail(craftFailMsg("Start", astContext));
|
||||
if (check && tree.pos == -1) fail(craftFailMsg("Start position of node not set: ", astContext));
|
||||
|
||||
// Ignore ast position validation on lombok generated nodes.
|
||||
if (lombokGeneratedNodes.isEmpty()) {
|
||||
Integer expectedPos = nodePositionMapper.nodePositions.get(tree);
|
||||
if (expectedPos != null && !expectedPos.equals(tree.pos)) {
|
||||
fail(craftFailMsg(String.format("Expected node position %d, actual node position %d: ", expectedPos, tree.pos), astContext));
|
||||
}
|
||||
}
|
||||
if (check && Javac.getEndPosition(tree, unit) == -1) {
|
||||
fail(craftFailMsg("End", astContext));
|
||||
fail(craftFailMsg("End position of node not set: ", astContext));
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
super.scan(tree);
|
||||
} finally {
|
||||
astContext.pop();
|
||||
JCTree _tree = astContext.pop();
|
||||
if (!lombokGeneratedNodes.isEmpty() && lombokGeneratedNodes.peek().equals(_tree)) {
|
||||
lombokGeneratedNodes.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user