diff options
-rw-r--r-- | doc/changelog.markdown | 1 | ||||
-rw-r--r-- | src/utils/lombok/javac/JavacTreeMaker.java | 72 |
2 files changed, 59 insertions, 14 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 4a19ed73..6b24ccc0 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -6,6 +6,7 @@ Lombok Changelog * FEATURE: The `@FieldNameConstants` feature now allows you to write the inner type by hand and add whatever you like to it; lombok will add the constants to this class. See the updated [FieldNameConstants feature](https://projectlombok.org/features/experimental/FieldNameConstants) page. * FEATURE: There is now a `lombok.config` key to configure `@ToString`'s call super behavior; it's just like `@EqualsAndHashCode` which has had it for a while now. [Issue #1918](https://github.com/rzwitserloot/lombok/issues/1918) * ENHANCEMENT: The toString generation of enums now contains the name of the enum constant. [Issue #1916](https://github.com/rzwitserloot/lombok/issues/1916) +* PLATFORM: Due to changes to switch statements in JDK12, lombok wasn't working with the JDK12 preview. [Issue #1888](https://github.com/rzwitserloot/lombok/issues/1888) ### v1.18.4 (October 30th, 2018) * PLATFORM: Support for Eclipse Photon. [Issue #1831](https://github.com/rzwitserloot/lombok/issues/1831) diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index 68a16af2..83d9c53f 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Project Lombok Authors. + * Copyright (C) 2013-2018 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 @@ -332,14 +332,15 @@ public class JavacTreeMaker { throw new InternalError("Not found: " + name); } - private static final ConcurrentHashMap<MethodId<?>, Method> METHOD_CACHE = new ConcurrentHashMap<MethodId<?>, Method>(); + private static final Object METHOD_NOT_FOUND = new Object[0]; + private static final Object METHOD_MULTIPLE_FOUND = new Object[0]; + private static final ConcurrentHashMap<MethodId<?>, Object> METHOD_CACHE = new ConcurrentHashMap<MethodId<?>, Object>(); private <J> J invoke(MethodId<J> m, Object... args) { return invokeAny(tm, m, args); } @SuppressWarnings("unchecked") private static <J> J invokeAny(Object owner, MethodId<J> m, Object... args) { - Method method = METHOD_CACHE.get(m); - if (method == null) method = addToCache(m); + Method method = getFromCache(m); try { if (m.returnType.isPrimitive()) { Object res = method.invoke(owner, args); @@ -358,7 +359,22 @@ public class JavacTreeMaker { } } - private static Method addToCache(MethodId<?> m) { + private static boolean tryResolve(MethodId<?> m) { + Object s = METHOD_CACHE.get(m); + if (s == null) s = addToCache(m); + if (s instanceof Method) return true; + return false; + } + + private static Method getFromCache(MethodId<?> m) { + Object s = METHOD_CACHE.get(m); + if (s == null) s = addToCache(m); + if (s == METHOD_MULTIPLE_FOUND) throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m); + if (s == METHOD_NOT_FOUND) throw new IllegalStateException("Lombok TreeMaker frontend issue: no match when looking for method: " + m); + return (Method) s; + } + + private static Object addToCache(MethodId<?> m) { Method found = null; outer: @@ -377,13 +393,19 @@ public class JavacTreeMaker { } } if (found == null) found = method; - else throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m); + else { + METHOD_CACHE.putIfAbsent(m, METHOD_MULTIPLE_FOUND); + return METHOD_MULTIPLE_FOUND; + } + } + if (found == null) { + METHOD_CACHE.putIfAbsent(m, METHOD_NOT_FOUND); + return METHOD_NOT_FOUND; } - if (found == null) throw new IllegalStateException("Lombok TreeMaker frontend issue: no match when looking for method: " + m); Permit.setAccessible(found); Object marker = METHOD_CACHE.putIfAbsent(m, found); if (marker == null) return found; - return METHOD_CACHE.get(m); + return marker; } //javac versions: 6-8 @@ -476,10 +498,28 @@ public class JavacTreeMaker { return invoke(Switch, selector, cases); } - //javac versions: 6-8 - private static final MethodId<JCCase> Case = MethodId("Case"); + //javac versions: 6-11 + private static final MethodId<JCCase> Case11 = MethodId("Case", JCCase.class, JCExpression.class, com.sun.tools.javac.util.List.class); + //javac version: 12+ + public static class Case12 { + private static final Class<?> CASE_KIND_CLASS = classForName(TreeMaker.class, "com.sun.source.tree.CaseTree$CaseKind"); + static final MethodId<JCCase> Case12 = MethodId("Case", JCCase.class, CASE_KIND_CLASS, com.sun.tools.javac.util.List.class, com.sun.tools.javac.util.List.class, JCTree.class); + static final Object CASE_KIND_STATEMENT = CASE_KIND_CLASS.getEnumConstants()[0]; + } + + static Class<?> classForName(Class<?> context, String name) { + try { + return context.getClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + Error x = new NoClassDefFoundError(e.getMessage()); + x.setStackTrace(e.getStackTrace()); + throw x; + } + } + public JCCase Case(JCExpression pat, List<JCStatement> stats) { - return invoke(Case, pat, stats); + if (tryResolve(Case11)) return invoke(Case11, pat, stats); + return invoke(Case12.Case12, Case12.CASE_KIND_STATEMENT, pat == null ? com.sun.tools.javac.util.List.nil() : com.sun.tools.javac.util.List.of(pat), stats, null); } //javac versions: 6-8 @@ -524,10 +564,14 @@ public class JavacTreeMaker { return invoke(Exec, expr); } - //javac versions: 6-8 - private static final MethodId<JCBreak> Break = MethodId("Break"); + //javac version: 6-11 + private static final MethodId<JCBreak> Break11 = MethodId("Break", JCBreak.class, Name.class); + //javac version: 12+ + private static final MethodId<JCBreak> Break12 = MethodId("Break", JCBreak.class, JCExpression.class); + public JCBreak Break(Name label) { - return invoke(Break, label); + if (tryResolve(Break11)) return invoke(Break11, label); + return invoke(Break12, label != null ? Ident(label) : null); } //javac versions: 6-8 |