diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 95944843f96..16d9eadb1b4 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -774,6 +774,12 @@
+
+
+
+
org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention
Kotlin
diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinPairMatcher.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinPairMatcher.kt
index 50caf00e354..8ea3290589d 100644
--- a/idea/src/org/jetbrains/kotlin/idea/KotlinPairMatcher.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/KotlinPairMatcher.kt
@@ -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
+ }
}
}
diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinDeclarationRangeHandler.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinDeclarationRangeHandler.kt
new file mode 100644
index 00000000000..69f298acbea
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KotlinDeclarationRangeHandler.kt
@@ -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 {
+ 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 {
+ 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
+ )
+ }
+}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/KotlinPairMatcherTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/KotlinPairMatcherTest.kt
new file mode 100644
index 00000000000..e7f07d6987e
--- /dev/null
+++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/KotlinPairMatcherTest.kt
@@ -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("")
+ if (startPos == -1) {
+ throw IllegalArgumentException(" marker not found in testdata")
+ }
+ docText = docText.replace("", "")
+ val bracePos = docText.indexOf("")
+ if (bracePos == -1) {
+ throw IllegalArgumentException(" marker not found in testdata")
+ }
+ docText = docText.replace("", "")
+ myFixture.configureByText(KotlinFileType.INSTANCE, docText)
+ val pos = KotlinPairMatcher().getCodeConstructStart(myFixture.file, bracePos)
+ assertEquals(startPos, pos)
+ }
+
+ fun testClass() {
+ doTest("/* Doc comment */ class Foo : Bar, Baz { fun xyzzy() { } }")
+ }
+
+ fun testFun() {
+ doTest("/* Doc comment */ fun xyzzy(x: Int, y: String): Any { }")
+ }
+}