diff options
Diffstat (limited to 'src')
17 files changed, 263 insertions, 25 deletions
diff --git a/src/core/lombok/CustomLog.java b/src/core/lombok/CustomLog.java index d1f45f7c..c6ea400d 100644 --- a/src/core/lombok/CustomLog.java +++ b/src/core/lombok/CustomLog.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field based on a custom logger implementation. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index a2dd5057..bb9b6dda 100755 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -983,7 +983,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { } if (field == null) { - FieldDeclaration fd = new FieldDeclaration(bfd.builderFieldName, 0, 0); + FieldDeclaration fd = new FieldDeclaration(bfd.builderFieldName.clone(), 0, 0); fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; fd.modifiers = ClassFileConstants.AccPrivate; fd.type = copyType(bfd.type); diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 558c6ec2..e91478e0 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -51,7 +51,6 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.Initializer; -import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; @@ -387,16 +386,16 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { injectMethod(job.builderType, generateStaticFillValuesMethod(job, annInstance.setterPrefix())); } - // Generate abstract self() and build() methods in the abstract builder. - injectMethod(job.builderType, generateAbstractSelfMethod(job, superclassBuilderClass != null, builderGenericName)); - job.setBuilderToAbstract(); - injectMethod(job.builderType, generateAbstractBuildMethod(job, superclassBuilderClass != null, classGenericName)); - // Create the setter methods in the abstract builder. for (BuilderFieldData bfd : job.builderFields) { generateSetterMethodsForBuilder(job, bfd, builderGenericName, annInstance.setterPrefix()); } + // Generate abstract self() and build() methods in the abstract builder. + injectMethod(job.builderType, generateAbstractSelfMethod(job, superclassBuilderClass != null, builderGenericName)); + job.setBuilderToAbstract(); + injectMethod(job.builderType, generateAbstractBuildMethod(job, superclassBuilderClass != null, classGenericName)); + // Create the toString() method for the abstract builder. if (methodExists("toString", job.builderType, 0) == MemberExistsResult.NOT_EXISTS) { List<Included<EclipseNode, ToString.Include>> fieldNodes = new ArrayList<Included<EclipseNode, ToString.Include>>(); @@ -948,7 +947,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } if (field == null) { - FieldDeclaration fd = new FieldDeclaration(bfd.builderFieldName, 0, 0); + FieldDeclaration fd = new FieldDeclaration(bfd.builderFieldName.clone(), 0, 0); fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; fd.modifiers = ClassFileConstants.AccPrivate; fd.type = copyType(bfd.type); @@ -1100,14 +1099,29 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { if (td.fields != null) { for (FieldDeclaration field : td.fields) { if (field instanceof Initializer) continue; - char[][] typeName = field.type.getTypeName(); - if (typeName.length >= 1) // Add the first token, because only that can collide. - usedNames.add(String.valueOf(typeName[0])); + addFirstToken(usedNames, field.type); + } + } + + // 4. Add extends and implements clauses. + addFirstToken(usedNames, td.superclass); + if (td.superInterfaces != null) { + for (TypeReference typeReference : td.superInterfaces) { + addFirstToken(usedNames, typeReference); } } return usedNames; } + + private void addFirstToken(java.util.Set<String> usedNames, TypeReference type) { + if (type == null) + return; + // Add the first token, because only that can collide. + char[][] typeName = type.getTypeName(); + if (typeName != null && typeName.length >= 1) + usedNames.add(String.valueOf(typeName[0])); + } private String generateNonclashingNameFor(String classGenericName, java.util.Set<String> typeParamStrings) { if (!typeParamStrings.contains(classGenericName)) return classGenericName; diff --git a/src/core/lombok/extern/apachecommons/CommonsLog.java b/src/core/lombok/extern/apachecommons/CommonsLog.java index ca808329..973f556f 100644 --- a/src/core/lombok/extern/apachecommons/CommonsLog.java +++ b/src/core/lombok/extern/apachecommons/CommonsLog.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/flogger/Flogger.java b/src/core/lombok/extern/flogger/Flogger.java index 3446e949..893032ed 100644 --- a/src/core/lombok/extern/flogger/Flogger.java +++ b/src/core/lombok/extern/flogger/Flogger.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/java/Log.java b/src/core/lombok/extern/java/Log.java index f2b5024f..96e52191 100644 --- a/src/core/lombok/extern/java/Log.java +++ b/src/core/lombok/extern/java/Log.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/jbosslog/JBossLog.java b/src/core/lombok/extern/jbosslog/JBossLog.java index 960a111b..a6e5e353 100644 --- a/src/core/lombok/extern/jbosslog/JBossLog.java +++ b/src/core/lombok/extern/jbosslog/JBossLog.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/log4j/Log4j.java b/src/core/lombok/extern/log4j/Log4j.java index 1b4a973b..3db01029 100644 --- a/src/core/lombok/extern/log4j/Log4j.java +++ b/src/core/lombok/extern/log4j/Log4j.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/log4j/Log4j2.java b/src/core/lombok/extern/log4j/Log4j2.java index 571b0563..3e59a532 100644 --- a/src/core/lombok/extern/log4j/Log4j2.java +++ b/src/core/lombok/extern/log4j/Log4j2.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/slf4j/Slf4j.java b/src/core/lombok/extern/slf4j/Slf4j.java index c4aded24..da65e27c 100644 --- a/src/core/lombok/extern/slf4j/Slf4j.java +++ b/src/core/lombok/extern/slf4j/Slf4j.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/extern/slf4j/XSlf4j.java b/src/core/lombok/extern/slf4j/XSlf4j.java index b99554a5..2dfef265 100644 --- a/src/core/lombok/extern/slf4j/XSlf4j.java +++ b/src/core/lombok/extern/slf4j/XSlf4j.java @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Causes lombok to generate a logger field. * <p> - * Complete documentation is found at <a href="https://projectlombok.org/features/Log">the project lombok features page for lombok log annotations</a>. + * Complete documentation is found at <a href="https://projectlombok.org/features/log">the project lombok features page for lombok log annotations</a>. * <p> * Example: * <pre> diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 7418ac87..913f838c 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -336,6 +336,11 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { injectMethod(job.builderType, sfvm); } + // Create the setter methods in the abstract builder. + for (BuilderFieldData bfd : job.builderFields) { + generateSetterMethodsForBuilder(job, bfd, builderGenericName, annInstance.setterPrefix()); + } + // Generate abstract self() and build() methods in the abstract builder. JCMethodDecl asm = generateAbstractSelfMethod(job, superclassBuilderClass != null, builderGenericName); recursiveSetGeneratedBy(asm, annotationNode); @@ -344,11 +349,6 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { recursiveSetGeneratedBy(abm, annotationNode); injectMethod(job.builderType, abm); - // Create the setter methods in the abstract builder. - for (BuilderFieldData bfd : job.builderFields) { - generateSetterMethodsForBuilder(job, bfd, builderGenericName, annInstance.setterPrefix()); - } - // Create the toString() method for the abstract builder. java.util.List<Included<JavacNode, ToString.Include>> fieldNodes = new ArrayList<Included<JavacNode, ToString.Include>>(); for (BuilderFieldData bfd : job.builderFields) { @@ -1051,9 +1051,28 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { } } + // 4. Add extends and implements clauses. + addFirstToken(usedNames, Javac.getExtendsClause(td)); + for (JCExpression impl : td.getImplementsClause()) { + addFirstToken(usedNames, impl); + } + return usedNames; } + private void addFirstToken(java.util.Set<String> usedNames, JCTree type) { + if (type == null) + return; + if (type instanceof JCTypeApply) { + type = ((JCTypeApply)type).clazz; + } + while (type instanceof JCFieldAccess && ((JCFieldAccess)type).selected != null) { + // Add the first token, because only that can collide. + type = ((JCFieldAccess)type).selected; + } + usedNames.add(type.toString()); + } + private String generateNonclashingNameFor(String classGenericName, java.util.HashSet<String> typeParamStrings) { if (!typeParamStrings.contains(classGenericName)) return classGenericName; int counter = 2; diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 605b9391..13836d77 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1448,6 +1448,31 @@ public class PrettyPrinter extends JCTree.Visitor { print(")"); } + void printConstantCaseLabel(JCTree tree) { + print((JCTree) readObject(tree, "expr", null)); + } + + void printPatternCaseLabel(JCTree tree) { + print((JCTree) readObject(tree, "pat", null)); + JCTree guard = readObject(tree, "guard", null); + if (guard != null) { + print(" when "); + print(guard); + } + } + + void printRecordPattern(JCTree tree) { + print((JCTree) readObject(tree, "deconstructor", null)); + print("("); + print(readObject(tree, "nested", List.<JCTree>nil()), ", "); + print(")"); + JCVariableDecl var = readObject(tree, "var", null); + if (var != null) { + print(" "); + print(var.name); + } + } + @Override public void visitTry(JCTry tree) { aPrint("try "); List<?> resources = readObject(tree, "resources", List.nil()); @@ -1672,6 +1697,12 @@ public class PrettyPrinter extends JCTree.Visitor { printGuardPattern(tree); } else if (className.endsWith("$JCParenthesizedPattern")) { // Introduced in JDK17 printParenthesizedPattern(tree); + } else if (className.endsWith("$JCConstantCaseLabel")) { // Introduced in JDK19 + printConstantCaseLabel(tree); + } else if (className.endsWith("$JCPatternCaseLabel")) { // Introduced in JDK19 + printPatternCaseLabel(tree); + } else if (className.endsWith("$JCRecordPattern")) { // Introduced in JDK19 + printRecordPattern(tree); } else { throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree); } diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index d893b724..c0bfbe09 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -109,6 +109,8 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchRenameField(sm); patchNullCheck(sm); + patchForTests(sm); + if (reloadExistingClasses) sm.reloadClasses(instrumentation); } @@ -1007,5 +1009,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .transplant() .build()); } + + private static void patchForTests(ScriptManager sm) { + sm.addScriptIfWitness(new String[] {"lombok/eclipse/EclipseTests"}, ScriptBuilder.wrapReturnValue() + .target(new MethodTarget("org.osgi.framework.FrameworkUtil", "getBundle", "org.osgi.framework.Bundle", "java.lang.Class")) + .request(StackRequest.RETURN_VALUE, StackRequest.PARAM1) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "getBundle", "java.lang.Object", "java.lang.Object", "java.lang.Class")) + .build()); + } } diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index a844239f..c7bdbc31 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -27,6 +27,7 @@ import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.security.CodeSource; import java.util.ArrayList; import java.util.List; import java.util.Stack; @@ -854,4 +855,28 @@ final class PatchFixesHider { return isGenerated(adjustment.getMember()); } } + + public static class Tests { + public static Object getBundle(Object original, Class<?> c) { + if (original != null) { + return original; + } + + CodeSource codeSource = c.getProtectionDomain().getCodeSource(); + if (codeSource == null) { + return null; + } + + String jar = codeSource.getLocation().getFile(); + String bundleName = jar.substring(jar.lastIndexOf("/") + 1, jar.indexOf("_")); + + org.osgi.framework.Bundle[] bundles = org.eclipse.core.runtime.adaptor.EclipseStarter.getSystemBundleContext().getBundles(); + for (org.osgi.framework.Bundle bundle : bundles) { + if (bundleName.equals(bundle.getSymbolicName())) { + return bundle; + } + } + return null; + } + } } diff --git a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java new file mode 100644 index 00000000..06e26bb6 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java @@ -0,0 +1,131 @@ +package lombok.eclipse.dependencies; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Download eclipse bundles. + */ +public class DownloadEclipseDependencies { + + public static void main(String[] args) throws IOException { + String target = args[0]; + String eclipseVersion = args[1]; + String updatePage = args[2]; + String[] packages = Arrays.copyOfRange(args, 3, args.length); + + String pluginTarget = target + "/" + eclipseVersion + "/plugins/"; + + String indexData = readUrlAsString(updatePage); + + for (String pkg : packages) { + Matcher matcher = Pattern.compile("(" + pkg.replace(".", "\\.") + "_.*?\\.jar)").matcher(indexData); + if (matcher.find()) { + String path = matcher.group(1); + + try { + downloadFile(path, updatePage, pluginTarget); + } catch (Exception e) { + } + try { + int index = path.lastIndexOf("_"); + String source = path.substring(0, index) + ".source" + path.substring(index); + downloadFile(source, updatePage, pluginTarget); + } catch (Exception e) { + } + } else { + System.out.println("Bundle \"" + pkg + "\" not found"); + } + } + + writeEclipseLibrary(target, eclipseVersion); + } + + private static String readUrlAsString(String url) throws MalformedURLException, IOException { + InputStream in = getStreamForUrl(url); + + StringBuilder sb = new StringBuilder(); + + int bufferSize = 1024; + char[] buffer = new char[bufferSize]; + InputStreamReader reader = new InputStreamReader(in, "UTF-8"); + for (int count = 0; (count = reader.read(buffer, 0, bufferSize)) > 0;) { + sb.append(buffer, 0, count); + } + return sb.toString(); + } + + private static void downloadFile(String filename, String repositoryUrl, String target) throws IOException { + Files.createDirectories(Paths.get(target)); + Path targetFile = Paths.get(target, filename); + if (Files.exists(targetFile)) { + System.out.println("File '" + filename + "' already exists"); + return; + } + System.out.print("Downloading '" + filename + "'... "); + try { + Files.copy(getStreamForUrl(repositoryUrl + filename), targetFile, StandardCopyOption.REPLACE_EXISTING); + System.out.println("[done]"); + } catch(IOException e) { + System.out.println("[error]"); + } + } + + private static InputStream getStreamForUrl(String url) throws IOException, MalformedURLException { + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setRequestProperty("User-Agent", "lombok"); + connection.setRequestProperty("Accept", "*/*"); + InputStream in = new BufferedInputStream(connection.getInputStream()); + return in; + } + + private static void writeEclipseLibrary(String target, String eclipseVersion) throws IOException { + StringBuilder sb = new StringBuilder(); + sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); + sb.append("<eclipse-userlibraries version=\"2\">\n"); + sb.append("<library name=\""); + sb.append(eclipseVersion); + sb.append("\" systemlibrary=\"false\">\n"); + + File[] files = new File(new File(target, eclipseVersion), "plugins").listFiles(new FilenameFilter() { + @Override public boolean accept(File dir, String name) { + return name.endsWith(".jar") && !name.contains(".source_"); + } + }); + Arrays.sort(files); + + for (File file : files) { + sb.append("<archive path=\""); + sb.append(file.getAbsolutePath()); + sb.append("\""); + + String path = file.getAbsolutePath(); + int index = path.lastIndexOf("_"); + + sb.append(" source=\""); + sb.append(path.substring(0, index) + ".source" + path.substring(index)); + sb.append("\""); + + sb.append(" />\n"); + } + + sb.append("</library>\n"); + sb.append("</eclipse-userlibraries>\n"); + + Files.writeString(Paths.get(target, eclipseVersion + ".userlibraries"), sb.toString()); + } +} diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index d369b4e4..09855951 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -610,6 +610,8 @@ public class JavacTreeMaker { List<JCTree> labels; if (pat == null) { labels = tryResolve(DefaultCaseLabel) ? List.of(DefaultCaseLabel()) : List.<JCTree>nil(); + } else if (tryResolve(ConstantCaseLabel)) { + labels = List.<JCTree>of(ConstantCaseLabel(pat)); } else { labels = List.<JCTree>of(pat); } @@ -622,6 +624,12 @@ public class JavacTreeMaker { return invoke(DefaultCaseLabel); } + //javac versions: 19 + private static final MethodId<JCTree> ConstantCaseLabel = MethodId("ConstantCaseLabel", JCTree.class, JCExpression.class); + public JCTree ConstantCaseLabel(JCExpression expr) { + return invoke(ConstantCaseLabel, expr); + } + //javac versions: 6-8 private static final MethodId<JCSynchronized> Synchronized = MethodId("Synchronized"); public JCSynchronized Synchronized(JCExpression lock, JCBlock body) { |