Skip to content

Commit

Permalink
Merge pull request #3587 from Rawi01/eclipse_fieldInitializer
Browse files Browse the repository at this point in the history
Set real field initializer source in eclipse
  • Loading branch information
rzwitserloot committed Jan 17, 2024
2 parents fd55c7a + 2db9ca7 commit 946c60a
Show file tree
Hide file tree
Showing 18 changed files with 466 additions and 3 deletions.
39 changes: 38 additions & 1 deletion src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2023 The Project Lombok Authors.
* Copyright (C) 2009-2024 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
Expand Down Expand Up @@ -100,6 +100,7 @@ public String mapResourceName(int classFileFormatVersion, String resourceName) {
patchJavadoc(sm);
patchASTConverterLiterals(sm);
patchASTNodeSearchUtil(sm);
patchFieldInitializer(sm);

patchPostCompileHookEcj(sm);

Expand Down Expand Up @@ -1029,6 +1030,42 @@ private static void patchASTNodeSearchUtil(ScriptManager sm) {
.build());
}

private static void patchFieldInitializer(ScriptManager sm) {
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")
.fieldName("$fieldInfo")
.fieldType("Ljava/lang/Object;")
.build());

sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
.targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")
.fieldName("$sourceFieldElementInfo")
.fieldType("Lorg/eclipse/jdt/internal/core/SourceFieldElementInfo;")
.build());

sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
.decisionMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeFieldInfo", "boolean", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
.request(StackRequest.THIS)
.transplant()
.build());

sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
.methodToWrap(new Hook("org.eclipse.jdt.internal.core.SourceFieldElementInfo", "<init>", "void"))
.wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeSourceFieldElementInfo", "void", "org.eclipse.jdt.internal.core.SourceFieldElementInfo", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
.requestExtra(StackRequest.THIS)
.transplant()
.build());

sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
.wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "overwriteInitializer", "void", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
.request(StackRequest.THIS)
.transplant()
.build());
}

private static void patchCrossModuleClassLoading(ScriptManager sm) {
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "<clinit>"))
Expand Down
68 changes: 67 additions & 1 deletion src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2023 The Project Lombok Authors.
* Copyright (C) 2010-2024 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
Expand Down Expand Up @@ -52,7 +52,9 @@
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.FieldInfo;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
Expand All @@ -61,7 +63,9 @@
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor;
import org.eclipse.jdt.internal.core.SourceField;
import org.eclipse.jdt.internal.core.SourceFieldElementInfo;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner;
Expand Down Expand Up @@ -935,6 +939,68 @@ public static String[] getRealCodeBlocks(String[] blocks, SourceProvider sourceP
}
}

public static class FieldInitializer {
public static final Field INFO_STACK;
public static final Field FIELD_INFO;
public static final Field SOURCE_FIELD_ELEMENT_INFO;
public static final Field INITIALIZATION_SOURCE;
public static final Field NODE;
public static final boolean INITIALIZED;

static {
INFO_STACK = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "infoStack");
FIELD_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$fieldInfo");
SOURCE_FIELD_ELEMENT_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$sourceFieldElementInfo");
INITIALIZATION_SOURCE = Permit.permissiveGetField(SourceFieldElementInfo.class, "initializationSource");
NODE = Permit.permissiveGetField(FieldInfo.class, "node");
INITIALIZED = INFO_STACK != null && FIELD_INFO != null && SOURCE_FIELD_ELEMENT_INFO != null && INITIALIZATION_SOURCE != null && NODE != null;
}

public static boolean storeFieldInfo(CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
try {
if (INITIALIZED) {
Stack<?> infoStack = Permit.get(INFO_STACK, compilationUnitStructureRequestor);
Object fieldInfo = infoStack.peek();
Permit.set(FIELD_INFO, compilationUnitStructureRequestor, fieldInfo);
}
} catch (Exception e) {
// do not break eclipse
}
return false;
}
public static void storeSourceFieldElementInfo(SourceFieldElementInfo fieldInfo, CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
try {
if (INITIALIZED) {
Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, fieldInfo);
}
} catch (Exception e) {
// do not break eclipse
}
}

public static void overwriteInitializer(CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
try {
if (INITIALIZED) {
FieldInfo fieldInfo = Permit.get(FIELD_INFO, compilationUnitStructureRequestor);
Permit.set(FIELD_INFO, compilationUnitStructureRequestor, null);

SourceFieldElementInfo sourceFieldElementInfo = Permit.get(SOURCE_FIELD_ELEMENT_INFO,compilationUnitStructureRequestor);
Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, null);

if (sourceFieldElementInfo.getInitializationSource() != null) {
AbstractVariableDeclaration node = Permit.get(NODE, fieldInfo);

if (PatchFixes.isGenerated(node)) {
Permit.set(INITIALIZATION_SOURCE, sourceFieldElementInfo, node.initialization.toString().toCharArray());
}
}
}
} catch (Exception e) {
// do not break eclipse
}
}
}

public static class Tests {
public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
return (StringBuffer) printMethod(methodDeclaration, tab, (Object) output, type);
Expand Down
@@ -0,0 +1,5 @@
package pkg;

public @interface Annotation {
String value();
}
@@ -0,0 +1,8 @@
package pkg;

import lombok.experimental.FieldNameConstants;

@FieldNameConstants
public class Constants {
String test;
}
@@ -0,0 +1,5 @@
package pkg;

@Annotation(Constants.Fields.test)
public class Usage {
}
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/EclipseRunner.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022 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.eclipse;

import java.io.File;
Expand Down
24 changes: 23 additions & 1 deletion test/eclipse/src/lombok/eclipse/EclipseTests.java
@@ -1,18 +1,40 @@
/*
* Copyright (C) 2022-2024 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.eclipse;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

import lombok.eclipse.cleanup.CleanupTest;
import lombok.eclipse.compile.NoErrorsTest;
import lombok.eclipse.edit.SelectTest;
import lombok.eclipse.refactoring.ExtractInterfaceTest;
import lombok.eclipse.refactoring.InlineTest;
import lombok.eclipse.refactoring.RenameTest;
import lombok.eclipse.references.FindReferencesTest;

@RunWith(Suite.class)
@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class})
@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class})
public class EclipseTests {

}
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/RefactoringUtils.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022 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.eclipse;

import static org.junit.Assert.assertTrue;
Expand Down
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022-2023 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.eclipse;

import static org.junit.Assert.assertEquals;
Expand Down
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022 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.eclipse;

import java.io.File;
Expand Down
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/SetupTest.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022 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.eclipse;

import java.io.File;
Expand Down
21 changes: 21 additions & 0 deletions test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java
@@ -1,3 +1,24 @@
/*
* Copyright (C) 2022 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.eclipse.cleanup;

import static lombok.eclipse.RefactoringUtils.performRefactoring;
Expand Down

0 comments on commit 946c60a

Please sign in to comment.