mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix first call in chain detection : IDEA-192777
This commit is contained in:
@@ -23,11 +23,8 @@ class MethodChainHintsPass(
|
||||
|
||||
override fun collectElementHints(element: PsiElement, collector: (offset: Int, hint: String) -> Unit) {
|
||||
val call = element as? PsiMethodCallExpression ?: return
|
||||
val qualifier = call.methodExpression.qualifierExpression
|
||||
if (qualifier != null && qualifier is PsiMethodCallExpression) {
|
||||
val callSibling = qualifier.nextSibling
|
||||
if (callSibling is PsiWhiteSpace && callSibling.textContains('\n')) return // Not first call
|
||||
}
|
||||
if (!isFirstCall(call)) return
|
||||
|
||||
val next = call.nextSibling
|
||||
if (!(next is PsiWhiteSpace && next.textContains('\n'))) return
|
||||
val chain = collectChain(call)
|
||||
@@ -50,6 +47,29 @@ class MethodChainHintsPass(
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFirstCall(call: PsiMethodCallExpression): Boolean {
|
||||
val document = myEditor.document
|
||||
val callLine = document.getLineNumber(call.argumentList.textOffset)
|
||||
|
||||
val callForQualifier = ExpressionUtils.getCallForQualifier(call)
|
||||
if (callForQualifier == null ||
|
||||
document.getLineNumber(callForQualifier.argumentList.textOffset) == callLine) return false
|
||||
|
||||
val firstQualifierCall = call.methodExpression.qualifier as? PsiMethodCallExpression
|
||||
if (firstQualifierCall != null) {
|
||||
if (document.getLineNumber(firstQualifierCall.argumentList.textOffset) != callLine) return false
|
||||
var currentQualifierCall: PsiMethodCallExpression = firstQualifierCall
|
||||
while (true) {
|
||||
val qualifier = currentQualifierCall.methodExpression.qualifier
|
||||
if (qualifier == null) return false
|
||||
if (qualifier !is PsiMethodCallExpression) return true
|
||||
if (document.getLineNumber(qualifier.argumentList.textOffset) != callLine) return false
|
||||
currentQualifierCall = qualifier
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun collectChain(call: PsiMethodCallExpression): List<PsiMethodCallExpression> {
|
||||
val chain = mutableListOf(call)
|
||||
var current = call
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.java.codeInsight.daemon.inlays
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HintRenderer
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.intellij.lang.annotations.Language
|
||||
|
||||
class MethodChainHintsTest: LightCodeInsightFixtureTestCase() {
|
||||
fun check(@Language("Java") text: String) {
|
||||
myFixture.configureByText("A.java", text)
|
||||
myFixture.testInlays({ (it.renderer as HintRenderer).text }, { it.renderer is HintRenderer })
|
||||
}
|
||||
|
||||
fun `test plain builder`() {
|
||||
check("""
|
||||
public class Chains {
|
||||
static class A {
|
||||
B b() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class B {
|
||||
A a() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class C {
|
||||
B b() {return null;}
|
||||
A a() {return null;}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new A()
|
||||
.b()<hint text="B"/>
|
||||
.c()<hint text="C"/>
|
||||
.a()<hint text="A"/>
|
||||
.c();
|
||||
}
|
||||
}""")
|
||||
}
|
||||
|
||||
fun `test duplicated builder`() {
|
||||
// IDEA-192777
|
||||
check("""public class Chains {
|
||||
static class A {
|
||||
B b() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class B {
|
||||
A a() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class C {
|
||||
B b() {return null;}
|
||||
A a() {return null;}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new A()
|
||||
.b()<hint text="B"/>
|
||||
.c().b()<hint text="B"/>
|
||||
.a()<hint text="A"/>
|
||||
.c()<hint text="C"/>
|
||||
.b()<hint text="B"/>
|
||||
.c();
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
fun `test duplicated call with reference qualifier`() {
|
||||
check("""public class Chains {
|
||||
static class A {
|
||||
B b() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class B {
|
||||
A a() {return null;}
|
||||
C c() {return null;}
|
||||
}
|
||||
|
||||
static class C {
|
||||
B b() {return null;}
|
||||
A a() {return null;}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
A a = new A();
|
||||
a.b().c()<hint text="C"/>
|
||||
.a()<hint text="A"/>
|
||||
.b()<hint text="B"/>
|
||||
.a()<hint text="A"/>
|
||||
.c()<hint text="C"/>
|
||||
.b();
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user