Refactor: repackage decompiler code and explicitly extract class file and js metafile parts
This commit is contained in:
+1
-36
@@ -16,10 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.FileIndexFacade
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
@@ -30,7 +28,7 @@ import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
abstract class KotlinClassFileViewProviderBase(
|
||||
abstract class KotlinDecompiledFileViewProviderBase(
|
||||
manager: PsiManager,
|
||||
file: VirtualFile,
|
||||
physical: Boolean) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) {
|
||||
@@ -55,37 +53,4 @@ abstract class KotlinClassFileViewProviderBase(
|
||||
}
|
||||
|
||||
override fun getContents() = content.get()
|
||||
}
|
||||
|
||||
public class KotlinClassFileViewProvider(
|
||||
manager: PsiManager,
|
||||
file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinClassFileViewProviderBase(manager, file, physical) {
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? {
|
||||
val fileIndex = ServiceManager.getService(project, javaClass<FileIndexFacade>())
|
||||
if (!fileIndex.isInLibraryClasses(file) && fileIndex.isInSource(file)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (isInternal) return null
|
||||
|
||||
return KtClsFile(this)
|
||||
}
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinClassFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
|
||||
public class KotlinJavascriptMetaFileViewProvider (
|
||||
manager: PsiManager,
|
||||
val file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinClassFileViewProviderBase(manager, file, physical) {
|
||||
|
||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType) =
|
||||
if (!isInternal) KotlinJavascriptMetaFile(this) else null
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinJavascriptMetaFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler
|
||||
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledTextFromJsMetadata
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public class KotlinJavascriptMetaFile(provider: KotlinClassFileViewProviderBase) : KtClsFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledTextFromJsMetadata(getVirtualFile())
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler
|
||||
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public class KtClsFile(provider: KotlinClassFileViewProviderBase) : KtClsFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledText(getVirtualFile())
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public abstract class KtClsFileBase(val provider: KotlinClassFileViewProviderBase) : KtFile(provider, true) {
|
||||
public abstract class KtDecompiledFileBase(val provider: KotlinDecompiledFileViewProviderBase) : KtFile(provider, true) {
|
||||
protected abstract val decompiledText: LockedClearableLazyValue<DecompiledText>
|
||||
|
||||
public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): KtDeclaration? {
|
||||
+2
-8
@@ -14,13 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
package org.jetbrains.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.ClassFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.caches.JarUserDataManager
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
@@ -43,8 +42,6 @@ public fun isKotlinJvmCompiledFile(file: VirtualFile): Boolean {
|
||||
return header != null
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@@ -74,9 +71,6 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
|
||||
header.isLocalClass || header.syntheticClassKind == "PACKAGE_PART"
|
||||
}
|
||||
|
||||
public fun isKotlinJavaScriptInternalCompiledFile(file: VirtualFile): Boolean =
|
||||
isKotlinJsMetaFile(file) && file.getNameWithoutExtension().contains('.')
|
||||
|
||||
public object HasCompiledKotlinInJar : JarUserDataManager.JarBooleanPropertyCounter(HasCompiledKotlinInJar::class.simpleName!!) {
|
||||
override fun hasProperty(file: VirtualFile) = isKotlinJvmCompiledFile(file)
|
||||
|
||||
@@ -91,4 +85,4 @@ public fun findMultifileClassParts(file: VirtualFile, multifileClass: KotlinJvmB
|
||||
return partNames.mapNotNull {
|
||||
partsFinder.findKotlinClass(ClassId(packageFqName, Name.identifier(it.substringAfterLast('/'))))
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
-5
@@ -14,25 +14,29 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
package org.jetbrains.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.BinaryClassAnnotationAndConstantLoaderImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeCapabilitiesDeserializer
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.serialization.ClassDataWithSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
|
||||
public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForClassfileDecompiler {
|
||||
public fun DeserializerForClassfileDecompiler(classFile: VirtualFile): DeserializerForClassfileDecompiler {
|
||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||
val packageFqName = kotlinClass!!.classId.packageFqName
|
||||
@@ -84,3 +88,51 @@ public class DeserializerForClassfileDecompiler(
|
||||
private val LOG = Logger.getInstance(DeserializerForClassfileDecompiler::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedClassFinder(
|
||||
val packageDirectory: VirtualFile,
|
||||
val directoryPackageFqName: FqName
|
||||
) : KotlinClassFinder {
|
||||
override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.classId)
|
||||
|
||||
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
|
||||
if (classId.getPackageFqName() != directoryPackageFqName) {
|
||||
return null
|
||||
}
|
||||
val targetName = classId.getRelativeClassName().pathSegments().joinToString("$", postfix = ".class")
|
||||
val virtualFile = packageDirectory.findChild(targetName)
|
||||
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedDataFinder(
|
||||
val classFinder: DirectoryBasedClassFinder,
|
||||
val log: Logger
|
||||
) : ClassDataFinder {
|
||||
override fun findClassData(classId: ClassId): ClassDataWithSource? {
|
||||
val binaryClass = classFinder.findKotlinClass(classId) ?: return null
|
||||
val classHeader = binaryClass.classHeader
|
||||
val data = classHeader.annotationData
|
||||
if (data == null) {
|
||||
log.error("Annotation data missing for ${binaryClass.classId}")
|
||||
return null
|
||||
}
|
||||
val strings = classHeader.strings
|
||||
if (strings == null) {
|
||||
log.error("String table not found in class ${binaryClass.classId}")
|
||||
return null
|
||||
}
|
||||
|
||||
return ClassDataWithSource(JvmProtoBufUtil.readClassDataFrom(data, strings))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val JavaClass.classId: ClassId
|
||||
get() {
|
||||
val outer = getOuterClass()
|
||||
return if (outer == null) ClassId.topLevel(getFqName()!!) else outer.classId.createNestedClassId(getName())
|
||||
}
|
||||
+1
-2
@@ -14,12 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
package org.jetbrains.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.KotlinClsStubBuilder
|
||||
|
||||
public class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
|
||||
private val stubBuilder = KotlinClsStubBuilder()
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.FileIndexFacade
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase
|
||||
|
||||
public class KotlinClassFileViewProvider(
|
||||
manager: PsiManager,
|
||||
file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinDecompiledFileViewProviderBase(manager, file, physical) {
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? {
|
||||
val fileIndex = ServiceManager.getService(project, javaClass<FileIndexFacade>())
|
||||
if (!fileIndex.isInLibraryClasses(file) && fileIndex.isInSource(file)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (isInternal) return null
|
||||
|
||||
return KtClsFile(this)
|
||||
}
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinClassFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
+50
-6
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
package org.jetbrains.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -22,19 +22,27 @@ import com.intellij.psi.compiled.ClsStubBuilder
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder
|
||||
import com.intellij.psi.stubs.PsiFileStub
|
||||
import com.intellij.util.indexing.FileContent
|
||||
import org.jetbrains.kotlin.idea.decompiler.findMultifileClassParts
|
||||
import org.jetbrains.kotlin.idea.decompiler.isKotlinInternalCompiledFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedClassFinder
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedDataFinder
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.*
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
|
||||
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
public open class KotlinClsStubBuilder : ClsStubBuilder() {
|
||||
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + 1
|
||||
@@ -93,7 +101,7 @@ public open class KotlinClsStubBuilder : ClsStubBuilder() {
|
||||
private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName): ClsStubBuilderComponents {
|
||||
val classFinder = DirectoryBasedClassFinder(file.getParent()!!, packageFqName)
|
||||
val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG)
|
||||
val annotationLoader = AnnotationLoaderForStubBuilder(classFinder, LoggingErrorReporter(LOG))
|
||||
val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder, LoggingErrorReporter(LOG))
|
||||
return ClsStubBuilderComponents(classDataFinder, annotationLoader)
|
||||
}
|
||||
|
||||
@@ -101,3 +109,39 @@ public open class KotlinClsStubBuilder : ClsStubBuilder() {
|
||||
val LOG = Logger.getInstance(KotlinClsStubBuilder::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class AnnotationLoaderForClassFileStubBuilder(
|
||||
kotlinClassFinder: KotlinClassFinder,
|
||||
errorReporter: ErrorReporter
|
||||
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>(
|
||||
LockBasedStorageManager.NO_LOCKS, kotlinClassFinder, errorReporter) {
|
||||
|
||||
override fun loadClassAnnotations(
|
||||
classProto: ProtoBuf.Class,
|
||||
nameResolver: NameResolver
|
||||
): List<ClassId> {
|
||||
val binaryAnnotationDescriptors = super.loadClassAnnotations(classProto, nameResolver)
|
||||
val serializedAnnotations = classProto.getExtension(JvmProtoBuf.classAnnotation).orEmpty()
|
||||
val serializedAnnotationDescriptors = serializedAnnotations.map { nameResolver.getClassId(it.id) }
|
||||
return binaryAnnotationDescriptors + serializedAnnotationDescriptors
|
||||
}
|
||||
|
||||
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId =
|
||||
nameResolver.getClassId(proto.getId())
|
||||
|
||||
override fun loadConstant(desc: String, initializer: Any) = null
|
||||
|
||||
override fun loadAnnotation(
|
||||
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
result.add(annotationClassId)
|
||||
return null
|
||||
}
|
||||
|
||||
override fun loadPropertyAnnotations(propertyAnnotations: List<ClassId>, fieldAnnotations: List<ClassId>): List<ClassIdWithTarget> {
|
||||
return propertyAnnotations.map { ClassIdWithTarget(it, null) } +
|
||||
fieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.FIELD) }
|
||||
}
|
||||
|
||||
override fun transformAnnotations(annotations: List<ClassId>) = annotations.map { ClassIdWithTarget(it, null) }
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.classFile
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations
|
||||
import org.jetbrains.kotlin.types.flexibility
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
import java.util.*
|
||||
|
||||
public class KtClsFile(provider: KotlinDecompiledFileViewProviderBase) : KtDecompiledFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledTextForClassFile(virtualFile)
|
||||
}
|
||||
}
|
||||
|
||||
private val descriptorRendererForClassFileDecompiler = DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
classWithPrimaryConstructor = true
|
||||
typeNormalizer = { type -> if (type.isFlexible()) type.flexibility().lowerBound else type }
|
||||
secondaryConstructorsAsPrimary = false
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
|
||||
}
|
||||
|
||||
private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI"
|
||||
private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI"
|
||||
|
||||
public val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled."
|
||||
public val INCOMPATIBLE_ABI_VERSION_COMMENT: String =
|
||||
"$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
|
||||
"//\n" +
|
||||
"// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" +
|
||||
"// File ABI version is $FILE_ABI_VERSION_MARKER"
|
||||
|
||||
public fun buildDecompiledTextForClassFile(
|
||||
classFile: VirtualFile,
|
||||
resolver: ResolverForDecompiler = DeserializerForClassfileDecompiler(classFile)
|
||||
): DecompiledText {
|
||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||
val classId = kotlinClass!!.getClassId()
|
||||
val classHeader = kotlinClass.getClassHeader()
|
||||
val packageFqName = classId.getPackageFqName()
|
||||
|
||||
return when {
|
||||
!classHeader.isCompatibleAbiVersion -> {
|
||||
DecompiledText(
|
||||
INCOMPATIBLE_ABI_VERSION_COMMENT
|
||||
.replace(CURRENT_ABI_VERSION_MARKER, JvmAbi.VERSION.toString())
|
||||
.replace(FILE_ABI_VERSION_MARKER, classHeader.version.toString()),
|
||||
mapOf())
|
||||
}
|
||||
classHeader.isCompatibleFileFacadeKind() ->
|
||||
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())), descriptorRendererForClassFileDecompiler)
|
||||
classHeader.isCompatibleClassKind() ->
|
||||
buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForClassFileDecompiler)
|
||||
classHeader.isCompatibleMultifileClassKind() -> {
|
||||
val partClasses = findMultifileClassParts(classFile, kotlinClass)
|
||||
val partMembers = partClasses.flatMap { partClass -> resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName()) }
|
||||
buildDecompiledText(packageFqName, partMembers, descriptorRendererForClassFileDecompiler)
|
||||
}
|
||||
else ->
|
||||
throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}")
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
package org.jetbrains.kotlin.idea.decompiler.js
|
||||
|
||||
import com.google.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClassIdWithTarget
|
||||
+6
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.navigation
|
||||
package org.jetbrains.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -24,6 +24,10 @@ import org.jetbrains.kotlin.serialization.js.isDefaultPackageMetafile
|
||||
import org.jetbrains.kotlin.serialization.js.isPackageClassFqName
|
||||
|
||||
public object JsMetaFileUtils {
|
||||
public fun isKotlinJsMetaFile(file: VirtualFile): Boolean = file.getFileType() == KotlinJavaScriptMetaFileType
|
||||
|
||||
public fun isKotlinJavaScriptInternalCompiledFile(file: VirtualFile): Boolean =
|
||||
isKotlinJsMetaFile(file) && file.getNameWithoutExtension().contains('.')
|
||||
|
||||
public fun getPackageFqName(file: VirtualFile): FqName = getPackageFqName(getRelativeToRootPath(file))
|
||||
|
||||
@@ -62,7 +66,7 @@ public object JsMetaFileUtils {
|
||||
private fun getModuleName(relPath: String): String = relPath.substringBefore(VfsUtilCore.VFS_SEPARATOR_CHAR)
|
||||
|
||||
private fun isPackageHeader(relPath: String): Boolean {
|
||||
val classFqName = JsMetaFileUtils.getClassFqName(relPath)
|
||||
val classFqName = getClassFqName(relPath)
|
||||
return classFqName.isPackageClassFqName()
|
||||
}
|
||||
|
||||
+31
-5
@@ -14,22 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
package org.jetbrains.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DeserializerForDecompilerBase
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassResolver
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.serialization.ClassDataWithSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths
|
||||
import org.jetbrains.kotlin.serialization.js.toPackageData
|
||||
import org.jetbrains.kotlin.serialization.js.*
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
public class KotlinJavaScriptDeserializerForDecompiler(
|
||||
@@ -82,3 +82,29 @@ public class KotlinJavaScriptDeserializerForDecompiler(
|
||||
private val LOG = Logger.getInstance(KotlinJavaScriptDeserializerForDecompiler::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedKotlinJavaScriptMetaFileFinder(
|
||||
val packageDirectory: VirtualFile,
|
||||
val directoryPackageFqName: FqName,
|
||||
val nameResolver: NameResolver
|
||||
) {
|
||||
fun findKotlinJavascriptMetaFile(classId: ClassId): VirtualFile? {
|
||||
if (classId.getPackageFqName() != directoryPackageFqName) return null
|
||||
|
||||
val targetName = classId.getRelativeClassName().pathSegments().joinToString(".", postfix = "." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION)
|
||||
return packageDirectory.findChild(targetName)
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedKotlinJavaScriptDataFinder(
|
||||
val classFinder: DirectoryBasedKotlinJavaScriptMetaFileFinder,
|
||||
val log: Logger
|
||||
) : ClassDataFinder {
|
||||
override fun findClassData(classId: ClassId): ClassDataWithSource? {
|
||||
val file = classFinder.findKotlinJavascriptMetaFile(classId) ?: return null
|
||||
|
||||
val content = file.contentsToByteArray(false)
|
||||
val classData = content.toClassData(classFinder.nameResolver)
|
||||
return ClassDataWithSource(classData)
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler;
|
||||
package org.jetbrains.kotlin.idea.decompiler.js;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.compiled.ClsStubBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.KotlinJavaScriptStubBuilder;
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
|
||||
|
||||
public class KotlinJavaScriptMetaFileDecompiler extends ClassFileDecompilers.Full {
|
||||
@@ -42,7 +41,6 @@ public class KotlinJavaScriptMetaFileDecompiler extends ClassFileDecompilers.Ful
|
||||
@NotNull
|
||||
@Override
|
||||
public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) {
|
||||
return new KotlinJavascriptMetaFileViewProvider(manager, file, physical, DecompiledUtilsKt.isKotlinJavaScriptInternalCompiledFile(
|
||||
file));
|
||||
return new KotlinJavascriptMetaFileViewProvider(manager, file, physical, JsMetaFileUtils.INSTANCE.isKotlinJavaScriptInternalCompiledFile(file));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
package org.jetbrains.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -35,4 +35,4 @@ public object KotlinJavaScriptMetaFileType : FileType {
|
||||
override fun isReadOnly() = true
|
||||
|
||||
override fun getCharset(file: VirtualFile, content: ByteArray) = null
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
package org.jetbrains.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -22,11 +22,9 @@ import com.intellij.psi.compiled.ClsStubBuilder
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder
|
||||
import com.intellij.psi.stubs.PsiFileStub
|
||||
import com.intellij.util.indexing.FileContent
|
||||
import org.jetbrains.kotlin.idea.decompiler.AnnotationLoaderForKotlinJavaScriptStubBuilder
|
||||
import org.jetbrains.kotlin.idea.decompiler.isKotlinJavaScriptInternalCompiledFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedKotlinJavaScriptDataFinder
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedKotlinJavaScriptMetaFileFinder
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClsStubBuilderComponents
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createPackageFacadeStub
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createTopLevelClassStub
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
@@ -37,13 +35,13 @@ import org.jetbrains.kotlin.serialization.js.toClassData
|
||||
import org.jetbrains.kotlin.serialization.js.toPackageData
|
||||
import java.io.ByteArrayInputStream
|
||||
|
||||
public open class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
|
||||
public class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
|
||||
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + 1
|
||||
|
||||
override fun buildFileStub(content: FileContent): PsiFileStub<*>? {
|
||||
val file = content.file
|
||||
|
||||
if (isKotlinJavaScriptInternalCompiledFile(file)) return null
|
||||
if (JsMetaFileUtils.isKotlinJavaScriptInternalCompiledFile(file)) return null
|
||||
|
||||
return doBuildFileStub(file)
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
import org.jetbrains.kotlin.load.kotlin.OldPackageFacadeClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
import java.util.*
|
||||
|
||||
public class KotlinJavascriptMetaFile(provider: KotlinJavascriptMetaFileViewProvider) : KtDecompiledFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledTextFromJsMetadata(getVirtualFile())
|
||||
}
|
||||
}
|
||||
|
||||
private val descriptorRendererForKotlinJavascriptDecompiler = DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
classWithPrimaryConstructor = true
|
||||
secondaryConstructorsAsPrimary = false
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
|
||||
}
|
||||
|
||||
public fun buildDecompiledTextFromJsMetadata(
|
||||
classFile: VirtualFile,
|
||||
resolver: ResolverForDecompiler = KotlinJavaScriptDeserializerForDecompiler(classFile)
|
||||
): DecompiledText {
|
||||
val packageFqName = JsMetaFileUtils.getPackageFqName(classFile)
|
||||
val isPackageHeader = JsMetaFileUtils.isPackageHeader(classFile)
|
||||
|
||||
if (isPackageHeader) {
|
||||
return buildDecompiledText(packageFqName,
|
||||
resolveDeclarationsInPackage(packageFqName, resolver),
|
||||
descriptorRendererForKotlinJavascriptDecompiler)
|
||||
}
|
||||
else {
|
||||
val classId = JsMetaFileUtils.getClassId(classFile)
|
||||
return buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForKotlinJavascriptDecompiler)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveDeclarationsInPackage(packageFqName: FqName, resolver: ResolverForDecompiler) =
|
||||
ArrayList(resolver.resolveDeclarationsInFacade(OldPackageFacadeClassUtils.getPackageClassFqName(packageFqName)))
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.js
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProviderBase
|
||||
|
||||
public class KotlinJavascriptMetaFileViewProvider (
|
||||
manager: PsiManager,
|
||||
val file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinDecompiledFileViewProviderBase(manager, file, physical) {
|
||||
|
||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType) =
|
||||
if (!isInternal) KotlinJavascriptMetaFile(this) else null
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinJavascriptMetaFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
+3
-3
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFileBase;
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFileBase;
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope;
|
||||
import org.jetbrains.kotlin.idea.stubindex.StaticFacadeIndexUtil;
|
||||
import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinderFactory;
|
||||
@@ -62,11 +62,11 @@ public final class DecompiledNavigationUtils {
|
||||
if (virtualFile == null) return null;
|
||||
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
|
||||
if (!(psiFile instanceof KtClsFileBase)) {
|
||||
if (!(psiFile instanceof KtDecompiledFileBase)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((KtClsFileBase) psiFile).getDeclarationForDescriptor(referencedDescriptor);
|
||||
return ((KtDecompiledFileBase) psiFile).getDeclarationForDescriptor(referencedDescriptor);
|
||||
}
|
||||
|
||||
private static boolean isLocal(DeclarationDescriptor descriptor) {
|
||||
|
||||
+4
-43
@@ -16,18 +16,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
|
||||
data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSiteTarget?)
|
||||
|
||||
@@ -96,39 +93,3 @@ internal fun ClsStubBuilderContext.child(nameResolver: NameResolver, typeTable:
|
||||
typeTable
|
||||
)
|
||||
}
|
||||
|
||||
class AnnotationLoaderForStubBuilder(
|
||||
kotlinClassFinder: KotlinClassFinder,
|
||||
errorReporter: ErrorReporter
|
||||
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>(
|
||||
LockBasedStorageManager.NO_LOCKS, kotlinClassFinder, errorReporter) {
|
||||
|
||||
override fun loadClassAnnotations(
|
||||
classProto: ProtoBuf.Class,
|
||||
nameResolver: NameResolver
|
||||
): List<ClassId> {
|
||||
val binaryAnnotationDescriptors = super.loadClassAnnotations(classProto, nameResolver)
|
||||
val serializedAnnotations = classProto.getExtension(JvmProtoBuf.classAnnotation).orEmpty()
|
||||
val serializedAnnotationDescriptors = serializedAnnotations.map { nameResolver.getClassId(it.id) }
|
||||
return binaryAnnotationDescriptors + serializedAnnotationDescriptors
|
||||
}
|
||||
|
||||
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId =
|
||||
nameResolver.getClassId(proto.getId())
|
||||
|
||||
override fun loadConstant(desc: String, initializer: Any) = null
|
||||
|
||||
override fun loadAnnotation(
|
||||
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
result.add(annotationClassId)
|
||||
return null
|
||||
}
|
||||
|
||||
override fun loadPropertyAnnotations(propertyAnnotations: List<ClassId>, fieldAnnotations: List<ClassId>): List<ClassIdWithTarget> {
|
||||
return propertyAnnotations.map { ClassIdWithTarget(it, null) } +
|
||||
fieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.FIELD) }
|
||||
}
|
||||
|
||||
override fun transformAnnotations(annotations: List<ClassId>) = annotations.map { ClassIdWithTarget(it, null) }
|
||||
}
|
||||
|
||||
+1
-92
@@ -17,112 +17,21 @@
|
||||
package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.decompiler.findMultifileClassParts
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.OldPackageFacadeClassUtils
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.ExcludedTypeAnnotations
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||
import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass
|
||||
import org.jetbrains.kotlin.types.flexibility
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
import java.util.*
|
||||
|
||||
private val FILE_ABI_VERSION_MARKER: String = "FILE_ABI"
|
||||
private val CURRENT_ABI_VERSION_MARKER: String = "CURRENT_ABI"
|
||||
|
||||
public val INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT: String = "// This class file was compiled with different version of Kotlin compiler and can't be decompiled."
|
||||
public val INCOMPATIBLE_ABI_VERSION_COMMENT: String =
|
||||
"$INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT\n" +
|
||||
"//\n" +
|
||||
"// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" +
|
||||
"// File ABI version is $FILE_ABI_VERSION_MARKER"
|
||||
|
||||
public fun buildDecompiledText(
|
||||
classFile: VirtualFile,
|
||||
resolver: ResolverForDecompiler = DeserializerForDecompiler(classFile)
|
||||
): DecompiledText {
|
||||
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
|
||||
assert(kotlinClass != null) { "Decompiled data factory shouldn't be called on an unsupported file: " + classFile }
|
||||
val classId = kotlinClass!!.getClassId()
|
||||
val classHeader = kotlinClass.getClassHeader()
|
||||
val packageFqName = classId.getPackageFqName()
|
||||
|
||||
return when {
|
||||
!classHeader.isCompatibleAbiVersion -> {
|
||||
DecompiledText(
|
||||
INCOMPATIBLE_ABI_VERSION_COMMENT
|
||||
.replace(CURRENT_ABI_VERSION_MARKER, JvmAbi.VERSION.toString())
|
||||
.replace(FILE_ABI_VERSION_MARKER, classHeader.version.toString()),
|
||||
mapOf())
|
||||
}
|
||||
classHeader.isCompatibleFileFacadeKind() ->
|
||||
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())))
|
||||
classHeader.isCompatibleClassKind() ->
|
||||
buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)))
|
||||
classHeader.isCompatibleMultifileClassKind() -> {
|
||||
val partClasses = findMultifileClassParts(classFile, kotlinClass)
|
||||
val partMembers = partClasses.flatMap { partClass -> resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName()) }
|
||||
buildDecompiledText(packageFqName, partMembers)
|
||||
}
|
||||
else ->
|
||||
throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
public fun buildDecompiledTextFromJsMetadata(
|
||||
classFile: VirtualFile,
|
||||
resolver: ResolverForDecompiler = KotlinJavaScriptDeserializerForDecompiler(classFile)
|
||||
): DecompiledText {
|
||||
val packageFqName = JsMetaFileUtils.getPackageFqName(classFile)
|
||||
val isPackageHeader = JsMetaFileUtils.isPackageHeader(classFile)
|
||||
|
||||
if (isPackageHeader) {
|
||||
return buildDecompiledText(packageFqName,
|
||||
resolveDeclarationsInPackage(packageFqName, resolver),
|
||||
descriptorRendererForKotlinJavascriptDecompiler)
|
||||
}
|
||||
else {
|
||||
val classId = JsMetaFileUtils.getClassId(classFile)
|
||||
return buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForKotlinJavascriptDecompiler)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveDeclarationsInPackage(packageFqName: FqName, resolver: ResolverForDecompiler) =
|
||||
ArrayList(resolver.resolveDeclarationsInFacade(OldPackageFacadeClassUtils.getPackageClassFqName(packageFqName)))
|
||||
|
||||
private val DECOMPILED_CODE_COMMENT = "/* compiled code */"
|
||||
private val DECOMPILED_COMMENT_FOR_PARAMETER = "/* = compiled code */"
|
||||
private val FLEXIBLE_TYPE_COMMENT = "/* platform type */"
|
||||
|
||||
private val descriptorRendererForDecompiler = DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
classWithPrimaryConstructor = true
|
||||
typeNormalizer = { type -> if (type.isFlexible()) type.flexibility().lowerBound else type }
|
||||
secondaryConstructorsAsPrimary = false
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
|
||||
}
|
||||
|
||||
private val descriptorRendererForKotlinJavascriptDecompiler = DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
classWithPrimaryConstructor = true
|
||||
secondaryConstructorsAsPrimary = false
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
|
||||
}
|
||||
|
||||
private val descriptorRendererForKeys = DescriptorRenderer.COMPACT_WITH_MODIFIERS.withOptions {
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
}
|
||||
@@ -136,7 +45,7 @@ public data class DecompiledText(public val text: String, public val renderedDes
|
||||
public fun buildDecompiledText(
|
||||
packageFqName: FqName,
|
||||
descriptors: List<DeclarationDescriptor>,
|
||||
descriptorRenderer: DescriptorRenderer = descriptorRendererForDecompiler
|
||||
descriptorRenderer: DescriptorRenderer
|
||||
): DecompiledText {
|
||||
val builder = StringBuilder()
|
||||
val renderedDescriptorsToRange = HashMap<String, TextRange>()
|
||||
|
||||
+8
-1
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleParameters
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
@@ -32,6 +34,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
@@ -79,4 +82,8 @@ public abstract class DeserializerForDecompilerBase(
|
||||
moduleDescriptor, targetPlatform.builtIns.builtInsModule, moduleContainingMissingDependencies
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ResolveEverythingToKotlinAnyLocalClassResolver(private val builtIns: KotlinBuiltIns) : LocalClassResolver {
|
||||
override fun resolveLocalClass(classId: ClassId): ClassDescriptor = builtIns.any
|
||||
}
|
||||
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.isKotlinWithCompatibleAbiVersion
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.ClassDataWithSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
||||
import org.jetbrains.kotlin.serialization.js.toClassData
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
|
||||
class DirectoryBasedClassFinder(
|
||||
val packageDirectory: VirtualFile,
|
||||
val directoryPackageFqName: FqName
|
||||
) : KotlinClassFinder {
|
||||
override fun findKotlinClass(javaClass: JavaClass) = findKotlinClass(javaClass.classId)
|
||||
|
||||
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
|
||||
if (classId.getPackageFqName() != directoryPackageFqName) {
|
||||
return null
|
||||
}
|
||||
val targetName = classId.getRelativeClassName().pathSegments().joinToString("$", postfix = ".class")
|
||||
val virtualFile = packageDirectory.findChild(targetName)
|
||||
if (virtualFile != null && isKotlinWithCompatibleAbiVersion(virtualFile)) {
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedKotlinJavaScriptMetaFileFinder(
|
||||
val packageDirectory: VirtualFile,
|
||||
val directoryPackageFqName: FqName,
|
||||
val nameResolver: NameResolver
|
||||
) {
|
||||
fun findKotlinJavascriptMetaFile(classId: ClassId): VirtualFile? {
|
||||
if (classId.getPackageFqName() != directoryPackageFqName) return null
|
||||
|
||||
val targetName = classId.getRelativeClassName().pathSegments().joinToString(".", postfix = "." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION)
|
||||
return packageDirectory.findChild(targetName)
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedDataFinder(
|
||||
val classFinder: DirectoryBasedClassFinder,
|
||||
val log: Logger
|
||||
) : ClassDataFinder {
|
||||
override fun findClassData(classId: ClassId): ClassDataWithSource? {
|
||||
val binaryClass = classFinder.findKotlinClass(classId) ?: return null
|
||||
val classHeader = binaryClass.classHeader
|
||||
val data = classHeader.annotationData
|
||||
if (data == null) {
|
||||
log.error("Annotation data missing for ${binaryClass.classId}")
|
||||
return null
|
||||
}
|
||||
val strings = classHeader.strings
|
||||
if (strings == null) {
|
||||
log.error("String table not found in class ${binaryClass.classId}")
|
||||
return null
|
||||
}
|
||||
|
||||
return ClassDataWithSource(JvmProtoBufUtil.readClassDataFrom(data, strings))
|
||||
}
|
||||
}
|
||||
|
||||
class DirectoryBasedKotlinJavaScriptDataFinder(
|
||||
val classFinder: DirectoryBasedKotlinJavaScriptMetaFileFinder,
|
||||
val log: Logger
|
||||
) : ClassDataFinder {
|
||||
override fun findClassData(classId: ClassId): ClassDataWithSource? {
|
||||
val file = classFinder.findKotlinJavascriptMetaFile(classId) ?: return null
|
||||
|
||||
val content = file.contentsToByteArray(false)
|
||||
val classData = content.toClassData(classFinder.nameResolver)
|
||||
return ClassDataWithSource(classData)
|
||||
}
|
||||
}
|
||||
|
||||
class ResolveEverythingToKotlinAnyLocalClassResolver(private val builtIns: KotlinBuiltIns) : LocalClassResolver {
|
||||
override fun resolveLocalClass(classId: ClassId): ClassDescriptor = builtIns.any
|
||||
}
|
||||
|
||||
private val JavaClass.classId: ClassId
|
||||
get() {
|
||||
val outer = getOuterClass()
|
||||
return if (outer == null) ClassId.topLevel(getFqName()!!) else outer.classId.createNestedClassId(getName())
|
||||
}
|
||||
+1
-1
@@ -22,7 +22,7 @@ import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
|
||||
//TODO: workaround for bug in JavaClsStructureViewBuilderProvider, remove when IDEA api is updated
|
||||
public class KtClsStructureViewBuilderProvider : StructureViewBuilderProvider {
|
||||
|
||||
@@ -20,8 +20,8 @@ import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.util.indexing.*
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinJavaScriptMetaFileType
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.JsMetaFileUtils
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileType
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.DataInput
|
||||
|
||||
@@ -32,8 +32,8 @@ import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinClassFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClassFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.util.*
|
||||
|
||||
@@ -558,8 +558,8 @@
|
||||
<stubIndex implementation="org.jetbrains.kotlin.idea.stubindex.KotlinMultifileClassPartIndex"/>
|
||||
<stubIndex implementation="org.jetbrains.kotlin.idea.stubindex.KotlinScriptFqnIndex"/>
|
||||
|
||||
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.KotlinClassFileDecompiler"/>
|
||||
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.KotlinJavaScriptMetaFileDecompiler"/>
|
||||
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClassFileDecompiler"/>
|
||||
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileDecompiler"/>
|
||||
|
||||
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinAbiVersionIndex"/>
|
||||
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinJavaScriptAbiVersionIndex"/>
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileTypeConsumer
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinJavaScriptMetaFileType
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileType
|
||||
|
||||
public class KotlinJavaScriptMetaFileTypeFactory : FileTypeFactory() {
|
||||
override fun createFileTypes(consumer: FileTypeConsumer) {
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.caches.JarUserDataManager;
|
||||
import org.jetbrains.kotlin.idea.debugger.filter.DebuggerFiltersUtilKt;
|
||||
import org.jetbrains.kotlin.idea.decompiler.HasCompiledKotlinInJar;
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.HasCompiledKotlinInJar;
|
||||
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil;
|
||||
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
|
||||
@@ -54,7 +54,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.debugger.breakpoints.getLambdasAtLineIfAny
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
|
||||
+1
-1
@@ -34,9 +34,9 @@ import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile;
|
||||
import org.jetbrains.kotlin.idea.test.JdkAndMockLibraryProjectDescriptor;
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile;
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
|
||||
|
||||
+1
@@ -24,6 +24,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.util.indexing.FileContentImpl
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClsStubBuilder
|
||||
import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtFileStubBuilder
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
|
||||
+3
-2
@@ -17,7 +17,8 @@
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClsStubBuilder
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.buildDecompiledTextForClassFile
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||
@@ -30,7 +31,7 @@ public class ClsStubConsistencyTest : StubConsistencyBaseTest() {
|
||||
|
||||
override fun createStubBuilder() = KotlinClsStubBuilder()
|
||||
|
||||
override fun getDecompiledText(packageFile: VirtualFile): String = buildDecompiledText(packageFile).text
|
||||
override fun getDecompiledText(packageFile: VirtualFile): String = buildDecompiledTextForClassFile(packageFile).text
|
||||
|
||||
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
}
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledTextFromJsMetadata
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptStubBuilder
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.buildDecompiledTextFromJsMetadata
|
||||
import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.OldPackageFacadeClassUtils
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.KotlinJavascriptMetaFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.KotlinJavascriptMetaFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest
|
||||
import org.jetbrains.kotlin.idea.test.ModuleKind
|
||||
import org.jetbrains.kotlin.idea.test.configureAs
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
+3
-1
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.DeserializerForClassfileDecompiler
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.buildDecompiledTextForClassFile
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder
|
||||
@@ -44,7 +46,7 @@ public class DecompiledTextConsistencyTest : TextConsistencyBaseTest() {
|
||||
JvmVirtualFileFinder.SERVICE.getInstance(project)
|
||||
|
||||
override fun getDecompiledText(packageFile: VirtualFile, resolver: ResolverForDecompiler?): String =
|
||||
(resolver?.let { buildDecompiledText(packageFile, it) } ?: buildDecompiledText(packageFile)).text
|
||||
(resolver?.let { buildDecompiledTextForClassFile(packageFile, it) } ?: buildDecompiledTextForClassFile(packageFile)).text
|
||||
|
||||
override fun getModuleDescriptor(): ModuleDescriptor =
|
||||
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext(
|
||||
|
||||
+2
-1
@@ -20,7 +20,8 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.AbstractInternalCompiledClassesTest
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.INCOMPATIBLE_ABI_VERSION_GENERAL_COMMENT
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest
|
||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.findClassFileByName
|
||||
import org.jetbrains.kotlin.idea.test.KotlinJdkAndLibraryProjectDescriptor
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.js.buildDecompiledTextFromJsMetadata
|
||||
import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.vfilefinder.JsVirtualFileFinder
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
|
||||
Reference in New Issue
Block a user