Decompile builtins (kotlin_class and kotlin_package files)

The main purpose of this is to be able to index builtin declarations and enable go to symbol/class functionality in ide
Also it makes sense to show builtin classes (Any, Int ...) as classes when browsing kotlin-runtime.jar

Refactor decompiler code to eliminate existing and potential duplication
Share the code between js (kjsm) decompilation and builtin decompilation heavily
This commit is contained in:
Pavel V. Talanov
2015-12-03 18:10:45 +03:00
parent 6164566cad
commit c40d6af1e5
21 changed files with 533 additions and 137 deletions
@@ -30,9 +30,9 @@ public object BuiltInsSerializedResourcePaths : SerializedResourcePaths() {
BuiltInsProtoBuf.registerAllExtensions(extensionRegistry)
}
private val CLASS_METADATA_FILE_EXTENSION = "kotlin_class"
private val PACKAGE_FILE_EXTENSION = "kotlin_package"
private val STRING_TABLE_FILE_EXTENSION = "kotlin_string_table"
val CLASS_METADATA_FILE_EXTENSION = "kotlin_class"
val PACKAGE_FILE_EXTENSION = "kotlin_package"
val STRING_TABLE_FILE_EXTENSION = "kotlin_string_table"
public override fun getClassMetadataPath(classId: ClassId): String {
return packageFqNameToPath(classId.getPackageFqName()) + "/" + classId.getRelativeClassName().asString() +
@@ -0,0 +1,118 @@
/*
* 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.builtIns
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.FileViewProvider
import com.intellij.psi.PsiManager
import com.intellij.psi.compiled.ClassFileDecompilers
import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths
import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
import org.jetbrains.kotlin.idea.decompiler.common.toClassProto
import org.jetbrains.kotlin.idea.decompiler.common.toPackageProto
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
class KotlinBuiltInDecompiler : ClassFileDecompilers.Full() {
private val stubBuilder = KotlinBuiltInStubBuilder()
override fun accepts(file: VirtualFile): Boolean {
return file.fileType == KotlinBuiltInClassFileType || file.fileType == KotlinBuiltInPackageFileType
}
override fun getStubBuilder() = stubBuilder
override fun createFileViewProvider(file: VirtualFile, manager: PsiManager, physical: Boolean): FileViewProvider {
return KotlinDecompiledFileViewProvider(manager, file, physical) { provider ->
if (isInternalBuiltInFile(provider.virtualFile)) {
null
}
else {
KtDecompiledFile(provider) { file ->
buildDecompiledTextForBuiltIns(file)
}
}
}
}
companion object {
val LOG = Logger.getInstance(KotlinBuiltInDecompiler::class.java)
}
}
private val decompilerRendererForBuiltIns = DescriptorRenderer.withOptions { defaultDecompilerRendererOptions() }
public fun buildDecompiledTextForBuiltIns(
builtInFile: VirtualFile
): DecompiledText {
val directory = builtInFile.parent!!
val nameResolver = readStringTable(directory, KotlinBuiltInDecompiler.LOG)!!
val content = builtInFile.contentsToByteArray()
return when (builtInFile.fileType) {
KotlinBuiltInPackageFileType -> {
val packageFqName = content.toPackageProto(BuiltInsSerializedResourcePaths.extensionRegistry).packageFqName(nameResolver)
val resolver = KotlinBuiltInDeserializerForDecompiler(directory, packageFqName, nameResolver)
buildDecompiledText(packageFqName, resolver.resolveDeclarationsInFacade(packageFqName), decompilerRendererForBuiltIns)
}
KotlinBuiltInClassFileType -> {
val classProto = content.toClassProto(BuiltInsSerializedResourcePaths.extensionRegistry)
val classId = nameResolver.getClassId(classProto.fqName)
val packageFqName = classId.packageFqName
val resolver = KotlinBuiltInDeserializerForDecompiler(directory, packageFqName, nameResolver)
buildDecompiledText(
packageFqName,
listOfNotNull(resolver.resolveTopLevelClass(classId)),
decompilerRendererForBuiltIns
)
}
else -> error("Unexpected filetype ${builtInFile.fileType}")
}
}
fun ProtoBuf.Package.packageFqName(nameResolver: NameResolverImpl): FqName {
return nameResolver.getPackageFqName(getExtension(BuiltInsProtoBuf.packageFqName))
}
fun isInternalBuiltInFile(virtualFile: VirtualFile): Boolean {
when (virtualFile.fileType) {
KotlinBuiltInPackageFileType -> {
// do not accept kotlin_package files without packageFqName extension to avoid failing on older runtimes
// this check may be costly but there are few kotlin_package files
val packageProto = virtualFile.contentsToByteArray().toPackageProto(BuiltInsSerializedResourcePaths.extensionRegistry)
return !packageProto.hasExtension(BuiltInsProtoBuf.packageFqName)
}
KotlinBuiltInClassFileType -> {
val correspondsToInnerClass = virtualFile.nameWithoutExtension.contains('.')
if (correspondsToInnerClass) {
return true
}
val classFileName = virtualFile.nameWithoutExtension + "." + JavaClassFileType.INSTANCE.defaultExtension
val classFileForTheSameClassIsPresent = virtualFile.parent!!.findChild(classFileName) != null
return classFileForTheSameClassIsPresent
}
else -> error("Unexpected filetype ${virtualFile.fileType}")
}
}
@@ -0,0 +1,57 @@
/*
* 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.builtIns
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder
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.name.FqName
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.serialization.deserialization.*
public class KotlinBuiltInDeserializerForDecompiler(
packageDirectory: VirtualFile,
packageFqName: FqName,
private val nameResolver: NameResolver
) : DeserializerForDecompilerBase(packageDirectory, packageFqName) {
override val targetPlatform: TargetPlatform get() = TargetPlatform.Default
private val classDataFinder = DirectoryBasedClassDataFinder(
packageDirectory, directoryPackageFqName, nameResolver, BuiltInsSerializedResourcePaths
)
override val deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, AnnotationAndConstantLoaderImpl(moduleDescriptor, BuiltInSerializerProtocol),
packageFragmentProvider, ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, FlexibleTypeCapabilitiesDeserializer.ThrowException, ClassDescriptorFactory.EMPTY
)
override fun resolveDeclarationsInFacade(facadeFqName: FqName): List<DeclarationDescriptor> {
return getDescriptorsFromPackageFile(facadeFqName, BuiltInsSerializedResourcePaths, LOG, nameResolver)
}
companion object {
private val LOG = Logger.getInstance(KotlinBuiltInDeserializerForDecompiler::class.java)
}
}
@@ -0,0 +1,106 @@
/*
* 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.builtIns
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VirtualFile
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.annotations.TestOnly
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths
import org.jetbrains.kotlin.idea.decompiler.common.AnnotationLoaderForStubBuilderImpl
import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder
import org.jetbrains.kotlin.idea.decompiler.common.toClassProto
import org.jetbrains.kotlin.idea.decompiler.common.toPackageProto
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.stubs.impl.KotlinFileStubImpl
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import java.io.ByteArrayInputStream
public class KotlinBuiltInStubBuilder : ClsStubBuilder() {
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + 1
override fun buildFileStub(content: FileContent): PsiFileStub<*>? {
if (isInternalBuiltInFile(content.file)) return null
return doBuildFileStub(content)
}
@TestOnly
fun doBuildFileStub(content: FileContent): KotlinFileStubImpl? {
val file = content.file
val directory = file.parent!!
val nameResolver = readStringTable(directory, LOG) ?: return null
val contentAsBytes = content.content
return when (file.fileType) {
KotlinBuiltInPackageFileType -> {
val packageProto = contentAsBytes.toPackageProto(BuiltInsSerializedResourcePaths.extensionRegistry)
val packageFqName = packageProto.packageFqName(nameResolver)
val components = createStubBuilderComponents(file, packageFqName, nameResolver)
val context = components.createContext(
nameResolver, packageFqName, TypeTable(packageProto.typeTable)
)
createPackageFacadeStub(packageProto, packageFqName, context)
}
KotlinBuiltInClassFileType -> {
val classProto = contentAsBytes.toClassProto(BuiltInsSerializedResourcePaths.extensionRegistry)
val classId = nameResolver.getClassId(classProto.fqName)
val packageFqName = classId.packageFqName
val components = createStubBuilderComponents(file, packageFqName, nameResolver)
val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable))
createTopLevelClassStub(classId, classProto, context)
}
else -> error("Unexpected filetype ${file.fileType}")
}
}
private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, nameResolver: NameResolver): ClsStubBuilderComponents {
val finder = DirectoryBasedClassDataFinder(file.parent!!, packageFqName, nameResolver, BuiltInsSerializedResourcePaths)
val annotationLoader = AnnotationLoaderForStubBuilderImpl(BuiltInSerializerProtocol)
return ClsStubBuilderComponents(finder, annotationLoader)
}
companion object {
val LOG = Logger.getInstance(KotlinBuiltInStubBuilder::class.java)
}
}
fun readStringTable(directory: VirtualFile, log: Logger): NameResolverImpl? {
val stringsFileName = "${directory.name}.${BuiltInsSerializedResourcePaths.STRING_TABLE_FILE_EXTENSION}"
val stringTableFile = directory.findFileByRelativePath(stringsFileName) ?: return run {
log.error("$stringsFileName not found in $directory")
null
}
val nameResolver = try {
NameResolverImpl.read(ByteArrayInputStream(stringTableFile.contentsToByteArray(false)))
}
catch (e: Exception) {
log.error("Error reading data from $stringTableFile ", e)
null
}
return nameResolver
}
@@ -0,0 +1,54 @@
/*
* 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.builtIns
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths
import org.jetbrains.kotlin.idea.KotlinIcons
public object KotlinBuiltInClassFileType : FileType {
override fun getName() = "kotlin_class"
override fun getDescription() = "Kotlin builtin class"
override fun getDefaultExtension() = BuiltInsSerializedResourcePaths.CLASS_METADATA_FILE_EXTENSION
override fun getIcon() = KotlinIcons.CLASS
override fun isBinary() = true
override fun isReadOnly() = true
override fun getCharset(file: VirtualFile, content: ByteArray) = null
}
public object KotlinBuiltInPackageFileType : FileType {
override fun getName() = "kotlin_package"
override fun getDescription() = "Kotlin builtin package"
override fun getDefaultExtension() = BuiltInsSerializedResourcePaths.PACKAGE_FILE_EXTENSION
override fun getIcon() = KotlinIcons.FILE
override fun isBinary() = true
override fun isReadOnly() = true
override fun getCharset(file: VirtualFile, content: ByteArray) = null
}
@@ -64,7 +64,7 @@ public class DeserializerForClassfileDecompiler(
LookupTracker.DO_NOTHING, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY
)
override fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection<DeclarationDescriptor> {
override fun resolveDeclarationsInFacade(facadeFqName: FqName): List<DeclarationDescriptor> {
val packageFqName = facadeFqName.parent()
assert(packageFqName == directoryPackageFqName) {
"Was called for $facadeFqName; only members of $directoryPackageFqName package are expected."
@@ -81,7 +81,7 @@ public class DeserializerForClassfileDecompiler(
val membersScope = DeserializedPackageMemberScope(
createDummyPackageFragment(packageFqName), packageProto, nameResolver, deserializationComponents
) { emptyList() }
return membersScope.getContributedDescriptors()
return membersScope.getContributedDescriptors().toList()
}
companion object {
@@ -26,14 +26,13 @@ import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
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.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
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 java.util.*
@@ -50,14 +49,10 @@ public class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
return KotlinDecompiledFileViewProvider(manager, file, physical) { provider ->
val virtualFile = provider.virtualFile
val fileIndex = ServiceManager.getService(project, FileIndexFacade::class.java)
if (!fileIndex.isInLibraryClasses(virtualFile) && fileIndex.isInSource(virtualFile)) {
null
}
else if (isKotlinInternalCompiledFile(virtualFile)) {
null
}
else {
KtClsFile(provider)
when {
!fileIndex.isInLibraryClasses(virtualFile) && fileIndex.isInSource(virtualFile) -> null
isKotlinInternalCompiledFile(virtualFile) -> null
else -> KtClsFile(provider)
}
}
}
@@ -65,13 +60,9 @@ public class KotlinClassFileDecompiler : ClassFileDecompilers.Full() {
class KtClsFile(provider: KotlinDecompiledFileViewProvider) : KtDecompiledFile(provider, { file -> buildDecompiledTextForClassFile(file) })
private val descriptorRendererForClassFileDecompiler = DescriptorRenderer.withOptions {
withDefinedIn = false
classWithPrimaryConstructor = true
private val decompilerRendererForClassFiles = DescriptorRenderer.withOptions {
defaultDecompilerRendererOptions()
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"
@@ -103,13 +94,13 @@ public fun buildDecompiledTextForClassFile(
mapOf())
}
classHeader.isCompatibleFileFacadeKind() ->
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())), descriptorRendererForClassFileDecompiler)
buildDecompiledText(packageFqName, ArrayList(resolver.resolveDeclarationsInFacade(classId.asSingleFqName())), decompilerRendererForClassFiles)
classHeader.isCompatibleClassKind() ->
buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForClassFileDecompiler)
buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), decompilerRendererForClassFiles)
classHeader.isCompatibleMultifileClassKind() -> {
val partClasses = findMultifileClassParts(classFile, kotlinClass)
val partMembers = partClasses.flatMap { partClass -> resolver.resolveDeclarationsInFacade(partClass.classId.asSingleFqName()) }
buildDecompiledText(packageFqName, partMembers, descriptorRendererForClassFileDecompiler)
buildDecompiledText(packageFqName, partMembers, decompilerRendererForClassFiles)
}
else ->
throw UnsupportedOperationException("Unknown header kind: ${classHeader.kind} ${classHeader.isCompatibleAbiVersion}")
@@ -14,25 +14,27 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.decompiler.js
package org.jetbrains.kotlin.idea.decompiler.common
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClassIdWithTarget
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.js.JsProtoBuf
import org.jetbrains.kotlin.types.KotlinType
public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget> {
public class AnnotationLoaderForStubBuilderImpl(
private val protocol: SerializerExtensionProtocol
) : AnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget> {
override fun loadClassAnnotations(
classProto: ProtoBuf.Class, nameResolver: NameResolver
): List<ClassId> =
classProto.getExtension(JsProtoBuf.classAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
classProto.getExtension(protocol.classAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadCallableAnnotations(
container: ProtoContainer,
@@ -40,9 +42,9 @@ public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndCon
kind: AnnotatedCallableKind
): List<ClassIdWithTarget> {
val annotations = when (proto) {
is ProtoBuf.Constructor -> proto.getExtension(JsProtoBuf.constructorAnnotation)
is ProtoBuf.Function -> proto.getExtension(JsProtoBuf.functionAnnotation)
is ProtoBuf.Property -> proto.getExtension(JsProtoBuf.propertyAnnotation)
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
is ProtoBuf.Property -> proto.getExtension(protocol.propertyAnnotation)
else -> error("Unknown message: $proto")
}.orEmpty()
return annotations.map {
@@ -57,7 +59,7 @@ public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndCon
parameterIndex: Int,
proto: ProtoBuf.ValueParameter
): List<ClassId> =
proto.getExtension(JsProtoBuf.parameterAnnotation).orEmpty().map {
proto.getExtension(protocol.parameterAnnotation).orEmpty().map {
container.nameResolver.getClassId(it.id)
}
@@ -71,10 +73,10 @@ public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndCon
proto: ProtoBuf.Type,
nameResolver: NameResolver
): List<ClassId> =
proto.getExtension(JsProtoBuf.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
proto.getExtension(protocol.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List<ClassId> =
proto.getExtension(JsProtoBuf.typeParameterAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
proto.getExtension(protocol.typeParameterAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadPropertyConstant(
container: ProtoContainer,
@@ -14,18 +14,16 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.serialization.js
package org.jetbrains.kotlin.idea.decompiler.common
import com.google.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.serialization.ProtoBuf
import java.io.ByteArrayInputStream
public fun ByteArray.toPackageProto(): ProtoBuf.Package {
val registry = KotlinJavascriptSerializedResourcePaths.extensionRegistry
return ProtoBuf.Package.parseFrom(ByteArrayInputStream(this), registry)!!
}
public fun ByteArray.toClassProto(): ProtoBuf.Class {
val registry = KotlinJavascriptSerializedResourcePaths.extensionRegistry
return ProtoBuf.Class.parseFrom(ByteArrayInputStream(this), registry)
fun ByteArray.toPackageProto(extensionRegistry: ExtensionRegistryLite): ProtoBuf.Package {
return ProtoBuf.Package.parseFrom(ByteArrayInputStream(this), extensionRegistry)!!
}
fun ByteArray.toClassProto(extensionRegistry: ExtensionRegistryLite): ProtoBuf.Class {
return ProtoBuf.Class.parseFrom(ByteArrayInputStream(this), extensionRegistry)
}
@@ -0,0 +1,49 @@
/*
* 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.common
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.ClassData
import org.jetbrains.kotlin.serialization.ClassDataWithSource
import org.jetbrains.kotlin.serialization.SerializedResourcePaths
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
class DirectoryBasedClassDataFinder(
private val packageDirectory: VirtualFile,
private val directoryPackageFqName: FqName,
private val nameResolver: NameResolver,
private val paths: SerializedResourcePaths
) : ClassDataFinder {
fun findFileForClass(classId: ClassId): VirtualFile? {
if (classId.packageFqName != directoryPackageFqName) return null
val pathRelativeToDir = paths.getClassMetadataPath(classId).substringAfterLast("/")
return packageDirectory.findChild(pathRelativeToDir)
}
override fun findClassData(classId: ClassId): ClassDataWithSource? {
val virtualFile = findFileForClass(classId) ?: return null
val content = virtualFile.contentsToByteArray(false)
val classProto = content.toClassProto(paths.extensionRegistry)
return ClassDataWithSource(ClassData(nameResolver, classProto))
}
}
@@ -19,19 +19,17 @@ 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.common.DirectoryBasedClassDataFinder
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.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.ClassData
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.*
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths
import java.io.ByteArrayInputStream
public class KotlinJavaScriptDeserializerForDecompiler(
@@ -48,62 +46,22 @@ public class KotlinJavaScriptDeserializerForDecompiler(
override val targetPlatform: TargetPlatform get() = JsPlatform
private val metaFileFinder = DirectoryBasedKotlinJavaScriptMetaFileFinder(packageDirectory, directoryPackageFqName, nameResolver)
private val classDataFinder = DirectoryBasedKotlinJavaScriptDataFinder(metaFileFinder, LOG)
private val finder = DirectoryBasedClassDataFinder(packageDirectory, directoryPackageFqName, nameResolver, KotlinJavascriptSerializedResourcePaths)
private val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(moduleDescriptor, JsSerializerProtocol)
override val deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
storageManager, moduleDescriptor, finder, annotationAndConstantLoader, packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassResolver(targetPlatform.builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, FlexibleTypeCapabilitiesDeserializer.Dynamic, ClassDescriptorFactory.EMPTY
)
override fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection<DeclarationDescriptor> {
override fun resolveDeclarationsInFacade(facadeFqName: FqName): List<DeclarationDescriptor> {
val packageFqName = facadeFqName.parent()
assert(packageFqName == directoryPackageFqName) {
"Was called for $facadeFqName; only members of $directoryPackageFqName package are expected."
}
val file = metaFileFinder.findKotlinJavascriptMetaFile(ClassId.topLevel(facadeFqName))
if (file == null) {
LOG.error("Could not read data for $facadeFqName")
return emptyList()
}
val content = file.contentsToByteArray(false)
val membersScope = DeserializedPackageMemberScope(
createDummyPackageFragment(packageFqName), content.toPackageProto(), nameResolver, deserializationComponents
) { emptyList() }
return membersScope.getContributedDescriptors()
return getDescriptorsFromPackageFile(packageFqName, KotlinJavascriptSerializedResourcePaths, LOG, nameResolver)
}
companion object {
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)
return ClassDataWithSource(ClassData(classFinder.nameResolver, content.toClassProto()))
}
}
@@ -26,11 +26,10 @@ import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
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.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
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.serialization.js.KotlinJavascriptSerializationUtil
import java.util.*
@@ -57,13 +56,7 @@ class KotlinJavaScriptMetaFileDecompiler : ClassFileDecompilers.Full() {
}
}
private val descriptorRendererForKotlinJavascriptDecompiler = DescriptorRenderer.withOptions {
withDefinedIn = false
classWithPrimaryConstructor = true
secondaryConstructorsAsPrimary = false
modifiers = DescriptorRendererModifier.ALL
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
}
private val decompilerRendererForJS = DescriptorRenderer.withOptions { defaultDecompilerRendererOptions() }
public fun buildDecompiledTextFromJsMetadata(
classFile: VirtualFile,
@@ -75,11 +68,11 @@ public fun buildDecompiledTextFromJsMetadata(
if (isPackageHeader) {
return buildDecompiledText(packageFqName,
resolveDeclarationsInPackage(packageFqName, resolver),
descriptorRendererForKotlinJavascriptDecompiler)
decompilerRendererForJS)
}
else {
val classId = JsMetaFileUtils.getClassId(classFile)
return buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), descriptorRendererForKotlinJavascriptDecompiler)
return buildDecompiledText(packageFqName, listOfNotNull(resolver.resolveTopLevelClass(classId)), decompilerRendererForJS)
}
}
@@ -16,12 +16,15 @@
package org.jetbrains.kotlin.idea.decompiler.js
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VirtualFile
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.common.AnnotationLoaderForStubBuilderImpl
import org.jetbrains.kotlin.idea.decompiler.common.DirectoryBasedClassDataFinder
import org.jetbrains.kotlin.idea.decompiler.common.toClassProto
import org.jetbrains.kotlin.idea.decompiler.common.toPackageProto
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClsStubBuilderComponents
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createPackageFacadeStub
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.createTopLevelClassStub
@@ -30,9 +33,8 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths
import org.jetbrains.kotlin.serialization.js.toClassProto
import org.jetbrains.kotlin.serialization.js.toPackageProto
import java.io.ByteArrayInputStream
public class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
@@ -61,14 +63,14 @@ public class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
val components = createStubBuilderComponents(file, packageFqName, nameResolver)
if (isPackageHeader) {
val packageProto = content.toPackageProto()
val packageProto = content.toPackageProto(KotlinJavascriptSerializedResourcePaths.extensionRegistry)
val context = components.createContext(
nameResolver, packageFqName, TypeTable(packageProto.typeTable)
)
return createPackageFacadeStub(packageProto, packageFqName, context)
}
else {
val classProto = content.toClassProto()
val classProto = content.toClassProto(KotlinJavascriptSerializedResourcePaths.extensionRegistry)
val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable))
val classId = JsMetaFileUtils.getClassId(file)
return createTopLevelClassStub(classId, classProto, context)
@@ -76,13 +78,10 @@ public class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
}
private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, nameResolver: NameResolver): ClsStubBuilderComponents {
val metaFileFinder = DirectoryBasedKotlinJavaScriptMetaFileFinder(file.parent!!, packageFqName, nameResolver)
val classDataFinder = DirectoryBasedKotlinJavaScriptDataFinder(metaFileFinder, LOG)
val annotationLoader = AnnotationLoaderForKotlinJavaScriptStubBuilder()
val classDataFinder = DirectoryBasedClassDataFinder(
file.parent!!, packageFqName, nameResolver, KotlinJavascriptSerializedResourcePaths
)
val annotationLoader = AnnotationLoaderForStubBuilderImpl(JsSerializerProtocol)
return ClsStubBuilderComponents(classDataFinder, annotationLoader)
}
companion object {
val LOG = Logger.getInstance(KotlinJavaScriptStubBuilder::class.java)
}
}
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
import org.jetbrains.kotlin.renderer.DescriptorRendererOptions
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
@@ -42,6 +44,14 @@ public fun descriptorToKey(descriptor: DeclarationDescriptor): String {
public data class DecompiledText(public val text: String, public val renderedDescriptorsToRange: Map<String, TextRange>)
fun DescriptorRendererOptions.defaultDecompilerRendererOptions() {
withDefinedIn = false
classWithPrimaryConstructor = true
secondaryConstructorsAsPrimary = false
modifiers = DescriptorRendererModifier.ALL
excludedTypeAnnotationClasses = ExcludedTypeAnnotations.annotationsForNullabilityAndMutability
}
public fun buildDecompiledText(
packageFqName: FqName,
descriptors: List<DeclarationDescriptor>,
@@ -16,25 +16,22 @@
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.descriptors.ModuleParameters
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
import org.jetbrains.kotlin.idea.decompiler.common.toPackageProto
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.TargetPlatform
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.SerializedResourcePaths
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolver
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
@@ -63,7 +60,31 @@ public abstract class DeserializerForDecompilerBase(
override fun resolveTopLevelClass(classId: ClassId) = deserializationComponents.deserializeClass(classId)
protected fun createDummyPackageFragment(fqName: FqName): MutablePackageFragmentDescriptor =
MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
MutablePackageFragmentDescriptor(moduleDescriptor, fqName)
protected fun getDescriptorsFromPackageFile(
packageFqName: FqName,
paths: SerializedResourcePaths,
log: Logger,
nameResolver: NameResolver
): List<DeclarationDescriptor> {
assert(packageFqName == directoryPackageFqName) {
"Was called for $packageFqName; only members of $directoryPackageFqName package are expected."
}
val packageFilePath = paths.getPackageFilePath(directoryPackageFqName).substringAfterLast("/")
val file = packageDirectory.findChild(packageFilePath)
if (file == null) {
log.error("Could not read data for package $packageFqName; $packageFilePath absent in $packageDirectory")
return emptyList()
}
val content = file.contentsToByteArray(false)
val packageProto = content.toPackageProto(paths.extensionRegistry)
val membersScope = DeserializedPackageMemberScope(
createDummyPackageFragment(packageFqName), packageProto, nameResolver, deserializationComponents
) { emptyList() }
return membersScope.getContributedDescriptors().toList()
}
private fun createDummyModule(name: String) = ModuleDescriptorImpl(Name.special("<$name>"), storageManager, ModuleParameters.Empty, targetPlatform.builtIns)
@@ -24,5 +24,5 @@ import org.jetbrains.kotlin.name.ClassId
public interface ResolverForDecompiler {
public fun resolveTopLevelClass(classId: ClassId): ClassDescriptor?
public fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection<DeclarationDescriptor>
public fun resolveDeclarationsInFacade(facadeFqName: FqName): List<DeclarationDescriptor>
}
@@ -16,14 +16,18 @@
package org.jetbrains.kotlin.idea.util
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.util.application.runReadAction
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDirectory
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.caches.resolve.JsProjectDetector
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInClassFileType
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInPackageFileType
import org.jetbrains.kotlin.idea.util.application.runReadAction
private val classFileLike = setOf(JavaClassFileType.INSTANCE, KotlinBuiltInClassFileType, KotlinBuiltInPackageFileType)
public object ProjectRootsUtil {
@JvmStatic
@@ -42,7 +46,7 @@ public object ProjectRootsUtil {
|| (includeLibraryClasses && fileIndex.isLibraryClassFile(file))
}
// NOTE: the following is a workaround for cases when class files are under library source roots and source files are under class roots
val isClassFile = file.getFileType() == JavaClassFileType.INSTANCE
val isClassFile = file.fileType in classFileLike
return (includeLibraryClasses && isClassFile && fileIndex.isInLibraryClasses(file))
|| (includeLibrarySource && !isClassFile && fileIndex.isInLibrarySource(file))
}
@@ -33,7 +33,7 @@ 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.KotlinDecompiledFileViewProvider
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
import org.jetbrains.kotlin.psi.KtFile
import java.util.*
@@ -106,7 +106,7 @@ public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWit
builtInsSources.forEach { unInvalidateFile(it) }
stdLibViewProviders.forEach {
it.allFiles.forEach { unInvalidateFile(it as KtClsFile) }
it.allFiles.forEach { unInvalidateFile(it as KtDecompiledFile) }
vFileToViewProviderMap.set(it.virtualFile, it)
}
}
+11 -3
View File
@@ -275,7 +275,7 @@
<projectService serviceInterface="org.jetbrains.kotlin.idea.caches.resolve.ClsJavaStubByVirtualFileCache"
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.ClsJavaStubByVirtualFileCache"/>
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
@@ -293,6 +293,7 @@
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinFileTypeFactory"/>
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinJavaScriptMetaFileTypeFactory"/>
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinBuiltInFileTypeFactory"/>
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinModuleFileFactory"/>
<compileServer.plugin classpath="jps/kotlin-jps-plugin.jar;kotlin-runtime.jar;kotlin-reflect.jar;kotlin-plugin.jar;kotlin-android-extensions-plugin.jar;kotlin-android-extensions-compiler-plugin.jar"/>
@@ -560,6 +561,7 @@
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClassFileDecompiler"/>
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileDecompiler"/>
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInDecompiler"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinJavaScriptAbiVersionIndex"/>
@@ -1300,11 +1302,17 @@
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
<filetype.stubBuilder filetype="KJSM" implementationClass="com.intellij.psi.impl.compiled.ClassFileStubBuilder"/>
<filetype.decompiler filetype="KJSM" implementationClass="com.intellij.psi.impl.compiled.ClassFileDecompiler"/>
<fileType.fileViewProviderFactory filetype="kotlin_class" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
<filetype.stubBuilder filetype="kotlin_class" implementationClass="com.intellij.psi.impl.compiled.ClassFileStubBuilder"/>
<filetype.decompiler filetype="kotlin_class" implementationClass="com.intellij.psi.impl.compiled.ClassFileDecompiler"/>
<fileType.fileViewProviderFactory filetype="kotlin_package" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
<filetype.stubBuilder filetype="kotlin_package" implementationClass="com.intellij.psi.impl.compiled.ClassFileStubBuilder"/>
<filetype.decompiler filetype="kotlin_package" implementationClass="com.intellij.psi.impl.compiled.ClassFileDecompiler"/>
<pathMacroExpandableProtocol protocol="kotlin-js-meta"/>
</extensions>
@@ -0,0 +1,28 @@
/*
* 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
import com.intellij.openapi.fileTypes.FileTypeConsumer
import com.intellij.openapi.fileTypes.FileTypeFactory
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInClassFileType
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInPackageFileType
class KotlinBuiltInFileTypeFactory : FileTypeFactory() {
override fun createFileTypes(consumer: FileTypeConsumer) {
consumer.consume(KotlinBuiltInClassFileType, KotlinBuiltInClassFileType.defaultExtension)
consumer.consume(KotlinBuiltInPackageFileType, KotlinBuiltInPackageFileType.defaultExtension)
}
}
@@ -77,7 +77,7 @@ public abstract class TextConsistencyBaseTest : KotlinLightCodeInsightFixtureTes
override fun resolveTopLevelClass(classId: ClassId): ClassDescriptor? =
module.resolveTopLevelClass(classId.asSingleFqName(), NoLookupLocation.FROM_TEST)
override fun resolveDeclarationsInFacade(facadeFqName: FqName): Collection<DeclarationDescriptor> =
override fun resolveDeclarationsInFacade(facadeFqName: FqName): List<DeclarationDescriptor> =
module.getPackage(facadeFqName.parent()).memberScope.getContributedDescriptors().filter {
it is CallableMemberDescriptor &&
it.module != module.builtIns.builtInsModule &&