diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2018-11-06 00:54:05 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2018-11-06 00:55:54 +0100 |
commit | a685d0828c3cda044073054c203d17bcf6ab1096 (patch) | |
tree | c4ec88529de8341f4fa3948f0a57c41fb64e2162 /src/utils/lombok/javac/JavacTreeMaker.java | |
parent | 7e79316a1f28d1eb1ef8569119b97a70387fd6c6 (diff) | |
download | lombok-a685d0828c3cda044073054c203d17bcf6ab1096.tar.gz lombok-a685d0828c3cda044073054c203d17bcf6ab1096.tar.bz2 lombok-a685d0828c3cda044073054c203d17bcf6ab1096.zip |
[fixes #1888] [jdk12] lombok can deal with the changes to case/break nodes in JDK12-preview javac.
Diffstat (limited to 'src/utils/lombok/javac/JavacTreeMaker.java')
-rw-r--r-- | src/utils/lombok/javac/JavacTreeMaker.java | 72 |
1 files changed, 58 insertions, 14 deletions
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 |