diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt index 8b53ee318f4..e343f6e6ee8 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt @@ -28,7 +28,7 @@ object KotlinStubVersions { // Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed // or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder). // Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files). - private const val BINARY_STUB_VERSION = 70 + private const val BINARY_STUB_VERSION = 71 // Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile) // Increasing this version will lead to reindexing of all classfiles. diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtModifierListElementType.java b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtModifierListElementType.java index 7c5eb64e0aa..575d6b25595 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtModifierListElementType.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtModifierListElementType.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi.stubs.elements; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; +import com.intellij.util.io.DataInputOutputUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.psi.KtModifierList; @@ -41,14 +42,14 @@ public class KtModifierListElementType extends KtStubE @Override public void serialize(@NotNull KotlinModifierListStub stub, @NotNull StubOutputStream dataStream) throws IOException { - int mask = ((KotlinModifierListStubImpl) stub).getMask(); - dataStream.writeVarInt(mask); + long mask = ((KotlinModifierListStubImpl) stub).getMask(); + DataInputOutputUtil.writeLONG(dataStream, mask); } @NotNull @Override public KotlinModifierListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { - int mask = dataStream.readVarInt(); + long mask = DataInputOutputUtil.readLONG(dataStream); return new KotlinModifierListStubImpl(parentStub, mask, this); } } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinModifierListStubImpl.java b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinModifierListStubImpl.java index f8f90c840d7..e6f3182870a 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinModifierListStubImpl.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinModifierListStubImpl.java @@ -25,14 +25,14 @@ import org.jetbrains.kotlin.psi.stubs.elements.KtModifierListElementType; public class KotlinModifierListStubImpl extends KotlinStubBaseImpl implements KotlinModifierListStub { - private final int mask; + private final long mask; - public KotlinModifierListStubImpl(StubElement parent, int mask, @NotNull KtModifierListElementType elementType) { + public KotlinModifierListStubImpl(StubElement parent, long mask, @NotNull KtModifierListElementType elementType) { super(parent, elementType); this.mask = mask; } - public int getMask() { + public long getMask() { return mask; } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/ModifierMaskUtils.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/ModifierMaskUtils.kt index 3e5bdb59d14..3fa26c4bc1a 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/ModifierMaskUtils.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/ModifierMaskUtils.kt @@ -23,32 +23,32 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken object ModifierMaskUtils { init { - assert(MODIFIER_KEYWORDS_ARRAY.size <= 32) { "Current implementation depends on the ability to represent modifier list as bit mask" } + assert(MODIFIER_KEYWORDS_ARRAY.size <= 64) { "Current implementation depends on the ability to represent modifier list as bit mask" } } @JvmStatic - fun computeMaskFromModifierList(modifierList: KtModifierList): Int = computeMask { modifierList.hasModifier(it) } + fun computeMaskFromModifierList(modifierList: KtModifierList): Long = computeMask { modifierList.hasModifier(it) } @JvmStatic - fun computeMask(hasModifier: (KtModifierKeywordToken) -> Boolean): Int { - var mask = 0 + fun computeMask(hasModifier: (KtModifierKeywordToken) -> Boolean): Long { + var mask = 0L for ((index, modifierKeywordToken) in MODIFIER_KEYWORDS_ARRAY.withIndex()) { if (hasModifier(modifierKeywordToken)) { - mask = mask or (1 shl index) + mask = mask or (1L shl index) } } return mask } @JvmStatic - fun maskHasModifier(mask: Int, modifierToken: KtModifierKeywordToken): Boolean { + fun maskHasModifier(mask: Long, modifierToken: KtModifierKeywordToken): Boolean { val index = MODIFIER_KEYWORDS_ARRAY.indexOf(modifierToken) assert(index >= 0) { "All JetModifierKeywordTokens should be present in MODIFIER_KEYWORDS_ARRAY" } - return (mask and (1 shl index)) != 0 + return (mask and (1L shl index)) != 0L } @JvmStatic - fun maskToString(mask: Int): String { + fun maskToString(mask: Long): String { val sb = StringBuilder() sb.append("[") var first = true diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt index 5e33587e154..2ab4b72d4f7 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt @@ -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) { classProto.nestedClassNameList.forEach { id -> val nestedClassName = c.nameResolver.getName(id) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/flags/flags.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/flags/flags.kt index 39cc268279e..5ee50593629 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/flags/flags.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/flags/flags.kt @@ -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) diff --git a/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration.expected.kt b/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration.expected.kt new file mode 100644 index 00000000000..b9c0ca8f966 --- /dev/null +++ b/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration.expected.kt @@ -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 { + public abstract fun invoke(t: T): R + } + + public fun interface KRunnable { + public abstract fun invoke(): kotlin.Unit + } +} diff --git a/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration/FunInterfaceDeclaration.kt b/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration/FunInterfaceDeclaration.kt new file mode 100644 index 00000000000..74c549bdb29 --- /dev/null +++ b/idea/testData/decompiler/decompiledText/FunInterfaceDeclaration/FunInterfaceDeclaration.kt @@ -0,0 +1,13 @@ +package test + +class FunInterfaceDeclaration { + @Suppress("UNSUPPORTED_FEATURE") + fun interface KRunnable { + fun invoke() + } + + @Suppress("UNSUPPORTED_FEATURE") + fun interface GenericKRunnable { + fun invoke(t: T): R + } +} diff --git a/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.kt b/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.kt new file mode 100644 index 00000000000..74c549bdb29 --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.kt @@ -0,0 +1,13 @@ +package test + +class FunInterfaceDeclaration { + @Suppress("UNSUPPORTED_FEATURE") + fun interface KRunnable { + fun invoke() + } + + @Suppress("UNSUPPORTED_FEATURE") + fun interface GenericKRunnable { + fun invoke(t: T): R + } +} diff --git a/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.txt b/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.txt new file mode 100644 index 00000000000..c1a8bdc702c --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/FunInterfaceDeclaration/FunInterfaceDeclaration.txt @@ -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] diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java index ed7bbb49ae6..ac1868f2890 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java @@ -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/"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextFromJsMetadataTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextFromJsMetadataTestGenerated.java index 35d60eca42e..7925cd5369e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextFromJsMetadataTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextFromJsMetadataTestGenerated.java @@ -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) diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextTestGenerated.java index ee2d98cd5c0..58c03281877 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/textBuilder/CommonDecompiledTextTestGenerated.java @@ -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)