DecompiledNavigationUtils, JetSourceNavigationHelper: fix support for Kotlin/Javascript projects

DecompiledUtils: add isKotlinJavaScriptInternalCompiledFile
DecompiledUtils: add isKotlinJsMetaFile
DecompiledNavigationUtils: use isKotlinJvmCompiledFile, isKotlinJsMetaFile
DecompiledNavigationUtils: isFromKotlinJavascript -> isFromKotlinJavasriptMetadata
This commit is contained in:
Michael Nedzelsky
2015-04-06 11:23:06 +03:00
parent f92d112564
commit 4f26c7fe42
4 changed files with 33 additions and 30 deletions
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
/**
* Checks if this file is a compiled Kotlin class file (not necessarily ABI-compatible with the current plugin)
*/
public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
public fun isKotlinJvmCompiledFile(file: VirtualFile): Boolean {
if (file.getExtension() != JavaClassFileType.INSTANCE!!.getDefaultExtension()) {
return false
}
@@ -38,11 +38,13 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
header.syntheticClassKind != KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL
}
public fun isKotlinJsMetaFile(file: VirtualFile): Boolean = file.getFileType() == KotlinJavaScriptMetaFileType
/**
* Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin
*/
public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
if (!isKotlinCompiledFile(file)) return false
if (!isKotlinJvmCompiledFile(file)) return false
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
return header != null && header.isCompatibleAbiVersion
@@ -53,7 +55,7 @@ public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
* which should NOT be decompiled (and, as a result, shown under the library in the Project view, be searchable via Find class, etc.)
*/
public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
if (!isKotlinCompiledFile(file)) {
if (!isKotlinJvmCompiledFile(file)) {
return false
}
@@ -64,3 +66,6 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
(header.kind == KotlinClassHeader.Kind.CLASS && header.classKind != null && header.classKind != KotlinClass.Kind.CLASS)
}
public fun isKotlinJavaScriptInternalCompiledFile(file: VirtualFile): Boolean =
isKotlinJsMetaFile(file) && file.getNameWithoutExtension().contains('.')
@@ -29,7 +29,7 @@ public class JetClassFileDecompiler extends ClassFileDecompilers.Full {
@Override
public boolean accepts(@NotNull VirtualFile file) {
return DecompilerPackage.isKotlinCompiledFile(file);
return DecompilerPackage.isKotlinJvmCompiledFile(file);
}
@NotNull
@@ -27,15 +27,17 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.idea.caches.resolve.JsProjectDetector;
import org.jetbrains.kotlin.idea.decompiler.DecompilerPackage;
import org.jetbrains.kotlin.idea.decompiler.KotlinClsFileBase;
import org.jetbrains.kotlin.idea.stubindex.JetSourceFilterScope;
import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinderFactory;
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinderFactory;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.psi.JetDeclaration;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
@@ -50,19 +52,11 @@ public final class DecompiledNavigationUtils {
@NotNull DeclarationDescriptor referencedDescriptor
) {
if (DescriptorUtils.isLocal(referencedDescriptor)) return null;
VirtualFile virtualFile;
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor);
if (JsProjectDetector.isJsProject(project) &&
NavigationPackage.getKotlinJavascriptLibraryWithMetadata(referencedDescriptor, project) != null)
{
JsMetaFileVirtualFileHolder system = JsMetaFileVirtualFileHolder.getInstance(project);
virtualFile = system.getFile(referencedDescriptor);
if (virtualFile == null) return null;
}
else {
virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor);
if (virtualFile == null || !DecompilerPackage.isKotlinCompiledFile(virtualFile)) return null;
}
if (virtualFile == null ||
!DecompilerPackage.isKotlinJvmCompiledFile(virtualFile) &&
!DecompilerPackage.isKotlinJsMetaFile(virtualFile)) return null;
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (!(psiFile instanceof KotlinClsFileBase)) {
@@ -86,10 +80,25 @@ public final class DecompiledNavigationUtils {
if (containerClassId == null) return null;
GlobalSearchScope scopeToSearchIn = JetSourceFilterScope.kotlinSourceAndClassFiles(GlobalSearchScope.allScope(project), project);
VirtualFileFinder fileFinder = VirtualFileFinderFactory.SERVICE.getInstance(project).create(scopeToSearchIn);
VirtualFileFinderFactory virtualFileFinderFactory;
if (isFromKotlinJavasriptMetadata(referencedDescriptor)) {
virtualFileFinderFactory = JsVirtualFileFinderFactory.SERVICE.getInstance(project);
}
else {
virtualFileFinderFactory = JvmVirtualFileFinderFactory.SERVICE.getInstance(project);
}
VirtualFileFinder fileFinder = virtualFileFinderFactory.create(scopeToSearchIn);
return fileFinder.findVirtualFileWithHeader(containerClassId);
}
private static boolean isFromKotlinJavasriptMetadata(@NotNull DeclarationDescriptor referencedDescriptor) {
PackageFragmentDescriptor packageFragmentDescriptor =
DescriptorUtils.getParentOfType(referencedDescriptor, PackageFragmentDescriptor.class, false);
return packageFragmentDescriptor instanceof KotlinJavascriptPackageFragment;
}
//TODO: navigate to inner classes
@Nullable
private static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) {
@@ -21,7 +21,6 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
@@ -44,7 +43,6 @@ import org.jetbrains.kotlin.context.MutableModuleContext;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.di.InjectorForLazyResolve;
import org.jetbrains.kotlin.idea.caches.resolve.JsProjectDetector;
import org.jetbrains.kotlin.idea.stubindex.JetFullClassNameIndex;
import org.jetbrains.kotlin.idea.stubindex.JetTopLevelFunctionFqnNameIndex;
import org.jetbrains.kotlin.idea.stubindex.JetTopLevelPropertyFqnNameIndex;
@@ -95,9 +93,7 @@ public class JetSourceNavigationHelper {
Project project = decompiledDeclaration.getProject();
ProjectFileIndex projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project);
boolean isJsProject = JsProjectDetector.isJsProject(project);
if (!isJsProject && !projectFileIndex.isInLibraryClasses(libraryFile)) {
if (!projectFileIndex.isInLibraryClasses(libraryFile)) {
return GlobalSearchScope.EMPTY_SCOPE;
}
@@ -108,13 +104,6 @@ public class JetSourceNavigationHelper {
}
}
if (isJsProject) {
Library library = NavigationPackage.getKotlinJavascriptLibrary(libraryFile, project);
if (library != null) {
KotlinPackage.addAll(sourceRootSet, library.getFiles(OrderRootType.SOURCES));
}
}
return new LibrarySourcesScope(project, sourceRootSet);
}