Implement display of code construct start for Kotlin
#KT-20470 Fixed
This commit is contained in:
@@ -774,6 +774,12 @@
|
||||
|
||||
<gotoRelatedProvider implementation="org.jetbrains.kotlin.idea.goto.KotlinExpectOrActualGotoRelatedProvider"/>
|
||||
|
||||
<declarationRangeHandler key="org.jetbrains.kotlin.psi.KtClassOrObject"
|
||||
implementationClass="org.jetbrains.kotlin.idea.codeInsight.KotlinClassDeclarationRangeHandler"/>
|
||||
|
||||
<declarationRangeHandler key="org.jetbrains.kotlin.psi.KtDeclarationWithBody"
|
||||
implementationClass="org.jetbrains.kotlin.idea.codeInsight.KotlinFunDeclarationRangeHandler"/>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention</className>
|
||||
<category>Kotlin</category>
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea
|
||||
|
||||
import com.intellij.codeInsight.hint.DeclarationRangeUtil
|
||||
import com.intellij.lang.BracePair
|
||||
import com.intellij.lang.PairedBraceMatcher
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtClassBody
|
||||
|
||||
class KotlinPairMatcher : PairedBraceMatcher {
|
||||
private val pairs = arrayOf(
|
||||
@@ -37,6 +40,12 @@ class KotlinPairMatcher : PairedBraceMatcher {
|
||||
}
|
||||
|
||||
override fun getCodeConstructStart(file: PsiFile, openingBraceOffset: Int): Int {
|
||||
return openingBraceOffset
|
||||
val element = file.findElementAt(openingBraceOffset)
|
||||
if (element == null || element is PsiFile) return openingBraceOffset
|
||||
val parent = element.parent
|
||||
return when (parent) {
|
||||
is KtClassBody, is KtBlockExpression -> DeclarationRangeUtil.getDeclarationRange(parent.parent).startOffset
|
||||
else -> openingBraceOffset
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.codeInsight.hint.DeclarationRangeHandler
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
class KotlinClassDeclarationRangeHandler : DeclarationRangeHandler<KtClassOrObject> {
|
||||
override fun getDeclarationRange(container: KtClassOrObject): TextRange {
|
||||
val body = container.getBody() ?: return container.textRange
|
||||
val prevSibling = body.getPrevSiblingIgnoringWhitespaceAndComments()
|
||||
return TextRange(
|
||||
container.getDeclarationKeyword()?.startOffset ?: container.startOffset,
|
||||
prevSibling?.endOffset ?: body.startOffset
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinFunDeclarationRangeHandler : DeclarationRangeHandler<KtDeclarationWithBody> {
|
||||
override fun getDeclarationRange(container: KtDeclarationWithBody): TextRange {
|
||||
val body = container.bodyExpression ?: return container.textRange
|
||||
val prevSibling = body.getPrevSiblingIgnoringWhitespaceAndComments()
|
||||
return TextRange(
|
||||
(container as? KtNamedFunction)?.funKeyword?.startOffset
|
||||
?: (container as? PsiNameIdentifierOwner)?.nameIdentifier?.startOffset
|
||||
?: container.modifierList?.startOffset
|
||||
?: container.startOffset,
|
||||
prevSibling?.endOffset ?: body.startOffset
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinPairMatcher
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
class KotlinPairMatcherTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor(): KotlinLightProjectDescriptor = KotlinLightProjectDescriptor.INSTANCE
|
||||
|
||||
private fun doTest(testData: String) {
|
||||
var docText = testData
|
||||
val startPos = docText.indexOf("<start>")
|
||||
if (startPos == -1) {
|
||||
throw IllegalArgumentException("<start> marker not found in testdata")
|
||||
}
|
||||
docText = docText.replace("<start>", "")
|
||||
val bracePos = docText.indexOf("<brace>")
|
||||
if (bracePos == -1) {
|
||||
throw IllegalArgumentException("<brace> marker not found in testdata")
|
||||
}
|
||||
docText = docText.replace("<brace>", "")
|
||||
myFixture.configureByText(KotlinFileType.INSTANCE, docText)
|
||||
val pos = KotlinPairMatcher().getCodeConstructStart(myFixture.file, bracePos)
|
||||
assertEquals(startPos, pos)
|
||||
}
|
||||
|
||||
fun testClass() {
|
||||
doTest("/* Doc comment */ <start>class Foo : Bar, Baz <brace>{ fun xyzzy() { } }")
|
||||
}
|
||||
|
||||
fun testFun() {
|
||||
doTest("/* Doc comment */ <start>fun xyzzy(x: Int, y: String): Any <brace>{ }")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user