diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index b6ebe59e92d5..098feac7b7d2 100644 --- a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -1,6 +1,7 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.java.decompiler.main.rels; +import org.jetbrains.annotations.Nullable; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; @@ -256,7 +257,6 @@ public class NestedClassProcessor { private static void computeLocalVarsAndDefinitions(ClassNode node) { // class name -> constructor descriptor -> var to field link Map>> mapVarMasks = new HashMap<>(); - int clTypes = 0; for (ClassNode nd : node.nested) { @@ -409,12 +409,17 @@ public class NestedClassProcessor { var attr = wrapper.methodStruct.getAttribute(StructGeneralAttribute.ATTRIBUTE_METHOD_PARAMETERS); if (attr != null) { for (var param : attr.getEntries()) { - mask.add((param.myAccessFlags & (CodeConstants.ACC_SYNTHETIC | CodeConstants.ACC_MANDATED)) == 0 ? null : new VarVersionPair(-1, 0)); + mask.add((param.myAccessFlags & (CodeConstants.ACC_SYNTHETIC | CodeConstants.ACC_MANDATED)) == 0 && + !groovyClosure(nestedNode) ? null : new VarVersionPair(-1, 0)); } } else { for (VarFieldPair pair : entry.getValue()) { VarVersionPair ver = pair != null && !pair.fieldKey.isEmpty() ? pair.varPair : null; - if (ver == null && mask.isEmpty() && nestedNode.type == ClassNode.CLASS_MEMBER && !ExprUtil.isStatic(nestedNode.classStruct)) { + if (ver == null && mask.isEmpty() && + nestedNode.type == ClassNode.CLASS_MEMBER && + !ExprUtil.isStatic(nestedNode.classStruct) && + (nestedNode.classStruct.getAccessFlags() & CodeConstants.ACC_ENUM) == 0 && //!enum + !groovyClosure(nestedNode)) { ver = new VarVersionPair(-1, 0); // non-static inners always have 'Outer.this' } mask.add(ver); @@ -425,6 +430,17 @@ public class NestedClassProcessor { } } + private static boolean groovyClosure(@Nullable ClassNode node) { + if (node == null) { + return false; + } + if (node.simpleName == null || !node.simpleName.startsWith("_closure")) return false; + StructClass struct = node.classStruct; + if (struct == null) return false; + if (struct.superClass == null || !struct.superClass.value.equals("groovy/lang/Closure")) return false; + return true; + } + private static void insertLocalVars(ClassNode parent, ClassNode child) { // enclosing method, is null iff member class MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); diff --git a/plugins/java-decompiler/engine/testData/results/TestFinally.dec b/plugins/java-decompiler/engine/testData/results/TestFinally.dec index 44023820b9f7..bcfc4ee2d794 100644 --- a/plugins/java-decompiler/engine/testData/results/TestFinally.dec +++ b/plugins/java-decompiler/engine/testData/results/TestFinally.dec @@ -24,8 +24,6 @@ public class TestFinally { }// 30 public class A { - public A(final TestFinally this$0) { - }// 8 } } @@ -80,14 +78,7 @@ class 'pkg/TestFinally' { } } -class 'pkg/TestFinally$A' { - method ' (Lpkg/TestFinally;)V' { - 4 27 - } -} - Lines mapping: -8 <-> 28 13 <-> 8 15 <-> 9 16 <-> 10 diff --git a/plugins/java-decompiler/plugin/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.kt b/plugins/java-decompiler/plugin/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.kt index 0e265d78e2f5..9f1437cf277b 100644 --- a/plugins/java-decompiler/plugin/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.kt +++ b/plugins/java-decompiler/plugin/test/org/jetbrains/java/decompiler/IdeaDecompilerTest.kt @@ -69,7 +69,6 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() { Registry.get("decompiler.dump.original.lines").withValue(true) { VfsUtilCore.visitChildrenRecursively(getTestFile("${JavaTestUtil.getJavaTestDataPath()}/psi/cls/mirror"), visitor) VfsUtilCore.visitChildrenRecursively(getTestFile("${PluginPathManager.getPluginHomePath("java-decompiler")}/engine/testData/classes"), visitor) - VfsUtilCore.visitChildrenRecursively(getTestFile("${PluginPathManager.getPluginHomePath("java-decompiler")}/engine/testData/classes"), visitor) VfsUtilCore.visitChildrenRecursively(getTestFile("${IdeaTestUtil.getMockJdk18Path().path}/jre/lib/rt.jar!/java/lang"), visitor) } }