())
+ FunctionalExpressionSearch.search(klass).forEach(PsiElementProcessorAdapter(functionalImplementations))
+ return if (functionalImplementations.collection.isNotEmpty()) "Has functional implementations" else null
+ }
+
+ val start = DaemonBundle.message(if (klass.isInterface) "interface.is.implemented.by.header" else "class.is.subclassed.by.header")
+ val shortcuts = ActionManager.getInstance().getAction(IdeActions.ACTION_GOTO_IMPLEMENTATION).shortcutSet.shortcuts
+ val shortcut = shortcuts.firstOrNull()
+ var postfix = "
Click"
+ if (shortcut != null) postfix += " or press " + KeymapUtil.getShortcutText(shortcut)
+ postfix += " to navigate
"
+
+ val renderer = DeclarationByModuleRenderer()
+ val comparator = renderer.comparator
+ return subclasses.toList().sortedWith(comparator).joinToString(
+ prefix = "$start", postfix = "$postfix", separator = "
"
+ ) {
+ val moduleNameRequired = if (it is KtLightClass) {
+ val origin = it.kotlinOrigin
+ origin?.hasActualModifier() == true || origin?.isExpectDeclaration() == true
+ } else false
+ val moduleName = it.module?.name
+ val elementText = renderer.getElementText(it) + (moduleName?.takeIf { moduleNameRequired }?.let { " [$it]" } ?: "")
+ val refText = (moduleName?.let { "$it:" } ?: "") + ClassPresentationUtil.getNameForClass(it, /* qualified = */ true)
+ " $elementText"
+ }
+}
+
fun getOverriddenMethodTooltip(method: PsiMethod): String? {
val processor = PsiElementProcessor.CollectElementsWithLimit(5)
method.forEachOverridingMethod(processor = PsiElementProcessorAdapter(processor)::process)
diff --git a/idea/testData/multiModuleLineMarker/actualDerived/common/common.kt b/idea/testData/multiModuleLineMarker/actualDerived/common/common.kt
new file mode 100644
index 00000000000..13b3b1fe791
--- /dev/null
+++ b/idea/testData/multiModuleLineMarker/actualDerived/common/common.kt
@@ -0,0 +1,6 @@
+
+open class ExpectedChild [testModule_Common]
ExpectedChild [testModule_JVM]
SimpleChild
Click or press Ctrl+Alt+B to navigate
">SimpleParent
+
+expect class ExpectedChild : SimpleParent
+
+class SimpleChild : SimpleParent()
\ No newline at end of file
diff --git a/idea/testData/multiModuleLineMarker/actualDerived/jvm/jvm.kt b/idea/testData/multiModuleLineMarker/actualDerived/jvm/jvm.kt
new file mode 100644
index 00000000000..3a4bd03e5ea
--- /dev/null
+++ b/idea/testData/multiModuleLineMarker/actualDerived/jvm/jvm.kt
@@ -0,0 +1,3 @@
+// !CHECK_HIGHLIGHTING
+
+actual class ExpectedChild : SimpleParent()
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTestGenerated.java
index 9798288dcde..1733b7d6321 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleLineMarkerTestGenerated.java
@@ -25,6 +25,11 @@ public class MultiModuleLineMarkerTestGenerated extends AbstractMultiModuleLineM
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
+ @TestMetadata("actualDerived")
+ public void testActualDerived() throws Exception {
+ runTest("idea/testData/multiModuleLineMarker/actualDerived/");
+ }
+
@TestMetadata("actualEnumEntries")
public void testActualEnumEntries() throws Exception {
runTest("idea/testData/multiModuleLineMarker/actualEnumEntries/");