mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
expose class file by given source class
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -15,22 +15,34 @@
|
||||
*/
|
||||
package com.intellij.openapi.compiler.ex;
|
||||
|
||||
import com.intellij.ide.util.JavaAnonymousClassesHelper;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.OrderEnumerationHandler;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiAnonymousClass;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.util.containers.OrderedSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -109,4 +121,97 @@ public class CompilerPathsEx extends CompilerPaths {
|
||||
}
|
||||
return ArrayUtil.toStringArray(outputPaths);
|
||||
}
|
||||
|
||||
public interface ClassFileDescriptor {
|
||||
byte[] loadFileBytes() throws IOException;
|
||||
String getPath();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassFileDescriptor findClassFileInOutput(@NotNull PsiClass sourceClass) {
|
||||
String classVMName = getClassVMName(sourceClass);
|
||||
if (classVMName == null) {
|
||||
return null;
|
||||
}
|
||||
Module module = ModuleUtilCore.findModuleForPsiElement(sourceClass);
|
||||
if (module == null){
|
||||
final Project project = sourceClass.getProject();
|
||||
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(sourceClass);
|
||||
final String qualifiedName = topLevelClass != null ? topLevelClass.getQualifiedName() : null;
|
||||
final PsiClass aClass = qualifiedName != null
|
||||
? JavaPsiFacade.getInstance(project).findClass(qualifiedName, sourceClass.getResolveScope())
|
||||
: null;
|
||||
if (aClass != null) {
|
||||
final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(aClass);
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
if (virtualFile != null && fileIndex.isInLibraryClasses(virtualFile)) {
|
||||
final VirtualFile rootForFile = fileIndex.getClassRootForFile(virtualFile);
|
||||
if (rootForFile != null) {
|
||||
final VirtualFile classFile = rootForFile.findFileByRelativePath("/" + classVMName.replace('.', '/') + ".class");
|
||||
if (classFile != null) {
|
||||
return new ClassFileDescriptor() {
|
||||
@Override
|
||||
public byte[] loadFileBytes() throws IOException {
|
||||
return classFile.contentsToByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return classFile.getPath();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiFile containingFile = sourceClass.getContainingFile();
|
||||
final VirtualFile virtualFile = containingFile.getVirtualFile();
|
||||
if (virtualFile == null) return null;
|
||||
final CompilerModuleExtension moduleExtension = CompilerModuleExtension.getInstance(module);
|
||||
if (moduleExtension == null) return null;
|
||||
VirtualFile classRoot;
|
||||
if (ProjectRootManager.getInstance(module.getProject()).getFileIndex().isInTestSourceContent(virtualFile)) {
|
||||
classRoot = moduleExtension.getCompilerOutputPathForTests();
|
||||
}
|
||||
else {
|
||||
classRoot = moduleExtension.getCompilerOutputPath();
|
||||
}
|
||||
if (classRoot == null) return null;
|
||||
|
||||
String classFilePath = classRoot.getPath() + "/" + classVMName.replace('.', '/') + ".class";
|
||||
|
||||
final File classFile = new File(classFilePath);
|
||||
if (!classFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
return new ClassFileDescriptor() {
|
||||
@Override
|
||||
public byte[] loadFileBytes() throws IOException {
|
||||
return FileUtil.loadFileBytes(classFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return classFile.getPath();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getClassVMName(PsiClass containingClass) {
|
||||
if (containingClass instanceof PsiAnonymousClass) {
|
||||
final PsiClass containingClassOfAnonymous = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
|
||||
if (containingClassOfAnonymous == null) {
|
||||
return null;
|
||||
}
|
||||
return getClassVMName(containingClassOfAnonymous) +
|
||||
JavaAnonymousClassesHelper.getName((PsiAnonymousClass)containingClass);
|
||||
}
|
||||
return ClassUtil.getJVMClassName(containingClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -16,26 +16,16 @@
|
||||
package com.intellij.byteCodeViewer;
|
||||
|
||||
import com.intellij.codeInsight.documentation.DockablePopupManager;
|
||||
import com.intellij.ide.util.JavaAnonymousClassesHelper;
|
||||
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.ui.content.Content;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -43,7 +33,6 @@ import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||
import org.jetbrains.org.objectweb.asm.util.Textifier;
|
||||
import org.jetbrains.org.objectweb.asm.util.TraceClassVisitor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
@@ -176,67 +165,14 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo
|
||||
PsiClass containingClass = getContainingClass(psiElement);
|
||||
//todo show popup
|
||||
if (containingClass == null) return null;
|
||||
final String classVMName = getClassVMName(containingClass);
|
||||
if (classVMName == null) return null;
|
||||
|
||||
Module module = ModuleUtilCore.findModuleForPsiElement(psiElement);
|
||||
if (module == null){
|
||||
final Project project = containingClass.getProject();
|
||||
final PsiClass topLevelClass = PsiUtil.getTopLevelClass(psiElement);
|
||||
final String qualifiedName = topLevelClass != null ? topLevelClass.getQualifiedName() : null;
|
||||
final PsiClass aClass = qualifiedName != null
|
||||
? JavaPsiFacade.getInstance(project).findClass(qualifiedName, psiElement.getResolveScope())
|
||||
: null;
|
||||
if (aClass != null) {
|
||||
final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(aClass);
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
if (virtualFile != null && fileIndex.isInLibraryClasses(virtualFile)) {
|
||||
try {
|
||||
final VirtualFile rootForFile = fileIndex.getClassRootForFile(virtualFile);
|
||||
if (rootForFile != null) {
|
||||
final VirtualFile classFile = rootForFile.findFileByRelativePath("/" + classVMName.replace('.', '/') + ".class");
|
||||
if (classFile != null) {
|
||||
return processClassFile(classFile.contentsToByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
CompilerPathsEx.ClassFileDescriptor file = CompilerPathsEx.findClassFileInOutput(containingClass);
|
||||
if (file != null) {
|
||||
try {
|
||||
return processClassFile(file.loadFileBytes());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final PsiFile containingFile = containingClass.getContainingFile();
|
||||
final VirtualFile virtualFile = containingFile.getVirtualFile();
|
||||
if (virtualFile == null) return null;
|
||||
final CompilerModuleExtension moduleExtension = CompilerModuleExtension.getInstance(module);
|
||||
if (moduleExtension == null) return null;
|
||||
String classPath;
|
||||
if (ProjectRootManager.getInstance(module.getProject()).getFileIndex().isInTestSourceContent(virtualFile)) {
|
||||
final VirtualFile pathForTests = moduleExtension.getCompilerOutputPathForTests();
|
||||
if (pathForTests == null) return null;
|
||||
classPath = pathForTests.getPath();
|
||||
} else {
|
||||
final VirtualFile compilerOutputPath = moduleExtension.getCompilerOutputPath();
|
||||
if (compilerOutputPath == null) return null;
|
||||
classPath = compilerOutputPath.getPath();
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
classPath += "/" + classVMName.replace('.', '/') + ".class";
|
||||
|
||||
final File classFile = new File(classPath);
|
||||
if (!classFile.exists()) {
|
||||
LOG.info("search in: " + classPath);
|
||||
return null;
|
||||
}
|
||||
return processClassFile(FileUtil.loadFileBytes(classFile));
|
||||
}
|
||||
catch (Exception e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -254,18 +190,6 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getClassVMName(PsiClass containingClass) {
|
||||
if (containingClass instanceof PsiAnonymousClass) {
|
||||
final PsiClass containingClassOfAnonymous = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
|
||||
if (containingClassOfAnonymous == null) {
|
||||
return null;
|
||||
}
|
||||
return getClassVMName(containingClassOfAnonymous) +
|
||||
JavaAnonymousClassesHelper.getName((PsiAnonymousClass)containingClass);
|
||||
}
|
||||
return ClassUtil.getJVMClassName(containingClass);
|
||||
}
|
||||
|
||||
public static PsiClass getContainingClass(PsiElement psiElement) {
|
||||
for (ClassSearcher searcher : CLASS_SEARCHER_EP.getExtensions()) {
|
||||
|
||||
Reference in New Issue
Block a user