Create KotlinLineIndentProvider and delegate it to formatter
#KT-22211
This commit is contained in:
+10
@@ -268,6 +268,16 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
|
||||
runTest("idea/testData/indentationOnNewline/ReturnContinue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Semicolon.kt")
|
||||
public void testSemicolon() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/Semicolon.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Semicolon2.kt")
|
||||
public void testSemicolon2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/Semicolon2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SettingAlignMultilineParametersInCalls.kt")
|
||||
public void testSettingAlignMultilineParametersInCalls() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/SettingAlignMultilineParametersInCalls.kt");
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
factoryClass="org.jetbrains.kotlin.idea.structureView.KtClsStructureViewBuilderProvider"/>
|
||||
|
||||
<lang.formatter language="kotlin" implementationClass="org.jetbrains.kotlin.idea.formatter.KotlinFormattingModelBuilder"/>
|
||||
<lineIndentProvider implementation="org.jetbrains.kotlin.idea.formatter.KotlinLineIndentProvider"/>
|
||||
<preFormatProcessor implementation="org.jetbrains.kotlin.idea.formatter.KotlinPreFormatProcessor"/>
|
||||
<postFormatProcessor implementation="org.jetbrains.kotlin.idea.formatter.TrailingCommaPostFormatProcessor"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.formatter
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider
|
||||
import com.intellij.psi.impl.source.codeStyle.lineIndent.FormatterBasedLineIndentProvider
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
|
||||
class KotlinLineIndentProvider : LineIndentProvider {
|
||||
private val formatterBasedProvider = FormatterBasedLineIndentProvider()
|
||||
|
||||
override fun getLineIndent(project: Project, editor: Editor, language: Language?, offset: Int): String? {
|
||||
val lineIndent = formatterBasedProvider.getLineIndent(project, editor, language, offset)
|
||||
return if (useFormatter) lineIndent else lineIndent
|
||||
}
|
||||
|
||||
override fun isSuitableFor(language: Language?): Boolean = language?.isKindOf(KotlinLanguage.INSTANCE) == true
|
||||
|
||||
companion object {
|
||||
@get:TestOnly
|
||||
@set:TestOnly
|
||||
internal var useFormatter: Boolean = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun test(i: Int) {
|
||||
test(
|
||||
<caret>
|
||||
)
|
||||
}
|
||||
|
||||
// SET_FALSE: CONTINUATION_INDENT_IN_ARGUMENT_LISTS
|
||||
@@ -0,0 +1,4 @@
|
||||
fun test() {
|
||||
val a = 44;
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun test() {
|
||||
val a = 44;<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun test() {
|
||||
val a = 44;
|
||||
<caret>val b = 42;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun test() {
|
||||
val a = 44;<caret> val b = 42;
|
||||
}
|
||||
@@ -5,13 +5,22 @@
|
||||
package org.jetbrains.kotlin.formatter
|
||||
|
||||
import com.intellij.application.options.CodeStyle
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.psi.codeStyle.lineIndent.LineIndentProvider
|
||||
import com.intellij.testFramework.EditorTestUtil
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.formatter.KotlinLineIndentProvider
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightPlatformCodeInsightTestCase
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.testFramework.runWriteAction
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractTypingIndentationTestBase : KotlinLightPlatformCodeInsightTestCase() {
|
||||
private val customLineIndentProvider: LineIndentProvider = KotlinLineIndentProvider()
|
||||
|
||||
fun doNewlineTestWithInvert(afterInvFilePath: String) {
|
||||
doNewlineTest(afterInvFilePath, true)
|
||||
}
|
||||
@@ -22,6 +31,11 @@ abstract class AbstractTypingIndentationTestBase : KotlinLightPlatformCodeInsigh
|
||||
val testFileExtension = afterFilePath.substring(afterFilePath.lastIndexOf("."))
|
||||
val originFilePath = testFileName + testFileExtension
|
||||
val originalFileText = FileUtil.loadFile(File(originFilePath), true)
|
||||
val withoutCustomLineIndentProvider = InTextDirectivesUtils.findStringWithPrefixes(
|
||||
originalFileText,
|
||||
"// WITHOUT_CUSTOM_LINE_INDENT_PROVIDER"
|
||||
) != null
|
||||
|
||||
try {
|
||||
val configurator = FormatSettingsUtil.createConfigurator(originalFileText, CodeStyle.getSettings(project))
|
||||
if (!inverted) {
|
||||
@@ -30,19 +44,48 @@ abstract class AbstractTypingIndentationTestBase : KotlinLightPlatformCodeInsigh
|
||||
configurator.configureInvertedSettings()
|
||||
}
|
||||
|
||||
doNewlineTest(originFilePath, afterFilePath)
|
||||
doNewlineTest(originFilePath, afterFilePath, withoutCustomLineIndentProvider)
|
||||
} finally {
|
||||
CodeStyle.getSettings(project).clearCodeStyleSettings()
|
||||
}
|
||||
}
|
||||
|
||||
private fun doNewlineTest(beforeFilePath: String, afterFilePath: String) {
|
||||
private fun doNewlineTest(beforeFilePath: String, afterFilePath: String, withoutCustomLineIndentProvider: Boolean) {
|
||||
KotlinLineIndentProvider.useFormatter = true
|
||||
typeAndCheck(beforeFilePath, afterFilePath, "with FormatterBasedLineIndentProvider")
|
||||
KotlinLineIndentProvider.useFormatter = false
|
||||
|
||||
if (!withoutCustomLineIndentProvider) {
|
||||
typeAndCheck(beforeFilePath, afterFilePath, "with ${customLineIndentProvider.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
configureByFile(beforeFilePath)
|
||||
type('\n')
|
||||
val caretModel = editor.caretModel
|
||||
val offset = caretModel.offset
|
||||
val actualTextWithCaret = StringBuilder(editor.document.text).insert(offset, EditorTestUtil.CARET_TAG).toString()
|
||||
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), actualTextWithCaret)
|
||||
assertCustomIndentExist(withoutCustomLineIndentProvider)
|
||||
}
|
||||
|
||||
private fun assertCustomIndentExist(withoutCustomLineIndentProvider: Boolean) {
|
||||
val offset = editor.caretModel.offset
|
||||
runWriteAction {
|
||||
editor.document.insertString(offset, "\n")
|
||||
}
|
||||
|
||||
val customIndent = customLineIndentProvider.getLineIndent(project, editor, KotlinLanguage.INSTANCE, offset + 1)
|
||||
val condition = customIndent == null
|
||||
Assert.assertTrue(
|
||||
"${if (withoutCustomLineIndentProvider) "Remove" else "Add"} \"// WITHOUT_CUSTOM_LINE_INDENT_PROVIDER\" or fix ${customLineIndentProvider.javaClass.simpleName}",
|
||||
if (withoutCustomLineIndentProvider) condition else !condition
|
||||
)
|
||||
}
|
||||
|
||||
private fun typeAndCheck(beforeFilePath: String, afterFilePath: String, errorMessage: String) {
|
||||
configureByFile(beforeFilePath)
|
||||
executeAction(IdeActions.ACTION_EDITOR_ENTER)
|
||||
val actualTextWithCaret = StringBuilder(editor.document.text).insert(
|
||||
editor.caretModel.offset,
|
||||
EditorTestUtil.CARET_TAG
|
||||
).toString()
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(errorMessage, File(afterFilePath), actualTextWithCaret)
|
||||
}
|
||||
|
||||
override fun getTestDataPath(): String = ""
|
||||
|
||||
+15
@@ -270,6 +270,16 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
runTest("idea/testData/indentationOnNewline/ReturnContinue.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Semicolon.after.kt")
|
||||
public void testSemicolon() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/Semicolon.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Semicolon2.after.kt")
|
||||
public void testSemicolon2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/Semicolon2.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SettingAlignMultilineParametersInCalls.after.kt")
|
||||
public void testSettingAlignMultilineParametersInCalls() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/SettingAlignMultilineParametersInCalls.after.kt");
|
||||
@@ -336,6 +346,11 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("ArgumentListNormalIndent.after.inv.kt")
|
||||
public void testArgumentListNormalIndent() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/ArgumentListNormalIndent.after.inv.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("AssignmentAfterEq.after.inv.kt")
|
||||
public void testAssignmentAfterEq() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/AssignmentAfterEq.after.inv.kt");
|
||||
|
||||
Reference in New Issue
Block a user