add KotlinJavaScriptStubBuilder
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
|
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.JetType
|
||||||
|
|
||||||
|
public class AnnotationLoaderForKotlinJavaScriptStubBuilder() : AnnotationAndConstantLoader<ClassId, Unit> {
|
||||||
|
|
||||||
|
override fun loadClassAnnotations(
|
||||||
|
classProto: ProtoBuf.Class, nameResolver: NameResolver
|
||||||
|
): List<ClassId> =
|
||||||
|
classProto.getExtension(JsProtoBuf.classAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
||||||
|
|
||||||
|
override fun loadCallableAnnotations(
|
||||||
|
container: ProtoContainer,
|
||||||
|
proto: ProtoBuf.Callable,
|
||||||
|
nameResolver: NameResolver,
|
||||||
|
kind: AnnotatedCallableKind
|
||||||
|
): List<ClassId> =
|
||||||
|
proto.getExtension(JsProtoBuf.callableAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
||||||
|
|
||||||
|
override fun loadValueParameterAnnotations(
|
||||||
|
container: ProtoContainer,
|
||||||
|
callable: ProtoBuf.Callable,
|
||||||
|
nameResolver: NameResolver,
|
||||||
|
kind: AnnotatedCallableKind,
|
||||||
|
proto: ProtoBuf.Callable.ValueParameter
|
||||||
|
): List<ClassId> =
|
||||||
|
proto.getExtension(JsProtoBuf.parameterAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
||||||
|
|
||||||
|
override fun loadTypeAnnotations(
|
||||||
|
proto: ProtoBuf.Type,
|
||||||
|
nameResolver: NameResolver
|
||||||
|
): List<ClassId> =
|
||||||
|
proto.getExtension(JsProtoBuf.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.getId()) }
|
||||||
|
|
||||||
|
override fun loadPropertyConstant(
|
||||||
|
container: ProtoContainer,
|
||||||
|
proto: ProtoBuf.Callable,
|
||||||
|
nameResolver: NameResolver,
|
||||||
|
expectedType: JetType
|
||||||
|
): Unit {}
|
||||||
|
}
|
||||||
+6
-13
@@ -21,24 +21,16 @@ import com.intellij.psi.FileViewProvider;
|
|||||||
import com.intellij.psi.PsiManager;
|
import com.intellij.psi.PsiManager;
|
||||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||||
import com.intellij.psi.compiled.ClsStubBuilder;
|
import com.intellij.psi.compiled.ClsStubBuilder;
|
||||||
import com.intellij.psi.stubs.PsiFileStub;
|
|
||||||
import com.intellij.util.indexing.FileContent;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.KotlinJavascriptStubBuilder;
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.KotlinClsStubBuilder;
|
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
|
||||||
|
|
||||||
public class KotlinJavascriptMetaFileDecompiler extends ClassFileDecompilers.Full {
|
public class KotlinJavascriptMetaFileDecompiler extends ClassFileDecompilers.Full {
|
||||||
private final ClsStubBuilder stubBuilder = new KotlinClsStubBuilder() {
|
private final ClsStubBuilder stubBuilder = new KotlinJavascriptStubBuilder();
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public PsiFileStub<?> buildFileStub(@NotNull FileContent fileContent) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accepts(@NotNull VirtualFile file) {
|
public boolean accepts(@NotNull VirtualFile file) {
|
||||||
return file.getName().endsWith(".meta");
|
return file.getName().endsWith("." + KotlinJavascriptSerializationUtil.CLASS_METADATA_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -50,6 +42,7 @@ public class KotlinJavascriptMetaFileDecompiler extends ClassFileDecompilers.Ful
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) {
|
public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, @NotNull PsiManager manager, boolean physical) {
|
||||||
return new KotlinJavascriptMetaFileViewProvider(manager, file, physical, DecompilerPackage.isKotlinInternalCompiledFile(file));
|
return new KotlinJavascriptMetaFileViewProvider(manager, file, physical, DecompilerPackage.isKotlinJavaScriptInternalCompiledFile(
|
||||||
|
file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||||
|
|
||||||
class ClsStubBuilderComponents(
|
class ClsStubBuilderComponents(
|
||||||
val classDataFinder: ClassDataFinder,
|
val classDataFinder: ClassDataFinder,
|
||||||
val annotationLoader: AnnotationLoaderForStubBuilder
|
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit>
|
||||||
) {
|
) {
|
||||||
fun createContext(
|
fun createContext(
|
||||||
nameResolver: NameResolver,
|
nameResolver: NameResolver,
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.stubBuilder
|
||||||
|
|
||||||
|
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.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.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||||
|
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializedResourcePaths
|
||||||
|
import org.jetbrains.kotlin.serialization.js.toClassData
|
||||||
|
import org.jetbrains.kotlin.serialization.js.toPackageData
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
|
|
||||||
|
public open class KotlinJavaScriptStubBuilder : ClsStubBuilder() {
|
||||||
|
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + 1
|
||||||
|
|
||||||
|
override fun buildFileStub(content: FileContent): PsiFileStub<*>? {
|
||||||
|
val file = content.getFile()
|
||||||
|
|
||||||
|
if (isKotlinJavaScriptInternalCompiledFile(file)) return null
|
||||||
|
|
||||||
|
return doBuildFileStub(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doBuildFileStub(file: VirtualFile): PsiFileStub<JetFile>? {
|
||||||
|
val packageFqName = JsMetaFileUtils.getPackageFqName(file)
|
||||||
|
|
||||||
|
val content = file.contentsToByteArray(false)
|
||||||
|
val isPackageHeader = JsMetaFileUtils.isPackageHeader(file)
|
||||||
|
|
||||||
|
val moduleDirectory = JsMetaFileUtils.getModuleDirectory(file)
|
||||||
|
val stringsFileName = KotlinJavascriptSerializedResourcePaths.getStringTableFilePath(packageFqName)
|
||||||
|
val stringsFile = moduleDirectory.findFileByRelativePath(stringsFileName)
|
||||||
|
assert(stringsFile != null, "strings file not found: $stringsFileName")
|
||||||
|
|
||||||
|
val nameResolver = NameResolver.read(ByteArrayInputStream(stringsFile!!.contentsToByteArray(false)))
|
||||||
|
val components = createStubBuilderComponents(file, packageFqName, nameResolver)
|
||||||
|
|
||||||
|
if (isPackageHeader) {
|
||||||
|
val packageData = content.toPackageData(nameResolver)
|
||||||
|
val context = components.createContext(packageData.getNameResolver(), packageFqName)
|
||||||
|
return createPackageFacadeFileStub(packageData.getPackageProto(), packageFqName, context)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val classData = content.toClassData(nameResolver)
|
||||||
|
val context = components.createContext(classData.getNameResolver(), packageFqName)
|
||||||
|
val classId = JsMetaFileUtils.getClassId(file)
|
||||||
|
return createTopLevelClassStub(classId, classData.getClassProto(), context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createStubBuilderComponents(file: VirtualFile, packageFqName: FqName, nameResolver: NameResolver): ClsStubBuilderComponents {
|
||||||
|
val metaFileFinder = DirectoryBasedKotlinJavaScriptMetaFileFinder(file.getParent()!!, packageFqName, nameResolver)
|
||||||
|
val classDataFinder = DirectoryBasedKotlinJavaScriptDataFinder(metaFileFinder, LOG)
|
||||||
|
val annotationLoader = AnnotationLoaderForKotlinJavaScriptStubBuilder()
|
||||||
|
return ClsStubBuilderComponents(classDataFinder, annotationLoader)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val LOG = Logger.getInstance(javaClass<KotlinJavaScriptStubBuilder>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+10
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.Type
|
|||||||
import org.jetbrains.kotlin.serialization.ProtoBuf.Type.Argument.Projection
|
import org.jetbrains.kotlin.serialization.ProtoBuf.Type.Argument.Projection
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf.TypeParameter.Variance
|
import org.jetbrains.kotlin.serialization.ProtoBuf.TypeParameter.Variance
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||||
|
import org.jetbrains.kotlin.types.DynamicTypeCapabilities
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
@@ -70,6 +71,15 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createClassReferenceTypeStub(parent: StubElement<out PsiElement>, type: Type) {
|
private fun createClassReferenceTypeStub(parent: StubElement<out PsiElement>, type: Type) {
|
||||||
|
if (type.hasFlexibleTypeCapabilitiesId()) {
|
||||||
|
val id = c.nameResolver.getString(type.getFlexibleTypeCapabilitiesId())
|
||||||
|
|
||||||
|
if (id == DynamicTypeCapabilities.id) {
|
||||||
|
KotlinPlaceHolderStubImpl<JetDynamicType>(parent, JetStubElementTypes.DYNAMIC_TYPE)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val classId = c.nameResolver.getClassId(type.getConstructor().getId())
|
val classId = c.nameResolver.getClassId(type.getConstructor().getId())
|
||||||
val fqName = classId.asSingleFqName().toUnsafe()
|
val fqName = classId.asSingleFqName().toUnsafe()
|
||||||
val isFunctionType = KotlinBuiltIns.isExactFunctionType(fqName)
|
val isFunctionType = KotlinBuiltIns.isExactFunctionType(fqName)
|
||||||
|
|||||||
Reference in New Issue
Block a user