From b5b48c828bfb5f0182d44228b01f1f1bbfb853b5 Mon Sep 17 00:00:00 2001 From: Bart van Helvert Date: Fri, 21 Jan 2022 12:31:34 +0100 Subject: [PATCH] [kssr] KTIJ-20631 Rework object matching Removes companion object matching by default and adds the `Also match companion object` modifier to allow matching companion objects. Also introduces a [0, 1] count filter for the object identifier to match unnamed/named companion objects and object expressions. GitOrigin-RevId: bd5176c8a28f9afbd91d4ca8117e2f309cd0d35b --- .../messages/KotlinBundle.properties | 5 +- .../KotlinPredefinedConfigurations.kt | 12 +- .../KotlinStructuralSearchProfile.kt | 11 +- .../AlsoMatchCompanionObjectModifier.kt | 15 ++ .../filters/KotlinFilterProvider.kt | 6 +- .../filters/OneStateFilter.kt | 3 +- ...KotlinAlsoMatchCompanionObjectPredicate.kt | 10 ++ .../visitor/KotlinMatchingVisitor.kt | 52 ++++--- .../search/KotlinSSObjectDeclarationTest.kt | 137 ++++++++++++++++-- .../search/KotlinSSPropertyTest.kt | 21 ++- .../filters/KotlinSSValVarModifierTests.kt | 26 ---- .../objectDeclaration/companionObject.kt | 3 - .../objectDeclaration/namedCompanionObject.kt | 3 - .../nestedNamedCompanionObject.kt | 3 - .../objectDeclaration/nestedObject.kt | 3 - .../objectDeclaration/object.kt | 3 - .../objectDeclaration/objectSuperType.kt | 5 - 17 files changed, 233 insertions(+), 85 deletions(-) create mode 100644 plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/AlsoMatchCompanionObjectModifier.kt create mode 100644 plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/predicates/KotlinAlsoMatchCompanionObjectPredicate.kt delete mode 100644 plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/filters/KotlinSSValVarModifierTests.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/companionObject.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/namedCompanionObject.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedNamedCompanionObject.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedObject.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/object.kt delete mode 100644 plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/objectSuperType.kt diff --git a/plugins/kotlin/frontend-independent/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/frontend-independent/resources-en/messages/KotlinBundle.properties index 694e4952a021..6c14ed9e155b 100644 --- a/plugins/kotlin/frontend-independent/resources-en/messages/KotlinBundle.properties +++ b/plugins/kotlin/frontend-independent/resources-en/messages/KotlinBundle.properties @@ -1960,13 +1960,15 @@ error.type.filter.node=Kotlin matching element should either be an expression or modifier.match.val=Match val modifier.match.var=Match var +modifier.match.companion.object=Match companion object modifier.also.match.val=Also match val modifier.also.match.var=Also match var +modifier.also.match.companion.object=Also match companion object predefined.configuration.all.methods.of.the.class=All methods of a class predefined.configuration.all.vars.of.the.class=All vars of a class -predefined.configuration.all.vars.of.the.object=All vars of an object or companion object +predefined.configuration.all.vars.of.the.object=All vars of an object predefined.configuration.annotations=Annotations predefined.configuration.anonymous.class=Anonymous class predefined.configuration.array.access=Array access @@ -1974,6 +1976,7 @@ predefined.configuration.assert.not.null=Not-null assertion operators predefined.configuration.assignments=Assignments predefined.configuration.casts=Casts predefined.configuration.class.annotation=Annotated classes +predefined.configuration.object.companion.object=Object and companion object predefined.configuration.comments.containing.word=Comments containing a given word predefined.configuration.do.while=Do...while loops predefined.configuration.elvis=Elvis operators diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinPredefinedConfigurations.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinPredefinedConfigurations.kt index 86bf17997f5a..9b1edd3039e2 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinPredefinedConfigurations.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinPredefinedConfigurations.kt @@ -1,5 +1,4 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - package org.jetbrains.kotlin.idea.structuralsearch import com.intellij.structuralsearch.PatternContext @@ -9,6 +8,7 @@ import org.jetbrains.annotations.Nls import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchCompanionObjectModifier import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchValModifier import org.jetbrains.kotlin.idea.structuralsearch.filters.OneStateFilter @@ -52,7 +52,7 @@ object KotlinPredefinedConfigurations { ), searchTemplate( KotlinBundle.message("predefined.configuration.all.vars.of.the.object"), - "all vars of an object or companion object", + "all vars of an object", """ object '_Object { var 'Field+ = '_Init? @@ -73,6 +73,14 @@ object KotlinPredefinedConfigurations { """.trimIndent(), CLASS_TYPE ), + searchTemplate( + KotlinBundle.message("predefined.configuration.object.companion.object"), + "object also match companion object", + """ + object '_Object{0,1}:[_${AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})] + """.trimIndent(), + CLASS_TYPE + ), // Expressions searchTemplate( diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinStructuralSearchProfile.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinStructuralSearchProfile.kt index e13372382f83..94448f1e1e81 100755 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinStructuralSearchProfile.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/KotlinStructuralSearchProfile.kt @@ -1,5 +1,4 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - package org.jetbrains.kotlin.idea.structuralsearch import com.intellij.dupLocator.util.NodeFilter @@ -28,9 +27,11 @@ import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.liveTemplates.KotlinTemplateContextType +import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchCompanionObjectModifier import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchValModifier import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchVarModifier import org.jetbrains.kotlin.idea.structuralsearch.filters.OneStateFilter +import org.jetbrains.kotlin.idea.structuralsearch.predicates.KotlinAlsoMatchCompanionObjectPredicate import org.jetbrains.kotlin.idea.structuralsearch.predicates.KotlinAlsoMatchValVarPredicate import org.jetbrains.kotlin.idea.structuralsearch.predicates.KotlinExprTypePredicate import org.jetbrains.kotlin.idea.structuralsearch.visitor.KotlinCompilingVisitor @@ -207,6 +208,8 @@ class KotlinStructuralSearchProfile : StructuralSearchProfile() { UIUtil.REFERENCE -> isApplicableReference(variableNode) AlsoMatchVarModifier.CONSTRAINT_NAME -> variableNode.parent is KtProperty && !(variableNode.parent as KtProperty).isVar AlsoMatchValModifier.CONSTRAINT_NAME -> variableNode.parent is KtProperty && (variableNode.parent as KtProperty).isVar + AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME -> variableNode.parent is KtObjectDeclaration && + !(variableNode.parent as KtObjectDeclaration).isCompanion() else -> super.isApplicableConstraint(constraintName, variableNode, completePattern, target) } @@ -260,6 +263,7 @@ class KotlinStructuralSearchProfile : StructuralSearchProfile() { private fun isApplicableMinCount(variableNode: PsiElement): Boolean { val family = ancestors(variableNode) return when { + family[0] is KtObjectDeclaration -> true family[0] !is KtNameReferenceExpression -> false family[1] is KtProperty -> true family[1] is KtDotQualifiedExpression -> true @@ -288,9 +292,9 @@ class KotlinStructuralSearchProfile : StructuralSearchProfile() { */ private fun isApplicableMinMaxCount(variableNode: PsiElement): Boolean { val family = ancestors(variableNode) -// println(family.map { if (it == null) "null" else it::class.java.toString().split(".").last() }) return when { // Containers (lists, bodies, ...) + family[0] is KtObjectDeclaration -> false family[1] is KtClassBody -> true family[0] is KtParameter && family[1] is KtParameterList -> true family[0] is KtTypeParameter && family[1] is KtTypeParameterList -> true @@ -334,6 +338,9 @@ class KotlinStructuralSearchProfile : StructuralSearchProfile() { if (getAdditionalConstraint(AlsoMatchValModifier.CONSTRAINT_NAME) == OneStateFilter.ENABLED || getAdditionalConstraint(AlsoMatchVarModifier.CONSTRAINT_NAME) == OneStateFilter.ENABLED ) result.add(KotlinAlsoMatchValVarPredicate()) + if (getAdditionalConstraint(AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME) == OneStateFilter.ENABLED) { + result.add(KotlinAlsoMatchCompanionObjectPredicate()) + } } return result } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/AlsoMatchCompanionObjectModifier.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/AlsoMatchCompanionObjectModifier.kt new file mode 100644 index 000000000000..f162a1af8a7b --- /dev/null +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/AlsoMatchCompanionObjectModifier.kt @@ -0,0 +1,15 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.structuralsearch.filters + +import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.idea.KotlinBundle + +class AlsoMatchCompanionObjectModifier : OneStateFilter( + KotlinBundle.lazyMessage("modifier.match.companion.object"), + KotlinBundle.message("modifier.also.match.companion.object"), + CONSTRAINT_NAME +) { + companion object { + const val CONSTRAINT_NAME: @NonNls String = "kotlinAlsoMatchCompanionObject" + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/KotlinFilterProvider.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/KotlinFilterProvider.kt index 39fcd59f85a2..b3499e1bf013 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/KotlinFilterProvider.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/KotlinFilterProvider.kt @@ -5,5 +5,9 @@ import com.intellij.structuralsearch.plugin.ui.filters.FilterAction import com.intellij.structuralsearch.plugin.ui.filters.FilterProvider class KotlinFilterProvider : FilterProvider { - override fun getFilters(): List = listOf(AlsoMatchValModifier(), AlsoMatchVarModifier()) + override fun getFilters(): List = listOf( + AlsoMatchValModifier(), + AlsoMatchVarModifier(), + AlsoMatchCompanionObjectModifier() + ) } \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/OneStateFilter.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/OneStateFilter.kt index 23e7c2f66a45..f641108ee805 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/OneStateFilter.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/filters/OneStateFilter.kt @@ -1,5 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.structuralsearch.filters import com.intellij.psi.PsiElement diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/predicates/KotlinAlsoMatchCompanionObjectPredicate.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/predicates/KotlinAlsoMatchCompanionObjectPredicate.kt new file mode 100644 index 000000000000..3c2cb61cc4d6 --- /dev/null +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/predicates/KotlinAlsoMatchCompanionObjectPredicate.kt @@ -0,0 +1,10 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.structuralsearch.predicates + +import com.intellij.psi.PsiElement +import com.intellij.structuralsearch.impl.matcher.MatchContext +import com.intellij.structuralsearch.impl.matcher.predicates.MatchPredicate + +class KotlinAlsoMatchCompanionObjectPredicate : MatchPredicate() { + override fun match(matchedNode: PsiElement, start: Int, end: Int, context: MatchContext): Boolean = true +} \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/visitor/KotlinMatchingVisitor.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/visitor/KotlinMatchingVisitor.kt index e45eef0a889d..c4a537030493 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/visitor/KotlinMatchingVisitor.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/structuralsearch/visitor/KotlinMatchingVisitor.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchReques import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.structuralsearch.* +import org.jetbrains.kotlin.idea.structuralsearch.predicates.KotlinAlsoMatchCompanionObjectPredicate import org.jetbrains.kotlin.idea.structuralsearch.predicates.KotlinAlsoMatchValVarPredicate import org.jetbrains.kotlin.idea.util.safeAnalyzeNonSourceRootCode import org.jetbrains.kotlin.kdoc.lexer.KDocTokens @@ -113,7 +114,18 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor private fun matchTextOrVariable(el1: PsiElement?, el2: PsiElement?): Boolean { if (el1 == null) return true - if (el2 == null) return el1 == el2 + if (el2 == null) return false + return substituteOrMatchText(el1, el2) + } + + private fun matchTextOrVariableEq(el1: PsiElement?, el2: PsiElement?): Boolean { + if (el1 == null && el2 == null) return true + if (el1 == null) return false + if (el2 == null) return false + return substituteOrMatchText(el1, el2) + } + + private fun substituteOrMatchText(el1: PsiElement, el2: PsiElement): Boolean { return when (val handler = getHandler(el1)) { is SubstitutionHandler -> handler.validate(el2, myMatchingVisitor.matchContext) else -> myMatchingVisitor.matchText(el1, el2) @@ -130,10 +142,10 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor KDocTokens.TEXT -> { myMatchingVisitor.result = when (val handler = leafPsiElement.getUserData(CompiledPattern.HANDLER_KEY)) { is LiteralWithSubstitutionHandler -> handler.match(leafPsiElement, other, myMatchingVisitor.matchContext) - else -> matchTextOrVariable(leafPsiElement, other) + else -> substituteOrMatchText(leafPsiElement, other) } } - KDocTokens.TAG_NAME, KtTokens.IDENTIFIER -> myMatchingVisitor.result = matchTextOrVariable(leafPsiElement, other) + KDocTokens.TAG_NAME, KtTokens.IDENTIFIER -> myMatchingVisitor.result = substituteOrMatchText(leafPsiElement, other) } } @@ -306,7 +318,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor override fun visitConstantExpression(expression: KtConstantExpression) { val other = getTreeElementDepar() ?: return - myMatchingVisitor.result = matchTextOrVariable(expression, other) + myMatchingVisitor.result = substituteOrMatchText(expression, other) } override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { @@ -337,7 +349,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor && other is KtDotQualifiedExpression && myMatchingVisitor.match(expression, other.selectorExpression) - myMatchingVisitor.result = skipReceiver || matchTextOrVariable( + myMatchingVisitor.result = skipReceiver || substituteOrMatchText( expression.getReferencedNameElement(), if (other is KtSimpleNameExpression) other.getReferencedNameElement() else other ) @@ -675,7 +687,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor override fun visitTypeParameter(parameter: KtTypeParameter) { val other = getTreeElementDepar() ?: return - myMatchingVisitor.result = matchTextOrVariable(parameter.firstChild, other.firstChild) // match generic identifier + myMatchingVisitor.result = substituteOrMatchText(parameter.firstChild, other.firstChild) // match generic identifier && myMatchingVisitor.match(parameter.extendsBound, other.extendsBound) && parameter.variance == other.variance parameter.nameIdentifier?.let { nameIdentifier -> @@ -872,17 +884,21 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor override fun visitObjectDeclaration(declaration: KtObjectDeclaration) { val other = getTreeElementDepar() ?: return - val otherIdentifier = - other.nameIdentifier ?: if (other.isCompanion()) (other.parent.parent as KtClass).nameIdentifier else null - myMatchingVisitor.result = myMatchingVisitor.match(declaration.modifierList, other.modifierList) - && matchTextOrVariable(declaration.nameIdentifier, otherIdentifier) + val inferredNameIdentifier = + declaration.nameIdentifier ?: if (declaration.isCompanion()) (declaration.parent.parent as KtClass).nameIdentifier else null + val handler = inferredNameIdentifier?.let { getHandler(inferredNameIdentifier) } + val matchIdentifier = if (handler is SubstitutionHandler && handler.maxOccurs > 0 && handler.minOccurs == 0) { + true // match count filter with companion object without identifier + } else matchTextOrVariableEq(declaration.nameIdentifier, other.nameIdentifier) + myMatchingVisitor.result = + (declaration.isCompanion() == other.isCompanion() || + (handler is SubstitutionHandler && handler.predicate is KotlinAlsoMatchCompanionObjectPredicate)) + && myMatchingVisitor.match(declaration.modifierList, other.modifierList) + && matchIdentifier && myMatchingVisitor.match(declaration.getSuperTypeList(), other.getSuperTypeList()) && myMatchingVisitor.match(declaration.body, other.body) - declaration.nameIdentifier?.let { declNameIdentifier -> - val handler = getHandler(declNameIdentifier) - if (myMatchingVisitor.result && handler is SubstitutionHandler) { - handler.handle(otherIdentifier, myMatchingVisitor.matchContext) - } + if (myMatchingVisitor.result && handler is SubstitutionHandler) { + handler.handle(other.nameIdentifier, myMatchingVisitor.matchContext) } } @@ -1129,7 +1145,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor val other = myMatchingVisitor.element myMatchingVisitor.result = when (val handler = entry.getUserData(CompiledPattern.HANDLER_KEY)) { is LiteralWithSubstitutionHandler -> handler.match(entry, other, myMatchingVisitor.matchContext) - else -> matchTextOrVariable(entry, other) + else -> substituteOrMatchText(entry, other) } } @@ -1140,7 +1156,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor override fun visitEscapeStringTemplateEntry(entry: KtEscapeStringTemplateEntry) { val other = getTreeElementDepar() ?: return - myMatchingVisitor.result = matchTextOrVariable(entry, other) + myMatchingVisitor.result = substituteOrMatchText(entry, other) } override fun visitBinaryWithTypeRHSExpression(expression: KtBinaryExpressionWithTypeRHS) { @@ -1243,7 +1259,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor override fun visitKDocLink(link: KDocLink) { val other = getTreeElementDepar() ?: return - myMatchingVisitor.result = matchTextOrVariable(link, other) + myMatchingVisitor.result = substituteOrMatchText(link, other) } companion object { diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSObjectDeclarationTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSObjectDeclarationTest.kt index 091135ecdfa1..d21edb1034e3 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSObjectDeclarationTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSObjectDeclarationTest.kt @@ -1,31 +1,144 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.structuralsearch.search import org.jetbrains.kotlin.idea.structuralsearch.KotlinSSResourceInspectionTest +import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchCompanionObjectModifier +import org.jetbrains.kotlin.idea.structuralsearch.filters.OneStateFilter class KotlinSSObjectDeclarationTest : KotlinSSResourceInspectionTest() { - override fun getBasePath(): String = "objectDeclaration" + fun testObject() { + doTest("object '_", """ + object A { } + class B { + companion object { } + } + fun main() { + val x = object { } + println(x) + } + """.trimIndent()) + } - fun testObject() { doTest("object '_") } + fun testNestedObject() { + doTest("object B", """ + object A { + object B { } + } + class C { + companion object B { } + } + """.trimIndent()) + } - fun testCompanionObject() { doTest("object A") } + fun testObjectAlsoMatchCompanionObject() { + doTest("object '_:[_${AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + """.trimIndent()) + } - fun testNestedObject() { doTest("object B") } + fun testObjectCountModifier() { + doTest("object '_{0,1}", """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + fun main() { + val x = object { } + println(x) + } + """.trimIndent()) + } + + fun testObjectAlsoMatchCompanionObjectCountModifier() { + doTest("object '_{0,1}:[_${AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + """.trimIndent()) + } + + fun testCompanionObject() { doTest(""" + class '_ { + companion object '_ { } + } + """.trimIndent(), """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + """.trimIndent()) + } + + fun testNamelessCompanionObject() { doTest(""" + class '_ { + companion object { } + } + """.trimIndent(), """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + """.trimIndent()) + } + + fun testCompanionObjectCountModifier() { doTest(""" + class '_ { + companion object '_{0,1} { } + } + """.trimIndent(), """ + class A { + companion object { } + } + class B { + companion object Factory { } + } + object C { } + """.trimIndent()) + } fun testNamedCompanionObject() { - doTest( - """class '_ { - companion object Foo { } - }""".trimMargin() + doTest(""" + class '_ { + companion object Foo { } + } + """.trimIndent(), """ + class A { + companion object Foo { } + } + """.trimIndent() ) } fun testNestedNamedCompanionObject() { - doTest( - """class '_ { + doTest(""" + class '_ { + companion object Foo { } + } + """.trimIndent(), """ + class ContainerForCompanion { companion object Foo { } - }""".trimMargin() + } + """.trimIndent() ) } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSPropertyTest.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSPropertyTest.kt index c26c512bad28..34272332cead 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSPropertyTest.kt +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/KotlinSSPropertyTest.kt @@ -1,9 +1,12 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.structuralsearch.search import org.jetbrains.kotlin.idea.structuralsearch.KotlinSSResourceInspectionTest import org.jetbrains.kotlin.idea.structuralsearch.KotlinStructuralSearchProfile +import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchValModifier +import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchVarModifier +import org.jetbrains.kotlin.idea.structuralsearch.filters.OneStateFilter class KotlinSSPropertyTest : KotlinSSResourceInspectionTest() { override fun getBasePath(): String = "property" @@ -55,4 +58,20 @@ class KotlinSSPropertyTest : KotlinSSResourceInspectionTest() { fun testReceiverTypeReference() { doTest("val Int.'_ : '_") } fun testReceiverFqTypeReference() { doTest("val kotlin.Int.'_ : '_") } + + fun testAlsoMatchValModifier() { doTest("var '_:[_${AlsoMatchValModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ + fun main() { + var x = 1 + val y = 1 + print(x + y) + } + """.trimIndent()) } + + fun testAlsoMatchVarModifier() { doTest("val '_:[_${AlsoMatchVarModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ + fun main() { + var x = 1 + val y = 1 + print(x + y) + } + """.trimIndent()) } } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/filters/KotlinSSValVarModifierTests.kt b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/filters/KotlinSSValVarModifierTests.kt deleted file mode 100644 index 9a095ae16010..000000000000 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/structuralsearch/search/filters/KotlinSSValVarModifierTests.kt +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.structuralsearch.search.filters - -import org.jetbrains.kotlin.idea.structuralsearch.KotlinSSResourceInspectionTest -import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchValModifier -import org.jetbrains.kotlin.idea.structuralsearch.filters.AlsoMatchVarModifier -import org.jetbrains.kotlin.idea.structuralsearch.filters.OneStateFilter - -class KotlinSSValVarModifierTests: KotlinSSResourceInspectionTest() { - fun testAlsoMatchValModifier() { doTest("var '_:[_${AlsoMatchValModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ - fun main() { - var x = 1 - val y = 1 - print(x + y) - } - """.trimIndent()) } - - fun testAlsoMatchVarModifier() { doTest("val '_:[_${AlsoMatchVarModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """ - fun main() { - var x = 1 - val y = 1 - print(x + y) - } - """.trimIndent()) } -} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/companionObject.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/companionObject.kt deleted file mode 100644 index 0a97e851012b..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/companionObject.kt +++ /dev/null @@ -1,3 +0,0 @@ -class A { - companion object { } -} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/namedCompanionObject.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/namedCompanionObject.kt deleted file mode 100644 index 7a13b58553b7..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/namedCompanionObject.kt +++ /dev/null @@ -1,3 +0,0 @@ -class A { - companion object Foo { } -} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedNamedCompanionObject.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedNamedCompanionObject.kt deleted file mode 100644 index 32bfd500858c..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedNamedCompanionObject.kt +++ /dev/null @@ -1,3 +0,0 @@ -class ContainerForCompanion { - companion object Foo { } -} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedObject.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedObject.kt deleted file mode 100644 index da8edc76b75a..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/nestedObject.kt +++ /dev/null @@ -1,3 +0,0 @@ -object A { - object B { } -} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/object.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/object.kt deleted file mode 100644 index c4fb15af6905..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/object.kt +++ /dev/null @@ -1,3 +0,0 @@ -object A { } - -class B { } \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/objectSuperType.kt b/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/objectSuperType.kt deleted file mode 100644 index 472a8cbe5fb3..000000000000 --- a/plugins/kotlin/idea/tests/testData/structuralsearch/objectDeclaration/objectSuperType.kt +++ /dev/null @@ -1,5 +0,0 @@ -import java.awt.event.MouseAdapter - -object A : MouseAdapter() { } - -object B { } \ No newline at end of file