Bug 485495 - [Formatter] does not insert space before semicolon at the end of the statement
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index d7cdd89..7c9a542 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13145,4 +13145,56 @@
assertTrue(false);
}
}
+/**
+ * https://bugs.eclipse.org/485495 - [Formatter] does not insert space before semicolon at the end of the statement
+ */
+public void testBug485495() {
+ this.formatterPrefs.insert_space_before_semicolon = true;
+ String source =
+ "package test ;\n" +
+ "\n" +
+ "import java.util.ArrayList ;\n" +
+ "\n" +
+ "public class Test {\n" +
+ "\n" +
+ " interface I {\n" +
+ " void method() ;\n" +
+ " }\n" +
+ "\n" +
+ " ArrayList<String> e = null ;\n" +
+ " int i ;\n" +
+ "\n" +
+ " void foo() {\n" +
+ " int i = 0 ;\n" +
+ " String s ;\n" +
+ " if (i > 0)\n" +
+ " return ;\n" +
+ " for (int j = 0; j < 5; j++) {\n" +
+ " Object o ;\n" +
+ " while (i < 0)\n" +
+ " o = new Object() {\n" +
+ " int f ;\n" +
+ "\n" +
+ " void bar() {\n" +
+ " if (f > 0)\n" +
+ " f = 5 ;\n" +
+ " else\n" +
+ " f = 16 ;\n" +
+ " try {\n" +
+ " f = 14 ;\n" +
+ " } catch (Exception e) {\n" +
+ " bar() ;\n" +
+ " }\n" +
+ " }\n" +
+ " } ;\n" +
+ " while (i < 0)\n" +
+ " switch (i) {\n" +
+ " case 4:\n" +
+ " foo() ;\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ formatSource(source);
+}
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index df0be65..5afb6fb 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014, 2015 Mateusz Matela and others.
+ * Copyright (c) 2014, 2016 Mateusz Matela and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -46,6 +46,7 @@
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.IntersectionType;
@@ -56,6 +57,7 @@
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PostfixExpression;
@@ -102,6 +104,18 @@
}
@Override
+ public boolean visit(PackageDeclaration node) {
+ handleSemicolon(node);
+ return true;
+ }
+
+ @Override
+ public boolean visit(ImportDeclaration node) {
+ handleSemicolon(node);
+ return true;
+ }
+
+ @Override
public boolean visit(TypeDeclaration node) {
if (node.getName().getStartPosition() == -1)
return true; // this is a fake type created by parsing in class body mode
@@ -234,6 +248,8 @@
handleTokenBefore(typeParameters.get(0), TokenNameLESS, true, false);
handleTokenAfter(typeParameters.get(typeParameters.size() - 1), TokenNameGREATER, false, true);
}
+
+ handleSemicolon(node);
return true;
}
@@ -255,6 +271,7 @@
handleToken((ASTNode) node.fragments().get(0), TokenNameIdentifier, true, false);
handleCommas(node.fragments(), this.options.insert_space_before_comma_in_multiple_field_declarations,
this.options.insert_space_after_comma_in_multiple_field_declarations);
+ handleSemicolon(node);
return true;
}
@@ -299,6 +316,7 @@
this.options.insert_space_before_closing_paren_in_switch, false);
handleTokenAfter(node.getExpression(), TokenNameLBRACE,
this.options.insert_space_before_opening_brace_in_switch, false);
+ handleSemicolon(node.statements());
return true;
}
@@ -509,6 +527,8 @@
@Override
public boolean visit(Block node) {
+ handleSemicolon(node.statements());
+
ASTNode parent = node.getParent();
if (parent.getLength() == 0)
return true; // this is a fake block created by parsing in statements mode
@@ -539,6 +559,8 @@
handleToken(thenStatement, TokenNameLBRACE, false, true);
this.tm.lastTokenIn(node, TokenNameRBRACE).spaceBefore();
}
+
+ handleSemicolon(thenStatement);
return true;
}
@@ -999,6 +1021,21 @@
return false;
}
+ private void handleSemicolon(ASTNode node) {
+ if (this.options.insert_space_before_semicolon) {
+ Token lastToken = this.tm.lastTokenIn(node, -1);
+ if (lastToken.tokenType == TokenNameSEMICOLON)
+ lastToken.spaceBefore();
+ }
+ }
+
+ private void handleSemicolon(List<ASTNode> nodes) {
+ if (this.options.insert_space_before_semicolon) {
+ for (ASTNode node : nodes)
+ handleSemicolon(node);
+ }
+ }
+
public void finishUp() {
this.tm.traverse(0, new TokenTraverser() {
boolean isPreviousJIDP = false;