From 50d59c789af61bea9819447bcd0839c7347df204 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Fri, 28 Feb 2014 17:54:20 +0400 Subject: [PATCH] Decompiler: do not create decompiled files for inner classes and anonymous functions Rewrite DecompiledUtils to Kotlin --- .../libraries/DecompiledNavigationUtils.java | 5 +- .../jet/plugin/libraries/DecompiledUtils.java | 45 -------------- .../jet/plugin/libraries/DecompiledUtils.kt | 62 +++++++++++++++++++ .../libraries/DeserializerForDecompiler.kt | 2 +- .../libraries/JetClassFileDecompiler.java | 4 +- .../libraries/JetClassFileViewProvider.kt | 8 ++- .../plugin/libraries/JetClsStubBuilder.java | 2 +- 7 files changed, 73 insertions(+), 55 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java create mode 100644 idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java index 721f48d8d43..1d5023991d5 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java @@ -57,7 +57,7 @@ public final class DecompiledNavigationUtils { DeclarationDescriptor effectiveReferencedDescriptor = getEffectiveReferencedDescriptor(referencedDescriptor); VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, effectiveReferencedDescriptor); - if (virtualFile == null || !DecompiledUtils.isKotlinCompiledFile(virtualFile)) return null; + if (virtualFile == null || !LibrariesPackage.isKotlinCompiledFile(virtualFile)) return null; PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (!(psiFile instanceof JetClsFile)) { @@ -112,8 +112,7 @@ public final class DecompiledNavigationUtils { return PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) containerDescriptor).getFqName()); } if (containerDescriptor instanceof ClassDescriptor) { - ClassKind classKind = ((ClassDescriptor) containerDescriptor).getKind(); - if (classKind == ClassKind.CLASS_OBJECT || classKind == ClassKind.ENUM_ENTRY + if (containerDescriptor.getContainingDeclaration() instanceof ClassDescriptor || DescriptorUtils.isLocal(containerDescriptor.getContainingDeclaration(), containerDescriptor)) { return getContainerFqName(containerDescriptor.getContainingDeclaration()); } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java deleted file mode 100644 index 210baff072c..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010-2013 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 org.jetbrains.jet.plugin.libraries; - -import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache; -import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader; - -public final class DecompiledUtils { - - public static boolean isKotlinCompiledFile(@NotNull VirtualFile file) { - if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) { - return false; - } - - KotlinClassHeader header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader(); - return header != null; - } - - public static boolean isKotlinInternalCompiledFile(@NotNull VirtualFile file) { - KotlinClassHeader header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader(); - return header != null && header.getKind() == KotlinClassHeader.Kind.PACKAGE_FRAGMENT; - } - - private DecompiledUtils() { - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt new file mode 100644 index 00000000000..6213d1be11d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledUtils.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-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 org.jetbrains.jet.plugin.libraries + +import com.intellij.openapi.fileTypes.StdFileTypes +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader +import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind +import com.intellij.psi.ClassFileViewProvider + + +//TODO: this should be done via generic mechanism (special header kind) +//TODO: should also check for local classes and functions +public fun isAnonymousFunction(file: VirtualFile): Boolean { + val name = file.getNameWithoutExtension() + val index = name.lastIndexOf('$', name.length()) + if (index > 0 && index < name.length() - 1) { + val nameAfterBucks = name.substring(index + 1, name.size) + return nameAfterBucks.isNotEmpty() && nameAfterBucks[0].isDigit() + } + return false +} + +public fun isKotlinCompiledFile(file: VirtualFile): Boolean { + if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) { + return false + } + if (isAnonymousFunction(file)) { + return true + } + val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() + return header != null +} + +public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean { + if (!isKotlinCompiledFile(file)) { + return false + } + if (ClassFileViewProvider.isInnerClass(file)) { + return true + } + if (isAnonymousFunction(file)) { + return true + } + val header = KotlinBinaryClassCache.getKotlinBinaryClass(file).getClassHeader() + return header != null && header.getKind() == KotlinClassHeader.Kind.PACKAGE_FRAGMENT +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt index 44331f5b8c7..f6a632c19ad 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt @@ -82,7 +82,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di val segments = DeserializedResolverUtils.kotlinFqNameToJavaFqName(classId.getRelativeClassName()).pathSegments() val targetName = segments.makeString("$", postfix = ".class") val virtualFile = packageDirectory.findChild(targetName) - if (virtualFile != null && DecompiledUtils.isKotlinCompiledFile(virtualFile)) { + if (virtualFile != null && isKotlinCompiledFile(virtualFile)) { return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile) } return null diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileDecompiler.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileDecompiler.java index e28dce3de13..9114b5da4e8 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileDecompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileDecompiler.java @@ -28,7 +28,7 @@ public class JetClassFileDecompiler extends ClassFileDecompilers.Full { @Override public boolean accepts(@NotNull VirtualFile file) { - return DecompiledUtils.isKotlinCompiledFile(file); + return LibrariesPackage.isKotlinCompiledFile(file); } @NotNull @@ -40,6 +40,6 @@ public class JetClassFileDecompiler extends ClassFileDecompilers.Full { @NotNull @Override public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) { - return new JetClassFileViewProvider(manager, file, physical, DecompiledUtils.isKotlinInternalCompiledFile(file)); + return new JetClassFileViewProvider(manager, file, physical, LibrariesPackage.isKotlinInternalCompiledFile(file)); } } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileViewProvider.kt b/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileViewProvider.kt index 4dc40cb76ae..4b3408aac37 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileViewProvider.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetClassFileViewProvider.kt @@ -22,7 +22,6 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager import com.intellij.psi.SingleRootFileViewProvider -import org.jetbrains.annotations.Nullable import org.jetbrains.jet.plugin.JetLanguage import kotlin.properties.Delegates @@ -41,10 +40,13 @@ public class JetClassFileViewProvider( } override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? { - return if (isInternal) null else JetClsFile(this) + //TODO: check index that file is library file, as in ClassFileViewProvider + if (isInternal) return null + + return JetClsFile(this) } override fun createCopy(copy: VirtualFile): SingleRootFileViewProvider { return JetClassFileViewProvider(getManager(), copy, false, isInternal) } -} +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetClsStubBuilder.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetClsStubBuilder.java index c387c7ac312..a3354a9981e 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetClsStubBuilder.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetClsStubBuilder.java @@ -37,7 +37,7 @@ public class JetClsStubBuilder extends ClsStubBuilder { public PsiFileStub buildFileStub(@NotNull FileContent content) throws ClsFormatException { VirtualFile file = content.getFile(); - if (DecompiledUtils.isKotlinInternalCompiledFile(file)) { + if (LibrariesPackage.isKotlinInternalCompiledFile(file)) { return null; }