From fdcbaa033d27b344adfea99d8d7bdd99cceacfb3 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 2 Feb 2021 09:44:36 +0100 Subject: Replace val with native final var in Java >= 10 --- src/core/lombok/eclipse/handlers/HandleVal.java | 20 ++++++++++++++++++-- src/core/lombok/javac/JavacAST.java | 2 +- src/core/lombok/javac/handlers/HandleVal.java | 6 ++++++ src/eclipseAgent/lombok/eclipse/agent/PatchVal.java | 12 ++++++++++++ src/utils/lombok/eclipse/Eclipse.java | 7 +++++-- .../javac/java8/CommentCollectingScannerFactory.java | 3 ++- 6 files changed, 44 insertions(+), 6 deletions(-) (limited to 'src') 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 { 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/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/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/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 { -- cgit