mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
[java-decompiler] IDEA-352102 support dumb mode in com.intellij.psi.impl.compiled.ClsModifierListImpl.setMirror
GitOrigin-RevId: 3d2e0562124a3fcc75c6f681a475dba59c15d69d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c4cdb539be
commit
795eecd6a7
@@ -1,6 +1,8 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.compiled;
|
||||
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.cache.ModifierFlags;
|
||||
@@ -12,6 +14,10 @@ import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierListStub> implements PsiModifierList {
|
||||
public ClsModifierListImpl(PsiModifierListStub stub) {
|
||||
@@ -136,17 +142,54 @@ public class ClsModifierListImpl extends ClsRepositoryPsiElement<PsiModifierList
|
||||
setMirrorCheckingType(element, JavaElementType.MODIFIER_LIST);
|
||||
PsiAnnotation[] annotations = getAnnotations();
|
||||
PsiAnnotation[] mirrorAnnotations = SourceTreeToPsiMap.<PsiModifierList>treeToPsiNotNull(element).getAnnotations();
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
String qualifiedName = annotation.getQualifiedName();
|
||||
// Annotations could be inconsistent, as in stubs all type annotations are attached to the types
|
||||
// not to modifier list
|
||||
if (qualifiedName != null) {
|
||||
PsiAnnotation mirror = ContainerUtil.find(mirrorAnnotations, m -> qualifiedName.equals(m.getQualifiedName()));
|
||||
// Annotations could be inconsistent, as in stubs all type annotations are attached to the types
|
||||
// not to modifier list
|
||||
Map<String, PsiAnnotation> annotationByShortName = getAnnotationByShortName(annotations);
|
||||
Map<String, PsiAnnotation> mirrorAnnotationByShortName = getAnnotationByShortName(mirrorAnnotations);
|
||||
if (!annotationByShortName.containsKey(null) &&
|
||||
!mirrorAnnotationByShortName.containsKey(null) &&
|
||||
annotationByShortName.size() == annotations.length &&
|
||||
mirrorAnnotationByShortName.size() == mirrorAnnotations.length) {
|
||||
//it is possible to work with short name without resolving
|
||||
for (Map.Entry<String, PsiAnnotation> annotationEntry : annotationByShortName.entrySet()) {
|
||||
String key = annotationEntry.getKey();
|
||||
PsiAnnotation mirror = mirrorAnnotationByShortName.get(key);
|
||||
if (mirror != null) {
|
||||
PsiAnnotation annotation = annotationEntry.getValue();
|
||||
setMirror(annotation, mirror);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
DumbService.getInstance(getProject()).runWithAlternativeResolveEnabled(() -> {
|
||||
//necessary to use AlternativeResolver, because of getQualifiedName()
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
String qualifiedName = annotation.getQualifiedName();
|
||||
if (qualifiedName != null) {
|
||||
PsiAnnotation mirror = ContainerUtil.find(mirrorAnnotations, m -> qualifiedName.equals(m.getQualifiedName()));
|
||||
if (mirror != null) {
|
||||
setMirror(annotation, mirror);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, PsiAnnotation> getAnnotationByShortName(@NotNull PsiAnnotation @NotNull [] annotations) {
|
||||
HashMap<String, PsiAnnotation> result = new HashMap<>();
|
||||
for (@NotNull PsiAnnotation annotation : annotations) {
|
||||
result.put(getAnnotationReferenceShortName(annotation), annotation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static @Nullable String getAnnotationReferenceShortName(@NotNull PsiAnnotation annotation) {
|
||||
PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
|
||||
if (referenceElement == null) return null;
|
||||
String name = referenceElement.getReferenceName();
|
||||
if (name == null) return null;
|
||||
return StringUtil.getShortName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
// IntelliJ API Decompiler stub source generated from a class file
|
||||
// Implementation of methods is not available
|
||||
|
||||
package com.demo;
|
||||
|
||||
public class FieldWithSimilarAnnotation {
|
||||
private static final long serialVersionUID = -1L;
|
||||
@javax.validation.constraints.NotNull(groups = {com.demo.SupplierSubmit.class})
|
||||
@io.swagger.v3.oas.annotations.media.Schema(description = "desc")
|
||||
@com.demo.NotNull
|
||||
private java.lang.@javax.validation.constraints.NotNull(groups = {com.demo.SupplierSubmit.class}) Long id;
|
||||
|
||||
protected FieldWithSimilarAnnotation(com.demo.FieldWithSimilarAnnotation.FieldWithSimilarAnnotationBuilder<?,?> b) { /* compiled code */ }
|
||||
|
||||
public static com.demo.FieldWithSimilarAnnotation.FieldWithSimilarAnnotationBuilder<?,?> builder() { /* compiled code */ }
|
||||
|
||||
public java.lang.Long getId() { /* compiled code */ }
|
||||
|
||||
public void setId(java.lang.Long id) { /* compiled code */ }
|
||||
|
||||
public java.lang.String toString() { /* compiled code */ }
|
||||
|
||||
public boolean equals(java.lang.Object o) { /* compiled code */ }
|
||||
|
||||
protected boolean canEqual(java.lang.Object other) { /* compiled code */ }
|
||||
|
||||
public int hashCode() { /* compiled code */ }
|
||||
|
||||
public FieldWithSimilarAnnotation() { /* compiled code */ }
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
|
||||
package com.demo;
|
||||
//
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@SuperBuilder
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@NoArgsConstructor
|
||||
public class FieldWithSimilarAnnotation {
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
@com.demo.NotNull
|
||||
@NotNull(groups = {SupplierSubmit.class})
|
||||
@Schema(description ="desc")
|
||||
private Long id;
|
||||
|
||||
}
|
||||
@@ -16,7 +16,9 @@ import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import com.intellij.psi.impl.compiled.InnerClassSourceStrategy;
|
||||
import com.intellij.psi.impl.compiled.StubBuildingVisitor;
|
||||
import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
|
||||
import com.intellij.testFramework.DumbModeTestUtils;
|
||||
import com.intellij.testFramework.LightIdeaTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||
|
||||
import java.io.File;
|
||||
@@ -62,6 +64,30 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
|
||||
public void testInheritFromDollar$1() { doTest(); }
|
||||
public void testSealed() { doTest(); }
|
||||
public void testCompanyDO() { doTest(); }
|
||||
public void testCompanyDOInDumbMode() {
|
||||
testDumbMode("CompanyDO");
|
||||
}
|
||||
|
||||
public void testFieldWithSimilarAnnotation() {
|
||||
testDumbMode("FieldWithSimilarAnnotation");
|
||||
}
|
||||
|
||||
private void testDumbMode(String testName) {
|
||||
String testDir = getTestDataDir();
|
||||
String clsPath = getClsPath(testName, testDir);
|
||||
String txtPath = getTxtPath(testName, testDir);
|
||||
VirtualFile file = (clsPath.contains("!/") ? StandardFileSystems.jar() : StandardFileSystems.local()).refreshAndFindFileByPath(clsPath);
|
||||
assertNotNull(clsPath, file);
|
||||
|
||||
DumbModeTestUtils.runInDumbModeSynchronously(getProject(), () -> {
|
||||
assertSameLinesWithFile(txtPath, ClsFileImpl.decompile(file).toString());
|
||||
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file);
|
||||
if (psiFile instanceof PsiCompiledElement compiledElement) {
|
||||
PsiElement mirror = compiledElement.getMirror();
|
||||
assertNotNull(mirror);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testTextPsiMismatch() {
|
||||
CommonCodeStyleSettings.IndentOptions options = CodeStyle.getSettings(getProject()).getIndentOptions(JavaFileType.INSTANCE);
|
||||
@@ -187,7 +213,15 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
|
||||
|
||||
private static void doTest(String name) {
|
||||
String testDir = getTestDataDir();
|
||||
doTest(testDir + "pkg/" + name + ".class", testDir + name + ".txt");
|
||||
doTest(getClsPath(name, testDir), getTxtPath(name, testDir));
|
||||
}
|
||||
|
||||
private static @NotNull String getTxtPath(String name, String testDir) {
|
||||
return testDir + name + ".txt";
|
||||
}
|
||||
|
||||
private static @NotNull String getClsPath(String name, String testDir) {
|
||||
return testDir + "pkg/" + name + ".class";
|
||||
}
|
||||
|
||||
private static void doTest(String clsPath, String txtPath) {
|
||||
|
||||
Reference in New Issue
Block a user