diff options
Diffstat (limited to 'src')
17 files changed, 132 insertions, 35 deletions
diff --git a/src/core/lombok/SneakyThrows.java b/src/core/lombok/SneakyThrows.java index 0506d615..2a8009a3 100644 --- a/src/core/lombok/SneakyThrows.java +++ b/src/core/lombok/SneakyThrows.java @@ -39,14 +39,14 @@ import java.lang.annotation.Target; * Example: * <pre> * @SneakyThrows(UnsupportedEncodingException.class) - * public void utf8ToString(byte[] bytes) { + * public String utf8ToString(byte[] bytes) { * return new String(bytes, "UTF-8"); * } * </pre> * * Becomes: * <pre> - * public void utf8ToString(byte[] bytes) { + * public String utf8ToString(byte[] bytes) { * try { * return new String(bytes, "UTF-8"); * } catch (UnsupportedEncodingException $uniqueName) { diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index 525f534a..1cac2de7 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -302,7 +302,7 @@ public class HandleLog { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_CUSTOM_FLAG_USAGE, "@CustomLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); LogDeclaration logDeclaration = annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_CUSTOM_DECLARATION); if (logDeclaration == null) { - annotationNode.addError("The @CustomLog annotation is not configured; please set log.custom.declaration in lombok.config."); + annotationNode.addError("The @CustomLog annotation is not configured; please set lombok.log.custom.declaration in lombok.config."); return; } LoggingFramework framework = new LoggingFramework(lombok.CustomLog.class, logDeclaration); diff --git a/src/core/lombok/eclipse/handlers/HandleVal.java b/src/core/lombok/eclipse/handlers/HandleVal.java index ac53e27e..0f70e66d 100644 --- a/src/core/lombok/eclipse/handlers/HandleVal.java +++ b/src/core/lombok/eclipse/handlers/HandleVal.java @@ -22,12 +22,14 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.handleFlagUsage; -import static lombok.eclipse.handlers.EclipseHandlerUtil.typeMatches; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + import lombok.ConfigurationKeys; import lombok.val; import lombok.var; import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; +import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseASTAdapter; import lombok.eclipse.EclipseASTVisitor; import lombok.eclipse.EclipseNode; @@ -39,10 +41,13 @@ import org.eclipse.jdt.internal.compiler.ast.ForStatement; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; +import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; /* - * This class just handles 3 basic error cases. The real meat of eclipse 'val' support is in {@code PatchVal} and {@code PatchValEclipse}. + * Java 1-9: This class just handles 3 basic error cases. The real meat of eclipse 'val' support is in {@code PatchVal} and {@code PatchValEclipse}. + * Java 10+: Lombok uses the native 'var' support and transforms 'val' to 'final var'. */ @Provides(EclipseASTVisitor.class) @DeferUntilPostDiet @@ -96,5 +101,16 @@ public class HandleVal extends EclipseASTAdapter { localNode.addError("variable initializer is 'null'"); return; } + + // For Java >= 10 we use native support + if (localNode.getSourceVersion() >= 10) { + if (isVal) { + TypeReference originalType = local.type; + local.type = new SingleTypeReference("var".toCharArray(), Eclipse.pos(local.type)); + local.modifiers |= ClassFileConstants.AccFinal; + local.annotations = addAnnotation(local.type, local.annotations, originalType.getTypeName()); + } + return; + } } } diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index f58de60f..0919c7d4 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -228,7 +228,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { int underscoreIdx = nm.indexOf('_'); if (underscoreIdx > -1) return Integer.parseInt(nm.substring(underscoreIdx + 1)); // assume java9+ - return Integer.parseInt(nm); + return Integer.parseInt(nm.substring(3)); } catch (Exception ignore) {} return 6; } diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index e96079e0..f1109f4e 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2020 The Project Lombok Authors. + * Copyright (C) 2011-2021 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,7 @@ import java.lang.reflect.Method; import java.util.ArrayDeque; import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import java.util.NoSuchElementException; @@ -45,6 +46,7 @@ import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type.TypeVar; import com.sun.tools.javac.code.Type.WildcardType; import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.comp.ArgumentAttr; import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Enter; @@ -68,6 +70,7 @@ import lombok.core.debug.AssertionLogger; import lombok.permit.Permit; public class JavacResolution { + private final Context context; private final Attr attr; private final CompilerMessageSuppressor messageSuppressor; @@ -82,6 +85,7 @@ public class JavacResolution { } public JavacResolution(Context context) { + this.context = context; attr = Attr.instance(context); messageSuppressor = new CompilerMessageSuppressor(context); } @@ -245,10 +249,19 @@ public class JavacResolution { } catch (Throwable ignore) { // This addresses issue #1553 which involves JDK9; if it doesn't exist, we probably don't need to set it. } - if (tree instanceof JCBlock) attr.attribStat(tree, env); - else if (tree instanceof JCMethodDecl) attr.attribStat(((JCMethodDecl) tree).body, env); - else if (tree instanceof JCVariableDecl) attr.attribStat(tree, env); - else throw new IllegalStateException("Called with something that isn't a block, method decl, or variable decl"); + + Map<?,?> cache = null; + try { + cache = ArgumentAttrReflect.enableTempCache(context); + + if (tree instanceof JCBlock) attr.attribStat(tree, env); + else if (tree instanceof JCMethodDecl) attr.attribStat(((JCMethodDecl) tree).body, env); + else if (tree instanceof JCVariableDecl) attr.attribStat(tree, env); + else throw new IllegalStateException("Called with something that isn't a block, method decl, or variable decl"); + } finally { + ArgumentAttrReflect.restoreCache(cache, context); + } + } public static class TypeNotConvertibleException extends Exception { @@ -283,6 +296,43 @@ public class JavacResolution { } } + /** + * ArgumentAttr was added in Java 9 and caches some method arguments. Lombok should cleanup its changes after resolution. + */ + private static class ArgumentAttrReflect { + private static Field ARGUMENT_TYPE_CACHE; + + static { + if (Javac.getJavaCompilerVersion() >= 9) { + try { + ARGUMENT_TYPE_CACHE = Permit.getField(ArgumentAttr.class, "argumentTypeCache"); + } catch (Exception ignore) {} + } + } + + public static Map<?, ?> enableTempCache(Context context) { + if (ARGUMENT_TYPE_CACHE == null) return null; + + ArgumentAttr argumentAttr = ArgumentAttr.instance(context); + try { + Map<?, ?> cache = (Map<?, ?>) Permit.get(ARGUMENT_TYPE_CACHE, argumentAttr); + Permit.set(ARGUMENT_TYPE_CACHE, argumentAttr, new LinkedHashMap<Object, Object>(cache)); + return cache; + } catch (Exception ignore) { } + + return null; + } + + public static void restoreCache(Map<?, ?> cache, Context context) { + if (ARGUMENT_TYPE_CACHE == null) return; + + ArgumentAttr argumentAttr = ArgumentAttr.instance(context); + try { + Permit.set(ARGUMENT_TYPE_CACHE, argumentAttr, cache); + } catch (Exception ignore) { } + } + } + public static Type ifTypeIsIterableToComponent(Type type, JavacAST ast) { if (type == null) return null; Types types = Types.instance(ast.getContext()); diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 47c4098f..40f7ff08 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -260,7 +260,7 @@ public class HandleLog { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_CUSTOM_FLAG_USAGE, "@CustomLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); LogDeclaration logDeclaration = annotationNode.getAst().readConfiguration(ConfigurationKeys.LOG_CUSTOM_DECLARATION); if (logDeclaration == null) { - annotationNode.addError("The @CustomLog is not configured; please set log.custom.declaration in lombok.config."); + annotationNode.addError("The @CustomLog is not configured; please set lombok.log.custom.declaration in lombok.config."); return; } LoggingFramework framework = new LoggingFramework(lombok.CustomLog.class, logDeclaration); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index a0634494..e5b2c062 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -43,7 +43,6 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCReturn; diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java index 0ed831ab..d4fb1027 100644 --- a/src/core/lombok/javac/handlers/HandleVal.java +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -115,6 +115,12 @@ public class HandleVal extends JavacASTAdapter { local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation); } + if (localNode.getSourceVersion() >= 10) { + local.vartype = null; + localNode.getAst().setChanged(); + return; + } + if (JavacResolution.platformHasTargetTyping()) { local.vartype = localNode.getAst().getTreeMaker().Ident(localNode.getAst().toName("___Lombok_VAL_Attrib__")); } else { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index 774e5b40..824ecefc 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -204,6 +204,8 @@ public class PatchVal { boolean var = isVar(local, scope); if (!(val || var)) return false; + if (hasNativeVarSupport(scope)) return false; + if (val) { StackTraceElement[] st = new Throwable().getStackTrace(); for (int i = 0; i < st.length - 2 && i < 10; i++) { @@ -281,6 +283,14 @@ public class PatchVal { return is(local.type, scope, "lombok.val"); } + private static boolean hasNativeVarSupport(Scope scope) { + long sl = scope.problemReporter().options.sourceLevel >> 16; + long cl = scope.problemReporter().options.complianceLevel >> 16; + if (sl == 0) sl = cl; + if (cl == 0) cl = sl; + return Math.min((int)(sl - 44), (int)(cl - 44)) >= 10; + } + public static boolean handleValForForEach(ForeachStatement forEach, BlockScope scope) { if (forEach.elementVariable == null) return false; @@ -288,6 +298,8 @@ public class PatchVal { boolean var = isVar(forEach.elementVariable, scope); if (!(val || var)) return false; + if (hasNativeVarSupport(scope)) return false; + TypeBinding component = getForEachComponentType(forEach.collection, scope); if (component == null) return false; TypeReference replacement = makeType(component, forEach.elementVariable.type, false); diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index bee30922..30c63cf0 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -419,6 +419,7 @@ final class PatchFixesHider { String className = visitor.getClass().getName(); if (!(className.startsWith("org.eclipse.jdt.internal.corext.fix") || className.startsWith("org.eclipse.jdt.internal.ui.fix"))) return false; + if (className.equals("org.eclipse.jdt.internal.corext.fix.VariableDeclarationFixCore$WrittenNamesFinder")) return false; boolean result = false; try { diff --git a/src/installer/lombok/installer/IdeLocation.java b/src/installer/lombok/installer/IdeLocation.java index 6b9a94c6..7cba1e2a 100644 --- a/src/installer/lombok/installer/IdeLocation.java +++ b/src/installer/lombok/installer/IdeLocation.java @@ -64,16 +64,4 @@ public abstract class IdeLocation { return x == null ? p.getPath() : x; } } - - private static final String LEGAL_PATH_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"; - private static final String LEGAL_PATH_CHARS_WINDOWS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,/;'[]{}!@#$^&()-_+= :\\"; - public static String escapePath(String path) { - StringBuilder out = new StringBuilder(); - String legalChars = OsUtils.getOS() == OsUtils.OS.UNIX ? LEGAL_PATH_CHARS : LEGAL_PATH_CHARS_WINDOWS; - for (char c : path.toCharArray()) { - if (legalChars.indexOf(c) == -1) out.append('\\'); - out.append(c); - } - return out.toString(); - } } diff --git a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java index 73f98a35..4cfd07f5 100644 --- a/src/installer/lombok/installer/eclipse/EclipseProductLocation.java +++ b/src/installer/lombok/installer/eclipse/EclipseProductLocation.java @@ -347,8 +347,10 @@ public final class EclipseProductLocation extends IdeLocation { pathPrefix = pathToLombokJarPrefix; } + // NB: You may be tempted to escape this, but don't; there is no possibility to escape this, but + // eclipse/java reads the string following the colon in 'raw' fashion. Spaces, colons - all works fine. newContents.append(String.format( - "-javaagent:%s", escapePath(pathPrefix + "lombok.jar"))).append(OS_NEWLINE); + "-javaagent:%s", pathPrefix + "lombok.jar")).append(OS_NEWLINE); FileOutputStream fos = new FileOutputStream(eclipseIniPath); try { diff --git a/src/stubs/com/sun/tools/javac/comp/ArgumentAttr.java b/src/stubs/com/sun/tools/javac/comp/ArgumentAttr.java new file mode 100644 index 00000000..954a4592 --- /dev/null +++ b/src/stubs/com/sun/tools/javac/comp/ArgumentAttr.java @@ -0,0 +1,12 @@ +/* + * These are stub versions of various bits of javac-internal API (for various different versions of javac). Lombok is compiled against these. + */ +package com.sun.tools.javac.comp; + +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.util.Context; + +// JDK9+ +public class ArgumentAttr extends JCTree.Visitor { + public static ArgumentAttr instance(Context context) { return null; } +}
\ No newline at end of file diff --git a/src/stubsstubs/com/sun/tools/javac/tree/JCTree.java b/src/stubsstubs/com/sun/tools/javac/tree/JCTree.java index 28edf665..3b86bf3d 100644 --- a/src/stubsstubs/com/sun/tools/javac/tree/JCTree.java +++ b/src/stubsstubs/com/sun/tools/javac/tree/JCTree.java @@ -2,4 +2,5 @@ package com.sun.tools.javac.tree; public class JCTree { public static class JCCompilationUnit extends JCTree {} + public static abstract class Visitor {} } diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java index 8af481b9..0f42ddc6 100644 --- a/src/utils/lombok/eclipse/Eclipse.java +++ b/src/utils/lombok/eclipse/Eclipse.java @@ -224,8 +224,11 @@ public class Eclipse { 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 (f.getName().startsWith("JDK")) { + String versionString = f.getName().substring("JDK".length()); + if (versionString.startsWith("1_")) versionString = versionString.substring("1_".length()); + + int thisVersion = Integer.parseInt(versionString); if (thisVersion > highestVersionSoFar) { highestVersionSoFar = thisVersion; latestEcjCompilerVersionConstantCached = (Long) f.get(null); diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java index 778e670d..44e26ab6 100644 --- a/src/utils/lombok/javac/TreeMirrorMaker.java +++ b/src/utils/lombok/javac/TreeMirrorMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2015 The Project Lombok Authors. + * Copyright (C) 2010-2021 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -58,14 +58,14 @@ public class TreeMirrorMaker extends TreeCopier<Void> { @Override public <T extends JCTree> T copy(T original) { T copy = super.copy(original); - originalToCopy.put(original, copy); + putIfAbsent(originalToCopy, original, copy); return copy; } @Override public <T extends JCTree> T copy(T original, Void p) { T copy = super.copy(original, p); - originalToCopy.put(original, copy); - return copy; + putIfAbsent(originalToCopy, original, copy); + return copy; } @Override public <T extends JCTree> List<T> copy(List<T> originals) { @@ -73,7 +73,7 @@ public class TreeMirrorMaker extends TreeCopier<Void> { if (originals != null) { Iterator<T> it1 = originals.iterator(); Iterator<T> it2 = copies.iterator(); - while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); + while (it1.hasNext()) putIfAbsent(originalToCopy, it1.next(), it2.next()); } return copies; } @@ -83,7 +83,7 @@ public class TreeMirrorMaker extends TreeCopier<Void> { if (originals != null) { Iterator<T> it1 = originals.iterator(); Iterator<T> it2 = copies.iterator(); - while (it1.hasNext()) originalToCopy.put(it1.next(), it2.next()); + while (it1.hasNext()) putIfAbsent(originalToCopy, it1.next(), it2.next()); } return copies; } @@ -137,4 +137,10 @@ public class TreeMirrorMaker extends TreeCopier<Void> { @Override public JCTree visitLabeledStatement(LabeledStatementTree node, Void p) { return node.getStatement().accept(this, p); } + + private <K, V> void putIfAbsent(Map<K, V> map, K key, V value) { + if (!map.containsKey(key)) { + map.put(key, value); + } + } } diff --git a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java index f29f501b..e625cd8d 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java +++ b/src/utils/lombok/javac/java8/CommentCollectingScannerFactory.java @@ -21,6 +21,7 @@ */ package lombok.javac.java8; +import java.nio.Buffer; import java.nio.CharBuffer; import com.sun.tools.javac.parser.Scanner; @@ -79,7 +80,7 @@ public class CommentCollectingScannerFactory extends ScannerFactory { int limit; if (input instanceof CharBuffer && ((CharBuffer) input).hasArray()) { CharBuffer cb = (CharBuffer) input; - cb.compact().flip(); + ((Buffer)cb.compact()).flip(); array = cb.array(); limit = cb.limit(); } else { |