[java-decompiler] IDEA-376435 "ClsElementImpl - Mirror wasn't set for PsiMethod" error when invoking PsiElement#getText() on a constructor

GitOrigin-RevId: 534662f7674a1023a124322be5145e02a192008d
This commit is contained in:
Mikhail Pyltsin
2025-11-25 18:04:13 +00:00
committed by intellij-monorepo-bot
parent 2c7b959813
commit 44849afee7
3 changed files with 26 additions and 23 deletions
@@ -28,10 +28,7 @@ import org.jetbrains.java.decompiler.IdeaDecompilerSettings;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
@@ -298,19 +295,22 @@ public class ClsPsiTest extends LightIdeaTestCase {
}
}, () -> {
PsiClass aClass = getFile("Modifiers").getClasses()[0];
PsiMethod constructor = aClass.getMethods()[0];
PsiMethod[] methods = aClass.getMethods();
PsiMethod constructor = Arrays.stream(methods)
.filter(t -> t.isConstructor())
.findFirst().get();
ClsModifierListImpl modifierList = (ClsModifierListImpl)constructor.getModifierList();
ClsReferenceListImpl throwsList = (ClsReferenceListImpl)constructor.getThrowsList();
// We are actually most interested in the side effect of calls to getText() (we want to ensure no warnings are being logged)
assertNull(modifierList.getMirror());
assertNotNull(modifierList.getMirror());
assertEquals("public", modifierList.getText());
assertNull(modifierList.getMirror()); // assert that calling getText() does not set a mirror
assertNotNull(modifierList.getMirror()); // assert that calling getText() does not set a mirror
assertNull(throwsList.getMirror());
assertNotNull(throwsList.getMirror());
assertEquals("", throwsList.getText());
assertNull(throwsList.getMirror()); // assert that calling getText() does not set a mirror
assertNotNull(throwsList.getMirror()); // assert that calling getText() does not set a mirror
});
assertEmpty(warnings);
@@ -42,7 +42,8 @@ private val highPreset: Map<String, String> = basePreset + mapOf(
IFernflowerPreferences.DECOMPILE_CLASS_1_4 to "1",
IFernflowerPreferences.DECOMPILE_ASSERTIONS to "1",
IFernflowerPreferences.HIDE_EMPTY_SUPER to "1",
IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR to "1",
//it is better to show it because it is hard to skip it in the stub builder
IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR to "0",
IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES to "1",
IFernflowerPreferences.NO_EXCEPTIONS_RETURN to "1",
IFernflowerPreferences.DECOMPILE_ENUM to "1",
@@ -129,9 +129,9 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
IdeaDecompilerSettings.getInstance().loadState(state)
myFixture.openFileInEditor(getTestFile("Navigation.class"))
doTestNavigation(8, 14, 11, 10) // to "m2()"
doTestNavigation(12, 21, 11, 17) // to "int i"
doTestNavigation(13, 28, 12, 13) // to "int r"
doTestNavigation(11, 14, 14, 10) // to "m2()"
doTestNavigation(15, 21, 14, 17) // to "int i"
doTestNavigation(16, 28, 15, 13) // to "int r"
}
fun testNavigation_medium() {
@@ -177,19 +177,19 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
myFixture.setReadEditorMarkupModel(true)
IdentifierHighlighterPassFactory.doWithIdentifierHighlightingEnabled(project, Runnable {
myFixture.openFileInEditor(getTestFile("Navigation.class"))
myFixture.editor.caretModel.moveToOffset(offset(8, 14)) // m2(): usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(11, 14)) // m2(): usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(11, 10)) // m2(): usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(14, 10)) // m2(): usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(11, 17)) // int i: usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(14, 17)) // int i: usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(12, 21)) // int i: usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(15, 21)) // int i: usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(12, 13)) // int r: usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(15, 13)) // int r: usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(13, 28)) // int r: usage, declaration
myFixture.editor.caretModel.moveToOffset(offset(16, 28)) // int r: usage, declaration
assertEquals(2, highlightUnderCaret().size)
myFixture.editor.caretModel.moveToOffset(offset(16, 24)) // throws: declaration, m4() call
myFixture.editor.caretModel.moveToOffset(offset(19, 24)) // throws: declaration, m4() call
assertEquals(2, highlightUnderCaret().size)
})
}
@@ -245,9 +245,9 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
}
fun testLineNumberMapping_high() = doTestLineMapping(DecompilerPreset.HIGH) { mapping ->
assertEquals(8, mapping.bytecodeToSource(3)) // Assert that line 8 in decompiled class file maps to line 3 in Java source file
assertEquals(18, mapping.bytecodeToSource(13))
assertEquals(13, mapping.sourceToBytecode(18)) // Assert that line 13 in Java source file maps to line 18 in Java class file
assertEquals(11, mapping.bytecodeToSource(3)) // Assert that line 8 in decompiled class file maps to line 3 in Java source file
assertEquals(21, mapping.bytecodeToSource(13))
assertEquals(13, mapping.sourceToBytecode(21)) // Assert that line 13 in Java source file maps to line 18 in Java class file
assertEquals(-1, mapping.bytecodeToSource(1000))
assertEquals(-1, mapping.sourceToBytecode(1000))
}
@@ -309,9 +309,11 @@ class IdeaDecompilerTest : LightJavaCodeInsightFixtureTestCase() {
-StructureView.java
-StructureView
-B
B()
-build(int): StructureView
-$1
class initializer
StructureView()
getData(): int
setData(int): void
data: int""")