This document describes the changes in the Java formatter engine of Jalopy 1.4 that may have an impact on formatting style (depending on your code convention).
The "Wrap on-demand after left parenthesis" option did not work for method declarations parameter lists when Endline indentation was enabled.
Pleaes note that you can enforce the former behavior with the new "Avoid bare left parenthesis" option!
public void foo(String theVeryFirstParameter, | String para2, | com.foo.MyObject param3, | Object param4, | FooBar anotherOne) { | } |
was wrongly printed as
public void foo(String theVeryFirstParameter, | String para2, | com.foo.MyObject param3, | Object param4, | FooBar anotherOne) { | } |
Now it does (depending on your settings)
public void foo( | String theVeryFirstParameter, | String para2, | com.foo.MyObject param3, | Object param4, | FooBar anotherOne) { | } |
With the three wrapping options "Prefer wrap after assignments", "Prefer wrap after return" and "Prefer wrap after left parenthesis" disabled, creator calls after either assignments or return statements or used as method arguments lead to wrong wrapping. In some cases a line break was inserted before creators even when the maximal line length was not exceeded.
return new CDRInputStream_1_2(); | | throw wrapper.invalidRequestPartitioningComponentValue(new Integer( | thePartitionToUse)); |
was wrongly printed as
return | new CDRInputStream_1_2(); | | throw wrapper.invalidRequestPartitioningComponentValue( | new Integer(thePartitionToUse)) |
Now it does (depending on your settings)
return new CDRInputStream_1_2(); | | throw wrapper.invalidRequestPartitioningComponentValue(new Integer( | thePartitionToUse)); |
Array initializers as part of an array creation expression, could exceed the maximal line length.
Object[] rArgs = new Object[] { | rParent, new Integer(nDefaultStyle) | }; |
was wrongly printed as
| Object[] rArgs = new Object[] { rParent, new Integer(nDefaultStyle) }; |
Now it does (depending on your settings)
Object[] rArgs = new Object[] { | rParent, new Integer(nDefaultStyle) | }; |
With "Keep line breaks for operators" enabled, line breaks for operators where not kept when the operand contained a dotted expression.
pm.LogDebug("TimeSeries response from " + | ddAddr + | " ID: " + | pi.pi.IcmpID + | "; Sequence: " + | pi.IcmpSeq); |
was wrongly formatted as
pm.LogDebug("TimeSeries response from " + | ddAddr + " ID: " + pi.pi.IcmpID +| "; Sequence: " + pi.IcmpSeq); |
Now it will be printed (depending on your settings)
pm.LogDebug("TimeSeries response from " + | ddAddr + | " ID: " + | pi.pi.IcmpID + | "; Sequence: " + | pi.IcmpSeq); |
With endline indentation enabled, blank lines between elements of multi-array initializers were not correctly printed.
public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, };
was wrongly formatted as
public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX ···· // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX ···· { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, };
Now it will be printed (depending on your settings)
public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // XXX { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, // Action messages { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, }; public static Object[][] contents = { { "SYSTEMNAME_VARIABLE", "%SystemName%" }, { "USERMSG_NODUPLICATES", "Please enter a unique action name." }, };
Multi-array initializers were wrongly printed when only one element was given in the second dimension.
public static Object[][] contents = { { "", "" }, };
was wrongly printed as
public static Object[][] contents = { { "", "" }, };
Now it is printed (depending on your settings)
public static Object[][] contents = { { "", "" }, };
When "Keep blank lines up to" disabled, the blank lines settings for comments were ignored, which could lead to wrongly removed blank lines.
// // The rows vector contains the actual data // private Vector rows = StorageFactory.getVector(); // // The columns vector is just used for maintaining the column names // private Vector columns = StorageFactory.getVector(); // // The table header for this table // private SortingTableHeader sortingTableHeader = null;
was wrongly formatted as
// // The rows vector contains the actual data // private Vector rows = StorageFactory.getVector(); // // The columns vector is just used for maintaining the column names // private Vector columns = StorageFactory.getVector(); // // The table header for this table // private SortingTableHeader sortingTableHeader = null;
when the "Blank lines before single-line comments" option was set to '1'. Now it will be printed
// // The rows vector contains the actual data // private Vector rows = StorageFactory.getVector(); // // The columns vector is just used for maintaining the column names // private Vector columns = StorageFactory.getVector(); // // The table header for this table // private SortingTableHeader sortingTableHeader = null;
With endline indentation enabled, method declarations could become wrongly indented, when an array type assignment expression did not fit into the maximal line length.
private void hideUnavailableMonitors(Hashtable hash) { PreferenceMap[] preferenceMap = { new PreferenceMap(Preferences.MONITOR_PROFILE, MonitorTypeManager.PROFILE_MONITOR) }; } /* getAvailableMonitors * Get a list of available monitors. */ public Object getAvailableMonitors() { }
was wrongly formatted as
private void hideUnavailableMonitors(Hashtable hash) { PreferenceMap[] preferenceMap = { new PreferenceMap(Preferences.MONITOR_PROFILE, MonitorTypeManager.PROFILE_MONITOR) }; } /* getAvailableMonitors * Get a list of available monitors. */ public Object getAvailableMonitors(){ }
private void hideUnavailableMonitors(Hashtable hash) { PreferenceMap[] preferenceMap = { new PreferenceMap(Preferences.MONITOR_PROFILE, MonitorTypeManager.PROFILE_MONITOR) }; } /* getAvailableMonitors * Get a list of available monitors. */ public Object getAvailableMonitors() { }
With "Insert
logging conditional"
enabled, debug calls inside an if
statement did not have a
conditional added.
if (i == 5) { _test.debug("This won't be formatted!"); }
was wrongly formatted as
if (i == 5) { _test.debug("This won't be formatted!"); }
Now it will be printed (depending on your settings)
if (i == 5) { if (_test.isDebugEnabled()) { _test.debug("This won't be formatted!"); } }
Comments after switch statements were not correctly indented when "Indent case from switch" was disabled.
switch (buf.charAt(i)) { // if another line break follows, we insert the given asterix // directly before the next line break case 'x': ... }
was wrongly formatted as
switch (buf.charAt(i)) { // if another line break follows, we insert the given asterix // directly before the next line break case 'x': ... }
Now it will be printed (depending on your settings)
switch (buf.charAt(i)) { // if another line break follows, we insert the given asterix // directly before the next line break case 'x': ... }
Comments after case
and default
statements were not correctly indented when
"Indent
case from switch" was disabled.
switch (c) { ... default: // event type cannot be consumed }
was wrongly formatted as
switch (c) { ... default: // event type cannot be consumed }
Now it will be printed (depending on your settings)
switch (c) { ... default: // event type cannot be consumed }
With endline indentation enabled, comments after elements could be wrongly aligned.
public static Object[][] contents = { // // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X." // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X." { "CONNECT_CP_SERVICE", "X" }, // Previous Value: None // Current Value: ERR_NO_MONITORS - "No X monitor is found." { "ERR_NO_MONITORS", "X" }, // // Previous Value: ERR_MONITOR_DELETED - "no Mon ID)." // Current Value: ERR_MONITOR_DELETED - "(no Mon ID)." { "ERR_MONITOR_DELETED", "X" }, // // Previous Value: ERR_OBSOLETE_DATA - "This data is too old." // Current Value: ERR_OBSOLETE_DATA - "No new X data." { "ERR_OBSOLETE_DATA", "X" }, // // Previous Value: None // Current Value: ERR_NO_DATA - "No data available." { "ERR_NO_DATA", "X" }, };
was wrongly printed as
public static Object[][] contents = { // // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X." // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X." { "CONNECT_CP_SERVICE", "X" }, // Previous Value: None // Current Value: ERR_NO_MONITORS - "No X monitor is found." { "ERR_NO_MONITORS", "X" }, // // Previous Value: ERR_MONITOR_DELETED - "(no Mon ID)." // Current Value: ERR_MONITOR_DELETED - "(no Mon ID)." { "ERR_MONITOR_DELETED", "X" }, // // Previous Value: ERR_OBSOLETE_DATA - "This data is too old." // Current Value: ERR_OBSOLETE_DATA - "No new X data." { "ERR_OBSOLETE_DATA", "X" }, // // Previous Value: None // Current Value: ERR_NO_DATA - "No data available." { "ERR_NO_DATA", "X" }, };
Now it does (depending on your settings)
public static Object[][] contents = { // // Previous Value: CONNECT_CP_SERVICE - "Trying to connect to X." // Current Value: CONNECT_CP_SERVICE - "Trying to connect to X." { "CONNECT_CP_SERVICE", "X" }, // Previous Value: None // Current Value: ERR_NO_MONITORS - "No X monitor is found." { "ERR_NO_MONITORS", "X" }, // // Previous Value: ERR_MONITOR_DELETED - "(no Mon ID)." // Current Value: ERR_MONITOR_DELETED - "(no Mon ID)." { "ERR_MONITOR_DELETED", "X" }, // // Previous Value: ERR_OBSOLETE_DATA - "This data is too old." // Current Value: ERR_OBSOLETE_DATA - "No new X data." { "ERR_OBSOLETE_DATA", "X" }, // // Previous Value: None // Current Value: ERR_NO_DATA - "No data available." { "ERR_NO_DATA", "X" }, };
With Javadoc formatting enabled, no line break was printed before the closing </li> tag of nested lists.
/** * <li>Verzeichnisse * <ul> * <li>Yahoo</li> * <li>Web.de</li> * <li>Dino-Online</li> * </ul> * </li> */
was formatted as
/** * <li>Verzeichnisse * <ul> * <li>Yahoo</li> * <li>Web.de</li> * <li>Dino-Online</li> * </ul></li> */
Now it will be printed as
/** * <li>Verzeichnisse * <ul> * <li>Yahoo</li> * <li>Web.de</li> * <li>Dino-Online</li> * </ul> * </li> */
With endline indentation enabled, closing parentheses were not correctly aligned with the corresponding left parentheses when a line break occured before the closing parenthesis.
myMethod( getSomeValue( param1 ), param2 );
was printed as
myMethod( getSomeValue( param1 ), param2 );
Now it will be printed (depending on your settings)
myMethod( getSomeValue( param1 ), param2 );
With "Align method declaration parameters" enabled, the parameters were wrongly aligned when a vararg was part of the list
public MethodDispatcher(Object rTarget, String sMethod, Class... rParamTypes) { }
was printed as
public MethodDispatcher(Object rTarget, String sMethod, Class... rParamTypes) { }
Now it will be printed (depending on your settings)
public MethodDispatcher(Object rTarget, String sMethod, Class... rParamTypes) { }
With Javadoc formatting enabled, a line break could be printed between the closing brace of an inline tag and a dot right after the brace.
/** | * <p>blahblahblahblahbahblahblah see {@link foof()}.</p> */ | void foo() { | } |
was wrongly formatted as
/** | * <p>blahblahblahblahbahblahblah see {@link foof()} | * .</p> | */ | void foo() { | } |
Now it will be printed (depending on your settings)
/** | * <p>blahblahblahblahbahblahblah see {@link | * foof()}.</p> | */ | void foo() { | } |
With either of the Reflow comment options enabled, one blank line above the specified blank line amount was printed after comments that got reflowed.
System.out.println("........"); // Strange end-line comment that | // spans several lines and islonger | // than the comment in the originaldd // example! | return; |
With "Blank lines before control statements" set to '0', was wrongly formatted as
System.out.println("........"); // Strange end-line comment that | // spans several lines and islonge | // than the comment in the | // originaldd example! | | return; |
Now it will be printed (depending on your settings)
System.out.println("........"); // Strange end-line comment that | // spans several lines and islonge | // than the comment in the | // originaldd example! | return; |
When no blank lines could be found between elements and comments, Jalopy always preferred to associate comments with the next element. Now it checks wether the column offsets of the preceding and following elements are different and if so adds the comment to the preceding element when their offsets match
switch (state) { default: stateError(); /* NOTREACHED */ case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): break; }
was wrongly formatted as
switch (state) { default: stateError(); /* NOTREACHED */ case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): break; }
Now it will be printed (depending on your settings)
switch (state) { default: stateError(); /* NOTREACHED */ case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): break; }
When the commetns blank lines settings specified any positive number of blank lines before comments, comments in front of expressions had the given number of blank lines inserted before the comment.
/* test */ System.out.println(); /* test */ System.out.println();
was formatted as
/* test */ System.out.println(); /* test */ System.out.println();
Now it will be printed (depending on your settings)
/* test */ System.out.println(); /* test */ System.out.println();
Prefix increment or decrement expressions that appeared right after blocks and contained comments before could lead to wrong number of blank lines between block and expression.
if (!sawDecimal) { } // If we have seen the decimal, but no significant digits yet, // then we account for leading zeros by decrementing the // digits.decimalAt into negative values. --digits.decimalAt;
was wrongly formatted as
if (!sawDecimal) { } // If we have seen the decimal, but no significant digits yet, // then we account for leading zeros by decrementing the // digits.decimalAt into negative values. --digits.decimalAt;
Now it will be printed (depending on your settings)
if (!sawDecimal) { } // If we have seen the decimal, but no significant digits yet, // then we account for leading zeros by decrementing the // digits.decimalAt into negative values. --digits.decimalAt;
Comments appearing before right parentheses were not correctly printed.
for (Enumeration enum = h.keys(); enum.hasMoreElements(); /* no increment portion */ ) { ... }
was wrongly formatted as
for (Enumeration enum = h.keys(); enum.hasMoreElements();/* no increment portion */ ) { ... }
Now it will be printed (depending on your settings)
for (Enumeration enum = h.keys(); enum.hasMoreElements(); /* no increment portion */ ) { }
Comments after the rhs of an operator enclosed with parentheses were wrongly printed after the right parenthesis.
private static final int RMASK = (1 << 1 /* U_RIGHT_TO_LEFT */) | (1 << 5 /* U_ARABIC_NUMBER */) | (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) | (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) | (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */);
was wrongly formatted as
private static final int RMASK = (1 << 1) /* U_RIGHT_TO_LEFT */ | (1 << 5) /* U_ARABIC_NUMBER */ | (1 << 13) /* U_RIGHT_TO_LEFT_ARABIC */ | (1 << 14) /* U_RIGHT_TO_LEFT_EMBEDDING */ | (1 << 15) /* U_RIGHT_TO_LEFT_OVERRIDE */;
Now it will be printed (depending on your settings)
private static final int RMASK = (1 << 1 /* U_RIGHT_TO_LEFT */) | (1 << 5 /* U_ARABIC_NUMBER */) | (1 << 13 /* U_RIGHT_TO_LEFT_ARABIC */) | (1 << 14 /* U_RIGHT_TO_LEFT_EMBEDDING */) | (1 << 15 /* U_RIGHT_TO_LEFT_OVERRIDE */);
With Javadoc formatting enabled, trailing white space after Javadoc inline tags was not removed.
/** | *~@return~~list~of~attached~annotations~(of~type~{@link~ | *~~~~~~~~~~com.foo.Annotation~<Annotation>}). | */ |
was wrongly formatted as
/** | *~@return~~list~of~attached~annotations~(of~type~{@link~ | *~~~~~~~~~~com.foo.Annotation~<Annotation>}). | */ |
Now it will be printed (depending on your settings)
/** | *~@return~~list~of~attached~annotations~(of~type~{@link | *~~~~~~~~~~com.foo.Annotation~<Annotation>}). | */ |
When wrapping for chained method calls were forced, a line break was always printed before the first chain link. Now a line break before the first chain link gets only printed when an identifier appears before the method or the method contains qualification.
foo().toString().test();
was formatted as
foo() .toString() .test();
Now it will be printed (depending on your settings)
foo().toString() .test();
With "Insert expression parentheses" disabled, expressions could be wrongly wrapped.
if (m.aMargins[0] == 0 && m.aMargins[1] == 0 && | m.aMargins[2] == 0) { | ... | } |
was wrongly formatted as
if (m.aMargins[0] == 0 && m.aMargins[1] == 0 && m | .aMargins[21] == 0) { | ... | } |
Now it will be printed (depending on your settings)
if (m.aMargins[0] == 0 && m.aMargins[1] == 0 && | m.aMargins[2] == 0) { | ... | } |
With "Insert expression
parentheses" enabled, no parentheses
was added for the instanceof
operator.
The following contrived (?) code
if (null != owner && owner instanceof org.w3c.dom.Node) { }
was wrongly formatted as
if ((null != owner) && owner instanceof org.w3c.dom.Node) { }
Now it will be printed (depending on your settings)
if ((null != owner) && (owner instanceof org.w3c.dom.Node)) { }