diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java index 624e521a49..e5afa7fd7b 100644 --- a/src/utils/lombok/eclipse/Eclipse.java +++ b/src/utils/lombok/eclipse/Eclipse.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2021 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 @@ -21,6 +21,7 @@ */ package lombok.eclipse; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; @@ -279,22 +280,50 @@ private static boolean ecjSupportsJava7Features() { } } - private static boolean caseStatementInit = false; - private static Field caseStatementConstantExpressions = null; + private static final Field CASE_STATEMENT_CONSTANT_EXPRESSIONS = Permit.permissiveGetField(CaseStatement.class, "constantExpressions"); + private static final Constructor CASE_STATEMENT_CONSTRUCTOR_SINGLE; + private static final Constructor CASE_STATEMENT_CONSTRUCTOR_ARRAY; + private static final Expression[] EMPTY_EXPRESSIONS; + static { + Constructor constructorSingle = null, constructorArray = null; + Expression[] emptyExpressions = new Expression[0]; + + try { + constructorSingle = Permit.getConstructor(CaseStatement.class, Expression.class, int.class, int.class); + } catch (NoSuchMethodException ignore) { + } + + try { + constructorArray = Permit.getConstructor(CaseStatement.class, Expression[].class, int.class, int.class); + } catch (NoSuchMethodException ignore) { + } + + try { + emptyExpressions = Permit.get(Permit.permissiveGetField(Expression.class, "NO_EXPRESSIONS"), null); + } catch (Throwable ignore) { + } + + CASE_STATEMENT_CONSTRUCTOR_SINGLE = constructorSingle; + CASE_STATEMENT_CONSTRUCTOR_ARRAY = constructorArray; + EMPTY_EXPRESSIONS = emptyExpressions; + } public static CaseStatement createCaseStatement(Expression expr) { - CaseStatement stat = new CaseStatement(expr, 0, 0); - if (expr == null) return stat; - if (!caseStatementInit) { - try { - caseStatementConstantExpressions = Permit.getField(CaseStatement.class, "constantExpressions"); - caseStatementConstantExpressions.setAccessible(true); - } catch (NoSuchFieldException ignore) {} - caseStatementInit = true; + final CaseStatement stat; + if (CASE_STATEMENT_CONSTRUCTOR_SINGLE != null) { + stat = Permit.newInstanceSneaky(CASE_STATEMENT_CONSTRUCTOR_SINGLE, expr, 0, 0); + if (stat != null && expr != null && CASE_STATEMENT_CONSTANT_EXPRESSIONS != null) { + try { + Permit.set(CASE_STATEMENT_CONSTANT_EXPRESSIONS, stat, new Expression[] {expr}); + } catch (IllegalAccessException ignore) { + } + } + } else { + Expression[] expressions = EMPTY_EXPRESSIONS; + if (expr != null) { + expressions = new Expression[] {expr}; + } + stat = Permit.newInstanceSneaky(CASE_STATEMENT_CONSTRUCTOR_ARRAY, expressions, 0, 0); } - if (caseStatementConstantExpressions != null) try { - caseStatementConstantExpressions.set(stat, new Expression[] {expr}); - } catch (IllegalArgumentException ignore) { - } catch (IllegalAccessException ignore) {} return stat; } } diff --git a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java index 76956aff5f..ba29926e36 100644 --- a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java +++ b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 The Project Lombok Authors. + * 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 @@ -23,6 +23,8 @@ import static lombok.eclipse.RefactoringUtils.performRefactoring; +import java.lang.reflect.Constructor; +import java.util.Map; import java.util.Map.Entry; import org.eclipse.jdt.core.ICompilationUnit; @@ -30,8 +32,8 @@ import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring; import org.eclipse.jdt.internal.corext.fix.CleanUpRegistry; import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.fix.CodeStyleCleanUp; import org.eclipse.jdt.internal.ui.fix.MapCleanUpOptions; +import org.eclipse.jdt.ui.cleanup.ICleanUp; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -59,7 +61,16 @@ public void useThis() throws Exception { CleanUpRefactoring ref = new CleanUpRefactoring(); ref.addCompilationUnit(cu); - ref.addCleanUp(new CodeStyleCleanUp(options.getMap())); + + // Load the class dynamically to avoid compile errors when running with older versions of Eclipse + Class cleanUpClass; + try { + cleanUpClass = Class.forName("org.eclipse.jdt.internal.ui.fix.CodeStyleCleanUp"); + } catch (ClassNotFoundException e) { + cleanUpClass = Class.forName("org.eclipse.jdt.internal.ui.fix.CodeStyleCleanUpCore"); + } + Constructor cleanUpConstructor = cleanUpClass.getConstructor(Map.class); + ref.addCleanUp((ICleanUp) cleanUpConstructor.newInstance(options.getMap())); performRefactoring(ref); }