- Support Java 21 preview feature: string templates (JEP 430) (#640 by @jtkiesel)
- Avoid breaking on certain method chains and arguments (Issue #626 closed by #632 by @jtkiesel)
- Consistent break after equals (Issue #638 fixed by #641 by @jtkiesel)
- Properly break and indent lambda with comments (Issue #581 fixed by #604 by @jtkiesel)
- Do not fail on constructor and method receiver parameter (Issue #607 fixed by #642 by @jtkiesel)
- No break in single-block switch case (Issue #635 fixed by #636 by @jtkiesel)
- Non-block if/else statements are now kept on their own lines (Issue #631 fixed by #633 by @jtkiesel)
- Create documentation website (#628 by @jtkiesel) available at https://www.jhipster.tech/prettier-java
- Supports Java 21 preview feature: unnamed patterns and variables (JEP 443) (#620 by @jtkiesel)
- New entrypoint lexAndParse to return both tokens and CST (#625 by @max-schaefer)
- Supports Java 21 record pattern (#611 by @jtkiesel)
- Supports Java 21 preview feature: unnamed class compilation unit (JEP 445) (#615)
- Break long lines on type arguments (#584)
- Break and indent binary expression with cast properly (#587)
- Adjust indentation of multiline string (Issue #593 fixed with #596)
- Improves binary expression formatting (#594)
- Supports JLS annotation style (#586
Thanks to @jtkiesel for all of these contributions !
- Fix browser compatibility issue when run in browser (Issue #597 fixed with #598) Thanks to @magic-akari for the contribution
- Upgrade prettier version to Prettier v3
- Support for require-pragma option (Issue #573 closed with #574) Thanks to @yannick-paz for the contribution !
// Input
/**
* @prettier
*/
public class Example {
private int test = -1;
}
// Output with require-pragma option activated
/**
* @prettier
*/
public class Example {
private int test = -1;
}
// Input
public class Example {
private int test = -1;
}
// Output with require-pragma option activated
public class Example {
private int test = -1;
}
// Input
class Example {
void example() {
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
new Object().someMethod();
Object[] aParticularlyLongAndObnoxiousNameForIllustrativePurposes2 =
new Object[] { new Object(), new Object() };
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes3 =
SomeClass.someStaticMethod();
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
someMethod().anotherMethod();
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
anotherValue != null ? anotherValue : new Object();
}
}
// Output
class Example {
void example() {
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
new Object().someMethod();
Object[] aParticularlyLongAndObnoxiousNameForIllustrativePurposes2 =
new Object[] { new Object(), new Object() };
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes3 =
SomeClass.someStaticMethod();
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
someMethod().anotherMethod();
Object aParticularlyLongAndObnoxiousNameForIllustrativePurposes =
anotherValue != null ? anotherValue : new Object();
}
}
- Drop support of Node.js 12
// Input
class T {
void test(Buyer other) {
return switch (other) {
case null -> true;
case Buyer b && this.bestPrice > b.bestPrice -> true;
case Buyer b && this.bestPrice > b.bestPrice -> {
return true;
}
case (Buyer b && this.bestPrice > b.bestPrice) -> true;
case Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice -> true;
case Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice -> {
return true;
}
case (
Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice
) -> true;
case (
Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice
) -> {
return true;
}
default -> false;
};
}
}
// Output
class T {
void test(Buyer other) {
return switch (other) {
case null -> true;
case Buyer b && this.bestPrice > b.bestPrice -> true;
case Buyer b && this.bestPrice > b.bestPrice -> {
return true;
}
case (Buyer b && this.bestPrice > b.bestPrice) -> true;
case Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice -> true;
case Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice -> {
return true;
}
case (
Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice
) -> true;
case (
Buyer b &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice &&
this.bestPrice > b.bestPrice
) -> {
return true;
}
default -> false;
};
}
}
public class Test {
public static final String REGEX = "^\s$";
}
- Fix unwanted space in "exports"-statement in module-info.java (Issue #550 closed with #551) Thanks to @BjornJaspers for the fix
// Input
open module org.myorg.module {
requires some.required.module;
exports org.myorg.module.exportpackage1;
exports org.myorg.module.exportpackage2;
}
// Prettier 1.6.2
open module org.myorg.module {
requires some.required.module;
exports org.myorg.module.exportpackage1;
exports org.myorg.module.exportpackage2;
}
// Prettier 1.6.3
open module org.myorg.module {
requires some.required.module;
exports org.myorg.module.exportpackage1;
exports org.myorg.module.exportpackage2;
}
- Fix parsing of nested sealed and non-sealed classes & interfaces inside interfaces (Issue #533 closed with #538)
public interface Test {
sealed interface Inner {}
public abstract static sealed class SealedParent {}
non-sealed interface Inner {}
public abstract static non-sealed class SealedParent {}
static final class SealedChild extends SealedParent {}
}
// Input
public class Foo<T> {
public <U extends @NotNull T> void example(U u) {}
public <U extends com.java.Any.@NotNull T> void example(U u) {}
}
// Prettier 1.6.1
public class Foo<T> {
public <U extends @NotNullT> void example(U u) {}
public <U extends com.java.Any.@NotNullT> void example(U u) {}
}
// Prettier 1.6.2
public class Foo<T> {
public <U extends @NotNull T> void example(U u) {}
public <U extends com.java.Any.@NotNull T> void example(U u) {}
}
// Input
public class SealedClasses {
public abstract static sealed class SealedParent permits SealedChild {}
static final class SealedChild extends SealedParent {}
}
// Output
public class NestedSealedClasses {
public abstract static sealed class SealedParent permits SealedChild {}
static final class SealedChild extends SealedParent {}
}
- Improve formatting of records parameters with annotations
// Input
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description")
Status status,
@NotNull Integer number
) {}
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description")
// comment
Status status,
// another comment
@NotNull Integer number
) {}
// Prettier v1.5.0
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description")
Status status,
@NotNull Integer number
) {}
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description") // comment
Status status,
// another comment
@NotNull Integer number
) {}
// Prettier v1.6.0
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description")
Status status,
@NotNull Integer number
) {}
public record Record(
@JsonSerialize(
using = StatusSerializer.class,
nullsUsing = NullSerializer.class
)
@Schema(type = "integer", description = "Some fancy description")
// comment
Status status,
// another comment
@NotNull Integer number
) {}
- Fix casting with additional bounds
// Input
class Example {
void should_cast_with_single_element() {
var myElem = (int) othrElement;
var myElem = (A) othrElement;
var myElem = (A) (othrElement, value) -> othrElement + value;
var myElem = (Aaeaozeaonzeoazneaozenazonelkadndpndpazdpazdpazdpazdpazeazpeaazdpazdpazpdazdpa) othrElement;
}
void should_cast_with_additional_bounds() {
foo((A & B) obj);
foo((A & B & C) obj);
foo((Aaeaozeaonzeoazneaozenazone & Bazoieoainzeonaozenoazne & Cjneazeanezoanezoanzeoaneonazeono) obj);
foo((Aaeaozeaonzeoazneaozenazone & Bazoieoainzeonaozenoazne & Cjneazeanezoanezoanzeoaneonazeono) (othrElement, value) -> othrElement + value);
}
}
// Prettier v1.5.0
class Example {
void should_cast_with_single_element() {
var myElem = (int) othrElement;
var myElem = (A) othrElement;
var myElem = (A) (othrElement, value) -> othrElement + value;
var myElem = (Aaeaozeaonzeoazneaozenazonelkadndpndpazdpazdpazdpazdpazeazpeaazdpazdpazpdazdpa) othrElement;
}
void should_cast_with_additional_bounds() {
foo((A) & B obj);
foo((A) & B& C obj);
foo(
(Aaeaozeaonzeoazneaozenazone) & Bazoieoainzeonaozenoazne& Cjneazeanezoanezoanzeoaneonazeono obj
);
foo(
(Aaeaozeaonzeoazneaozenazone) & Bazoieoainzeonaozenoazne& Cjneazeanezoanezoanzeoaneonazeono (
othrElement,
value
) ->
othrElement + value
);
}
}
// Prettier v1.6.0
class Example {
void should_cast_with_single_element() {
var myElem = (int) othrElement;
var myElem = (A) othrElement;
var myElem = (A) (othrElement, value) -> othrElement + value;
var myElem = (Aaeaozeaonzeoazneaozenazonelkadndpndpazdpazdpazdpazdpazeazpeaazdpazdpazpdazdpa) othrElement;
}
void should_cast_with_additional_bounds() {
foo((A & B) obj);
foo((A & B & C) obj);
foo(
(
Aaeaozeaonzeoazneaozenazone
& Bazoieoainzeonaozenoazne
& Cjneazeanezoanezoanzeoaneonazeono
) obj
);
foo(
(
Aaeaozeaonzeoazneaozenazone
& Bazoieoainzeonaozenoazne
& Cjneazeanezoanezoanzeoaneonazeono
) (othrElement, value) -> othrElement + value
);
}
}
-
Split record parameters on several lines if they do not fit on a single line (#509)
// Input public record Person( String firstName, String lastName, String email, String phoneNumber, String streetAddress, String city, String state, String zipCode ) {} // Prettier 1.4.0 public record Person( String firstName, String lastName, String email, String phoneNumber, String streetAddress, String city, String state, String zipCode ) {} // Prettier 1.5.0 public record Person( String firstName, String lastName, String email, String phoneNumber, String streetAddress, String city, String state, String zipCode ) {}
-
Support pattern matching in switch statements preview feature (#511)
// Input class T { static String formatterPatternSwitch(Object o) { return switch (o) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); case TOTO -> String.format("TOTO %s", o); case null -> String.format("Null !"); case default -> String.format("Default !"); default -> o.toString(); }; } } // Output class T { static String formatterPatternSwitch(Object o) { return switch (o) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); case TOTO -> String.format("TOTO %s", o); case null -> String.format("Null !"); case default -> String.format("Default !"); default -> o.toString(); }; } }
-
Improve printing of class with long typeParameterList (#512)
// Input public class ComplexGenericClass< BEAN extends AbstractBean & BeanItemSelect<BEANTYPE>, BEANTYPE, CONFIG extends BeanConfig<BEAN, BEANTYPE, CONFIG> > {} // Prettier 1.4.0 public class ComplexGenericClass< BEAN extends AbstractBean & BeanItemSelect<BEANTYPE>, BEANTYPE, CONFIG extends BeanConfig<BEAN, BEANTYPE, CONFIG> > {} // Prettier 1.5.0 public class ComplexGenericClass< BEAN extends AbstractBean & BeanItemSelect<BEANTYPE>, BEANTYPE, CONFIG extends BeanConfig<BEAN, BEANTYPE, CONFIG> > {}
- Improve method invocation with lambda parameters (#497)
- Fix interface member detection to support inner records (From @rnorth: #492)
- Remove yarn-error.log file from releases
- Add a space after generic constructor type parameters (#485)
// Input
public <T> GenericConstructor(T genericParameter) {}
// Prettier 1.2.0
public <T>GenericConstructor(T genericParameter) {}
// Prettier 1.2.1
public <T> GenericConstructor(T genericParameter) {}
- Supports of instance of pattern matching (#476)
// Input
if (o instanceof Integer i || p instanceof Point || q instanceof Circle c || r instanceof Square) {
formatted = String.format("int %d", i);
} else if (o instanceof Long l) {
formatted = String.format("long %d", l);
} else if (o instanceof Double d) {
formatted = String.format("double %f", d);
} else if (o instanceof String s) {
formatted = String.format("String %s", s);
}
// Output
if (
o instanceof Integer i ||
p instanceof Point ||
q instanceof Circle c ||
r instanceof Square
) {
formatted = String.format("int %d", i);
} else if (o instanceof Long l) {
formatted = String.format("long %d", l);
} else if (o instanceof Double d) {
formatted = String.format("double %f", d);
} else if (o instanceof String s) {
formatted = String.format("String %s", s);
}
- Supports of sealed classes and interfaces (#478)
// Input
public sealed class Rectangle implements Shape permits Square {
private final double length;
private final double height;
public Rectangle(double length, double height) {
this.length = length;
this.height = height;
}
@Override
public double area() {
return length * height;
}
}
// Output
public sealed class Rectangle implements Shape permits Square {
private final double length;
private final double height;
public Rectangle(double length, double height) {
this.length = length;
this.height = height;
}
@Override
public double area() {
return length * height;
}
}
- Add copy/pastable Checkstyle configuration compatible with Prettier (#477)
- Fix parsing records inside class declarations and records with simplified constructors (#470)
- Update links to Chevrotain library (From @Austin-Scott: #472)
- Supports of Records (#460)
// Input
public record Pet(
@NotNull String name,
int age,
String... others,
Object @Nullable... errorMessageArgs
) {
public Pet {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Name cannot be blank");
}
}
public void test() {}
}
// Output
public record Pet(
@NotNull String name,
int age,
String... others,
Object @Nullable... errorMessageArgs
) {
public Pet {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("Name cannot be blank");
}
}
public void test() {}
}
- Keep space between annotation and type identifiers in unannClassType expressions (#455)
// Input
class T {
SomeClass.@Valid SomeInnerClass someInnerClass = someClass.getInteractions().get(0);
void process(
Map.@NonNull Entry<String, SkeletonConfiguration> entry,
@NonNull Map<String, Object> context
) {}
}
// Prettier 1.0.1
class T {
SomeClass.@ValidSomeInnerClass someInnerClass = someClass
.getInteractions()
.get(0);
void process(
Map.@NonNullEntry<String, SkeletonConfiguration> entry,
@NonNull Map<String, Object> context
) {}
}
// Prettier 1.0.2
class T {
SomeClass.@Valid SomeInnerClass someInnerClass = someClass
.getInteractions()
.get(0);
void process(
Map.@NonNull Entry<String, SkeletonConfiguration> entry,
@NonNull Map<String, Object> context
) {}
}
- Fix inconsistent indentation between chained method on method and new object (#456)
// Input
class T {
public void method() {
new Foo(stuff, thing, "auaaaaaaaaa some very long stuff", "some more")
.bar(10);
foo(stuff, thing, "some very longuuuuuuuuuuuuuu stuff", "some more")
.bar(10);
}
}
// Prettier 1.0.1
class T {
public void method() {
new Foo(stuff, thing, "auaaaaaaaaa some very long stuff", "some more")
.bar(10);
foo(stuff, thing, "some very longuuuuuuuuuuuuuu stuff", "some more")
.bar(10);
}
}
// Prettier 1.0.2
class T {
public void method() {
new Foo(stuff, thing, "auaaaaaaaaa some very long stuff", "some more")
.bar(10);
foo(stuff, thing, "some very longuuuuuuuuuuuuuu stuff", "some more")
.bar(10);
}
}
- Fix unstable formatting for method invocations with only comments (#457)
// Input
class T {
public void method() {
Arrays.asList( // a
// b
// c
// d
);
}
}
// Prettier 1.0.1
class T {
public void method() {
Arrays.asList( // b // a
// c
// d
);
}
}
// Prettier 1.0.2
class T {
public void method() {
Arrays.asList( // a
// b
// c
// d
);
}
}
- Update lodash dependency to 4.17.21 (#458)
- Correct spaces emplacement in multi-value switch expression case label (#440)
// Input
public class Test {
public void test(TestEnum testEnum) {
switch (testEnum) {
case FOO -> System.out.println("Foo!");
case BAR, BAZ -> System.out.println("Not Foo!");
}
}
}
// Prettier 1.0.0
public class Test {
public void test(TestEnum testEnum) {
switch (testEnum) {
case FOO -> System.out.println("Foo!");
case BAR, BAZ -> System.out.println("Not Foo!");
}
}
}
// Prettier 1.0.1
public class Test {
public void test(TestEnum testEnum) {
switch (testEnum) {
case FOO -> System.out.println("Foo!");
case BAR, BAZ -> System.out.println("Not Foo!");
}
}
}
- Update prettier dependency to 2.2.1
-
Support of Java 15 ! 🚀
-
Support of Text blocks
-
Support of new switch rules and yield statements
-
Improve throws rendering (From @jhaber: #384)
// Input
void throwException7(String string1, String string2, String string3, String string4) throws RuntimeException {
throw new RuntimeException();
}
// Prettier 0.8.3
void throwException7(
String string1,
String string2,
String string3,
String string4
)
throws RuntimeException {
throw new RuntimeException();
}
// Prettier 1.0.0
void throwException7(
String string1,
String string2,
String string3,
String string4
) throws RuntimeException {
throw new RuntimeException();
}
- Parsing of unannPrimitiveType in primary (#421)
- Update dependencies
-
Revert: Parsing of unannPrimitiveType in primary (#421). It was causing a breaking change in the java-parser
-
uses exact dependencies when releasing a new version of java-parser and prettier-plugin-java
- Generated a type definition for the Java parser (#422)
- Wrong indent in some chained methods invocation (#404)
// Input
class Indent {
void indetMethod() {
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
);
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo();
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo()
.anotherInvocation(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
);
myInstanceObject
.assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo();
}
}
// Output
class Indent {
void indetMethod() {
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
);
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo();
assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo()
.anotherInvocation(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa,
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
);
myInstanceObject
.assertThat(
useraaaaaaaaaaojzapjzpozjapjzpoajzpozaaaaaaaaaaaMapperlaaaaaaaaaaaaaaaaaaaaaaaa
)
.isEqualTo();
}
}
- Parsing of unannPrimitiveType in primary (#421)
// Throws in Prettier 0.8.0
double[][]::new
// Prettier 0.9.0
double[][]::new
- Possibility to run the Prettier Java package on every entrypoint defined in the following list (#395):
[ "variableInitializerList", "block", "blockStatements", "blockStatement", "localVariableDeclarationStatement", "localVariableDeclaration", "localVariableType", "statement", "statementWithoutTrailingSubstatement", "emptyStatement", "labeledStatement", "expressionStatement", "statementExpression", "ifStatement", "assertStatement", "switchStatement", "switchBlock", "switchCase", "switchLabel", "enumConstantName", "whileStatement", "doStatement", "forStatement", "basicForStatement", "forInit", "forUpdate", "statementExpressionList", "enhancedForStatement", "breakStatement", "continueStatement", "returnStatement", "throwStatement", "synchronizedStatement", "tryStatement", "catches", "catchClause", "catchFormalParameter", "catchType", "finally", "tryWithResourcesStatement", "resourceSpecification", "resourceList", "resource", "resourceInit", "variableAccess", "isBasicForStatement", "isLocalVariableDeclaration", "classDeclaration", "normalClassDeclaration", "classModifier", "typeParameters", "typeParameterList", "superclass", "superinterfaces", "interfaceTypeList", "classBody", "classBodyDeclaration", "classMemberDeclaration", "fieldDeclaration", "fieldModifier", "variableDeclaratorList", "variableDeclarator", "variableDeclaratorId", "variableInitializer", "unannType", "unannPrimitiveType", "unannReferenceType", "unannClassOrInterfaceType", "unannClassType", "unannInterfaceType", "unannTypeVariable", "methodDeclaration", "methodModifier", "methodHeader", "result", "methodDeclarator", "receiverParameter", "formalParameterList", "formalParameter", "variableParaRegularParameter", "variableArityParameter", "variableModifier", "throws", "exceptionTypeList", "exceptionType", "methodBody", "instanceInitializer", "staticInitializer", "constructorDeclaration", "constructorModifier", "constructorDeclarator", "simpleTypeName", "constructorBody", "explicitConstructorInvocation", "unqualifiedExplicitConstructorInvocation", "qualifiedExplicitConstructorInvocation", "enumDeclaration", "enumBody", "enumConstantList", "enumConstant", "enumConstantModifier", "enumBodyDeclarations", "isClassDeclaration", "identifyClassBodyDeclarationType", "isDims", "constantExpression", "expression", "lambdaExpression", "lambdaParameters", "lambdaParametersWithBraces", "lambdaParameterList", "inferredLambdaParameterList", "explicitLambdaParameterList", "lambdaParameter", "regularLambdaParameter", "lambdaParameterType", "lambdaBody", "ternaryExpression", "binaryExpression", "unaryExpression", "unaryExpressionNotPlusMinus", "primary", "primaryPrefix", "primarySuffix", "fqnOrRefType", "fqnOrRefTypePartRest", "fqnOrRefTypePartCommon", "fqnOrRefTypePartFirst", "parenthesisExpression", "castExpression", "primitiveCastExpression", "referenceTypeCastExpression", "newExpression", "unqualifiedClassInstanceCreationExpression", "classOrInterfaceTypeToInstantiate", "typeArgumentsOrDiamond", "diamond", "methodInvocationSuffix", "argumentList", "arrayCreationExpression", "arrayCreationDefaultInitSuffix", "arrayCreationExplicitInitSuffix", "dimExprs", "dimExpr", "classLiteralSuffix", "arrayAccessSuffix", "methodReferenceSuffix", "identifyNewExpressionType", "isLambdaExpression", "isCastExpression", "isPrimitiveCastExpression", "isReferenceTypeCastExpression", "isRefTypeInMethodRef", "interfaceDeclaration", "normalInterfaceDeclaration", "interfaceModifier", "extendsInterfaces", "interfaceBody", "interfaceMemberDeclaration", "constantDeclaration", "constantModifier", "interfaceMethodDeclaration", "interfaceMethodModifier", "annotationTypeDeclaration", "annotationTypeBody", "annotationTypeMemberDeclaration", "annotationTypeElementDeclaration", "annotationTypeElementModifier", "defaultValue", "annotation", "elementValuePairList", "elementValuePair", "elementValue", "elementValueArrayInitializer", "elementValueList", "identifyInterfaceBodyDeclarationType", "identifyAnnotationBodyDeclarationType", "isSimpleElementValueAnnotation", "literal", "integerLiteral", "floatingPointLiteral", "booleanLiteral", "moduleName", "packageName", "typeName", "expressionName", "methodName", "packageOrTypeName", "ambiguousName", "compilationUnit", "ordinaryCompilationUnit", "modularCompilationUnit", "packageDeclaration", "packageModifier", "importDeclaration", "typeDeclaration", "moduleDeclaration", "moduleDirective", "requiresModuleDirective", "exportsModuleDirective", "opensModuleDirective", "usesModuleDirective", "providesModuleDirective", "requiresModifier", "isModuleCompilationUnit", "primitiveType", "numericType", "integralType", "floatingPointType", "referenceType", "classOrInterfaceType", "classType", "interfaceType", "typeVariable", "dims", "typeParameter", "typeParameterModifier", "typeBound", "additionalBound", "typeArguments", "typeArgumentList", "typeArgument", "wildcard", "wildcardBounds" ];
-
Fix formatting of empty enums to not insert commas when trailing-comma is enabled #385)
// Input public enum Enum {} // Prettier v0.7.1 public enum Enum { } // Prettier v0.8.0 public enum Enum {}
-
Fix formatting of enum with comments #385)
- Update prettier dependency to 2.0.5 (#379) & (#400)
- Binary artefacts creation for each release (#399)
- Document Maven plugin (#394)
- Fix stable formatting for fields and methods with annotations (#369)
-
Add support for trailing commas option (#354)
For enumerations:
// Input public enum Enum { ONE, TWO, THREE } // Output public enum Enum { ONE, TWO, THREE }
For arrays:
// Input public class T { void t() { int[] ints = { 1, 2, 3 }; int[] ints = { aVeryLongArrayValue, anotherVeryLongArrayValue, andYetAnotherVeryLongArrayValue }; } } // Output public class T { void t() { int[] ints = { 1, 2, 3 }; int[] ints = { aVeryLongArrayValue, anotherVeryLongArrayValue, andYetAnotherVeryLongArrayValue }; } }
-
By default, remove trailing comma in arrays (#354)
// Input public class T { void t() { int[] ints = { 1, 2, 3 }; } } // Output public class T { void t() { int[] ints = { 1, 2, 3 }; } }
-
Allow blank lines in enumerations' constant list (#350)
// Input public enum OtherEnum { ONE, TWO, THREE, FOUR, /* Five */ FIVE, /* Six */ SIX } // Output public enum OtherEnum { ONE, TWO, THREE, FOUR, /* Five */ FIVE, /* Six */ SIX }
-
Always add a blank line between an enumeration's constants and declarations (#351)
// This input public enum EnumWithExtraCommaAndEnumBodyDeclarations { THIS_IS_GOOD("abc"), THIS_IS_FINE("abc"); public static final String thisWillBeDeleted = "DELETED"; } // will be formatted to this output public enum EnumWithExtraCommaAndEnumBodyDeclarations { THIS_IS_GOOD("abc"), THIS_IS_FINE("abc"); public static final String thisWillBeDeleted = "DELETED"; }
-
Fix blank lines with empty statements (#360)
// Input public class Test { public TestField testField; @Override public void someMethod() {} } // Output (v0.6.0) public class Test { public TestField testField; @Override public void someMethod() {} } // Output (v0.7.0) public class Test { public TestField testField; @Override public void someMethod() {} }
-
Fix line wrapping in switch statements (#359)
// Input public String shouldWrapEvenForSmallSwitchCases() { switch (answer) { case "YES": return "YES"; default: return "NO"; } } // Output (v0.6.0) public String shouldWrapEvenForSmallSwitchCases() { switch (answer) { case "YES": return "YES"; default: return "NO"; } } // Output (v0.7.0) public String shouldWrapEvenForSmallSwitchCases() { switch (answer) { case "YES": return "YES"; default: return "NO"; } }
-
Fix stable reformating of comments in binary expression (#353)
// Input public boolean binaryOperationWithComments() { boolean a = one || two >> 1 // one // two // three || // five // four three; boolean b = one || two >> 1 // one // two // three || three; boolean c = one || two >> 1 // one // two // three || three; return a || b || c; } // Output (v0.6.0) public boolean binaryOperationWithComments() { boolean a = one || two >> 1 // two // one // three || // five // four three; boolean b = one || two >> 1 // two // one // three || three; boolean c = one || two >> 1 // two // one // three || three; return a || b || c; } // Output (v0.7.0) public boolean binaryOperationWithComments() { boolean a = one || two >> 1 || // one // five // two // three // four three; boolean b = one || two >> 1 || // one // two // three three; boolean c = one || two >> 1 || // one // two // three three; return a || b || c; }
-
Fix comments indentation when they are at the end of a block: indent the comments based on the block they are in (#345)
// Input public class T { int i; // comment } // Output (v0.6.0) public class T { int i; // comment } // Output (v0.7.0) public class T { int i; // comment }
-
Fix respect of blank lines with comments (#348)
// Input void t() { int i; // comment int j; } // Output (v0.6.0) void t() { int i; // comment int j; } // Output (v0.7.0) void t() { int i; // comment int j; }
- Optimize parser performance by reducing the global maxLookahead to 1 (#321)
-
Support
// formater-off
and// formater-on
comments to disable formating on some parts of the code (#323)// Input // @formatter:off public class PrettierIgnoreClass { public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) { } } // @formatter:on public class PrettierIgnoreClass { public void myMethod( int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10 ) {} }
// Output // @formatter:off public class PrettierIgnoreClass { public void myMethod(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10) { } } // @formatter:on public class PrettierIgnoreClass { public void myMethod( int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10 ) {} }
-
Print enums' values on their own line (#319)
// Input public enum Enum { SOME_ENUM, ANOTHER_ENUM, LAST_ENUM } // Output public enum Enum { SOME_ENUM, ANOTHER_ENUM, LAST_ENUM }
-
Remove extra comma in enums (#319)
// Input public enum EnumWithExtraComma { SOME_ENUM, ANOTHER_ENUM, LAST_ENUM } // Output public enum Enum { SOME_ENUM, ANOTHER_ENUM, LAST_ENUM }
-
Respect case when sorting imports (#330)
// Input import java.util.ArrayList; // Output import java.util.ArrayList; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.concurrent.*; import java.util.concurrent.*; import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore; import java.util.functioN.Consumer; import java.util.functioN.Consumer; import java.util.function.Consumer; import java.util.function.Consumer; import java.util.function.ConsumerTwo; import java.util.function.ConsumerTwo;
-
Improve formatting of lambda expressions when they break (#333)
// Input && v0.5.1 public void lambdaWithoutBracesWhichBreak() { call(x -> foo.isVeryVeryVeryLongConditionTrue() && foo.isAnotherVeryVeryLongConditionTrue()); } // Output public void lambdaWithoutBracesWhichBreak() { call( x -> foo.isVeryVeryVeryLongConditionTrue() && foo.isAnotherVeryVeryLongConditionTrue() ); }
-
Don't indent binary operators (#329)
// Input && v0.5.1 @Annotation( "This operation with two very long string should break" + "in a very nice way" ) public void method() {} // Output @Annotation( "This operation with two very long string should break" + "in a very nice way" ) public void method() {}
-
Improve ternary expression line wrapping (#318)
// Input && v0.5.1 return (columnIndex == null) ? ImmutableMap.<R, V>of() : new Column(columnIndex); // Output return (columnIndex == null) ? ImmutableMap.<R, V>of() : new Column(columnIndex);
-
Improve formatting of variable initialization with methods (#332)
// Input && v0.5.1 boolean willDrop = predictDropResponse.getSendResult().isIgnorableFailure() || predictDropResponse.getSendResult().isFatalError(); // Output boolean willDrop = predictDropResponse.getSendResult().isIgnorableFailure() || predictDropResponse.getSendResult().isFatalError();
- Fix brackets considered as a cast with byte shifting or comparison
(e.g.
(left) << right
or(left) < right
). The parser is now able to parse completely the ElasticSearch Repository (#325)
-
Fix stable reformating of variable declaration with comments (#336)
// Input && v0.5.1 Map<String, String> map = // there is a random comment on this line up here // and then there is a separate comment on this line down here new HashMap<>(someMethodThatReturnsAMap()); // Output Map<String, String> map = // there is a random comment on this line up here // and then there is a separate comment on this line down here new HashMap<>(someMethodThatReturnsAMap());
- Check stable reformating for repositories in tests (#335)
- Add template for submitting an issue (#340)
- Optimize parser initialisation (#295)
-
Sort class, method and field modifiers (#302). See this doc for more information
// Input final private static @Annotation String S = "abc"; // Output @Annotation private static final String S = "abc";
- Fix lexer gap: align use of
transitive
keyword with the specs (#297)
- Fix enforcement of printWidth for nodes with leading comments (#278)
- Fix switch statements indentation with comments (#278)
- Fix unstable formating when wrapping in return statements (#294)
- Fix variable arity parameters formating (#304)
- Drop testing on Node 8 and add testing on Node 13
public enum EnumWhichBreak {
ONE_VALUE,
TWO_VALUE,
THREE_VALUE,
FOUR_VALUE,
FIVE_VALUE,
SIX_VALUE,
SEVEN_VALUE,
EIGHT_VALUE,
NINE_VALUE,
TEN_VALUE
}
would be transformed in:
public enum EnumWhichBreak {
ONE_VALUE,
TWO_VALUE,
THREE_VALUE,
FOUR_VALUE,
FIVE_VALUE,
SIX_VALUE,
SEVEN_VALUE,
EIGHT_VALUE,
NINE_VALUE,
TEN_VALUE
}
When
public enum EnumWhichNotBreak {
SOME_ENUM,
ANOTHER_ENUM,
LAST_ENUM
}
would be kept as it is:
public enum EnumWhichNotBreak {
SOME_ENUM,
ANOTHER_ENUM,
LAST_ENUM
}
- Remove extra semicolons in enums when possible (#266)
public enum EnumWhichNotBreak {
SOME_ENUM,
ANOTHER_ENUM,
LAST_ENUM
}
would be transformed in:
public enum EnumWhichNotBreak {
SOME_ENUM,
ANOTHER_ENUM,
LAST_ENUM
}
when the following is kept as it is:
public enum Enum {
THIS_IS_GOOD("abc"), THIS_IS_FINE("abc");
public static final String thisWillBeDeleted = "DELETED";
private final String value;
public Enum(String value) {
this.value = value;
}
public String toString() {
return "STRING";
}
package my.own.pkg;
import static abc.def;
import static abc.def.Another;
import static abc.def.Something;
import static java.utils.*;
import static something.Different;
import abc.def;
import abc.def.Another;
import abc.def.Something;
import java.utils.*;
import one.last;
import something.Different;
public class PackageAndImports {}
is transformed in:
package my.own.pkg;
import static abc.def;
import static abc.def.Another;
import static abc.def.Something;
import static java.utils.*;
import static something.Different;
import abc.def;
import abc.def.Another;
import abc.def.Something;
import java.utils.*;
import one.last;
import something.Different;
public class PackageAndImports {}
- Better display of local variable declarations (#283)
public boolean localVariableDeclarationWhichBreak() {
@Nullable final BackupStatus lastStatus = BackupStatus.fromDbValue(backupRepository.getLastStatus());
final BackupStatus lastStatus = BackupStatus.fromDbValue(backupRepository.getLastStatus());
@Nullable BackupStatus lastStatus = BackupStatus.fromDbValue(backupRepository.getLastStatus());
BackupStatus lastStatus = BackupStatus.fromDbValue(backupRepository.getLastStatus());
}
public boolean localVariableDeclarationWhichDoNotBreak() {
@Nullable final BackupStatus lastStatus = value;
final BackupStatus lastStatus = value;
@Nullable BackupStatus lastStatus = value;
BackupStatus lastStatus = value;
}
is transformed in:
public boolean localVariableDeclarationWhichBreak() {
@Nullable
final BackupStatus lastStatus = BackupStatus.fromDbValue(
backupRepository.getLastStatus()
);
final BackupStatus lastStatus = BackupStatus.fromDbValue(
backupRepository.getLastStatus()
);
@Nullable
BackupStatus lastStatus = BackupStatus.fromDbValue(
backupRepository.getLastStatus()
);
BackupStatus lastStatus = BackupStatus.fromDbValue(
backupRepository.getLastStatus()
);
}
public boolean localVariableDeclarationWhichDoNotBreak() {
@Nullable
final BackupStatus lastStatus = value;
final BackupStatus lastStatus = value;
@Nullable
BackupStatus lastStatus = value;
BackupStatus lastStatus = value;
}
- Improve binary operations indentation (#255):
Obj newObject = new Object().something().more().and().that().as().well().but().not().something();
Object.test.creation thisObject = classWithName.invocationOne().invocationTwo();
Object.test.creation thisObject1 = classWithName.invocationOne(argument1, argument2, argument3);
Object.test.creation thisObject2 = classWithName.invocationOne(argument1, argument2, argument3).invocationTwo();
Object.test.creation thisObject3 = classWithName.invocationOne().invocationTwo(argument1, argument2, argument3);
Object.test.creation thisObject4 = classWithName.invocationOne(argument1, argument2, argument3).invocationTwo(argument1, argument2);
Object.test.creation thisObject5 = classWithName.invocationOne(argument1WithAVeryVeryVeryVeryLongName, argument2, argument3).attributeOne.attributeTwo
.invocationTwo(argument1, argument2).attributeThree.invocationThree();
Object.test.creation thisObject6 = classWithName.invocationOne(argument1, argument2,
argument3).attributeOne.attributeTwo.invocationTwo(argument1, argument2).attributeThree.invocationThree();
is transformed in:
Obj newObject = new Object()
.something()
.more()
.and()
.that()
.as()
.well()
.but()
.not()
.something();
Object.test.creation thisObject = classWithName
.invocationOne()
.invocationTwo();
Object.test.creation thisObject1 = classWithName.invocationOne(
argument1,
argument2,
argument3
);
Object.test.creation thisObject2 = classWithName
.invocationOne(argument1, argument2, argument3)
.invocationTwo();
Object.test.creation thisObject3 = classWithName
.invocationOne()
.invocationTwo(argument1, argument2, argument3);
Object.test.creation thisObject4 = classWithName
.invocationOne(argument1, argument2, argument3)
.invocationTwo(argument1, argument2);
Object.test.creation thisObject5 = classWithName
.invocationOne(
argument1WithAVeryVeryVeryVeryLongName,
argument2,
argument3
)
.attributeOne.attributeTwo.invocationTwo(argument1, argument2)
.attributeThree.invocationThree();
Object.test.creation thisObject6 = classWithName
.invocationOne(argument1, argument2, argument3)
.attributeOne.attributeTwo.invocationTwo(argument1, argument2)
.attributeThree.invocationThree();
- Improve return statement rendering (#255)
Object returnSomethingWhichDoNotBreak() {
return oneVariable + secondVariable;
}
Object returnSomethingWhichBreak() {
return oneVariable + secondVariable + thirdVariable + fourthVariable + fifthVariable + sixthVariable + seventhVariable;
}
Object returnSomethingWhichBreakAndAlreadyInParenthesis() {
return (
oneVariable +
secondVariable +
thirdVariable +
fourthVariable +
fifthVariable +
sixthVariable +
seventhVariable
);
}
is transformed in:
Object returnSomethingWhichDoNotBreak() {
return oneVariable + secondVariable;
}
Object returnSomethingWhichBreak() {
return (
oneVariable +
secondVariable +
thirdVariable +
fourthVariable +
fifthVariable +
sixthVariable +
seventhVariable
);
}
Object returnSomethingWhichBreakAndAlreadyInParenthesis() {
return (
oneVariable +
secondVariable +
thirdVariable +
fourthVariable +
fifthVariable +
sixthVariable +
seventhVariable
);
}