### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java,v retrieving revision 1.102 diff -u -r1.102 DefaultCodeFormatterConstants.java --- formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java 22 Feb 2010 16:44:31 -0000 1.102 +++ formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java 23 Feb 2010 10:17:42 -0000 @@ -197,6 +197,17 @@ public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.alignment_for_expressions_in_array_initializer"; //$NON-NLS-1$ /** *
+ * FORMATTER / Option for alignment of method declaration
+ * - option id: "org.eclipse.jdt.core.formatter.alignment_for_method_declaration"
+ * - possible values: values returned by createAlignmentValue(boolean, int, int)
call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ *
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 3.6
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_method_declaration"; //$NON-NLS-1$
+ /**
+ * * FORMATTER / Option for alignment of multiple fields * - option id: "org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" * - possible values: values returned bycreateAlignmentValue(boolean, int, int)
call Index: formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java,v retrieving revision 1.228 diff -u -r1.228 CodeFormatterVisitor.java --- formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 22 Feb 2010 16:44:32 -0000 1.228 +++ formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java 23 Feb 2010 10:17:44 -0000 @@ -4126,84 +4126,109 @@ return false; } - /* - * Print comments to get proper line number - */ - this.scribe.printComment(); - int line = this.scribe.line; - - this.scribe.printModifiers(methodDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_MEMBER); - - if (this.scribe.line > line) { - // annotations introduced new line, but this is not a line wrapping - // see 158267 - line = this.scribe.line; - } - this.scribe.space(); - - TypeParameter[] typeParameters = methodDeclaration.typeParameters; - if (typeParameters != null) { - this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters); - if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) { - this.scribe.space(); - } - int length = typeParameters.length; - for (int i = 0; i < length - 1; i++) { - typeParameters[i].traverse(this, methodDeclaration.scope); - this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters); - if (this.preferences.insert_space_after_comma_in_type_parameters) { - this.scribe.space(); - } - } - typeParameters[length - 1].traverse(this, methodDeclaration.scope); - if (isClosingGenericToken()) { - this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters); - } - if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) { - this.scribe.space(); - } - } - /* - * Print the method return type + * Print comments to get proper line number */ - final TypeReference returnType = methodDeclaration.returnType; + this.scribe.printComment(); + int line = this.scribe.line; + + // Create alignment + Alignment methodDeclAlignment = this.scribe.createAlignment( + "methodDeclaration",//$NON-NLS-1$ + this.preferences.alignment_for_method_declaration, + Alignment.R_INNERMOST, + 3, + this.scribe.scanner.currentPosition); + this.scribe.enterAlignment(methodDeclAlignment); + boolean ok = false; final MethodScope methodDeclarationScope = methodDeclaration.scope; + do { + try { - if (returnType != null) { - returnType.traverse(this, methodDeclarationScope); - } - /* - * Print the method name - */ - this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); + this.scribe.printModifiers(methodDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_MEMBER); + int fragmentIndex = 0; + this.scribe.alignFragment(methodDeclAlignment, fragmentIndex); + + if (this.scribe.line > line) { + // annotations introduced new line, but this is not a line wrapping + // see 158267 + line = this.scribe.line; + } + this.scribe.space(); + + TypeParameter[] typeParameters = methodDeclaration.typeParameters; + if (typeParameters != null) { + this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters); + if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) { + this.scribe.space(); + } + int length = typeParameters.length; + for (int i = 0; i < length - 1; i++) { + typeParameters[i].traverse(this, methodDeclaration.scope); + this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters); + if (this.preferences.insert_space_after_comma_in_type_parameters) { + this.scribe.space(); + } + } + typeParameters[length - 1].traverse(this, methodDeclaration.scope); + if (isClosingGenericToken()) { + this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters); + } + if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) { + this.scribe.space(); + } + this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex); + } - formatMethodArguments( - methodDeclaration, - this.preferences.insert_space_before_opening_paren_in_method_declaration, - this.preferences.insert_space_between_empty_parens_in_method_declaration, - this.preferences.insert_space_before_closing_paren_in_method_declaration, - this.preferences.insert_space_after_opening_paren_in_method_declaration, - this.preferences.insert_space_before_comma_in_method_declaration_parameters, - this.preferences.insert_space_after_comma_in_method_declaration_parameters, - this.preferences.alignment_for_parameters_in_method_declaration); + /* + * Print the method return type + */ + final TypeReference returnType = methodDeclaration.returnType; + + if (returnType != null) { + returnType.traverse(this, methodDeclarationScope); + } + this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex); - /* - * Check for extra dimensions - */ - int extraDimensions = getDimensions(); - if (extraDimensions != 0) { - for (int i = 0; i < extraDimensions; i++) { - this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET); - this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET); - } - } + /* + * Print the method name + */ + this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); + + // Format arguments + formatMethodArguments( + methodDeclaration, + this.preferences.insert_space_before_opening_paren_in_method_declaration, + this.preferences.insert_space_between_empty_parens_in_method_declaration, + this.preferences.insert_space_before_closing_paren_in_method_declaration, + this.preferences.insert_space_after_opening_paren_in_method_declaration, + this.preferences.insert_space_before_comma_in_method_declaration_parameters, + this.preferences.insert_space_after_comma_in_method_declaration_parameters, + this.preferences.alignment_for_parameters_in_method_declaration); + + /* + * Check for extra dimensions + */ + int extraDimensions = getDimensions(); + if (extraDimensions != 0) { + for (int i = 0; i < extraDimensions; i++) { + this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET); + this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET); + } + } - formatThrowsClause( - methodDeclaration, - this.preferences.insert_space_before_comma_in_method_declaration_throws, - this.preferences.insert_space_after_comma_in_method_declaration_throws, - this.preferences.alignment_for_throws_clause_in_method_declaration); + // Format throws + formatThrowsClause( + methodDeclaration, + this.preferences.insert_space_before_comma_in_method_declaration_throws, + this.preferences.insert_space_after_comma_in_method_declaration_throws, + this.preferences.alignment_for_throws_clause_in_method_declaration); + ok = true; + } catch (AlignmentException e) { + this.scribe.redoAlignment(e); + } + } while (!ok); + this.scribe.exitAlignment(methodDeclAlignment, true); if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract() && ((methodDeclaration.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0)) { /* @@ -4249,6 +4274,7 @@ } return false; } + public boolean visit(NormalAnnotation annotation, BlockScope scope) { this.scribe.printNextToken(TerminalTokens.TokenNameAT); if (this.preferences.insert_space_after_at_in_annotation) { Index: formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java,v retrieving revision 1.98 diff -u -r1.98 DefaultCodeFormatterOptions.java --- formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java 22 Feb 2010 16:44:32 -0000 1.98 +++ formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java 23 Feb 2010 10:17:46 -0000 @@ -58,6 +58,7 @@ public int alignment_for_conditional_expression; public int alignment_for_enum_constants; public int alignment_for_expressions_in_array_initializer; + public int alignment_for_method_declaration; public int alignment_for_multiple_fields; public int alignment_for_parameters_in_constructor_declaration; public int alignment_for_parameters_in_method_declaration; @@ -348,6 +349,7 @@ options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION, getAlignment(this.alignment_for_conditional_expression)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS, getAlignment(this.alignment_for_enum_constants)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER, getAlignment(this.alignment_for_expressions_in_array_initializer)); + options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION, getAlignment(this.alignment_for_method_declaration)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS, getAlignment(this.alignment_for_multiple_fields)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION, getAlignment(this.alignment_for_parameters_in_constructor_declaration)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION, getAlignment(this.alignment_for_parameters_in_method_declaration)); @@ -732,6 +734,16 @@ this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT; } } + final Object alignmentForMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION); + if (alignmentForMethodDeclarationOption != null) { + try { + this.alignment_for_method_declaration = Integer.parseInt((String) alignmentForMethodDeclarationOption); + } catch (NumberFormatException e) { + this.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT; + } catch(ClassCastException e) { + this.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT; + } + } final Object alignmentForMultipleFieldsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS); if (alignmentForMultipleFieldsOption != null) { try { #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java,v retrieving revision 1.21 diff -u -r1.21 FormatterBugsTests.java --- src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 22 Feb 2010 16:44:26 -0000 1.21 +++ src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java 23 Feb 2010 10:17:49 -0000 @@ -977,6 +977,252 @@ } /** + * @bug 284789: [formatter] Does not line-break method declaration exception with parameters + * @test Verify that the new preference to split method declaration works properly + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=284789" + */ +public void testBug284789() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT; + String source = + "public class Test {\n" + + "public synchronized List> getMeTheFantasticContainer() {\n" + + " return null;\n" + + "}\n" + + "}\n"; + formatSource(source, + "public class Test {\n" + + " public synchronized\n" + + " List >\n" + + " getMeTheFantasticContainer() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01a() throws JavaModelException { + // default is no wrapping for method declaration + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01b() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT; + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized java.lang.String\n" + + " a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01c() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_COMPACT_FIRST_BREAK_SPLIT; + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized\n" + + " java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01d() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_ONE_PER_LINE_SPLIT; + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized\n" + + " java.lang.String\n" + + " a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01e() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_NEXT_SHIFTED_SPLIT; + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized\n" + + " java.lang.String\n" + + " a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_01f() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_NEXT_PER_LINE_SPLIT; + String source = + "class X01 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X01 {\n" + + " public final synchronized java.lang.String\n" + + " a_method_which_have_a_very_long_name() {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02a() throws JavaModelException { + // default is no wrapping for method declaration + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(\n" + + " String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02b() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT; + this.formatterPrefs.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT; + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized java.lang.String\n" + + " a_method_which_have_a_very_long_name(String first, String second,\n" + + " String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02c() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_COMPACT_FIRST_BREAK_SPLIT; + this.formatterPrefs.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_FIRST_BREAK_SPLIT; + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized\n" + + " java.lang.String a_method_which_have_a_very_long_name(\n" + + " String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02d() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_ONE_PER_LINE_SPLIT; + this.formatterPrefs.alignment_for_parameters_in_method_declaration = Alignment.M_ONE_PER_LINE_SPLIT; + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized\n" + + " java.lang.String\n" + + " a_method_which_have_a_very_long_name(\n" + + " String first,\n" + + " String second,\n" + + " String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02e() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_NEXT_SHIFTED_SPLIT; + this.formatterPrefs.alignment_for_parameters_in_method_declaration = Alignment.M_NEXT_SHIFTED_SPLIT; + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized\n" + + " java.lang.String\n" + + " a_method_which_have_a_very_long_name(\n" + + " String first,\n" + + " String second,\n" + + " String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} +public void testBug284789_02f() throws JavaModelException { + this.formatterPrefs.alignment_for_method_declaration = Alignment.M_NEXT_PER_LINE_SPLIT; + this.formatterPrefs.alignment_for_parameters_in_method_declaration = Alignment.M_NEXT_PER_LINE_SPLIT; + String source = + "class X02 {\n" + + " public final synchronized java.lang.String a_method_which_have_a_very_long_name(String first, String second, String third) {\n" + + " return null;\n" + + " }\n" + + "}\n"; + formatSource(source, + "class X02 {\n" + + " public final synchronized java.lang.String\n" + + " a_method_which_have_a_very_long_name(String first,\n" + + " String second,\n" + + " String third) {\n" + + " return null;\n" + + " }\n" + + "}\n" + ); +} + +/** * @bug 285565: [formatter] wrong indentation with 'Never join lines' selected * @test Test to make sure that use either formatter or {@link IndentManipulation} * API methods an indentation set to zero does not thrown any exception.