projectlombok.org/ 版本 1.18.23
查看ant版本 D:\git\lombok\buildScripts\setup.ant.xml,已经提示ant需要至少1.10.9,jdk必须jdk11以上才能编译
<fail>ant needs to be at least v1.10.0 or higher to build lombok. Your version is: ${ant.version}
<condition>
<not><antversion atleast="1.10.0" /></not>
</condition>
</fail>
<fail>lombok must be compiled on jdk11 or later. Your version is: ${ant.java.version}
<condition>
<not><matches string="${ant.java.version}" pattern="${pattern.jdk11plus}" /></not>
</condition>
</fail>
设置ant环境变量,jdk环境变量,运行即可查看,操作步骤,写得很详细。
D:\git\lombok>ant
Buildfile: D:\git\lombok\build.xml
quickstart:
[echo]
[echo] Dear contributor,
[echo]
[echo] For full instructions and information on what this project contains, run:
[echo]
[echo] > ant help
[echo]
[echo] If you want to get started quickly:
[echo]
[echo] 1. Run `ant eclipse`.
[echo] 2. Start up eclipse (https://www.eclipse.org/).
[echo] 3. In the menu: File > Import... > Existing Project Into Workspace
[echo] 4. Browse to this directory and import it:
[echo] (D:\git\lombok)
[echo] 5. In eclipse: Run > Debug configurations... >
[echo] then pick one of the configs named `Lombok test`.
[echo] 6. Run `ant dist`.
[echo]
[echo] Have fun!
BUILD SUCCESSFUL
Total time: 0 seconds
D:\git\lombok>
用eclipse调试一个,就用自带的 D:\git\lombok\test\transform\src\lombok\transform\TestWithDelombok.java
test/transform/resource/before这里面类太多了,
就用这个,这个简单
class AccessorsMakeFinalLombokConfig {
@lombok.Setter
private String test;
}
D:\git\lombok\test\core\src\lombok\DirectoryRunner.java这个accept方法改一下,只调试一个简单的类
private static final FileFilter JAVA_FILE_FILTER = new FileFilter() {
@Override public boolean accept(File file) {
if(file.getName().equals("AccessorsMakeFinalLombokConfig.java")) {
return true;
}
return false;
// if (!file.isFile() || !file.getName().endsWith(".java")) return false;
// boolean positiveFilter = false;
// for (String dfof : DEBUG_FOCUS_ON_FILE) {
// if (dfof.isEmpty()) continue;
// if (!dfof.endsWith(".java")) dfof = dfof + ".java";
// boolean invert = dfof.startsWith("!");
// if (invert) dfof = dfof.substring(1);
// positiveFilter = positiveFilter || !invert;
// int starIdx = dfof.indexOf('*');
// if (starIdx == -1) {
// if (file.getName().equals(dfof)) return !invert;
// } else {
// if (file.getName().startsWith(dfof.substring(0, starIdx)) && file.getName().endsWith(dfof.substring(starIdx + 1))) return !invert;
// }
// }
// return !positiveFilter;
}
};
调试一下,decl就是set方法
记录一下调试的调用
Thread [main] (Suspended)
HandleSetter.createSetterWithRecv(long, boolean, JavacNode, JavacTreeMaker, String, Name, Name, JCExpression, JCStatement, JavacNode, List<JCAnnotation>, List<JCAnnotation>, JCVariableDecl) line: 289
HandleSetter.createSetter(long, boolean, JavacNode, JavacTreeMaker, String, Name, Name, JCExpression, JCStatement, JavacNode, List<JCAnnotation>, List<JCAnnotation>) line: 222
HandleSetter.createSetter(long, boolean, JavacNode, JavacTreeMaker, String, Name, Name, boolean, JavacNode, List<JCAnnotation>, List<JCAnnotation>) line: 205
HandleSetter.createSetter(long, JavacNode, JavacTreeMaker, JavacNode, List<JCAnnotation>, List<JCAnnotation>) line: 192
HandleSetter.createSetterForField(AccessLevel, JavacNode, JavacNode, boolean, List<JCAnnotation>, List<JCAnnotation>) line: 184
HandleSetter.createSetterForFields(AccessLevel, Collection<JavacNode>, JavacNode, boolean, List<JCAnnotation>, List<JCAnnotation>) line: 140
HandleSetter.handle(AnnotationValues<Setter>, JCAnnotation, JavacNode) line: 130
HandlerLibrary$AnnotationHandlerContainer<T>.handle(JavacNode) line: 113
HandlerLibrary.handleAnnotation(JCTree$JCCompilationUnit, JavacNode, JCTree$JCAnnotation, long) line: 256
JavacTransformer$AnnotationVisitor.visitAnnotationOnField(JCTree$JCVariableDecl, JavacNode, JCTree$JCAnnotation) line: 84
JavacNode.traverse(JavacASTVisitor) line: 135
JavacAST.traverseChildren(JavacASTVisitor, JavacNode) line: 222
JavacNode.traverse(JavacASTVisitor) line: 100
JavacAST.traverseChildren(JavacASTVisitor, JavacNode) line: 222
JavacNode.traverse(JavacASTVisitor) line: 95
JavacAST.traverseChildren(JavacASTVisitor, JavacNode) line: 222
JavacNode.traverse(JavacASTVisitor) line: 90
JavacAST.traverse(JavacASTVisitor) line: 218
JavacTransformer.transform(long, Context, List<JCCompilationUnit>, CleanupRegistry) line: 63
LombokProcessor.process(Set<TypeElement>, RoundEnvironment) line: 328
JavacProcessingEnvironment.callProcessor(Processor, Set<TypeElement>, RoundEnvironment) line: 1023
JavacProcessingEnvironment.discoverAndRunProcs(Set<TypeElement>, List<ClassSymbol>, List<PackageSymbol>, List<ModuleSymbol>) line: 939
JavacProcessingEnvironment$Round.run(boolean, boolean) line: 1267
JavacProcessingEnvironment.doProcessing(List<JCCompilationUnit>, List<ClassSymbol>, Iterable<PackageSymbol>, DeferredDiagnosticHandler) line: 1382
JavaCompiler.processAnnotations(List<JCCompilationUnit>, Collection<String>) line: 1234
Delombok.delombok() line: 788
RunTestsViaDelombok.transformCode(Collection<CompilerMessage>, StringWriter, File, String, Map<String,String>, int, boolean) line: 93
AbstractRunTests$1.runTest() line: 97
DirectoryRunner.run(RunNotifier) line: 170
JUnit4TestReference.run(TestExecution) line: 93
TestExecution.run(ITestReference[]) line: 40
RemoteTestRunner.runTests(String[], String, TestExecution) line: 529
RemoteTestRunner.runTests(TestExecution) line: 756
RemoteTestRunner.run() line: 452
RemoteTestRunner.main(String[]) line: 210
D:\git\lombok\test\core\src\lombok\AbstractRunTests.java expected和actualFile是否一致。
private void compare(String name, LombokTestSource expected, String actualFile, LinkedHashSet<CompilerMessage> actualMessages, boolean printErrors, boolean skipCompareContent) throws Throwable {
if (!skipCompareContent) try {
compareContent(name, expected.getContent(), actualFile);
} catch (Throwable e) {
if (printErrors) {
System.out.println("***** " + name + " *****");
System.out.println(e.getMessage());
System.out.println("**** Expected ******");
System.out.println(expected.getContent());
System.out.println("**** Actual ******");
System.out.println(actualFile);
if (actualMessages != null && !actualMessages.isEmpty()) {
System.out.println("**** Actual Errors *****");
for (CompilerMessage actualMessage : actualMessages) {
System.out.println(actualMessage);
}
}
System.out.println("*******************");
}
if (dumpActualFilesHere != null) {
dumpToFile(new File(dumpActualFilesHere, name), actualFile);
}
throw e;
}
try {
compareMessages(name, expected.getMessages(), actualMessages);
} catch (Throwable e) {
if (printErrors) {
System.out.println("***** " + name + " *****");
System.out.println(e.getMessage());
System.out.println("**** Expected ******");
for (CompilerMessageMatcher expectedMessage : expected.getMessages()) {
System.out.println(expectedMessage);
}
System.out.println("**** Actual ******");
for (CompilerMessage actualMessage : actualMessages) {
System.out.println(actualMessage);
}
System.out.println("**** Actual File ******");
System.out.println(lineNumber(actualFile));
System.out.println("*******************");
}
if (dumpActualFilesHere != null) {
dumpToFile(new File(dumpActualFilesHere, name + ".messages"), actualMessages);
}
throw e;
}
}
expected就是getAfterDirectory()里面写好的文件。
/*
* Copyright (C) 2009-2021 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.transform;
import java.io.File;
import lombok.DirectoryRunner;
import org.junit.runner.RunWith;
@RunWith(DirectoryRunner.class)
public class TestWithDelombok extends DirectoryRunner.TestParams {
@Override
public DirectoryRunner.Compiler getCompiler() {
return DirectoryRunner.Compiler.DELOMBOK;
}
@Override
public boolean printErrors() {
return true;
}
@Override
public File getBeforeDirectory() {
return new File("test/transform/resource/before");
}
@Override
public File getAfterDirectory() {
return new File("test/transform/resource/after-delombok");
}
@Override
public File getMessagesDirectory() {
return new File("test/transform/resource/messages-delombok");
}
@Override
public boolean expectChanges() {
return true;
}
@Override public String testNamePrefix() {
return "javac-";
}
}
这个只调试了一个setter,如下图还有很多。常用的HandlerData可以再里面设置断点,自己调试。