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) * 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()) { if (file.getExtension() != JavaClassFileType.INSTANCE!!.getDefaultExtension()) {
return false return false
} }
@@ -38,11 +38,13 @@ public fun isKotlinCompiledFile(file: VirtualFile): Boolean {
header.syntheticClassKind != KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL 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 * Checks if this file is a compiled Kotlin class file ABI-compatible with the current plugin
*/ */
public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean { public fun isKotlinWithCompatibleAbiVersion(file: VirtualFile): Boolean {
if (!isKotlinCompiledFile(file)) return false if (!isKotlinJvmCompiledFile(file)) return false
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader() val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
return header != null && header.isCompatibleAbiVersion 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.) * 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 { public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
if (!isKotlinCompiledFile(file)) { if (!isKotlinJvmCompiledFile(file)) {
return false return false
} }
@@ -64,3 +66,6 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS || return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
(header.kind == KotlinClassHeader.Kind.CLASS && header.classKind != null && header.classKind != KotlinClass.Kind.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 @Override
public boolean accepts(@NotNull VirtualFile file) { public boolean accepts(@NotNull VirtualFile file) {
return DecompilerPackage.isKotlinCompiledFile(file); return DecompilerPackage.isKotlinJvmCompiledFile(file);
} }
@NotNull @NotNull
@@ -27,15 +27,17 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassOrPackageFragmentDescriptor; import org.jetbrains.kotlin.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; 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.DecompilerPackage;
import org.jetbrains.kotlin.idea.decompiler.KotlinClsFileBase; import org.jetbrains.kotlin.idea.decompiler.KotlinClsFileBase;
import org.jetbrains.kotlin.idea.stubindex.JetSourceFilterScope; 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.VirtualFileFinder;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory; import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.psi.JetDeclaration; import org.jetbrains.kotlin.psi.JetDeclaration;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptPackageFragment;
import org.jetbrains.kotlin.types.ErrorUtils; import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils; import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
@@ -50,19 +52,11 @@ public final class DecompiledNavigationUtils {
@NotNull DeclarationDescriptor referencedDescriptor @NotNull DeclarationDescriptor referencedDescriptor
) { ) {
if (DescriptorUtils.isLocal(referencedDescriptor)) return null; if (DescriptorUtils.isLocal(referencedDescriptor)) return null;
VirtualFile virtualFile; VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, referencedDescriptor);
if (JsProjectDetector.isJsProject(project) && if (virtualFile == null ||
NavigationPackage.getKotlinJavascriptLibraryWithMetadata(referencedDescriptor, project) != null) !DecompilerPackage.isKotlinJvmCompiledFile(virtualFile) &&
{ !DecompilerPackage.isKotlinJsMetaFile(virtualFile)) return 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;
}
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (!(psiFile instanceof KotlinClsFileBase)) { if (!(psiFile instanceof KotlinClsFileBase)) {
@@ -86,10 +80,25 @@ public final class DecompiledNavigationUtils {
if (containerClassId == null) return null; if (containerClassId == null) return null;
GlobalSearchScope scopeToSearchIn = JetSourceFilterScope.kotlinSourceAndClassFiles(GlobalSearchScope.allScope(project), project); 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); 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 //TODO: navigate to inner classes
@Nullable @Nullable
private static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) { 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.module.Module;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade; 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.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.di.InjectorForLazyResolve; 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.JetFullClassNameIndex;
import org.jetbrains.kotlin.idea.stubindex.JetTopLevelFunctionFqnNameIndex; import org.jetbrains.kotlin.idea.stubindex.JetTopLevelFunctionFqnNameIndex;
import org.jetbrains.kotlin.idea.stubindex.JetTopLevelPropertyFqnNameIndex; import org.jetbrains.kotlin.idea.stubindex.JetTopLevelPropertyFqnNameIndex;
@@ -95,9 +93,7 @@ public class JetSourceNavigationHelper {
Project project = decompiledDeclaration.getProject(); Project project = decompiledDeclaration.getProject();
ProjectFileIndex projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project); ProjectFileIndex projectFileIndex = ProjectFileIndex.SERVICE.getInstance(project);
boolean isJsProject = JsProjectDetector.isJsProject(project); if (!projectFileIndex.isInLibraryClasses(libraryFile)) {
if (!isJsProject && !projectFileIndex.isInLibraryClasses(libraryFile)) {
return GlobalSearchScope.EMPTY_SCOPE; 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); return new LibrarySourcesScope(project, sourceRootSet);
} }