mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-04 08:31:30 +00:00
KT-41538 Use matchOptionally for [0,0] count filters
This commit is contained in:
@@ -302,18 +302,6 @@ class KotlinCompilingVisitor(private val myCompilingVisitor: GlobalCompilingVisi
|
||||
constructor.setAbsenceOfMatchHandlerIfApplicable()
|
||||
}
|
||||
|
||||
override fun visitSuperTypeList(list: KtSuperTypeList) {
|
||||
super.visitSuperTypeList(list)
|
||||
list.setAbsenceOfMatchHandlerIfApplicable()
|
||||
}
|
||||
|
||||
override fun visitConstructorCalleeExpression(constructorCalleeExpression: KtConstructorCalleeExpression) {
|
||||
super.visitConstructorCalleeExpression(constructorCalleeExpression)
|
||||
if (constructorCalleeExpression.allowsAbsenceOfMatch) {
|
||||
setHandler(constructorCalleeExpression.parent, absenceOfMatchHandler(constructorCalleeExpression))
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitWhenEntry(jetWhenEntry: KtWhenEntry) {
|
||||
super.visitWhenEntry(jetWhenEntry)
|
||||
val condition = jetWhenEntry.firstChild.firstChild
|
||||
@@ -328,6 +316,23 @@ class KotlinCompilingVisitor(private val myCompilingVisitor: GlobalCompilingVisi
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitConstructorCalleeExpression(expression: KtConstructorCalleeExpression) {
|
||||
super.visitConstructorCalleeExpression(expression)
|
||||
val handler = getHandler(expression)
|
||||
if (handler is SubstitutionHandler && handler.minOccurs == 0) {
|
||||
setHandler(expression.parent, SubstitutionHandler("${expression.parent.hashCode()}_optional", false, 0, handler.maxOccurs, false))
|
||||
expression.parent.parent.setAbsenceOfMatchHandlerIfApplicable()
|
||||
}
|
||||
}
|
||||
|
||||
// override fun visitSuperTypeEntry(specifier: KtSuperTypeEntry) {
|
||||
// super.visitSuperTypeEntry(specifier)
|
||||
// if (specifier.allowsAbsenceOfMatch) {
|
||||
// specifier.parent.setAbsenceOfMatchHandler()
|
||||
// specifier.parent.parent.setAbsenceOfMatchHandlerIfApplicable()
|
||||
// }
|
||||
// }
|
||||
|
||||
override fun visitKDoc(kDoc: KDoc) {
|
||||
getHandler(kDoc).setFilter { it is KDoc }
|
||||
}
|
||||
@@ -340,12 +345,16 @@ class KotlinCompilingVisitor(private val myCompilingVisitor: GlobalCompilingVisi
|
||||
getHandler(tag).setFilter { it is KDocTag }
|
||||
}
|
||||
|
||||
private fun PsiElement.setAbsenceOfMatchHandler() {
|
||||
setHandler(this, absenceOfMatchHandler(this))
|
||||
}
|
||||
|
||||
private fun PsiElement.setAbsenceOfMatchHandlerIfApplicable(considerAllChildren: Boolean = false) {
|
||||
val childrenAllowAbsenceOfMatch =
|
||||
if (considerAllChildren) this.allChildren.all { it.allowsAbsenceOfMatch }
|
||||
else this.children.all { it.allowsAbsenceOfMatch }
|
||||
if (childrenAllowAbsenceOfMatch)
|
||||
setHandler(this, absenceOfMatchHandler(this))
|
||||
setAbsenceOfMatchHandler()
|
||||
}
|
||||
|
||||
private fun absenceOfMatchHandler(element: PsiElement): SubstitutionHandler =
|
||||
|
||||
@@ -295,10 +295,6 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor
|
||||
)
|
||||
val handler = getHandler(expression.getReferencedNameElement())
|
||||
if (myMatchingVisitor.result && handler is SubstitutionHandler) {
|
||||
if (handler.maxOccurs == 0) {
|
||||
myMatchingVisitor.result = false
|
||||
return
|
||||
}
|
||||
handler.handle(
|
||||
if (other is KtSimpleNameExpression) other.getReferencedNameElement() else other,
|
||||
myMatchingVisitor.matchContext
|
||||
@@ -427,12 +423,9 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
||||
val other = getTreeElementDepar<KtExpression>() ?: return
|
||||
val handler = getHandler(expression.receiverExpression)
|
||||
if (other is KtDotQualifiedExpression && handler is SubstitutionHandler && handler.maxOccurs == 0) {
|
||||
// Don't match '_{0,0}.'_
|
||||
myMatchingVisitor.result = false
|
||||
} else if (other is KtDotQualifiedExpression) {
|
||||
if (other is KtDotQualifiedExpression) {
|
||||
// Regular matching
|
||||
myMatchingVisitor.result = myMatchingVisitor.match(expression.receiverExpression, other.receiverExpression)
|
||||
myMatchingVisitor.result = myMatchingVisitor.matchOptionally(expression.receiverExpression, other.receiverExpression)
|
||||
&& myMatchingVisitor.match(expression.selectorExpression, other.selectorExpression)
|
||||
} else {
|
||||
// Match '_?.'_
|
||||
@@ -608,7 +601,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor
|
||||
override fun visitCallableReferenceExpression(expression: KtCallableReferenceExpression) {
|
||||
val other = getTreeElementDepar<KtCallableReferenceExpression>() ?: return
|
||||
myMatchingVisitor.result = myMatchingVisitor.match(expression.callableReference, other.callableReference)
|
||||
&& myMatchingVisitor.match(expression.receiverExpression, other.receiverExpression)
|
||||
&& myMatchingVisitor.matchOptionally(expression.receiverExpression, other.receiverExpression)
|
||||
}
|
||||
|
||||
override fun visitTypeParameter(parameter: KtTypeParameter) {
|
||||
@@ -1018,7 +1011,7 @@ class KotlinMatchingVisitor(private val myMatchingVisitor: GlobalMatchingVisitor
|
||||
&& matchTextOrVariable(property.nameIdentifier, other.nameIdentifier)
|
||||
&& property.isVar == other.isVar
|
||||
&& myMatchingVisitor.match(property.docComment, other.docComment)
|
||||
&& myMatchingVisitor.match(
|
||||
&& myMatchingVisitor.matchOptionally(
|
||||
property.delegateExpressionOrInitializer,
|
||||
other.delegateExpressionOrInitializer
|
||||
)
|
||||
|
||||
@@ -7,19 +7,19 @@ class KotlinSSCountFilterTest : KotlinSSResourceInspectionTest() {
|
||||
|
||||
// isApplicableMinCount
|
||||
|
||||
fun testMinProperty() { doTest("var '_ = '_?") }
|
||||
fun testMinProperty() { doTest("var '_ = '_{0,0}") }
|
||||
|
||||
fun testMinDotQualifierExpression() { doTest("'_?.'_") }
|
||||
fun testMinDotQualifierExpression() { doTest("'_{0,0}.'_") }
|
||||
|
||||
fun testMinFunctionTypeReference() { doTest("fun '_{0,0}.'_()") }
|
||||
|
||||
fun testMinCallableReferenceExpression() { doTest("'_{0,0}::'_") }
|
||||
|
||||
fun testMinWhenExpression() { doTest("when ('_?) {}") }
|
||||
fun testMinWhenExpression() { doTest("when ('_{0,0}) {}") }
|
||||
|
||||
fun testMinConstructorCallee() { doTest("class '_ : '_?('_*)") }
|
||||
fun testMinConstructorCallee() { doTest("class '_ : '_{0,0}('_*)") }
|
||||
|
||||
fun testMinSuperType() { doTest("class '_ : '_?()") }
|
||||
fun testMinSuperType() { doTest("class '_ : '_{0,0}()") }
|
||||
|
||||
// isApplicableMaxCount
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<warning descr="SSR">open class Foo</warning>
|
||||
|
||||
<warning descr="SSR">class Bar: Foo()</warning>
|
||||
class Bar: Foo()
|
||||
@@ -5,7 +5,7 @@ class A {
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val a = <warning descr="SSR">A.FOO</warning>
|
||||
<warning descr="SSR">print(<warning descr="SSR">Int.hashCode()</warning>)</warning>
|
||||
val a = A.FOO
|
||||
<warning descr="SSR">print(Int.hashCode())</warning>
|
||||
<warning descr="SSR">print(<warning descr="SSR">a</warning>)</warning>
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
class A {
|
||||
<warning descr="SSR">lateinit var x: String</warning>
|
||||
<warning descr="SSR">var y = 1</warning>
|
||||
var y = 1
|
||||
|
||||
fun init() { x = "a" }
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
<warning descr="SSR">open class A</warning>
|
||||
<warning descr="SSR">class B : A()</warning>
|
||||
class B : A()
|
||||
Reference in New Issue
Block a user