diff options
-rw-r--r-- | doc/changelog.markdown | 1 | ||||
-rwxr-xr-x | src/delombok/lombok/delombok/Delombok.java | 13 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/PrettyPrinter.java | 69 | ||||
-rw-r--r-- | src/delombok/lombok/delombok/ant/DelombokTask.java | 4 | ||||
-rw-r--r-- | src/eclipseAgent/lombok/eclipse/agent/PatchVal.java | 14 | ||||
-rw-r--r-- | src/utils/lombok/javac/JavacTreeMaker.java | 6 | ||||
-rw-r--r-- | src/utils/lombok/permit/Permit.java | 27 | ||||
-rw-r--r-- | test/core/src/lombok/DirectoryRunner.java | 2 | ||||
-rw-r--r-- | test/pretty/resource/after/Java11Var.java (renamed from test/pretty/resource/after/Java11Var.javva) | 0 | ||||
-rw-r--r-- | test/pretty/resource/after/Switch11.java | 11 | ||||
-rw-r--r-- | test/pretty/resource/after/Switch12.java | 28 | ||||
-rw-r--r-- | test/pretty/resource/before/Switch11.java | 12 | ||||
-rw-r--r-- | test/pretty/resource/before/Switch12.java | 30 | ||||
-rw-r--r-- | website/extra/htaccess | 4 | ||||
-rw-r--r-- | website/resources/js/main.js | 16 | ||||
-rw-r--r-- | website/templates/credits.html | 2 | ||||
-rw-r--r-- | website/templates/main.html | 2 | ||||
-rw-r--r-- | website/templates/presentations/7lessons.html | 25 |
18 files changed, 243 insertions, 23 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 64ddcc7f..b7f678a7 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -4,6 +4,7 @@ Lombok Changelog ### v1.18.7 "Edgy Guinea Pig" * FEATURE: You can now suppress generation of the `builder` method when using `@Builder`; usually because you're only interested in the `toBuilder` method. As a convenience we won't emit warnings about missing `@Builder.Default` annotations when you do this. [Issue #2046](https://github.com/rzwitserloot/lombok/issues/2046) * FEATURE: When using `@NonNull`, or any other annotation that would result in a null-check, you can configure to generate an assert statement instead. [Issue #2078](https://github.com/rzwitserloot/lombok/issues/2078). +* PLATFORM: A few lombok features (most notably delombok) failed on JDK12. [Issue #2082](https://github.com/rzwitserloot/lombok/issues/2082) * BUGFIX: var/val on methods that return an intersection type would now work in Eclipse. [Issue #1986](https://github.com/rzwitserloot/lombok/issues/1986) * BUGFIX: Fix for java6 regression if a field has javadoc. [Issue #2066](https://github.com/rzwitserloot/lombok/issues/2066) * BUGFIX: Delombok now delomboks java10's own `var` as `var` and not as the actual underlying type. [Issue #2049](https://github.com/rzwitserloot/lombok/issues/2049) diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 8f4f99e5..76b2715a 100755 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -93,6 +93,7 @@ public class Delombok { private boolean noCopy; private boolean onlyChanged; private boolean force = false; + private boolean disablePreview; private String classpath, sourcepath, bootclasspath, modulepath; private LinkedHashMap<File, File> fileToBase = new LinkedHashMap<File, File>(); private List<File> filesToParse = new ArrayList<File>(); @@ -158,6 +159,10 @@ public class Delombok { @Description("Output only changed files (implies -n)") private boolean onlyChanged; + @Description("By default lombok enables preview features if available (introduced in JDK 12). With this option, lombok won't do that.") + @FullName("disable-preview") + private boolean disablePreview; + private boolean help; } @@ -281,6 +286,7 @@ public class Delombok { if (args.verbose) delombok.setVerbose(true); if (args.nocopy || args.onlyChanged) delombok.setNoCopy(true); + if (args.disablePreview) delombok.setDisablePreview(true); if (args.onlyChanged) delombok.setOnlyChanged(true); if (args.print) { delombok.setOutputToStandardOut(); @@ -516,6 +522,10 @@ public class Delombok { this.noCopy = noCopy; } + public void setDisablePreview(boolean disablePreview) { + this.disablePreview = disablePreview; + } + public void setOnlyChanged(boolean onlyChanged) { this.onlyChanged = onlyChanged; } @@ -684,6 +694,9 @@ public class Delombok { argsList.add("--module-path"); argsList.add(modulepath); } + + if (!disablePreview && Javac.getJavaCompilerVersion() >= 11) argsList.add("--enable-preview"); + String[] argv = argsList.toArray(new String[0]); args.init("javac", argv); options.put("diags.legacy", "TRUE"); diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 832dbe0a..3477c51c 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1046,9 +1046,17 @@ public class PrettyPrinter extends JCTree.Visitor { @Override public void visitBreak(JCBreak tree) { aPrint("break"); - if (tree.label != null) { + + JCExpression value = readObject(tree, "value", null); // JDK 12+ + if (value != null) { print(" "); - print(tree.label); + print(value); + } else { + Name label = readObject(tree, "label", null); + if (label != null) { + print(" "); + print(label); + } } println(";", tree); } @@ -1230,16 +1238,41 @@ public class PrettyPrinter extends JCTree.Visitor { } @Override public void visitCase(JCCase tree) { - if (tree.pat == null) { + // Starting with JDK12, switches allow multiple expressions per case, and can take the form of an expression (preview feature). + + List<JCExpression> pats = readObject(tree, "pats", null); // JDK 12+ + if (pats == null) { + JCExpression pat = readObject(tree, "pat", null); // JDK -11 + pats = pat == null ? List.<JCExpression>nil() : List.of(pat); + } + + if (pats.isEmpty()) { aPrint("default"); } else { aPrint("case "); - print(tree.pat); + print(pats, ", "); + } + + Enum<?> caseKind = readObject(tree, "caseKind", null); // JDK 12+ + + if (caseKind != null && caseKind.name().equalsIgnoreCase("RULE")) { + print(" -> "); + if (tree.stats.head instanceof JCBreak) { + JCBreak b = (JCBreak) tree.stats.head; + print((JCExpression) readObject(b, "value", null)); + print(";"); + needsNewLine = true; + needsAlign = true; + } else { + print(tree.stats.head); + if (tree.stats.head instanceof JCBlock) needsNewLine = false; + } + } else { + println(": "); + indent++; + print(tree.stats, ""); + indent--; } - println(": "); - indent++; - print(tree.stats, ""); - indent--; } @Override public void visitCatch(JCCatch tree) { @@ -1259,10 +1292,26 @@ public class PrettyPrinter extends JCTree.Visitor { print(")"); } println(" {"); - print(tree.cases, "\n"); + print(tree.cases, ""); aPrintln("}", tree); } + void printSwitchExpression(JCTree tree) { + aPrint("switch "); + JCExpression selector = readObject(tree, "selector", null); + if (selector instanceof JCParens) { + print(selector); + } else { + print("("); + print(selector); + print(")"); + } + println(" {"); + List<JCCase> cases = readObject(tree, "cases", null); + print(cases, ""); + aPrint("}"); + } + @Override public void visitTry(JCTry tree) { aPrint("try "); List<?> resources = readObject(tree, "resources", List.nil()); @@ -1481,6 +1530,8 @@ public class PrettyPrinter extends JCTree.Visitor { printAnnotatedType0(tree); } else if ("JCPackageDecl".equals(simpleName)) { // Starting with JDK9, this is inside the import list, but we've already printed it. Just ignore it. + } else if ("JCSwitchExpression".equals(simpleName)) { // Introduced as preview feature in JDK12 + printSwitchExpression(tree); } else { throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree); } diff --git a/src/delombok/lombok/delombok/ant/DelombokTask.java b/src/delombok/lombok/delombok/ant/DelombokTask.java index e09b8ed2..cb31ef4d 100644 --- a/src/delombok/lombok/delombok/ant/DelombokTask.java +++ b/src/delombok/lombok/delombok/ant/DelombokTask.java @@ -154,10 +154,6 @@ class Tasks { path.add(set); } - public Format createFormat() { - return new Format(); - } - public void addFormat(Format format) { formatOptions.add(format); } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index 12f4ad3d..b32c99cd 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -263,11 +263,15 @@ public class PatchVal { resolved = null; } if (resolved != null) { - try { - replacement = makeType(resolved, local.type, false); - if (!decomponent) init.resolvedType = replacement.resolveType(scope); - } catch (Exception e) { - // Some type thing failed. + if (resolved.getClass().getSimpleName().startsWith("IntersectionTypeBinding")) { + // We intentionally deconstruct these into simply 'Object', because picking an arbitrary type amongst the intersection feels worse. + } else { + try { + replacement = makeType(resolved, local.type, false); + if (!decomponent) init.resolvedType = replacement.resolveType(scope); + } catch (Exception e) { + // Some type thing failed. + } } } } diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index 83d9c53f..84293f11 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -441,7 +441,11 @@ public class JavacTreeMaker { //javac versions: 6-8 private static final MethodId<JCVariableDecl> VarDef = MethodId("VarDef"); public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) { - return invoke(VarDef, mods, name, vartype, init); + JCVariableDecl varDef = invoke(VarDef, mods, name, vartype, init); + // We use 'position of the type is -1' as indicator in delombok that the original node was written using JDK10's 'var' feature, because javac desugars 'var' to the real type and doesn't leave any markers other than the + // node position to indicate that it did so. Unfortunately, that means vardecls we generate look like 'var' to delombok. Adjust the position to avoid this. + if (varDef.vartype != null && varDef.vartype.pos == -1) varDef.vartype.pos = 0; + return varDef; } //javac versions: 8 diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java index 9f0434b8..b7c5f0d9 100644 --- a/src/utils/lombok/permit/Permit.java +++ b/src/utils/lombok/permit/Permit.java @@ -46,8 +46,7 @@ public class Permit { Throwable ex; try { - f = AccessibleObject.class.getDeclaredField("override"); - g = UNSAFE.objectFieldOffset(f); + g = getOverrideFieldOffset(); ex = null; } catch (Throwable t) { f = null; @@ -74,6 +73,30 @@ public class Permit { return accessor; } + private static long getOverrideFieldOffset() throws Throwable { + Field f = null; + Throwable saved = null; + try { + f = AccessibleObject.class.getDeclaredField("override"); + } catch (Throwable t) { + saved = t; + } + + if (f != null) { + return UNSAFE.objectFieldOffset(f); + } + // The below seems very risky, but for all AccessibleObjects in java today it does work, and starting with JDK12, making the field accessible is no longer possible. + try { + return UNSAFE.objectFieldOffset(Fake.class.getDeclaredField("override")); + } catch (Throwable t) { + throw saved; + } + } + + static class Fake { + boolean override; + } + public static Method getMethod(Class<?> c, String mName, Class<?>... parameterTypes) throws NoSuchMethodException { Method m = null; Class<?> oc = c; diff --git a/test/core/src/lombok/DirectoryRunner.java b/test/core/src/lombok/DirectoryRunner.java index ea15cdb9..9410b4c7 100644 --- a/test/core/src/lombok/DirectoryRunner.java +++ b/test/core/src/lombok/DirectoryRunner.java @@ -91,7 +91,7 @@ public class DirectoryRunner extends Runner { public DirectoryRunner(Class<?> testClass) throws Exception { description = Description.createSuiteDescription(testClass); - this.params = (TestParams) testClass.newInstance(); + this.params = (TestParams) testClass.getConstructor().newInstance(); Throwable error = null; try { diff --git a/test/pretty/resource/after/Java11Var.javva b/test/pretty/resource/after/Java11Var.java index cec4be6d..cec4be6d 100644 --- a/test/pretty/resource/after/Java11Var.javva +++ b/test/pretty/resource/after/Java11Var.java diff --git a/test/pretty/resource/after/Switch11.java b/test/pretty/resource/after/Switch11.java new file mode 100644 index 00000000..d24012a2 --- /dev/null +++ b/test/pretty/resource/after/Switch11.java @@ -0,0 +1,11 @@ +public class Switch11 { + public void basic() { + switch (5) { + case 1: + case 2: + System.out.println("OK"); + break; + default: + } + } +} diff --git a/test/pretty/resource/after/Switch12.java b/test/pretty/resource/after/Switch12.java new file mode 100644 index 00000000..89825223 --- /dev/null +++ b/test/pretty/resource/after/Switch12.java @@ -0,0 +1,28 @@ +public class Switch12 { + public void basic() { + switch (5) { + case 1: + case 2: + System.out.println("OK"); + break; + default: + } + } + public void multiCase() { + switch (5) { + case 1, 2: + System.out.println("OK"); + default: + } + } + + public int switchExpr() { + return switch (5) { + case 1, 2 -> 0; + case 3 -> { + break 10; + } + default -> 10; + } + 10; + } +} diff --git a/test/pretty/resource/before/Switch11.java b/test/pretty/resource/before/Switch11.java new file mode 100644 index 00000000..556631f0 --- /dev/null +++ b/test/pretty/resource/before/Switch11.java @@ -0,0 +1,12 @@ +// version :11 +public class Switch11 { + public void basic() { + switch (5) { + case 1: + case 2: + System.out.println("OK"); + break; + default: + } + } +} diff --git a/test/pretty/resource/before/Switch12.java b/test/pretty/resource/before/Switch12.java new file mode 100644 index 00000000..f1bd8a79 --- /dev/null +++ b/test/pretty/resource/before/Switch12.java @@ -0,0 +1,30 @@ +// version 12: +public class Switch12 { + public void basic() { + switch (5) { + case 1: + case 2: + System.out.println("OK"); + break; + default: + } + } + + public void multiCase() { + switch (5) { + case 1, 2: + System.out.println("OK"); + default: + } + } + + public int switchExpr() { + return switch (5) { + case 1, 2 -> 0; + case 3 -> { + break 10; + } + default -> 10; + } + 10; + } +} diff --git a/website/extra/htaccess b/website/extra/htaccess index e7b54de4..d2c7a292 100644 --- a/website/extra/htaccess +++ b/website/extra/htaccess @@ -67,3 +67,7 @@ RewriteRule ^features/experimental/index(\.html)?/?$ /features/experimental/all RewriteRule ^features/experimental/${pg?no_esc}$ /features/experimental/${pg?no_esc}.html [L,END] RewriteRule ^features/experimental/${pg?no_esc}(\.html)?/?$ /features/experimental/${pg?no_esc} [NC,R=301] </#list> + +RewriteRule ^presentations/7lessons$ /presentations/7lessons.html [L,END] +RewriteRule ^presentations/7lessons(\.html)?/?$ /presentations/7lessons [NC,R=301] +RewriteRule ^presentations/7mistakes(\.html)?/?$ /presentations/7lessons [NC,R=301] diff --git a/website/resources/js/main.js b/website/resources/js/main.js index 5608a3c3..eaaf2df5 100644 --- a/website/resources/js/main.js +++ b/website/resources/js/main.js @@ -94,7 +94,23 @@ }); } + function seekVideo() { + var t = window.location.hash; + if (!t) return; + var s = /^#?(?:(\d\d?):)?(\d\d?):(\d\d?)$/.exec(t); + if (!s) return; + var videoj = $("#presentationVideo"); + if (!videoj || videoj.length == 0) return; + var video = videoj[0]; + var h = parseInt(s[1]); + if (!h) h = 0; + var m = parseInt(s[2]); + var s = parseInt(s[3]); + video.currentTime = (((h * 60) + m) * 60) + s; + } + $(ajaxFeaturePages); $(clickToTap); $(clickForVideo); + $(seekVideo); })($); diff --git a/website/templates/credits.html b/website/templates/credits.html index 3390d762..b5c033ad 100644 --- a/website/templates/credits.html +++ b/website/templates/credits.html @@ -29,6 +29,8 @@ </li><li> <strong>Tor Norbye</strong>, <strong>Jan Lahoda</strong>, and <strong>Petr Jiricka</strong> for helping out with Netbeans internals and/or javac. </li><li> + <strong>nqzero</strong> for the <a href="https://github.com/nqzero/permit-reflect">permit-reflect</a> library, whose ideas are also used in lombok. + </li><li> All contributors who submitted patches or helped answering questions!</li> </ul> diff --git a/website/templates/main.html b/website/templates/main.html index fc925d61..03073436 100644 --- a/website/templates/main.html +++ b/website/templates/main.html @@ -25,7 +25,7 @@ </video> <div class="row"> <div class="text-center"> - <a href="http://jnb.ociweb.com/jnb/jnbJan2010.html">Show me a text and images based explanation and tutorial instead!</a> + <a href="https://objectcomputing.com/resources/publications/sett/january-2010-reducing-boilerplate-code-with-project-lombok">Show me a text and images based explanation and tutorial instead!</a> </div> </div> </div> diff --git a/website/templates/presentations/7lessons.html b/website/templates/presentations/7lessons.html new file mode 100644 index 00000000..3027fbad --- /dev/null +++ b/website/templates/presentations/7lessons.html @@ -0,0 +1,25 @@ +<#import "../_scaffold.html" as main> +<@main.scaffold> + <div class="page-header top5"> + <div class="row text-center"> + <@main.h1 title="The 7 biggest mistakes we made in Project Lombok" /> + <p> + A presentation by Lombok's 2 core authors: Roel Spilker and Reinier Zwitserloot.<br /> + We talk about the 7 biggest mistakes we made managing an open source project for the past 10 years.<br /> + First given at <a href="https://programm.javaland.eu/2019/#/scheduledEvent/579921">Javaland (in Brühl, Germany) on March 19th, 2019</a>. Total length: 40 minutes. + </p> + </div> + <div class="video text-center"> + <video id="presentationVideo" width="640" height="360" poster="/presentations/7lessons-poster.jpg" controls="controls" preload="none"> + <source src="https://projectlombok.org/presentations/7lessons-vp9.webm" type="video/webm" /> + <source src="https://projectlombok.org/presentations/7lessons.webm" type="video/webm" /> + <source src="https://projectlombok.org/presentations/7lessons.mp4" type="video/mp4" /> + <@main.h1 title="Can't watch the video?" /> + <p> + You can download it and watch it with, for example, <a href="https://www.videolan.org/vlc/index.html">The open source VLC media player</a>:<br /> + <a href="/videos/7lessons.mp4">Download: 7 biggest mistakes we made in Project Lombok</a> + </p> + </video> + </div> + </div> +</@main.scaffold> |