Restructure JetDecompiledData
JetDecompiledData now stores file text and uses descriptors serialized to String to find declarations
This commit is contained in:
@@ -16,74 +16,64 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.libraries;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.impl.compiled.ClsElementImpl;
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||
import org.jetbrains.jet.lang.resolve.MemberComparator;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.KotlinClassFileHeader;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.jet.renderer.DescriptorRendererBuilder;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DecompiledDataFactory {
|
||||
import static org.jetbrains.jet.plugin.libraries.JetDecompiledData.descriptorToKey;
|
||||
|
||||
public final class DecompiledDataFactory {
|
||||
private static final String DECOMPILED_COMMENT = "/* compiled code */";
|
||||
private static final DescriptorRenderer DESCRIPTOR_RENDERER =
|
||||
public static final DescriptorRenderer DESCRIPTOR_RENDERER =
|
||||
new DescriptorRendererBuilder().setWithDefinedIn(false).setClassWithPrimaryConstructor(true).build();
|
||||
|
||||
@NotNull
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
private final ClsFileImpl clsFile;
|
||||
private final BindingContext bindingContext;
|
||||
private final Map<PsiElement, TextRange> clsMembersToRanges = new HashMap<PsiElement, TextRange>();
|
||||
|
||||
private final Map<ClsElementImpl, JetDeclaration> clsElementsToJetElements = new HashMap<ClsElementImpl, JetDeclaration>();
|
||||
@NotNull
|
||||
private final Map<String, TextRange> renderedDescriptorsToRange = new HashMap<String, TextRange>();
|
||||
@NotNull
|
||||
private final JavaDescriptorResolver javaDescriptorResolver;
|
||||
@NotNull
|
||||
private final KotlinClassFileHeader kotlinClassFileHeader;
|
||||
@NotNull
|
||||
private final VirtualFile classFile;
|
||||
@NotNull
|
||||
private final Project project;
|
||||
|
||||
private DecompiledDataFactory(ClsFileImpl clsFile) {
|
||||
this.clsFile = clsFile;
|
||||
|
||||
BindingTraceContext trace = new BindingTraceContext();
|
||||
this.bindingContext = trace.getBindingContext();
|
||||
InjectorForJavaDescriptorResolver injector = new InjectorForJavaDescriptorResolver(clsFile.getProject(), trace);
|
||||
private DecompiledDataFactory(@NotNull VirtualFile classFile, @NotNull Project project) {
|
||||
this.classFile = classFile;
|
||||
this.project = project;
|
||||
InjectorForJavaDescriptorResolver injector =
|
||||
new InjectorForJavaDescriptorResolver(project, new BindingTraceContext());
|
||||
this.javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||
this.kotlinClassFileHeader = KotlinClassFileHeader.readKotlinHeaderFromClassFile(classFile);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static JetDecompiledData createDecompiledData(@NotNull ClsFileImpl clsFile) {
|
||||
return new DecompiledDataFactory(clsFile).build();
|
||||
static JetDecompiledData createDecompiledData(@NotNull VirtualFile virtualFile, @NotNull Project project) {
|
||||
return new DecompiledDataFactory(virtualFile, project).build();
|
||||
}
|
||||
|
||||
private JetDecompiledData build() {
|
||||
builder.append("// IntelliJ API Decompiler stub source generated from a class file\n" +
|
||||
"// Implementation of methods is not available");
|
||||
builder.append("\n\n");
|
||||
|
||||
String packageName = clsFile.getPackageName();
|
||||
if (packageName.length() > 0) {
|
||||
builder.append("package ").append(packageName).append("\n\n");
|
||||
}
|
||||
|
||||
PsiClass psiClass = clsFile.getClasses()[0];
|
||||
|
||||
if (DescriptorResolverUtils.isCompiledKotlinPackageClass(psiClass)) {
|
||||
NamespaceDescriptor nd = javaDescriptorResolver.resolveNamespace(new FqName(packageName), DescriptorSearchRule.INCLUDE_KOTLIN);
|
||||
|
||||
FqName packageFqName = kotlinClassFileHeader.getJvmClassName().getFqName().parent();
|
||||
appendDecompiledTextAndPackageName(packageFqName);
|
||||
KotlinClassFileHeader.HeaderType type = kotlinClassFileHeader.getType();
|
||||
if (type == KotlinClassFileHeader.HeaderType.PACKAGE) {
|
||||
NamespaceDescriptor nd = javaDescriptorResolver.resolveNamespace(packageFqName, DescriptorSearchRule.INCLUDE_KOTLIN);
|
||||
if (nd != null) {
|
||||
for (DeclarationDescriptor member : sortDeclarations(nd.getMemberScope().getAllDescriptors())) {
|
||||
if (member instanceof ClassDescriptor || member instanceof NamespaceDescriptor
|
||||
@@ -96,29 +86,28 @@ public class DecompiledDataFactory {
|
||||
}
|
||||
}
|
||||
else {
|
||||
ClassDescriptor cd = javaDescriptorResolver.resolveClass(new FqName(psiClass.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN);
|
||||
assert type == KotlinClassFileHeader.HeaderType.CLASS;
|
||||
ClassDescriptor cd = javaDescriptorResolver.resolveClass(kotlinClassFileHeader.getJvmClassName().getFqName(),
|
||||
DescriptorSearchRule.INCLUDE_KOTLIN);
|
||||
if (cd != null) {
|
||||
appendDescriptor(cd, "");
|
||||
}
|
||||
}
|
||||
|
||||
JetFile jetFile = JetDummyClassFileViewProvider.createJetFile(clsFile.getManager(), clsFile.getVirtualFile(), builder.toString());
|
||||
for (Map.Entry<PsiElement, TextRange> clsMemberToRange : clsMembersToRanges.entrySet()) {
|
||||
PsiElement clsMember = clsMemberToRange.getKey();
|
||||
assert clsMember instanceof ClsElementImpl;
|
||||
|
||||
TextRange range = clsMemberToRange.getValue();
|
||||
JetDeclaration jetDeclaration = PsiTreeUtil.findElementOfClassAtRange(jetFile, range.getStartOffset(), range.getEndOffset(),
|
||||
JetDeclaration.class);
|
||||
assert jetDeclaration != null : "Can't find declaration at " + range + ": "
|
||||
+ jetFile.getText().substring(range.getStartOffset(), range.getEndOffset());
|
||||
clsElementsToJetElements.put((ClsElementImpl) clsMember, jetDeclaration);
|
||||
}
|
||||
|
||||
return new JetDecompiledData(jetFile, clsElementsToJetElements);
|
||||
JetFile jetFile = JetDummyClassFileViewProvider.createJetFile(PsiManager.getInstance(project), classFile, builder.toString());
|
||||
return new JetDecompiledData(jetFile, renderedDescriptorsToRange);
|
||||
}
|
||||
|
||||
private static List<DeclarationDescriptor> sortDeclarations(Collection<DeclarationDescriptor> input) {
|
||||
private void appendDecompiledTextAndPackageName(@NotNull FqName packageName) {
|
||||
builder.append("// IntelliJ API Decompiler stub source generated from a class file\n" +
|
||||
"// Implementation of methods is not available");
|
||||
builder.append("\n\n");
|
||||
if (!packageName.isRoot()) {
|
||||
builder.append("package ").append(packageName).append("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DeclarationDescriptor> sortDeclarations(@NotNull Collection<DeclarationDescriptor> input) {
|
||||
ArrayList<DeclarationDescriptor> r = new ArrayList<DeclarationDescriptor>(input);
|
||||
Collections.sort(r, MemberComparator.INSTANCE);
|
||||
return r;
|
||||
@@ -150,10 +139,11 @@ public class DecompiledDataFactory {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||
boolean firstPassed = false;
|
||||
String subindent = indent + " ";
|
||||
if (classDescriptor.getClassObjectDescriptor() != null) {
|
||||
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor();
|
||||
if (classObjectDescriptor != null) {
|
||||
firstPassed = true;
|
||||
builder.append(subindent);
|
||||
appendDescriptor(classDescriptor.getClassObjectDescriptor(), subindent);
|
||||
appendDescriptor(classObjectDescriptor, subindent);
|
||||
}
|
||||
for (DeclarationDescriptor member : sortDeclarations(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) {
|
||||
if (member.getContainingDeclaration() != descriptor) {
|
||||
@@ -180,28 +170,18 @@ public class DecompiledDataFactory {
|
||||
}
|
||||
|
||||
builder.append("\n");
|
||||
saveClsMemberToRange(descriptor, startOffset, endOffset);
|
||||
saveDescriptorToRange(descriptor, startOffset, endOffset);
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ConstructorDescriptor primaryConstructor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
|
||||
if (primaryConstructor != null) {
|
||||
saveClsMemberToRange(primaryConstructor, startOffset, endOffset);
|
||||
saveDescriptorToRange(primaryConstructor, startOffset, endOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveClsMemberToRange(DeclarationDescriptor descriptor, int startOffset, int endOffset) {
|
||||
PsiElement clsMember = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
if (clsMember != null) {
|
||||
clsMembersToRanges.put(clsMember, new TextRange(startOffset, endOffset));
|
||||
|
||||
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.OBJECT) {
|
||||
assert clsMember instanceof PsiClass;
|
||||
PsiField instanceField = ((PsiClass) clsMember).findFieldByName(JvmAbi.INSTANCE_FIELD, false);
|
||||
assert instanceField != null;
|
||||
clsMembersToRanges.put(instanceField, new TextRange(startOffset, endOffset));
|
||||
}
|
||||
}
|
||||
private void saveDescriptorToRange(DeclarationDescriptor descriptor, int startOffset, int endOffset) {
|
||||
renderedDescriptorsToRange.put(descriptorToKey(descriptor), new TextRange(startOffset, endOffset));
|
||||
}
|
||||
|
||||
private static boolean isNamedObjectProperty(@NotNull DeclarationDescriptor descriptor) {
|
||||
|
||||
@@ -23,12 +23,11 @@ import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.plugin.highlighter.JetHighlighter;
|
||||
|
||||
public class JetContentBasedFileSubstitutor implements ContentBasedClassFileProcessor {
|
||||
public final class JetContentBasedFileSubstitutor implements ContentBasedClassFileProcessor {
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(@Nullable Project project, @NotNull final VirtualFile file) {
|
||||
@@ -48,16 +47,14 @@ public class JetContentBasedFileSubstitutor implements ContentBasedClassFileProc
|
||||
return false;
|
||||
}
|
||||
|
||||
return JetDecompiledData.isKotlinFile(project, file);
|
||||
return DecompiledUtils.isKotlinCompiledFile(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String obtainFileText(Project project, VirtualFile file) {
|
||||
if (JetDecompiledData.isKotlinFile(project, file)) {
|
||||
ClsFileImpl clsFile = JetDecompiledData.getClsFile(project, file);
|
||||
assert clsFile != null;
|
||||
return JetDecompiledData.getDecompiledData(clsFile).getJetFile().getText();
|
||||
if (DecompiledUtils.isKotlinCompiledFile(file)) {
|
||||
return JetDecompiledData.getDecompiledData(file, project).getFileText();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -16,85 +16,77 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.libraries;
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.compiled.ClsElementImpl;
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
|
||||
public class JetDecompiledData {
|
||||
private final JetFile jetFile;
|
||||
private final Map<ClsElementImpl, JetDeclaration> clsElementsToJetElements;
|
||||
|
||||
private static final Object LOCK = new String("decompiled data lock");
|
||||
private static final Key<JetDecompiledData> USER_DATA_KEY = new Key<JetDecompiledData>("USER_DATA_KEY");
|
||||
private static final Object LOCK = new String("decompiled data lock");
|
||||
|
||||
JetDecompiledData(JetFile jetFile, Map<ClsElementImpl, JetDeclaration> clsElementJetDeclarationMap) {
|
||||
this.jetFile = jetFile;
|
||||
clsElementsToJetElements = clsElementJetDeclarationMap;
|
||||
@NotNull
|
||||
private final JetFile file;
|
||||
@NotNull
|
||||
private final Map<String, TextRange> renderedDescriptorsToRanges;
|
||||
|
||||
JetDecompiledData(@NotNull JetFile file, @NotNull Map<String,TextRange> renderedDescriptorsToRanges) {
|
||||
this.file = file;
|
||||
this.renderedDescriptorsToRanges = renderedDescriptorsToRanges;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetFile getJetFile() {
|
||||
return jetFile;
|
||||
}
|
||||
|
||||
public JetDeclaration getJetDeclarationByClsElement(ClsElementImpl clsElement) {
|
||||
return clsElementsToJetElements.get(clsElement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClsFileImpl getClsFile(@NotNull Project project, @NotNull VirtualFile vFile) {
|
||||
if (!FileTypeManager.getInstance().isFileOfType(vFile, JavaClassFileType.INSTANCE)) {
|
||||
return null;
|
||||
}
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
|
||||
if (!(psiFile instanceof ClsFileImpl)) {
|
||||
return null;
|
||||
}
|
||||
ClsFileImpl clsFile = (ClsFileImpl) psiFile;
|
||||
if (clsFile.getClasses().length != 1) {
|
||||
return null;
|
||||
}
|
||||
return clsFile;
|
||||
}
|
||||
|
||||
public static boolean isKotlinFile(@NotNull Project project, @NotNull VirtualFile vFile) {
|
||||
ClsFileImpl clsFile = getClsFile(project, vFile);
|
||||
return clsFile != null && isKotlinFile(clsFile);
|
||||
}
|
||||
|
||||
public static boolean isKotlinFile(@NotNull ClsFileImpl clsFile) {
|
||||
return DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(clsFile.getClasses()[0]);
|
||||
public String getFileText() {
|
||||
return file.getText();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetDecompiledData getDecompiledData(@NotNull ClsFileImpl clsFile) {
|
||||
public static JetDecompiledData getDecompiledData(@NotNull VirtualFile virtualFile, @NotNull Project project) {
|
||||
synchronized (LOCK) {
|
||||
if (clsFile.getUserData(USER_DATA_KEY) == null) {
|
||||
clsFile.putUserData(USER_DATA_KEY, DecompiledDataFactory.createDecompiledData(clsFile));
|
||||
if (virtualFile.getUserData(USER_DATA_KEY) == null) {
|
||||
virtualFile.putUserData(USER_DATA_KEY, DecompiledDataFactory.createDecompiledData(virtualFile, project));
|
||||
}
|
||||
JetDecompiledData decompiledData = clsFile.getUserData(USER_DATA_KEY);
|
||||
JetDecompiledData decompiledData = virtualFile.getUserData(USER_DATA_KEY);
|
||||
assert decompiledData != null;
|
||||
return decompiledData;
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
Map<ClsElementImpl, JetDeclaration> getClsElementsToJetElements() {
|
||||
return clsElementsToJetElements;
|
||||
@NotNull
|
||||
public Map<String, TextRange> getRenderedDescriptorsToRanges() {
|
||||
return renderedDescriptorsToRanges;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetDeclaration getDeclarationForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||
String key = descriptorToKey(descriptor);
|
||||
TextRange range = renderedDescriptorsToRanges.get(key);
|
||||
if (range == null) {
|
||||
return null;
|
||||
}
|
||||
return PsiTreeUtil.findElementOfClassAtRange(file, range.getStartOffset(), range.getEndOffset(), JetDeclaration.class);
|
||||
}
|
||||
|
||||
//TODO: should use more accurate way to identify descriptors
|
||||
@NotNull
|
||||
static String descriptorToKey(@NotNull DeclarationDescriptor descriptor) {
|
||||
return DecompiledDataFactory.DESCRIPTOR_RENDERER.render(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetFile getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
package testData.libraries
|
||||
|
||||
[[public final enum class Color(rgb: jet.Int) : jet.Enum<testData.libraries.Color> {
|
||||
public class object {
|
||||
[[public class object {
|
||||
[public final val BLUE: testData.libraries.Color] /* compiled code */
|
||||
|
||||
[public final val GREEN: testData.libraries.Color] /* compiled code */
|
||||
|
||||
[public final val RED: testData.libraries.Color] /* compiled code */
|
||||
|
||||
public final fun valueOf(value: jet.String): testData.libraries.Color { /* compiled code */ }
|
||||
[public final fun valueOf(value: jet.String): testData.libraries.Color { /* compiled code */ }]
|
||||
|
||||
public final fun values(): jet.Array<testData.libraries.Color> { /* compiled code */ }
|
||||
}
|
||||
[public final fun values(): jet.Array<testData.libraries.Color> { /* compiled code */ }]
|
||||
}]]
|
||||
|
||||
[internal final val rgb: jet.Int] /* compiled code */
|
||||
}]]
|
||||
@@ -4,9 +4,9 @@
|
||||
package testData.libraries
|
||||
|
||||
[[public final class WithInnerAndObject() {
|
||||
public class object {
|
||||
[[public class object {
|
||||
[internal final fun foo(): jet.Unit { /* compiled code */ }]
|
||||
}
|
||||
}]]
|
||||
|
||||
[[internal final class MyInner() {
|
||||
[internal trait MyInnerInner {
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
package testData.libraries
|
||||
|
||||
[[public final class WithTraitClassObject() {
|
||||
public class object : testData.libraries.SimpleTrait {
|
||||
}
|
||||
[[public class object : testData.libraries.SimpleTrait {
|
||||
}]]
|
||||
}]]
|
||||
|
||||
+27
-22
@@ -16,18 +16,21 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.libraries;
|
||||
|
||||
import com.beust.jcommander.internal.Maps;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.compiled.ClsElementImpl;
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.plugin.libraries.JetDecompiledData.getDecompiledData;
|
||||
|
||||
public class NavigateToDecompiledLibraryTest extends AbstractNavigateToLibraryTest {
|
||||
private VirtualFile classFile;
|
||||
|
||||
@@ -77,15 +80,15 @@ public class NavigateToDecompiledLibraryTest extends AbstractNavigateToLibraryTe
|
||||
|
||||
private void doTest() {
|
||||
classFile = getClassFile();
|
||||
|
||||
Map<ClsElementImpl, JetDeclaration> map = getDecompiledData(classFile).getClsElementsToJetElements();
|
||||
checkNavigationElements(map);
|
||||
JetDecompiledData decompiledData = JetDecompiledData.getDecompiledData(classFile, getProject());
|
||||
Map<String, JetDeclaration> map = getRenderedDescriptorToKotlinPsiMap(decompiledData.getFile(),
|
||||
getDecompiledData(classFile, getProject()) .getRenderedDescriptorsToRanges());
|
||||
String decompiledTextWithMarks = getDecompiledTextWithMarks(map);
|
||||
|
||||
assertSameLinesWithFile(TEST_DATA_PATH + "/decompiled/" + getTestName(false) + ".kt", decompiledTextWithMarks);
|
||||
}
|
||||
|
||||
private String getDecompiledTextWithMarks(Map<ClsElementImpl, JetDeclaration> map) {
|
||||
private String getDecompiledTextWithMarks(Map<String, JetDeclaration> map) {
|
||||
String decompiledText = getDecompiledText();
|
||||
|
||||
int[] openings = new int[decompiledText.length() + 1];
|
||||
@@ -113,21 +116,6 @@ public class NavigateToDecompiledLibraryTest extends AbstractNavigateToLibraryTe
|
||||
return document.getText();
|
||||
}
|
||||
|
||||
private JetDecompiledData getDecompiledData(VirtualFile classFile) {
|
||||
PsiFile classPsiFile = getPsiManager().findFile(classFile);
|
||||
assertInstanceOf(classPsiFile, ClsFileImpl.class);
|
||||
ClsFileImpl clsFile = (ClsFileImpl) classPsiFile;
|
||||
return JetDecompiledData.getDecompiledData(clsFile);
|
||||
}
|
||||
|
||||
private void checkNavigationElements(Map<ClsElementImpl, JetDeclaration> map) {
|
||||
PsiFile classPsiFile = getPsiManager().findFile(classFile);
|
||||
for (Map.Entry<ClsElementImpl, JetDeclaration> clsToJet : map.entrySet()) {
|
||||
assertSame(classPsiFile, clsToJet.getKey().getContainingFile());
|
||||
assertSame(clsToJet.getValue(), clsToJet.getKey().getNavigationElement());
|
||||
}
|
||||
}
|
||||
|
||||
private VirtualFile getClassFile() {
|
||||
VirtualFile packageDir = libraryDir.findFileByRelativePath(PACKAGE.replace(".", "/"));
|
||||
assertNotNull(packageDir);
|
||||
@@ -140,4 +128,21 @@ public class NavigateToDecompiledLibraryTest extends AbstractNavigateToLibraryTe
|
||||
protected boolean isWithSources() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, JetDeclaration> getRenderedDescriptorToKotlinPsiMap(
|
||||
@NotNull JetFile file, @NotNull Map<String, TextRange> renderedDescriptorsToRanges
|
||||
) {
|
||||
Map<String, JetDeclaration> renderedDescriptorsToJetDeclarations = Maps.newHashMap();
|
||||
for (Map.Entry<String, TextRange> renderedDescriptorToRange : renderedDescriptorsToRanges.entrySet()) {
|
||||
String renderedDescriptor = renderedDescriptorToRange.getKey();
|
||||
TextRange range = renderedDescriptorToRange.getValue();
|
||||
JetDeclaration jetDeclaration = PsiTreeUtil.findElementOfClassAtRange(file, range.getStartOffset(), range.getEndOffset(),
|
||||
JetDeclaration.class);
|
||||
assert jetDeclaration != null : "Can't find declaration at " + range + ": "
|
||||
+ file.getText().substring(range.getStartOffset(), range.getEndOffset());
|
||||
renderedDescriptorsToJetDeclarations.put(renderedDescriptor, jetDeclaration);
|
||||
}
|
||||
return renderedDescriptorsToJetDeclarations;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user