| /* |
| * Copyright 2000-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 com.intellij.psi.formatter.java; |
| |
| import com.intellij.openapi.fileTypes.StdFileTypes; |
| import com.intellij.psi.codeStyle.CommonCodeStyleSettings; |
| import com.intellij.util.IncorrectOperationException; |
| |
| /** |
| * Is intended to hold java formatting indentation-specific tests. |
| * |
| * @author Denis Zhdanov |
| * @since Apr 27, 2010 6:29:25 PM |
| */ |
| public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest { |
| |
| public void testClassInitializationBlockIndentation() throws Exception { |
| // Checking that initialization block body is correctly indented. |
| doMethodTest( |
| "checking(new Expectations() {{\n" + |
| "one(tabConfiguration).addFilter(with(equal(PROPERTY)), with(aListContaining(\"a-c\")));\n" + |
| "}});", |
| "checking(new Expectations() {{\n" + |
| " one(tabConfiguration).addFilter(with(equal(PROPERTY)), with(aListContaining(\"a-c\")));\n" + |
| "}});" |
| ); |
| |
| // Checking that closing curly brace of initialization block that is not the first block on a line is correctly indented. |
| doTextTest("class Class {\n" + " private Type field; {\n" + " }\n" + "}", |
| "class Class {\n" + " private Type field;\n\n {\n" + " }\n" + "}"); |
| doTextTest( |
| "class T {\n" + |
| " private final DecimalFormat fmt = new DecimalFormat(); {\n" + |
| " fmt.setGroupingUsed(false);\n" + |
| " fmt.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));\n" + |
| " }\n" + |
| "}", |
| "class T {\n" + |
| " private final DecimalFormat fmt = new DecimalFormat();\n\n {\n" + |
| " fmt.setGroupingUsed(false);\n" + |
| " fmt.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));\n" + |
| " }\n" + |
| "}" |
| ); |
| } |
| |
| public void testNestedMethodsIndentation() throws Exception { |
| // Inspired by IDEA-43962 |
| |
| getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 4; |
| |
| doMethodTest( |
| "BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| ".add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE)))))))));", |
| "BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE\n" + |
| " .add(BigDecimal.ONE)))))))));" |
| ); |
| } |
| |
| public void testShiftedChainedIfElse() throws Exception { |
| getSettings().BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED2; |
| getSettings().ELSE_ON_NEW_LINE = true; |
| getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).INDENT_SIZE = 4; |
| doMethodTest( |
| "long a = System.currentTimeMillis();\n" + |
| " if (a == 0){\n" + |
| " }else if (a > 1){\n" + |
| " }else if (a > 2){\n" + |
| " }else if (a > 3){\n" + |
| " }else if (a > 4){\n" + |
| " }else if (a > 5){\n" + |
| " }else{\n" + |
| " }", |
| "long a = System.currentTimeMillis();\n" + |
| "if (a == 0)\n" + |
| " {\n" + |
| " }\n" + |
| "else if (a > 1)\n" + |
| " {\n" + |
| " }\n" + |
| "else if (a > 2)\n" + |
| " {\n" + |
| " }\n" + |
| "else if (a > 3)\n" + |
| " {\n" + |
| " }\n" + |
| "else if (a > 4)\n" + |
| " {\n" + |
| " }\n" + |
| "else if (a > 5)\n" + |
| " {\n" + |
| " }\n" + |
| "else\n" + |
| " {\n" + |
| " }" |
| ); |
| } |
| |
| public void testAlignedSubBlockIndentation() { |
| getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; |
| getSettings().getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 8; |
| |
| // Inspired by IDEA-54671 |
| doTextTest( |
| "class Test {\n" + |
| " public void foo() {\n" + |
| " test(11\n" + |
| " + 12\n" + |
| " + 13,\n" + |
| " 21\n" + |
| " + 22\n" + |
| " + 23\n" + |
| " )" + |
| " }\n" + |
| "}", |
| |
| "class Test {\n" + |
| " public void foo() {\n" + |
| " test(11\n" + |
| " + 12\n" + |
| " + 13,\n" + |
| " 21\n" + |
| " + 22\n" + |
| " + 23\n" + |
| " )\n" + |
| " }\n" + |
| "}" |
| ); |
| } |
| |
| public void testEnumIndentation() throws IncorrectOperationException { |
| // Inspired by IDEADEV-2840 |
| doTextTest("enum Xyz {\n" + "FOO,\n" + "BAR,\n" + "}", "enum Xyz {\n" + " FOO,\n" + " BAR,\n" + "}"); |
| } |
| |
| public void testFirstColumnComment() throws IncorrectOperationException { |
| // Inspired by IDEADEV-14116 |
| getSettings().KEEP_FIRST_COLUMN_COMMENT = false; |
| |
| doTextTest("class Foo{\n" + "private int foo; // this is a foo\n" + "}", |
| "class Foo {\n" + " private int foo; // this is a foo\n" + "}"); |
| } |
| |
| public void testCaseFromSwitch() throws IncorrectOperationException { |
| // Inspired by IDEADEV-22920 |
| getSettings().INDENT_CASE_FROM_SWITCH = false; |
| doTextTest( |
| "class Foo{\n" + |
| "void foo () {\n" + |
| "switch(someValue) {\n" + |
| " // This comment is correctly not-indented\n" + |
| " case 1:\n" + |
| " doSomething();\n" + |
| " break;\n" + |
| "\n" + |
| " // This comment should not be indented, but it is\n" + |
| " case 2:\n" + |
| " doSomethingElse();\n" + |
| " break;\n" + |
| "}\n" + |
| "}\n" + |
| "}", |
| |
| "class Foo {\n" + |
| " void foo() {\n" + |
| " switch (someValue) {\n" + |
| " // This comment is correctly not-indented\n" + |
| " case 1:\n" + |
| " doSomething();\n" + |
| " break;\n" + |
| "\n" + |
| " // This comment should not be indented, but it is\n" + |
| " case 2:\n" + |
| " doSomethingElse();\n" + |
| " break;\n" + |
| " }\n" + |
| " }\n" + |
| "}"); |
| } |
| |
| public void testBinaryExpressionsWithRelativeIndents() { |
| // Inspired by IDEA-21795 |
| getIndentOptions().USE_RELATIVE_INDENTS = true; |
| getIndentOptions().CONTINUATION_INDENT_SIZE = 4; |
| |
| doTextTest( |
| "public class FormattingTest {\n" + |
| "\n" + |
| " public boolean test1(int a, int b, int c, int d) {\n" + |
| " return a == 1 &&\n" + |
| " b == 2;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" + |
| " return a == 0 &&\n" + |
| " (b == 0 ||\n" + |
| " c == 0) &&\n" + |
| " d == 0;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" + |
| " return a == 0\n" + |
| " && (b == 0\n" + |
| " || c == 0)\n" + |
| " && d == 0;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" + |
| " return a == 0\n" + |
| " && (b == 0\n" + |
| " || c == 0)\n" + |
| " && d == 0;\n" + |
| " }\n" + |
| "}", |
| |
| "public class FormattingTest {\n" + |
| "\n" + |
| " public boolean test1(int a, int b, int c, int d) {\n" + |
| " return a == 1 &&\n" + |
| " b == 2;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean multilineSignOnCurrent(int a, int b, int c, int d) {\n" + |
| " return a == 0 &&\n" + |
| " (b == 0 ||\n" + |
| " c == 0) &&\n" + |
| " d == 0;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean multilineSignOnNext(int a, int b, int c, int d) {\n" + |
| " return a == 0\n" + |
| " && (b == 0\n" + |
| " || c == 0)\n" + |
| " && d == 0;\n" + |
| " }\n" + |
| "\n" + |
| " public boolean expectedMultilineSignOnNext(int a, int b, int c, int d) {\n" + |
| " return a == 0\n" + |
| " && (b == 0\n" + |
| " || c == 0)\n" + |
| " && d == 0;\n" + |
| " }\n" + |
| "}" |
| ); |
| } |
| |
| public void testBracesShiftedOnNextLineOnMethodWithJavadoc() throws Exception { |
| // Inspired by IDEA-62997 |
| getSettings().METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE_SHIFTED; |
| |
| String precededByJavadoc = |
| "/**\n" + |
| " * test\n" + |
| " */\n" + |
| "public int getFoo()\n" + |
| " {\n" + |
| " return foo;\n" + |
| " }"; |
| |
| String precededBySingleLineComment = |
| "// test\n" + |
| "public int getFoo()\n" + |
| " {\n" + |
| " return foo;\n" + |
| " }"; |
| |
| String precededByMultiLineComment = |
| "/*\n" + |
| "test\n" + |
| "*/\n" + |
| "public int getFoo()\n" + |
| " {\n" + |
| " return foo;\n" + |
| " }"; |
| |
| doClassTest(precededByJavadoc, precededByJavadoc); |
| doClassTest(precededBySingleLineComment, precededBySingleLineComment); |
| doClassTest(precededByMultiLineComment, precededByMultiLineComment); |
| } |
| |
| public void testAnonymousClassInstancesAsMethodCallArguments() throws Exception { |
| // Inspired by IDEA-65987 |
| |
| doMethodTest( |
| "foo(\"long string as the first argument\", new Runnable() {\n" + |
| "public void run() { \n" + |
| "} \n" + |
| "}, \n" + |
| "new Runnable() { \n" + |
| "public void run() { \n" + |
| "} \n" + |
| "} \n" + |
| "); ", |
| "foo(\"long string as the first argument\", new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " },\n" + |
| " new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " }\n" + |
| ");" |
| ); |
| |
| doMethodTest( |
| "foo(1,\n" + |
| "2, new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "});", |
| "foo(1,\n" + |
| " 2, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " });" |
| ); |
| |
| doMethodTest( |
| "foo(new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "},\n" + |
| "new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "});", |
| "foo(new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " },\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " });" |
| ); |
| } |
| |
| public void testAnonymousClassInstancesAsAlignedMethodCallArguments() throws Exception { |
| getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; |
| |
| doMethodTest( |
| "foo(new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "},\n" + |
| "new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "});", |
| "foo(new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " },\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " });" |
| ); |
| |
| doMethodTest( |
| "foo(123456789, new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "},\n" + |
| "new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}\n" + |
| "});", |
| "foo(123456789, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " },\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " });" |
| ); |
| |
| doMethodTest( |
| "foo(new Runnable() {\n" + |
| "@Override\n" + |
| "public void run() {\n" + |
| "}" + |
| "}, 1, 2);", |
| "foo(new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " }\n" + |
| "}, 1, 2);" |
| ); |
| } |
| |
| public void testAnonymousClassesOnSameLineAtMethodCallExpression() throws Exception { |
| doMethodTest( |
| "foo(new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " }, new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " });", |
| "foo(new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| "}, new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| "});" |
| ); |
| } |
| |
| public void testAlignMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception { |
| String text = "test(new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"AAA!\");\n" + |
| " }\n" + |
| "}, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"BBB!\");\n" + |
| " }\n" + |
| "});\n"; |
| doMethodTest(text, text); |
| } |
| |
| public void testAlignmentAdditionalParamsWithMultipleAnonymousClasses_PassedAsMethodParameters() throws Exception { |
| String text = "foo(1221, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"A\");\n" + |
| " }\n" + |
| "}, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"BB\");\n" + |
| " }\n" + |
| "});"; |
| doMethodTest(text, text); |
| } |
| |
| public void testAlignmentMultipleParamsWithAnonymousClass_PassedAsMethodParams() throws Exception { |
| getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; |
| String text = "test(1000,\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"BBB\");\n" + |
| " }\n" + |
| " }\n" + |
| ");"; |
| doMethodTest(text, text); |
| } |
| |
| public void testAlignmentMultipleAnonymousClassesOnNewLines() throws Exception { |
| getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; |
| String text = "test(1000,\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"BBB\");\n" + |
| " }\n" + |
| " },\n" + |
| " new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| " System.out.println(\"BBB\");\n" + |
| " }\n" + |
| " }\n" + |
| ");"; |
| doMethodTest(text, text); |
| } |
| |
| public void testEnforceChildrenIndent_OfAnonymousClasses_IfAnyOfParamsIsLocatedOnNewLine() throws Exception { |
| getSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; |
| String text = "test(\"Suuuuuuuuuuuuuuuuuper loooooooooooong string\",\n" + |
| " \"Next loooooooooooooooooooooong striiiiiiiiiiing\", new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| "\n" + |
| " }\n" + |
| " }, new Runnable() {\n" + |
| " @Override\n" + |
| " public void run() {\n" + |
| "\n" + |
| " }\n" + |
| " }\n" + |
| ");\n"; |
| doMethodTest(text, text); |
| } |
| |
| public void testPackagePrivateAnnotation() { |
| // Inspired by IDEA-67294 |
| |
| String text = |
| "@Retention(RUNTIME)\n" + |
| "@Target({FIELD, PARAMETER, METHOD})\n" + |
| "@interface MyAnnotation {\n" + |
| "\n" + |
| "}"; |
| doTextTest(text, text); |
| } |
| |
| public void testIncompleteMethodCall() throws Exception { |
| // Inspired by IDEA-79836. |
| |
| doMethodTest( |
| "test(new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " }, new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| " }, )", |
| "test(new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| "}, new Runnable() {\n" + |
| " public void run() {\n" + |
| " }\n" + |
| "}, )" |
| ); |
| } |
| |
| public void testCStyleCommentIsNotMoved() throws Exception { |
| // IDEA-87087 |
| doClassTest( |
| " /*\n" + |
| " this is a c-style comment\n" + |
| " */\n" + |
| " // This is a line comment", |
| " /*\n" + |
| " this is a c-style comment\n" + |
| " */\n" + |
| "// This is a line comment" |
| ); |
| } |
| |
| public void testMultilineCommentAtFileStart() { |
| // IDEA-90860 |
| String text = |
| "\n" + |
| "/*\n" + |
| " * comment\n" + |
| " */\n" + |
| "\n" + |
| "class Test {\n" + |
| "}"; |
| doTextTest(text, text); |
| } |
| |
| public void testMultilineCommentAndTabsIndent() { |
| // IDEA-91703 |
| String initial = |
| "\t/*\n" + |
| "\t\t* comment\n" + |
| "\t */\n" + |
| "class Test {\n" + |
| "}"; |
| |
| String expected = |
| "/*\n" + |
| "\t* comment\n" + |
| " */\n" + |
| "class Test {\n" + |
| "}"; |
| |
| getIndentOptions().USE_TAB_CHARACTER = true; |
| doTextTest(initial, expected); |
| } |
| |
| public void testLambdaIndentation() throws Exception { |
| String before = "Runnable r = () ->\n" + |
| "{\n" + |
| " System.out.println(\"olo\");\n" + |
| "};"; |
| doMethodTest(before, before); |
| } |
| |
| } |