KT-1161 Formatter: indent parameters after function call on new line (not very beautiful but it will be refactored in future)

#KT-1161 fixed
This commit is contained in:
Nikolay Krasko
2012-04-04 14:05:51 +04:00
parent 5ffbc87b3f
commit 0d1767fbf1
23 changed files with 289 additions and 48 deletions
+70 -4
View File
@@ -63,14 +63,57 @@
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<ADDITIONAL_INDENT_OPTIONS fileType="gsp">
<option name="INDENT_SIZE" value="2" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="html">
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="CFML">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="ECMA Script Level 4">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="GSP">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Groovy">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
@@ -114,11 +157,13 @@
<codeStyleSettings language="JAVA">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
@@ -147,10 +192,31 @@
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="BINARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
+4
View File
@@ -240,6 +240,10 @@
<inspection_tool class="MethodOverloadsParentMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesPrivateMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MissingOverrideAnnotation" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreObjectMethods" value="true" />
<option name="ignoreAnonymousClassMethods" value="false" />
</inspection_tool>
<inspection_tool class="MisspelledCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
+2
View File
@@ -57,6 +57,8 @@
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/java/compiler/openapi/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/java/idea-ui/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/java/openapi/src" />
<root url="jar://$USER_HOME$/Downloads/picocontainer-2.10-20100209.093751-5-sources.jar!/" />
<root url="jar://$USER_HOME$/Downloads/picocontainer-1.3-20061227.142936-4-sources.jar!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/core" recursive="false" />
</library>
+8
View File
@@ -23,9 +23,17 @@
</option>
<envs />
<patterns />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Profile ">
<option name="myExternalizedOptions" value="&#10;additional-options2=onexit\=snapshot&#10;" />
</RunnerSettings>
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>
</component>
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2012 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 org.jetbrains.jet.plugin.formatter;
import com.intellij.formatting.Alignment;
import com.intellij.formatting.alignment.AlignmentStrategy;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
*
*
* @author Nikolay Krasko
*/
public abstract class ASTAlignmentStrategy {
private static final ASTAlignmentStrategy NULL_STRATEGY = fromTypes(AlignmentStrategy.wrap(null));
/** @return shared strategy instance that returns <code>null</code> all the time */
public static ASTAlignmentStrategy getNullStrategy() {
return NULL_STRATEGY;
}
public static ASTAlignmentStrategy fromTypes(AlignmentStrategy strategy) {
return new AlignmentStrategyWrapper(strategy);
}
@Nullable
public abstract Alignment getAlignment(ASTNode node);
public static class AlignmentStrategyWrapper extends ASTAlignmentStrategy {
private final AlignmentStrategy internalStrategy;
public AlignmentStrategyWrapper(@NotNull AlignmentStrategy internalStrategy) {
this.internalStrategy = internalStrategy;
}
@Nullable
@Override
public Alignment getAlignment(@NotNull ASTNode node) {
ASTNode parent = node.getTreeParent();
if (parent != null) {
return internalStrategy.getAlignment(parent.getElementType(), node.getElementType());
}
return internalStrategy.getAlignment(node.getElementType());
}
}
}
@@ -17,7 +17,6 @@
package org.jetbrains.jet.plugin.formatter;
import com.intellij.formatting.*;
import com.intellij.formatting.alignment.AlignmentStrategy;
import com.intellij.lang.ASTNode;
import com.intellij.psi.TokenType;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -152,6 +151,15 @@ public class JetBlock extends AbstractBlock {
else if (type == JetNodeTypes.DOT_QUALIFIED_EXPRESSION) {
return new ChildAttributes(Indent.getContinuationWithoutFirstIndent(), null);
}
else if (type == JetNodeTypes.VALUE_PARAMETER_LIST || type == JetNodeTypes.VALUE_ARGUMENT_LIST) {
// Child index 1 - cursor is after ( - parameter alignment should be recreated
// Child index 0 - before expression - know nothing about it
if (newChildIndex != 1 && newChildIndex != 0 && newChildIndex < getSubBlocks().size()) {
Block block = getSubBlocks().get(newChildIndex);
return new ChildAttributes(block.getIndent(), block.getAlignment());
}
return new ChildAttributes(Indent.getContinuationIndent(), null);
}
return new ChildAttributes(Indent.getNoneIndent(), null);
}
@@ -165,18 +173,18 @@ public class JetBlock extends AbstractBlock {
protected Map<ASTNode, Alignment> createChildrenAlignments() {
CommonCodeStyleSettings jetCommonSettings = mySettings.getCommonSettings(JetLanguage.INSTANCE);
// Prepare strategies for setting up alignments - no alignment should be set by default
AlignmentStrategy[] strategies = new AlignmentStrategy[] { AlignmentStrategy.getNullStrategy() };
// Prepare default null strategy
ASTAlignmentStrategy strategy = ASTAlignmentStrategy.getNullStrategy();
// Redefine list of strategies for some special elements
IElementType parentType = myNode.getElementType();
if (parentType == JetNodeTypes.VALUE_PARAMETER_LIST) {
strategies = getAlignmentForChildInParenthesis(
strategy = getAlignmentForChildInParenthesis(
jetCommonSettings.ALIGN_MULTILINE_PARAMETERS, JetNodeTypes.VALUE_PARAMETER, JetTokens.COMMA,
jetCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, JetTokens.LPAR, JetTokens.RPAR);
}
else if (parentType == JetNodeTypes.VALUE_ARGUMENT_LIST) {
strategies = getAlignmentForChildInParenthesis(
strategy = getAlignmentForChildInParenthesis(
jetCommonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, JetNodeTypes.VALUE_ARGUMENT, JetTokens.COMMA,
jetCommonSettings.ALIGN_MULTILINE_METHOD_BRACKETS, JetTokens.LPAR, JetTokens.RPAR);
}
@@ -193,32 +201,57 @@ public class JetBlock extends AbstractBlock {
continue;
}
for (AlignmentStrategy strategy : strategies) {
Alignment childAlignment = strategy.getAlignment(parentType, child.getElementType());
if (childAlignment != null) {
result.put(child, childAlignment);
break;
}
Alignment childAlignment = strategy.getAlignment(child);
if (childAlignment != null) {
result.put(child, childAlignment);
}
}
return result;
}
private static AlignmentStrategy[] getAlignmentForChildInParenthesis(
boolean shouldAlignChild, IElementType parameter, IElementType delimiter,
boolean shouldAlignParenthesis, IElementType openParenth, IElementType closeParenth
private static ASTAlignmentStrategy getAlignmentForChildInParenthesis(
boolean shouldAlignChild, final IElementType parameter, final IElementType delimiter,
boolean shouldAlignParenthesis, final IElementType openParenth, final IElementType closeParenth
) {
return new AlignmentStrategy[] {
AlignmentStrategy.wrap(shouldAlignChild ? Alignment.createAlignment() : null, false, parameter),
AlignmentStrategy.wrap(shouldAlignChild ? Alignment.createAlignment() : null, false, delimiter),
AlignmentStrategy.wrap(shouldAlignParenthesis ? Alignment.createAlignment() : null, false, openParenth, closeParenth)
// TODO: Check this approach in other situations and refactor
final Alignment parameterAlignment = shouldAlignChild ? Alignment.createAlignment() : null;
final Alignment parenthesisAlignment = shouldAlignParenthesis ? Alignment.createAlignment() : null;
return new ASTAlignmentStrategy() {
@Override
public Alignment getAlignment(ASTNode node) {
IElementType childNodeType = node.getElementType();
ASTNode prev = getPrevWithoutWhitespace(node);
if ((prev != null && prev.getElementType() == TokenType.ERROR_ELEMENT) || childNodeType == TokenType.ERROR_ELEMENT) {
return parameterAlignment;
}
if (childNodeType == openParenth || childNodeType == closeParenth) {
return parenthesisAlignment;
}
if (childNodeType == parameter || childNodeType == delimiter) {
return parameterAlignment;
}
return null;
}
};
}
@Override
protected Indent getChildIndent() {
return super.getChildIndent(); //To change body of overridden methods use File | Settings | File Templates.
}
@Nullable
protected Indent createChildIndent(@NotNull ASTNode child) {
CommonCodeStyleSettings commonSettings = mySettings.getCommonSettings(JetLanguage.INSTANCE);
ASTNode childParent = child.getTreeParent();
IElementType childType = child.getElementType();
if (CODE_BLOCKS.contains(myNode.getElementType())) {
return indentIfNotBrace(child);
@@ -226,13 +259,13 @@ public class JetBlock extends AbstractBlock {
if (childParent != null &&
childParent.getElementType() == JetNodeTypes.BODY &&
child.getElementType() != JetNodeTypes.BLOCK) {
childType != JetNodeTypes.BLOCK) {
// For a single statement if 'for'
return Indent.getNormalIndent();
}
if (child.getElementType() == JetNodeTypes.WHEN_ENTRY) {
if (childType == JetNodeTypes.WHEN_ENTRY) {
// For the entry in when
// TODO: Add an option for configuration?
return Indent.getNormalIndent();
@@ -245,7 +278,7 @@ public class JetBlock extends AbstractBlock {
}
}
if (STATEMENT_PARTS.contains(myNode.getElementType()) && child.getElementType() != JetNodeTypes.BLOCK) {
if (STATEMENT_PARTS.contains(myNode.getElementType()) && childType != JetNodeTypes.BLOCK) {
return Indent.getNormalIndent();
}
@@ -255,16 +288,21 @@ public class JetBlock extends AbstractBlock {
}
}
if (childParent != null &&
(childParent.getElementType() == JetNodeTypes.VALUE_PARAMETER_LIST ||
childParent.getElementType() == JetNodeTypes.TYPE_PARAMETER_LIST ||
childParent.getElementType() == JetNodeTypes.VALUE_ARGUMENT_LIST ||
childParent.getElementType() == JetNodeTypes.TYPE_ARGUMENT_LIST)) {
if (child.getElementType() == JetTokens.RPAR) {
return Indent.getNoneIndent();
if (childParent != null) {
IElementType parentType = childParent.getElementType();
if (parentType == JetNodeTypes.VALUE_PARAMETER_LIST || parentType == JetNodeTypes.VALUE_ARGUMENT_LIST) {
ASTNode prev = getPrevWithoutWhitespace(child);
if (childType == JetTokens.RPAR && (prev == null || prev.getElementType() != TokenType.ERROR_ELEMENT)) {
return Indent.getNoneIndent();
}
return Indent.getContinuationWithoutFirstIndent();
}
return Indent.getContinuationWithoutFirstIndent(false);
if (parentType == JetNodeTypes.TYPE_PARAMETER_LIST || parentType == JetNodeTypes.TYPE_ARGUMENT_LIST) {
return Indent.getContinuationWithoutFirstIndent();
}
}
return Indent.getNoneIndent();
@@ -47,8 +47,7 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti
" return 0\n" +
" }\n" +
" private fun foo2():Int {\n" +
" return foo1(\n" +
" 12,\n" +
" return foo1(12,\n" +
" 13,\n" +
" 14\n" +
" )\n" +
@@ -1,3 +0,0 @@
fun testParam(
<caret>) {
}
@@ -1,3 +1,2 @@
fun testParam(
<caret>) {
fun testParam(<caret>) {
}
@@ -0,0 +1,4 @@
fun testParam(
<caret>
) {
}
@@ -1,3 +1,3 @@
fun testParam(a : String, b : Int,
<caret>) {
<caret>) {
}
@@ -0,0 +1,5 @@
fun test() {
testVeryLong(12,<caret>)
}
// SET_TRUE: ALIGN_MULTILINE_PARAMETERS_IN_CALLS
@@ -0,0 +1,6 @@
fun test() {
testVeryLong(12,
<caret>)
}
// SET_TRUE: ALIGN_MULTILINE_PARAMETERS_IN_CALLS
@@ -0,0 +1,6 @@
fun test() {
testVeryLong(12,
<caret>)
}
// SET_TRUE: ALIGN_MULTILINE_PARAMETERS_IN_CALLS
@@ -161,7 +161,7 @@ public abstract class AbstractJetFormatterTest extends LightIdeaTestCase {
return doc.getText();
}
public static String loadFile(String name) throws Exception {
protected static String loadFile(String name) throws Exception {
String text = FileUtil.loadFile(new File(BASE_PATH, name));
text = StringUtil.convertLineSeparators(text);
return text;
@@ -16,8 +16,12 @@
package org.jetbrains.jet.formatter;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.testFramework.LightCodeInsightTestCase;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings;
import java.io.File;
@@ -38,8 +42,7 @@ public class JetTypingIndentationTest extends LightCodeInsightTestCase {
doFileNewlineTest();
}
// TODO
public void enabletestEmptyParameters() {
public void testEmptyParameters() {
doFileNewlineTest();
}
@@ -56,19 +59,59 @@ public class JetTypingIndentationTest extends LightCodeInsightTestCase {
doFileNewlineTest();
}
// TODO
public void enabletestNotFirstParameter() {
public void testNotFirstParameter() {
doFileNewlineTest();
}
public void testSettingAlignMultilineParametersInCalls() throws Exception {
doFileSettingNewLineTest();
}
public void testWhile() {
doFileNewlineTest();
}
public void doFileNewlineTest() {
configureByFile(getTestName(false) + ".kt");
doNewlineTest(getBeforeFileName(), getAfterFileName());
}
public String getBeforeFileName() {
return getTestName(false) + ".kt";
}
public String getAfterFileName() {
return getTestName(false) + "_after.kt";
}
public String getInvertedAfterFileName() {
return getTestName(false) + "_after_inv.kt";
}
public void doFileSettingNewLineTest() throws Exception {
String originalFileText = FileUtil.loadFile(new File(getTestDataPath(), getBeforeFileName()));
FormattingSettingsConfigurator configurator = new FormattingSettingsConfigurator(originalFileText);
configurator.configureSettings(getSettings());
doNewlineTest(getBeforeFileName(), getAfterFileName());
configurator.configureInvertedSettings(getSettings());
doNewlineTest(getBeforeFileName(), getInvertedAfterFileName());
getSettings().clearCodeStyleSettings();
}
private void doNewlineTest(String beforeFileName, String afterFileName) {
configureByFile(beforeFileName);
type('\n');
checkResultByFile(getTestName(false) + ".after.kt");
checkResultByFile(afterFileName);
}
public static JetCodeStyleSettings getJetSettings() {
return getSettings().getCustomSettings(JetCodeStyleSettings.class);
}
public static CodeStyleSettings getSettings() {
return CodeStyleSettingsManager.getSettings(getProject());
}
@Override