mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[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
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f1907e692b
commit
b5b48c828b
@@ -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
|
||||
|
||||
+10
-2
@@ -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(
|
||||
|
||||
+9
-2
@@ -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
|
||||
}
|
||||
|
||||
+15
@@ -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"
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -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<FilterAction> = listOf(AlsoMatchValModifier(), AlsoMatchVarModifier())
|
||||
override fun getFilters(): List<FilterAction> = listOf(
|
||||
AlsoMatchValModifier(),
|
||||
AlsoMatchVarModifier(),
|
||||
AlsoMatchCompanionObjectModifier()
|
||||
)
|
||||
}
|
||||
+1
-2
@@ -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
|
||||
|
||||
+10
@@ -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
|
||||
}
|
||||
+34
-18
@@ -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<KtExpression>() ?: 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<KtTypeParameter>() ?: 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<KtObjectDeclaration>() ?: 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<KtEscapeStringTemplateEntry>() ?: 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<KDocLink>() ?: return
|
||||
myMatchingVisitor.result = matchTextOrVariable(link, other)
|
||||
myMatchingVisitor.result = substituteOrMatchText(link, other)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+125
-12
@@ -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 '_", """
|
||||
<warning descr="SSR">object A { }</warning>
|
||||
class B {
|
||||
companion object { }
|
||||
}
|
||||
fun main() {
|
||||
val x = object { }
|
||||
println(x)
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testObject() { doTest("object '_") }
|
||||
fun testNestedObject() {
|
||||
doTest("object B", """
|
||||
object A {
|
||||
<warning descr="SSR">object B { }</warning>
|
||||
}
|
||||
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 {
|
||||
<warning descr="SSR">companion object Factory { }</warning>
|
||||
}
|
||||
<warning descr="SSR">object C { }</warning>
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testNestedObject() { doTest("object B") }
|
||||
fun testObjectCountModifier() {
|
||||
doTest("object '_{0,1}", """
|
||||
class A {
|
||||
companion object { }
|
||||
}
|
||||
class B {
|
||||
companion object Factory { }
|
||||
}
|
||||
<warning descr="SSR">object C { }</warning>
|
||||
fun main() {
|
||||
val x = <warning descr="SSR">object { }</warning>
|
||||
println(x)
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testObjectAlsoMatchCompanionObjectCountModifier() {
|
||||
doTest("object '_{0,1}:[_${AlsoMatchCompanionObjectModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """
|
||||
class A {
|
||||
<warning descr="SSR">companion object { }</warning>
|
||||
}
|
||||
class B {
|
||||
<warning descr="SSR">companion object Factory { }</warning>
|
||||
}
|
||||
<warning descr="SSR">object C { }</warning>
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testCompanionObject() { doTest("""
|
||||
class '_ {
|
||||
companion object '_ { }
|
||||
}
|
||||
""".trimIndent(), """
|
||||
class A {
|
||||
companion object { }
|
||||
}
|
||||
<warning descr="SSR">class B {
|
||||
companion object Factory { }
|
||||
}</warning>
|
||||
object C { }
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testNamelessCompanionObject() { doTest("""
|
||||
class '_ {
|
||||
companion object { }
|
||||
}
|
||||
""".trimIndent(), """
|
||||
<warning descr="SSR">class A {
|
||||
companion object { }
|
||||
}</warning>
|
||||
class B {
|
||||
companion object Factory { }
|
||||
}
|
||||
object C { }
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testCompanionObjectCountModifier() { doTest("""
|
||||
class '_ {
|
||||
companion object '_{0,1} { }
|
||||
}
|
||||
""".trimIndent(), """
|
||||
<warning descr="SSR">class A {
|
||||
companion object { }
|
||||
}</warning>
|
||||
<warning descr="SSR">class B {
|
||||
companion object Factory { }
|
||||
}</warning>
|
||||
object C { }
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun testNamedCompanionObject() {
|
||||
doTest(
|
||||
"""class '_ {
|
||||
companion object Foo { }
|
||||
}""".trimMargin()
|
||||
doTest("""
|
||||
class '_ {
|
||||
companion object Foo { }
|
||||
}
|
||||
""".trimIndent(), """
|
||||
<warning descr="SSR">class A {
|
||||
companion object Foo { }
|
||||
}</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
fun testNestedNamedCompanionObject() {
|
||||
doTest(
|
||||
"""class '_ {
|
||||
doTest("""
|
||||
class '_ {
|
||||
companion object Foo { }
|
||||
}
|
||||
""".trimIndent(), """
|
||||
<warning descr="SSR">class ContainerForCompanion {
|
||||
companion object Foo { }
|
||||
}""".trimMargin()
|
||||
}</warning>
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+20
-1
@@ -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() {
|
||||
<warning descr="SSR">var x = 1</warning>
|
||||
<warning descr="SSR">val y = 1</warning>
|
||||
print(x + y)
|
||||
}
|
||||
""".trimIndent()) }
|
||||
|
||||
fun testAlsoMatchVarModifier() { doTest("val '_:[_${AlsoMatchVarModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """
|
||||
fun main() {
|
||||
<warning descr="SSR">var x = 1</warning>
|
||||
<warning descr="SSR">val y = 1</warning>
|
||||
print(x + y)
|
||||
}
|
||||
""".trimIndent()) }
|
||||
}
|
||||
-26
@@ -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() {
|
||||
<warning descr="SSR">var x = 1</warning>
|
||||
<warning descr="SSR">val y = 1</warning>
|
||||
print(x + y)
|
||||
}
|
||||
""".trimIndent()) }
|
||||
|
||||
fun testAlsoMatchVarModifier() { doTest("val '_:[_${AlsoMatchVarModifier.CONSTRAINT_NAME}(${OneStateFilter.ENABLED})]", """
|
||||
fun main() {
|
||||
<warning descr="SSR">var x = 1</warning>
|
||||
<warning descr="SSR">val y = 1</warning>
|
||||
print(x + y)
|
||||
}
|
||||
""".trimIndent()) }
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
class A {
|
||||
<warning descr="SSR">companion object { }</warning>
|
||||
}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
<warning descr="SSR">class A {
|
||||
companion object Foo { }
|
||||
}</warning>
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
<warning descr="SSR">class ContainerForCompanion {
|
||||
companion object Foo { }
|
||||
}</warning>
|
||||
@@ -1,3 +0,0 @@
|
||||
object A {
|
||||
<warning descr="SSR">object B { }</warning>
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<warning descr="SSR">object A { }</warning>
|
||||
|
||||
class B { }
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
import java.awt.event.MouseAdapter
|
||||
|
||||
<warning descr="SSR">object A : MouseAdapter() { }</warning>
|
||||
|
||||
object B { }
|
||||
Reference in New Issue
Block a user