From a582b91c0ce31ad713010492f05af9085db42a4e Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 11 Feb 2014 10:51:19 +0100 Subject: [PATCH] New decompiler API (ability to call default decompiler from extensions) --- ...ava => DeprecatedClassFileDecompiler.java} | 21 ++---- .../impl/compiled/ClassFileDecompiler.java | 64 +++++++++++++++++++ .../psi/impl/compiled/ClsFileImpl.java | 41 +++++++----- resources/src/META-INF/IdeaPlugin.xml | 5 ++ 4 files changed, 97 insertions(+), 34 deletions(-) rename java/java-impl/src/com/intellij/psi/impl/compiled/{ClassFileDecompiler.java => DeprecatedClassFileDecompiler.java} (67%) create mode 100644 java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java b/java/java-impl/src/com/intellij/psi/impl/compiled/DeprecatedClassFileDecompiler.java similarity index 67% rename from java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java rename to java/java-impl/src/com/intellij/psi/impl/compiled/DeprecatedClassFileDecompiler.java index d2c66287f821..2e4c134b8ea1 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/DeprecatedClassFileDecompiler.java @@ -13,36 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl.compiled; import com.intellij.openapi.extensions.Extensions; -import com.intellij.openapi.fileTypes.BinaryFileDecompiler; import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.compiled.ClassFileDecompilers; import org.jetbrains.annotations.NotNull; -public class ClassFileDecompiler implements BinaryFileDecompiler { +/** @deprecated temporary solution, to remove in IDEA 14 */ +@SuppressWarnings("deprecation") +public class DeprecatedClassFileDecompiler implements ClassFileDecompiler.PlatformDecompiler { @Override - @NotNull public CharSequence decompile(@NotNull VirtualFile file) { - ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file); - if (decompiler instanceof ClassFileDecompilers.Full) { - PsiManager manager = PsiManager.getInstance(ProjectManager.getInstance().getDefaultProject()); - return ((ClassFileDecompilers.Full)decompiler).createFileViewProvider(file, manager, true).getContents(); - } - Project[] projects = ProjectManager.getInstance().getOpenProjects(); if (projects.length > 0) { Project project = projects[0]; - //noinspection deprecation for (ContentBasedFileSubstitutor processor : Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME)) { if (processor.isApplicable(project, file)) { return processor.obtainFileText(project, file); @@ -50,6 +37,6 @@ public class ClassFileDecompiler implements BinaryFileDecompiler { } } - return ClsFileImpl.decompile(file); + return null; } } \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java new file mode 100644 index 000000000000..9626aa451746 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileDecompiler.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.compiled; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.fileTypes.BinaryFileDecompiler; +import com.intellij.openapi.project.DefaultProjectFactory; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.compiled.ClassFileDecompilers; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author max + */ +public class ClassFileDecompiler implements BinaryFileDecompiler { + /** @deprecated temporary solution, to remove in IDEA 14 */ + public interface PlatformDecompiler { + @Nullable + CharSequence decompile(@NotNull VirtualFile file); + } + + @Override + @NotNull + public CharSequence decompile(@NotNull VirtualFile file) { + ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file); + if (decompiler instanceof ClassFileDecompilers.Full) { + PsiManager manager = PsiManager.getInstance(DefaultProjectFactory.getInstance().getDefaultProject()); + return ((ClassFileDecompilers.Full)decompiler).createFileViewProvider(file, manager, true).getContents(); + } + + @SuppressWarnings("deprecation") PlatformDecompiler platformDecompiler = ServiceManager.getService(PlatformDecompiler.class); + if (platformDecompiler != null) { + CharSequence result = platformDecompiler.decompile(file); + if (result != null) return result; + } + + return decompileText(file); + } + + @NotNull + public static CharSequence decompileText(@NotNull VirtualFile file) { + ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file); + if (decompiler instanceof ClassFileDecompilers.Light) { + return ((ClassFileDecompilers.Light)decompiler).getText(file); + } + + return ClsFileImpl.decompile(file); + } +} \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java index c52a41f8eded..bc8cffaaa854 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -35,7 +35,6 @@ import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; -import com.intellij.psi.compiled.ClassFileDecompilers; import com.intellij.psi.impl.JavaPsiImplementationHelper; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.impl.java.stubs.PsiClassStub; @@ -73,6 +72,8 @@ public class ClsFileImpl extends ClsRepositoryPsiElement implements PsiJavaFile, PsiFileWithStubSupport, PsiFileEx, Queryable, PsiClassOwnerEx, PsiCompiledFile { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsFileImpl"); + private static final ThreadLocal> ourStubToProcess = new ThreadLocal>(); + /** NOTE: you absolutely MUST NOT hold PsiLock under the mirror lock */ private final Object myMirrorLock = new Object(); private final Object myStubLock = new Object(); @@ -317,7 +318,7 @@ public class ClsFileImpl extends ClsRepositoryPsiElement mirrorTreeElement = myMirrorFileElement; if (mirrorTreeElement == null) { VirtualFile file = getVirtualFile(); - CharSequence mirrorText = decompile(file, getStub()); + CharSequence mirrorText = decompileInternal(file); String ext = JavaFileType.INSTANCE.getDefaultExtension(); PsiClass[] classes = getClasses(); @@ -496,30 +497,36 @@ public class ClsFileImpl extends ClsRepositoryPsiElement // default decompiler implementation - @NotNull - public static CharSequence decompile(@NotNull VirtualFile file) { - ClassFileDecompilers.Decompiler decompiler = ClassFileDecompilers.find(file); - if (decompiler instanceof ClassFileDecompilers.Light) { - return ((ClassFileDecompilers.Light)decompiler).getText(file); - } - - PsiJavaFileStub stub = null; + private CharSequence decompileInternal(VirtualFile file) { + ourStubToProcess.set(getStub()); try { - stub = buildFileStub(file, file.contentsToByteArray()); + return ClassFileDecompiler.decompileText(file); } - catch (Exception e) { - LOG.warn(e); + finally { + ourStubToProcess.set(null); } - return stub == null ? "" : decompile(file, stub); } @NotNull - private static CharSequence decompile(@NotNull VirtualFile file, @NotNull PsiClassHolderFileStub stub) { - PsiManager manager = PsiManager.getInstance(DefaultProjectFactory.getInstance().getDefaultProject()); + public static CharSequence decompile(@NotNull VirtualFile file) { + PsiClassHolderFileStub stub = ourStubToProcess.get(); + if (stub == null) { + try { + stub = buildFileStub(file, file.contentsToByteArray()); + } + catch (Exception e) { + LOG.warn(e); + } + } + if (stub == null) { + return ""; + } + PsiManager manager = PsiManager.getInstance(DefaultProjectFactory.getInstance().getDefaultProject()); ClsFileImpl psi = new ClsFileImpl(new ClassFileViewProvider(manager, file), stub); if (stub.getPsi() == null) { - ((PsiJavaFileStubImpl)stub).setPsi(psi); + @SuppressWarnings("unchecked") PsiFileStubImpl impl = (PsiFileStubImpl)stub; + impl.setPsi(psi); } StringBuilder buffer = new StringBuilder(); diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 0dacc3cdc655..9e81e0c3101c 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -231,7 +231,9 @@ + + @@ -1017,6 +1019,9 @@ + +