Replace val with native final var in Java >= 10

This commit is contained in:
Rawi01 authored and Roel Spilker committed 2021-09-06 11:58:05 +02:00
1 parent e050dafc90
commit fdcbaa033d
36 files changed
+128 -16

No files matched your search

@@ -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;
}
}
}
+1 -1
View File
@@ -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;
}
@@ -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 {
@@ -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);
+5 -2
View File
@@ -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);
@@ -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 {
@@ -1,9 +1,9 @@
// version 14:
public class ValSwitchExpression {
public void method(int arg) {
final int x = switch (arg) {
final var x = switch (arg) {
default -> {
final java.lang.String s = "string";
final var s = "string";
yield arg;
}
};
@@ -0,0 +1,15 @@
// version 10:
import java.io.IOException;
import java.util.Arrays;
public class ValToNative {
private void test() throws IOException {
final var intField = 1;
for (final var s : Arrays.asList("1")) {
final var s2 = s;
}
try (var in = getClass().getResourceAsStream("ValToNative.class")) {
final var j = in.read();
}
}
}
@@ -5,10 +5,10 @@ public class ValSwitchExpression {
super();
}
public void method(int arg) {
final @val int x = switch (arg) {
final @val var x = switch (arg) {
default ->
{
final @val java.lang.String s = "string";
final @val var s = "string";
yield arg;
}
};
@@ -0,0 +1,19 @@
import java.io.IOException;
import java.util.Arrays;
import lombok.val;
public class ValToNative {
public ValToNative() {
super();
}
private void test() throws IOException {
final @val var intField = 1;
for (final @val var s : Arrays.asList("1"))
{
final @val var s2 = s;
}
try (final @val var in = getClass().getResourceAsStream("ValToNative.class"))
{
final @val var j = in.read();
}
}
}
@@ -1,3 +1,4 @@
// version :9
import lombok.Getter;
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.*;
class TrickyDoNothing {
@interface Getter {}
@@ -1,3 +1,4 @@
// version :9
// issue 205: val inside anonymous inner classes is a bit tricky in javac, this test ensures we don't break it.
import java.util.*;
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValComplex {
@@ -1,4 +1,4 @@
// version 8:
// version 8:9
interface ValDefault {
int size();
@@ -1,4 +1,4 @@
//version 8:
//version 8:9
//platform !eclipse: Requires a 'full' eclipse with intialized workspace, and we don't (yet) have that set up properly in the test run.
import lombok.Getter;
import lombok.Setter;
@@ -1,3 +1,4 @@
// version :9
// unchanged
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValFinal {
public void test() {
@@ -1,3 +1,4 @@
// version :9
// unchanged
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValInFor {
@@ -1,4 +1,4 @@
// version 8:
// version 8:9
import java.util.function.Function;
import java.util.function.Supplier;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValInMultiDeclaration {
public void test() {
@@ -1,4 +1,4 @@
//version 7:
//version 7:9
import lombok.val;
import java.io.IOException;
@@ -1,4 +1,4 @@
// version 8:
// version 8:9
import java.io.Serializable;
class ValLambda {
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValLessSimple {
@@ -1,3 +1,4 @@
// version :9
class ValLub {
public void easyLub() {
java.util.Map<String, Number> m = java.util.Collections.emptyMap();
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
class ValNullInit {
@@ -1,3 +1,4 @@
// version :9
import java.util.*;
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import java.util.List;
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValSimple {
@@ -0,0 +1,19 @@
// version 10:
import java.io.IOException;
import java.util.Arrays;
import lombok.val;
public class ValToNative {
private void test() throws IOException {
val intField = 1;
for (val s : Arrays.asList("1")) {
val s2 = s;
}
try (val in = getClass().getResourceAsStream("ValToNative.class")) {
val j = in.read();
}
}
}
@@ -1,4 +1,4 @@
// version 8: In java6/7, lub types worked differently, so, the `arraysAsList` method has a slightly different inferred type there.
// version 8:9 In java6/7, lub types worked differently, so, the `arraysAsList` method has a slightly different inferred type there.
import java.math.BigDecimal;
import java.util.*;
import lombok.val;
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValWithLabel {
@@ -1,3 +1,4 @@
// version :9
//issue 694: In javac, resolving the RHS (which is what val does) can cause an entire class to be resolved, breaking all usage of val inside that class. This tests that we handle that better.
class ValWithLocalClasses1 {
{
@@ -1,3 +1,4 @@
// version :9
import lombok.val;
public class ValWithSelfRefGenerics {
public void run(Thing<? extends Comparable<?>> thing, Thing<?> thing2, java.util.List<? extends Number> z) {
+3
View File
@@ -5,6 +5,9 @@
<p>
<code>val</code> was introduced in lombok 0.10.
</p>
<p>
<em>NEW in Lombok 1.18.22: </em><code>val</code> gets replaced with <code>final var</code>.
</p>
</@f.history>
<@f.overview>
<p>