FIC: support fun interfaces in stub builder

This commit is contained in:
Mikhail Zarechenskiy
2019-12-19 13:41:48 +03:00
parent 70094884ca
commit 8206cadce2
13 changed files with 143 additions and 15 deletions
@@ -104,6 +104,9 @@ private class ClassClsStubBuilder(
relevantFlags.add(MODALITY)
relevantFlags.add(INLINE_CLASS)
}
if (isInterface()) {
relevantFlags.add(FUN_INTERFACE)
}
val additionalModifiers = when (classKind) {
ProtoBuf.Class.Kind.ENUM_CLASS -> listOf(KtTokens.ENUM_KEYWORD)
ProtoBuf.Class.Kind.COMPANION_OBJECT -> listOf(KtTokens.COMPANION_KEYWORD)
@@ -227,6 +230,10 @@ private class ClassClsStubBuilder(
classKind == ProtoBuf.Class.Kind.ANNOTATION_CLASS
}
private fun isInterface(): Boolean {
return classKind == ProtoBuf.Class.Kind.INTERFACE
}
private fun createInnerAndNestedClasses(classBody: KotlinPlaceHolderStubImpl<KtClassBody>) {
classProto.nestedClassNameList.forEach { id ->
val nestedClassName = c.nameResolver.getName(id)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.decompiler.stubBuilder.flags
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
@@ -51,6 +52,7 @@ val EXTERNAL_PROPERTY = createBooleanFlagToModifier(Flags.IS_EXTERNAL_PROPERTY,
val EXTERNAL_CLASS = createBooleanFlagToModifier(Flags.IS_EXTERNAL_CLASS, KtTokens.EXTERNAL_KEYWORD)
val INLINE = createBooleanFlagToModifier(Flags.IS_INLINE, KtTokens.INLINE_KEYWORD)
val INLINE_CLASS = createBooleanFlagToModifier(Flags.IS_INLINE_CLASS, KtTokens.INLINE_KEYWORD)
val FUN_INTERFACE = createBooleanFlagToModifier(Flags.IS_FUN_INTERFACE, KtTokens.FUN_KEYWORD)
val TAILREC = createBooleanFlagToModifier(Flags.IS_TAILREC, KtTokens.TAILREC_KEYWORD)
val SUSPEND = createBooleanFlagToModifier(Flags.IS_SUSPEND, KtTokens.SUSPEND_KEYWORD)
@@ -0,0 +1,14 @@
// IntelliJ API Decompiler stub source generated from a class file
// Implementation of methods is not available
package test
public final class FunInterfaceDeclaration public constructor() {
public fun interface GenericKRunnable<T, R> {
public abstract fun invoke(t: T): R
}
public fun interface KRunnable {
public abstract fun invoke(): kotlin.Unit
}
}
@@ -0,0 +1,13 @@
package test
class FunInterfaceDeclaration {
@Suppress("UNSUPPORTED_FEATURE")
fun interface KRunnable {
fun invoke()
}
@Suppress("UNSUPPORTED_FEATURE")
fun interface GenericKRunnable<T, R> {
fun invoke(t: T): R
}
}
@@ -0,0 +1,13 @@
package test
class FunInterfaceDeclaration {
@Suppress("UNSUPPORTED_FEATURE")
fun interface KRunnable {
fun invoke()
}
@Suppress("UNSUPPORTED_FEATURE")
fun interface GenericKRunnable<T, R> {
fun invoke(t: T): R
}
}
@@ -0,0 +1,37 @@
PsiJetFileStubImpl[package=test]
PACKAGE_DIRECTIVE
REFERENCE_EXPRESSION[referencedName=test]
IMPORT_LIST
CLASS[fqName=test.FunInterfaceDeclaration, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=FunInterfaceDeclaration, superNames=[]]
MODIFIER_LIST[public final]
PRIMARY_CONSTRUCTOR
MODIFIER_LIST[public]
VALUE_PARAMETER_LIST
CLASS_BODY
CLASS[fqName=test.FunInterfaceDeclaration.GenericKRunnable, isEnumEntry=false, isInterface=true, isLocal=false, isTopLevel=false, name=GenericKRunnable, superNames=[]]
MODIFIER_LIST[public fun]
TYPE_PARAMETER_LIST
TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=T]
TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=R]
CLASS_BODY
FUN[fqName=test.FunInterfaceDeclaration.GenericKRunnable.invoke, hasBlockBody=true, hasBody=false, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, mayHaveContract=false, name=invoke]
MODIFIER_LIST[abstract public]
VALUE_PARAMETER_LIST
VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=t]
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=T]
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=R]
CLASS[fqName=test.FunInterfaceDeclaration.KRunnable, isEnumEntry=false, isInterface=true, isLocal=false, isTopLevel=false, name=KRunnable, superNames=[]]
MODIFIER_LIST[public fun]
CLASS_BODY
FUN[fqName=test.FunInterfaceDeclaration.KRunnable.invoke, hasBlockBody=true, hasBody=false, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, mayHaveContract=false, name=invoke]
MODIFIER_LIST[abstract public]
VALUE_PARAMETER_LIST
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Unit]
@@ -118,6 +118,11 @@ public class ClsStubBuilderTestGenerated extends AbstractClsStubBuilderTest {
runTest("idea/testData/decompiler/stubBuilder/FlexibleTypes/");
}
@TestMetadata("FunInterfaceDeclaration")
public void testFunInterfaceDeclaration() throws Exception {
runTest("idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/");
}
@TestMetadata("InheritingClasses")
public void testInheritingClasses() throws Exception {
runTest("idea/testData/decompiler/stubBuilder/InheritingClasses/");
@@ -79,6 +79,11 @@ public class CommonDecompiledTextFromJsMetadataTestGenerated extends AbstractCom
runTest("idea/testData/decompiler/decompiledText/Enum/");
}
@TestMetadata("FunInterfaceDeclaration")
public void testFunInterfaceDeclaration() throws Exception {
runTest("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration/");
}
@TestMetadata("FunctionTypes")
public void testFunctionTypes() throws Exception {
runTest("idea/testData/decompiler/decompiledText/FunctionTypes/");
@@ -277,6 +282,19 @@ public class CommonDecompiledTextFromJsMetadataTestGenerated extends AbstractCom
}
}
@TestMetadata("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunInterfaceDeclaration extends AbstractCommonDecompiledTextFromJsMetadataTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInFunInterfaceDeclaration() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JS, true);
}
}
@TestMetadata("idea/testData/decompiler/decompiledText/FunctionTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -83,6 +83,11 @@ public class CommonDecompiledTextTestGenerated extends AbstractCommonDecompiledT
runTest("idea/testData/decompiler/decompiledText/FlexibleTypes/");
}
@TestMetadata("FunInterfaceDeclaration")
public void testFunInterfaceDeclaration() throws Exception {
runTest("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration/");
}
@TestMetadata("FunctionTypes")
public void testFunctionTypes() throws Exception {
runTest("idea/testData/decompiler/decompiledText/FunctionTypes/");
@@ -281,6 +286,19 @@ public class CommonDecompiledTextTestGenerated extends AbstractCommonDecompiledT
}
}
@TestMetadata("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunInterfaceDeclaration extends AbstractCommonDecompiledTextTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInFunInterfaceDeclaration() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/decompiler/decompiledText/FunInterfaceDeclaration"), Pattern.compile("^([^\\.]+)$"), null, true);
}
}
@TestMetadata("idea/testData/decompiler/decompiledText/FunctionTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)