mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-03 05:20:17 +00:00
Fixed more issues related to java7's try-with-resources,
and updated ECJ version detection.
This commit is contained in:
1 parent
9c1e29842e
commit
6b5a0e2cb3
4 files changed
+103
-17
No files matched your search
@@ -54,7 +54,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
private final String fileName;
|
||||
private final String packageDeclaration;
|
||||
private final ImportList imports;
|
||||
Map<N, Void> identityDetector = new IdentityHashMap<N, Void>();
|
||||
Map<N, N> identityDetector = new IdentityHashMap<N, N>();
|
||||
private Map<N, L> nodeMap = new IdentityHashMap<N, L>();
|
||||
private boolean changed = false;
|
||||
|
||||
@@ -105,7 +105,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
*/
|
||||
protected L putInMap(L node) {
|
||||
nodeMap.put(node.get(), node);
|
||||
identityDetector.put(node.get(), null);
|
||||
identityDetector.put(node.get(), node.get());
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
/** Clears the registry that avoids endless loops, and empties the node map. The existing node map
|
||||
* object is left untouched, and instead a new map is created. */
|
||||
protected void clearState() {
|
||||
identityDetector = new IdentityHashMap<N, Void>();
|
||||
identityDetector = new IdentityHashMap<N, N>();
|
||||
nodeMap = new IdentityHashMap<N, L>();
|
||||
}
|
||||
|
||||
@@ -127,9 +127,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
* case you should do nothing lest the AST build process loops endlessly.
|
||||
*/
|
||||
protected boolean setAndGetAsHandled(N node) {
|
||||
if (identityDetector.containsKey(node)) return true;
|
||||
identityDetector.put(node, null);
|
||||
return false;
|
||||
return identityDetector.put(node, node) != null;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
@@ -234,14 +232,12 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
}
|
||||
}
|
||||
|
||||
for (Class<?> statementType : getStatementTypes()) {
|
||||
if (statementType.isAssignableFrom(t)) {
|
||||
f.setAccessible(true);
|
||||
fields.add(new FieldAccess(f, dim));
|
||||
break;
|
||||
}
|
||||
if (shouldDrill(c, t, f.getName())) {
|
||||
f.setAccessible(true);
|
||||
fields.add(new FieldAccess(f, dim));
|
||||
}
|
||||
}
|
||||
|
||||
getFields(c.getSuperclass(), fields);
|
||||
}
|
||||
|
||||
@@ -258,6 +254,14 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
|
||||
* though some platforms (such as Eclipse) group these under one common supertype. */
|
||||
protected abstract Collection<Class<? extends N>> getStatementTypes();
|
||||
|
||||
protected boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) {
|
||||
for (Class<?> statementType : getStatementTypes()) {
|
||||
if (statementType.isAssignableFrom(childType)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* buildTree implementation that uses reflection to find all child nodes by way of inspecting
|
||||
* the fields. */
|
||||
|
||||
@@ -24,6 +24,7 @@ package lombok.javac;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.processing.Messager;
|
||||
@@ -39,6 +40,7 @@ import com.sun.tools.javac.model.JavacElements;
|
||||
import com.sun.tools.javac.model.JavacTypes;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCatch;
|
||||
import com.sun.tools.javac.tree.JCTree.JCTry;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCBlock;
|
||||
@@ -224,6 +226,46 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
return putInMap(new JavacNode(this, local, childNodes, kind));
|
||||
}
|
||||
|
||||
private static boolean JCTRY_RESOURCES_FIELD_INITIALIZED;
|
||||
private static Field JCTRY_RESOURCES_FIELD;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<JCTree> getResourcesForTryNode(JCTry tryNode) {
|
||||
if (!JCTRY_RESOURCES_FIELD_INITIALIZED) {
|
||||
try {
|
||||
JCTRY_RESOURCES_FIELD = JCTry.class.getField("resources");
|
||||
} catch (NoSuchFieldException ignore) {
|
||||
// Java 1.6 or lower won't have this at all.
|
||||
} catch (Exception ignore) {
|
||||
// Shouldn't happen. Best thing we can do is just carry on and break on try/catch.
|
||||
}
|
||||
JCTRY_RESOURCES_FIELD_INITIALIZED = true;
|
||||
}
|
||||
|
||||
if (JCTRY_RESOURCES_FIELD == null) return Collections.emptyList();
|
||||
Object rv = null;
|
||||
try {
|
||||
rv = JCTRY_RESOURCES_FIELD.get(tryNode);
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
if (rv instanceof List) return (List<JCTree>) rv;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private JavacNode buildTry(JCTry tryNode) {
|
||||
if (setAndGetAsHandled(tryNode)) return null;
|
||||
List<JavacNode> childNodes = new ArrayList<JavacNode>();
|
||||
for (JCTree varDecl : getResourcesForTryNode(tryNode)) {
|
||||
if (varDecl instanceof JCVariableDecl) {
|
||||
addIfNotNull(childNodes, buildLocalVar((JCVariableDecl) varDecl, Kind.LOCAL));
|
||||
}
|
||||
}
|
||||
addIfNotNull(childNodes, buildStatement(tryNode.body));
|
||||
for (JCCatch jcc : tryNode.catchers) addIfNotNull(childNodes, buildTree(jcc, Kind.STATEMENT));
|
||||
addIfNotNull(childNodes, buildStatement(tryNode.finalizer));
|
||||
return putInMap(new JavacNode(this, tryNode, childNodes, Kind.STATEMENT));
|
||||
}
|
||||
|
||||
private JavacNode buildInitializer(JCBlock initializer) {
|
||||
if (setAndGetAsHandled(initializer)) return null;
|
||||
List<JavacNode> childNodes = new ArrayList<JavacNode>();
|
||||
@@ -265,6 +307,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
|
||||
if (statement instanceof JCAnnotation) return null;
|
||||
if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement);
|
||||
if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL);
|
||||
if (statement instanceof JCTry) return buildTry((JCTry) statement);
|
||||
|
||||
if (setAndGetAsHandled(statement)) return null;
|
||||
|
||||
|
||||
@@ -37,8 +37,10 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Literal;
|
||||
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
|
||||
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
|
||||
|
||||
@@ -180,8 +182,31 @@ public class Eclipse {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int ecjCompilerVersionCached = -1;
|
||||
private static long latestEcjCompilerVersionConstantCached = 0;
|
||||
|
||||
public static long getLatestEcjCompilerVersionConstant() {
|
||||
if (latestEcjCompilerVersionConstantCached != 0) return latestEcjCompilerVersionConstantCached;
|
||||
|
||||
int highestVersionSoFar = 0;
|
||||
for (Field f : ClassFileConstants.class.getDeclaredFields()) {
|
||||
try {
|
||||
if (f.getName().startsWith("JDK1_")) {
|
||||
int thisVersion = Integer.parseInt(f.getName().substring("JDK1_".length()));
|
||||
if (thisVersion > highestVersionSoFar) {
|
||||
highestVersionSoFar = thisVersion;
|
||||
latestEcjCompilerVersionConstantCached = (Long) f.get(null);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
if (highestVersionSoFar > 6 && !ecjSupportsJava7Features()) {
|
||||
latestEcjCompilerVersionConstantCached = ClassFileConstants.JDK1_6;
|
||||
}
|
||||
return latestEcjCompilerVersionConstantCached;
|
||||
}
|
||||
|
||||
private static int ecjCompilerVersionCached = -1;
|
||||
public static int getEcjCompilerVersion() {
|
||||
if (ecjCompilerVersionCached >= 0) return ecjCompilerVersionCached;
|
||||
|
||||
@@ -194,6 +219,20 @@ public class Eclipse {
|
||||
}
|
||||
|
||||
if (ecjCompilerVersionCached < 5) ecjCompilerVersionCached = 5;
|
||||
if (!ecjSupportsJava7Features()) ecjCompilerVersionCached = Math.min(6, ecjCompilerVersionCached);
|
||||
return ecjCompilerVersionCached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Certain ECJ versions that only go up to -source 6 report that they support -source 7 and even fail to error when -source 7 is applied.
|
||||
* We detect this and correctly say that no more than -source 6 is supported. (when this is the case, this method returns false).
|
||||
*/
|
||||
private static boolean ecjSupportsJava7Features() {
|
||||
try {
|
||||
TryStatement.class.getDeclaredField("resources");
|
||||
return true;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import lombok.eclipse.Eclipse;
|
||||
import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
|
||||
|
||||
import org.eclipse.jdt.core.compiler.CategorizedProblem;
|
||||
@@ -43,7 +44,6 @@ import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
|
||||
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
|
||||
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
|
||||
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
|
||||
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
|
||||
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
|
||||
@@ -51,9 +51,9 @@ import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
|
||||
public class RunTestsViaEcj extends AbstractRunTests {
|
||||
protected CompilerOptions ecjCompilerOptions() {
|
||||
CompilerOptions options = new CompilerOptions();
|
||||
options.complianceLevel = ClassFileConstants.JDK1_6;
|
||||
options.sourceLevel = ClassFileConstants.JDK1_6;
|
||||
options.targetJDK = ClassFileConstants.JDK1_6;
|
||||
options.complianceLevel = Eclipse.getLatestEcjCompilerVersionConstant();
|
||||
options.sourceLevel = Eclipse.getLatestEcjCompilerVersionConstant();
|
||||
options.targetJDK = Eclipse.getLatestEcjCompilerVersionConstant();
|
||||
options.parseLiteralExpressionsAsConstants = true;
|
||||
options.inlineJsrBytecode = true;
|
||||
options.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = false;
|
||||
|
||||
Reference in new issue
Block a user