diff --git a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewModel.kt b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewModel.kt index 68fd8c80e08d..2bd9afee8c6a 100644 --- a/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewModel.kt +++ b/plugins/kotlin/code-insight/impl-base/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewModel.kt @@ -25,11 +25,14 @@ open class KotlinStructureViewModel(ktFile: KtFile, editor: Editor?, rootElement withSorters(KotlinVisibilitySorter, Sorter.ALPHA_SORTER) } - override fun isSuitable(element: PsiElement?): Boolean = element is KtDeclaration && + override fun isSuitable(element: PsiElement?): Boolean = + element is KtDeclaration && element !is KtPropertyAccessor && element !is KtFunctionLiteral && - !(element is KtProperty && element.parent !is KtFile && element.containingClassOrObject !is KtNamedDeclaration) && - !(element is KtFunction && element.parent !is KtFile && element.containingClassOrObject !is KtNamedDeclaration) + !((element is KtProperty || element is KtFunction) && !element.topLevelDeclaration && element.containingClassOrObject !is KtNamedDeclaration) + + private val KtDeclaration.topLevelDeclaration: Boolean + get() = parent is KtFile || parent is KtBlockExpression && parent.parent is KtScript override fun getFilters() = FILTERS diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarModelExtension.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarModelExtension.kt index 408eb6d4e4da..f1b88fbc475b 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarModelExtension.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarModelExtension.kt @@ -3,20 +3,19 @@ package org.jetbrains.kotlin.idea.navigationToolbar import com.intellij.psi.PsiElement +import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.idea.KotlinIconProvider import org.jetbrains.kotlin.idea.projectView.KtDeclarationTreeNode.Companion.tryGetRepresentableText import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNamedFunction class KotlinNavBarModelExtension : AbstractNavBarModelExtensionCompatBase() { - override fun getPresentableText(item: Any?): String? { - val fullText = (item as? KtDeclaration)?.let { tryGetRepresentableText(it) } - return when (item) { - is KtNamedFunction -> fullText?.substringBefore('(') - else -> fullText + override fun getPresentableText(item: Any?): String? = + when (item) { + is KtDeclaration -> tryGetRepresentableText(item, renderArguments = false) + is PsiNamedElement -> item.name + else -> null } - } override fun adjustElementImpl(psiElement: PsiElement?): PsiElement? { if (psiElement is KtDeclaration) { @@ -24,7 +23,6 @@ class KotlinNavBarModelExtension : AbstractNavBarModelExtensionCompatBase() { } val containingFile = psiElement?.containingFile as? KtFile ?: return psiElement - if (containingFile.isScript()) return psiElement return KotlinIconProvider.getSingleClass(containingFile) ?: psiElement } } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/projectView/KtDeclarationTreeNode.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/projectView/KtDeclarationTreeNode.kt index fee1ffb12b5a..48280ce48512 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/projectView/KtDeclarationTreeNode.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/projectView/KtDeclarationTreeNode.kt @@ -36,7 +36,7 @@ internal class KtDeclarationTreeNode private constructor( private fun String?.orErrorName() = if (!isNullOrBlank()) this else ERROR_NAME @NlsSafe - fun tryGetRepresentableText(declaration: KtDeclaration): String { + fun tryGetRepresentableText(declaration: KtDeclaration, renderArguments: Boolean = true): String { val settings = declaration.containingKtFile.kotlinCustomSettings fun StringBuilder.appendColon() { if (settings.SPACE_BEFORE_TYPE_COLON) append(" ") @@ -58,21 +58,23 @@ internal class KtDeclarationTreeNode private constructor( append('.') } append(name.orErrorName()) - append("(") - val valueParameters = valueParameters - valueParameters.forEachIndexed { index, parameter -> - parameter.name?.let { parameterName -> - append(parameterName) - appendColon() - } - parameter.typeReference?.text?.let { typeReference -> - append(typeReference) - } - if (index != valueParameters.size - 1) { - append(", ") + if (renderArguments) { + append("(") + val valueParameters = valueParameters + valueParameters.forEachIndexed { index, parameter -> + parameter.name?.let { parameterName -> + append(parameterName) + appendColon() + } + parameter.typeReference?.text?.let { typeReference -> + append(typeReference) + } + if (index != valueParameters.size - 1) { + append(", ") + } } + append(")") } - append(")") typeReference?.text?.let { returnTypeReference -> appendColon() diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureElementPresentation.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureElementPresentation.kt index 8b463f757e5d..961c0838a886 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureElementPresentation.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureElementPresentation.kt @@ -14,10 +14,8 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider import org.jetbrains.kotlin.idea.KotlinIdeaBundle -import org.jetbrains.kotlin.psi.KtAnonymousInitializer -import org.jetbrains.kotlin.psi.KtModifierListOwner -import org.jetbrains.kotlin.psi.KtObjectDeclaration -import org.jetbrains.kotlin.psi.KtPsiUtil +import org.jetbrains.kotlin.idea.projectView.KtDeclarationTreeNode.Companion.tryGetRepresentableText +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.renderer.DescriptorRenderer.Companion.ONLY_NAMES_WITH_SHORT_TYPES import org.jetbrains.kotlin.resolve.DescriptorUtils.getAllOverriddenDeclarations import org.jetbrains.kotlin.resolve.OverridingUtil.filterOutOverridden @@ -82,16 +80,9 @@ internal class KotlinStructureElementPresentation( return ONLY_NAMES_WITH_SHORT_TYPES.render(descriptor) } - val text = navigatablePsiElement.name - if (!text.isNullOrEmpty()) { - return text - } + navigatablePsiElement.name.takeUnless { it.isNullOrEmpty() }?.let { return it } - if (navigatablePsiElement is KtAnonymousInitializer) { - return KotlinIdeaBundle.message("class.initializer") - } - - return null + return (navigatablePsiElement as? KtDeclaration)?.let { tryGetRepresentableText(it) } } private fun getElementLocationString(isInherited: Boolean, descriptor: DeclarationDescriptor?): String? { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt index 057a4c391c35..21f015cf220d 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt @@ -66,7 +66,15 @@ class KotlinStructureViewElement( override fun getChildrenBase(): Collection { val children = when (val element = element) { - is KtFile -> element.declarations + is KtFile -> { + val declarations = element.declarations + // it is a bit faster that `element.isScript()` + if (declarations.size == 1 && declarations[0] is KtScript) { + declarations[0] as KtScript + } else { + element + }.declarations + } is KtClass -> element.getStructureDeclarations() is KtClassOrObject -> element.declarations is KtFunction, is KtClassInitializer, is KtProperty -> element.collectLocalDeclarations() diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarTestGenerated.java index 95cbd109b1c0..0a66a9a2531a 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/navigationToolbar/KotlinNavBarTestGenerated.java @@ -23,6 +23,16 @@ public class KotlinNavBarTestGenerated extends AbstractKotlinNavBarTest { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } + @TestMetadata("build1.gradle.kts") + public void testBuild1_gradle() throws Exception { + runTest("testData/navigationToolbar/build1.gradle.kts"); + } + + @TestMetadata("build2.gradle.kts") + public void testBuild2_gradle() throws Exception { + runTest("testData/navigationToolbar/build2.gradle.kts"); + } + @TestMetadata("ClassProperty.kt") public void testClassProperty() throws Exception { runTest("testData/navigationToolbar/ClassProperty.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/AbstractKotlinFileStructureTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/AbstractKotlinFileStructureTest.kt index 8daa64427666..7740107f0aa8 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/AbstractKotlinFileStructureTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/AbstractKotlinFileStructureTest.kt @@ -13,7 +13,9 @@ import java.io.File abstract class AbstractKotlinFileStructureTest : KotlinFileStructureTestBase() { override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.getInstance() - override val fileExtension = "kt" + override val fileExtension: String + get() = fileName().substringAfter(".") + override val treeFileName: String get() = getFileName("after") fun doTest(path: String) { @@ -25,7 +27,7 @@ abstract class AbstractKotlinFileStructureTest : KotlinFileStructureTestBase() { } protected fun FileStructurePopup.setup() { - val fileText = FileUtil.loadFile(File(testDataPath, fileName()), true) + val fileText = FileUtil.loadFile(File(testDataDirectory, fileName()), true) val withInherited = InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_INHERITED") setTreeActionState(nodeProviderClass(), withInherited) diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/KotlinFileStructureTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/KotlinFileStructureTestGenerated.java index d1a2f36e094f..9b86ee3d44a7 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/KotlinFileStructureTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structureView/KotlinFileStructureTestGenerated.java @@ -103,6 +103,11 @@ public class KotlinFileStructureTestGenerated extends AbstractKotlinFileStructur runTest("testData/structureView/fileStructure/Render.kt"); } + @TestMetadata("Script.kts") + public void testScript() throws Exception { + runTest("testData/structureView/fileStructure/Script.kts"); + } + @TestMetadata("SeveralClasses.kt") public void testSeveralClasses() throws Exception { runTest("testData/structureView/fileStructure/SeveralClasses.kt"); diff --git a/plugins/kotlin/idea/tests/testData/navigationToolbar/build1.gradle.kts b/plugins/kotlin/idea/tests/testData/navigationToolbar/build1.gradle.kts new file mode 100644 index 000000000000..3334a2310449 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/navigationToolbar/build1.gradle.kts @@ -0,0 +1,14 @@ +// NAV_BAR_ITEMS: src, build1.gradle.kts, repositories + +plugins { + kotlin("jvm") version "1.7.10" + application +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/navigationToolbar/build2.gradle.kts b/plugins/kotlin/idea/tests/testData/navigationToolbar/build2.gradle.kts new file mode 100644 index 000000000000..3cb22a9464a2 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/navigationToolbar/build2.gradle.kts @@ -0,0 +1,18 @@ +// NAV_BAR_ITEMS: src, build2.gradle.kts, someFun + +plugins { + kotlin("jvm") version "1.7.10" + application +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) +} + +fun someFun() { + TODO() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.after b/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.after new file mode 100644 index 000000000000..3f19ea01f3d0 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.after @@ -0,0 +1,5 @@ +-Script.kts + dependencies + foo(): Unit + plugins + repositories \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.kts b/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.kts new file mode 100644 index 000000000000..57847f030cb6 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/structureView/fileStructure/Script.kts @@ -0,0 +1,14 @@ +plugins { + kotlin("jvm") version "1.7.10" + application +} + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) +} + +fun foo() {} \ No newline at end of file diff --git a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt index 9b5efb43803b..e4bded6e36e9 100644 --- a/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt +++ b/plugins/kotlin/util/test-generator-fe10/test/org/jetbrains/kotlin/fe10/testGenerator/Fe10GenerateTests.kt @@ -781,7 +781,7 @@ private fun assembleWorkspace(): TWorkspace = workspace { } testClass { - model("structureView/fileStructure", pattern = KT_WITHOUT_DOTS) + model("structureView/fileStructure", pattern = KT_OR_KTS_WITHOUT_DOTS) } testClass { @@ -993,7 +993,7 @@ private fun assembleWorkspace(): TWorkspace = workspace { } testClass { - model("navigationToolbar", isRecursive = false) + model("navigationToolbar", pattern = KT_OR_KTS, isRecursive = false) } }