import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* An API to extend default IDEA .class file decompiler and handle files compiled from sources other than Java.
}
}
- public @Nullable Decompiler find(@NotNull VirtualFile file) {
- return EP_NAME.findFirstSafe(decompiler -> (decompiler instanceof Light || decompiler instanceof Full) && decompiler.accepts(file));
+ @SuppressWarnings("unchecked")
+ public <D extends Decompiler> D find(@NotNull VirtualFile file, @NotNull Class<D> decompilerClass) {
+ return (D)EP_NAME.findFirstSafe(d -> decompilerClass.isInstance(d) && d.accepts(file));
}
}
\ No newline at end of file
<codeInsight.containerProvider implementation="com.intellij.codeInsight.JavaContainerProvider" id="JAVA"/>
<constantExpressionEvaluator language="JAVA" implementationClass="com.intellij.psi.impl.PsiExpressionEvaluator" />
<lang.psiAugmentProvider implementation="com.intellij.psi.impl.RecordAugmentProvider"/>
+ <psi.classFileDecompiler id="clsStubBuilder" implementation="com.intellij.psi.impl.compiled.ClsDecompilerImpl" order="last"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.uast">
Language language,
@NotNull PsiManager manager,
boolean eventSystemEnabled) {
- ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.getInstance().find(file);
- if (decompiler instanceof Full) {
- return ((Full)decompiler).createFileViewProvider(file, manager, eventSystemEnabled);
- }
-
- return new ClassFileViewProvider(manager, file, eventSystemEnabled);
+ Full decompiler = ClassFileDecompilers.getInstance().find(file, Full.class);
+ return decompiler.createFileViewProvider(file, manager, eventSystemEnabled);
}
}
\ No newline at end of file
@Override
public @NotNull CharSequence decompile(@NotNull VirtualFile file) {
- ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.getInstance().find(file);
+ ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.getInstance().find(file, ClassFileDecompilers.Decompiler.class);
if (decompiler instanceof ClassFileDecompilers.Full) {
PsiManager manager = PsiManager.getInstance(DefaultProjectFactory.getInstance().getDefaultProject());
return ((ClassFileDecompilers.Full)decompiler).createFileViewProvider(file, manager, true).getContents();
}
}
- return ClsFileImpl.decompile(file);
+ throw new IllegalStateException(decompiler.getClass().getName() +
+ " should be on of " +
+ ClassFileDecompilers.Full.class.getName() +
+ " or " +
+ ClassFileDecompilers.Light.class.getName());
}
}
\ No newline at end of file
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.compiled.ClassFileDecompilers;
-import com.intellij.psi.impl.source.JavaFileElementType;
import com.intellij.psi.stubs.BinaryFileStubBuilder;
-import com.intellij.psi.stubs.PsiFileStub;
import com.intellij.psi.stubs.Stub;
import com.intellij.util.cls.ClsFormatException;
import com.intellij.util.indexing.FileContent;
import static com.intellij.psi.compiled.ClassFileDecompilers.Full;
-public class ClassFileStubBuilder implements BinaryFileStubBuilder.CompositeBinaryFileStubBuilder<ClassFileDecompilers.Decompiler> {
+public class ClassFileStubBuilder implements BinaryFileStubBuilder.CompositeBinaryFileStubBuilder<Full> {
private static final Logger LOG = Logger.getInstance(ClassFileStubBuilder.class);
- public static final int STUB_VERSION = 25 + JavaFileElementType.STUB_VERSION;
+ public static final int STUB_VERSION = 26;
@Override
public boolean acceptsFile(@NotNull VirtualFile file) {
}
@Override
- public @NotNull Stream<ClassFileDecompilers.Decompiler> getAllSubBuilders() {
- return ClassFileDecompilers.getInstance().EP_NAME.extensions().filter(decompiler -> decompiler instanceof Full);
+ public @NotNull Stream<Full> getAllSubBuilders() {
+ return ClassFileDecompilers.getInstance().EP_NAME.extensions().filter(d -> d instanceof Full).map(d -> (Full) d);
}
@Override
- public @Nullable ClassFileDecompilers.Decompiler getSubBuilder(@NotNull FileContent fileContent) {
+ public @Nullable Full getSubBuilder(@NotNull FileContent fileContent) {
return fileContent.getFile()
- .computeWithPreloadedContentHint(fileContent.getContent(), () -> ClassFileDecompilers.getInstance().find(fileContent.getFile()));
+ .computeWithPreloadedContentHint(fileContent.getContent(), () -> ClassFileDecompilers.getInstance().find(fileContent.getFile(), Full.class));
}
@Override
- public @NotNull String getSubBuilderVersion(@Nullable ClassFileDecompilers.Decompiler decompiler) {
+ public @NotNull String getSubBuilderVersion(@Nullable Full decompiler) {
if (decompiler == null) return "default";
- int version = decompiler instanceof Full ? ((Full)decompiler).getStubBuilder().getStubVersion() : 0;
+ int version = decompiler.getStubBuilder().getStubVersion();
return decompiler.getClass().getName() + ":" + version;
}
@Override
- public @Nullable Stub buildStubTree(@NotNull FileContent fileContent, @Nullable ClassFileDecompilers.Decompiler decompiler) {
+ public @Nullable Stub buildStubTree(@NotNull FileContent fileContent, @Nullable Full decompiler) {
+ if (decompiler == null) return null;
return fileContent.getFile().computeWithPreloadedContentHint(fileContent.getContent(), () -> {
VirtualFile file = fileContent.getFile();
try {
- if (decompiler instanceof Full) {
- return ((Full)decompiler).getStubBuilder().buildFileStub(fileContent);
- }
+ return decompiler.getStubBuilder().buildFileStub(fileContent);
}
catch (ClsFormatException e) {
if (LOG.isDebugEnabled()) LOG.debug(file.getPath(), e);
else LOG.info(file.getPath() + ": " + e.getMessage());
}
-
- try {
- PsiFileStub<?> stub = ClsFileImpl.buildFileStub(file, fileContent.getContent());
- if (stub == null && fileContent.getFileName().indexOf('$') < 0) {
- LOG.info("No stub built for the file " + fileContent);
- }
- return stub;
- }
- catch (ClsFormatException e) {
- if (LOG.isDebugEnabled()) LOG.debug(file.getPath(), e);
- else LOG.info(file.getPath() + ": " + e.getMessage());
- }
-
return null;
});
}
--- /dev/null
+// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.psi.impl.compiled;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.ClassFileViewProvider;
+import com.intellij.psi.FileViewProvider;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.compiled.ClassFileDecompilers;
+import com.intellij.psi.compiled.ClsStubBuilder;
+import com.intellij.psi.impl.source.JavaFileElementType;
+import com.intellij.psi.stubs.PsiFileStub;
+import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.indexing.FileContent;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class ClsDecompilerImpl extends ClassFileDecompilers.Full {
+ private static final Logger LOG = Logger.getInstance(ClsDecompilerImpl.class);
+ private final ClsStubBuilder myStubBuilder = new MyClsStubBuilder();
+
+ @Override
+ public boolean accepts(@NotNull VirtualFile file) {
+ return true;
+ }
+
+ @Override
+ public @NotNull ClsStubBuilder getStubBuilder() {
+ return myStubBuilder;
+ }
+
+ @Override
+ public @NotNull FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) {
+ return new ClassFileViewProvider(manager, file, physical);
+ }
+
+ private static class MyClsStubBuilder extends ClsStubBuilder {
+ @Override
+ public int getStubVersion() {
+ return JavaFileElementType.STUB_VERSION;
+ }
+
+ @Override
+ public @Nullable PsiFileStub<?> buildFileStub(@NotNull FileContent fileContent) throws ClsFormatException {
+ PsiFileStub<?> stub = ClsFileImpl.buildFileStub(fileContent.getFile(), fileContent.getContent());
+ if (stub == null && fileContent.getFileName().indexOf('$') < 0) {
+ LOG.info("No stub built for the file " + fileContent);
+ }
+ return stub;
+ }
+ }
+}
}
private static Exception wrapException(InvalidMirrorException e, VirtualFile file) {
- ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.getInstance().find(file);
- if (decompiler instanceof ClassFileDecompilers.Light) {
+ ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.getInstance().find(file, ClassFileDecompilers.Light.class);
+ if (decompiler != null) {
PluginId pluginId = PluginManagerCore.getPluginByClassName(decompiler.getClass().getName());
if (pluginId != null) {
return new PluginException(e, pluginId);
<resource-bundle>messages.Decompiler</resource-bundle>
<extensions defaultExtensionNs="com.intellij">
- <psi.classFileDecompiler implementation="org.jetbrains.java.decompiler.IdeaDecompiler" order="last"/>
+ <psi.classFileDecompiler implementation="org.jetbrains.java.decompiler.IdeaDecompiler" order="last, before clsStubBuilder"/>
</extensions>
<applicationListeners>
override fun beforeFileOpened(source: FileEditorManager, file: VirtualFile) {
if (myShowNotice && file.fileType === JavaClassFileType.INSTANCE) {
- val decompiler = ClassFileDecompilers.getInstance().find(file)
+ val decompiler = ClassFileDecompilers.getInstance().find(file, ClassFileDecompilers.Light::class.java)
if (decompiler is IdeaDecompiler) {
TASK_KEY.set(file, ApplicationManager.getApplication().executeOnPooledThread(Callable { decompiler.decompile(file) }))