You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sk...@apache.org on 2020/05/22 09:36:31 UTC
[netbeans] branch master updated: [NETBEANS-4235]:Fixed formatting
issue in Java Record
This is an automated email from the ASF dual-hosted git repository.
skygo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new d7dc630 [NETBEANS-4235]:Fixed formatting issue in Java Record
new 11d2883 Merge pull request #2138 from arusinha/netbeans-4235
d7dc630 is described below
commit d7dc630a7e9baafda9d3cd14d381f39457ef6fae
Author: Arunava Sinha <ar...@oracle.com>
AuthorDate: Fri May 15 12:51:11 2020 +0530
[NETBEANS-4235]:Fixed formatting issue in Java Record
---
.../modules/java/source/save/Reformatter.java | 132 +++++++++++++++------
.../modules/java/source/save/Reindenter.java | 103 ++++++++++++++++
.../modules/java/source/save/FormatingTest.java | 102 ++++++++++++++++
.../modules/java/source/save/ReindenterTest.java | 89 ++++++++++++++
4 files changed, 391 insertions(+), 35 deletions(-)
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
index 799e173..1df27b2 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java
@@ -1268,13 +1268,15 @@ public class Reformatter implements ReformatTask {
return true;
}
- public Boolean scanRecord(ClassTree node, Void p) {
+ private Boolean scanRecord(ClassTree node, Void p) {
boolean old = continuationIndent;
+ int oldIndent = indent;
try {
+ continuationIndent = true;
ModifiersTree mods = node.getModifiers();
if (mods != null) {
if (scan(mods, p)) {
- continuationIndent = true;
+
if (cs.placeNewLineAfterModifiers()) {
newline();
} else {
@@ -1287,12 +1289,17 @@ public class Reformatter implements ReformatTask {
}
accept(IDENTIFIER);
space();
+
+ if (!ERROR.contentEquals(node.getSimpleName())) {
+ accept(IDENTIFIER, UNDERSCORE);
+ }
+
List<? extends TypeParameterTree> tparams = node.getTypeParameters();
if (tparams != null && !tparams.isEmpty()) {
if (LT == accept(LT)) {
tpLevel++;
}
- continuationIndent = true;
+
for (Iterator<? extends TypeParameterTree> it = tparams.iterator(); it.hasNext();) {
TypeParameterTree tparam = it.next();
scan(tparam, p);
@@ -1316,16 +1323,11 @@ public class Reformatter implements ReformatTask {
break;
}
}
- spaces(1, true);
+ spaces(0, true);
}
- if (!ERROR.contentEquals(node.getSimpleName())) {
- accept(IDENTIFIER, UNDERSCORE);
- }
- //continuationIndent = true;
spaces(cs.spaceBeforeMethodDeclParen() ? 1 : 0);
accept(LPAREN);
- int oldIndent = indent;
List<? extends Tree> members = node.getMembers();
List recParams = new ArrayList<Tree>();
@@ -1333,52 +1335,112 @@ public class Reformatter implements ReformatTask {
if (member.getKind() == Tree.Kind.VARIABLE) {
ModifiersTree modifiers = ((VariableTree) member).getModifiers();
Set<Modifier> modifierSet = modifiers.getFlags();
- boolean isPublicModPresent = false;
- if (modifiers == null || !modifierSet.contains(Modifier.STATIC)) {
+ if (!modifierSet.contains(Modifier.STATIC)) {
recParams.add(member);
}
}
}
- if (members != null && !members.isEmpty()) {
- int oldLastIndent = lastIndent;
- try {
- spaces(cs.spaceWithinMethodDeclParens() ? 1 : 0, true);
- wrapList(cs.wrapMethodParams(), cs.alignMultilineMethodParams(), false, COMMA, recParams);
- accept(RPAREN);
- spaces(true ? 1 : 0, tokens.offset() < startOffset);
- accept(LBRACE);
- continuationIndent = old;
- indent += indentSize;
+ if (!recParams.isEmpty()) {
+ spaces(cs.spaceWithinMethodDeclParens() ? 1 : 0, true);
+ wrapList(cs.wrapMethodParams(), cs.alignMultilineMethodParams(), false, COMMA, recParams);
+ }
+ accept(RPAREN);
+ List<? extends Tree> impls = node.getImplementsClause();
+ if (impls != null && !impls.isEmpty()) {
+ wrapToken(cs.wrapExtendsImplementsKeyword(), 1, IMPLEMENTS);
+ wrapList(cs.wrapExtendsImplementsList(), cs.alignMultilineImplements(), true, COMMA, impls);
+ }
+ int oldLastIndent = lastIndent;
+ int lastMaxPreservedBlankLines = maxPreservedBlankLines;
+ maxPreservedBlankLines = cs.getMaximumBlankLinesInDeclarations();
+ classLeftBracePlacement();
+
+ continuationIndent = old;
+ try {
+ if (members != null && !members.isEmpty()) {
+ boolean isFirstMember = true;
+ blankLines(node.getSimpleName().length() == 0 ? 0 : cs.getBlankLinesAfterClassHeader());
for (Tree member : members) {
- if (member.getKind() != Tree.Kind.VARIABLE || !recParams.contains(member)) {
- newline();
- scan(member, p);
+ if (recParams.contains(member)) {
+ continue;
+ }
+ blankLines(0);
+ switch (member.getKind()) {
+ case VARIABLE:
+ boolean b = tokens.moveNext();
+ if (b) {
+ tokens.movePrevious();
+ if (!isFirstMember) {
+ blankLines(cs.getBlankLinesBeforeFields());
+ }
+ scan(member, p);
+ blankLines(cs.getBlankLinesAfterFields());
+ }
+ break;
+ default:
+ if (!isFirstMember) {
+ blankLines(cs.getBlankLinesBeforeMethods());
+ }
+ scan(member, p);
+ blankLines(cs.getBlankLinesAfterMethods());
+ }
+ if (isFirstMember) {
+ isFirstMember = false;
}
}
- } finally {
- indent = oldIndent;
- lastIndent = oldLastIndent;
- continuationIndent = isLastIndentContinuation;
+ spaces(cs.spaceWithinMethodDeclParens() ? 1 : 0, true);
}
- spaces(cs.spaceWithinMethodDeclParens() ? 1 : 0, true);
- } else {
- accept(RPAREN);
- accept(LBRACE);
+ } finally {
+ indent = oldIndent;
+ lastIndent = oldLastIndent;
+ continuationIndent = old;
+ maxPreservedBlankLines = lastMaxPreservedBlankLines;
}
-
newline();
- indent = oldIndent;
accept(RBRACE);
} finally {
continuationIndent = old;
}
-
return true;
}
+
+ private void classLeftBracePlacement() {
+ CodeStyle.BracePlacement bracePlacement = cs.getClassDeclBracePlacement();
+ boolean spaceBeforeLeftBrace = cs.spaceBeforeClassDeclLeftBrace();
+ int old = indent = lastIndent;
+ int halfIndent = lastIndent;
+ switch (bracePlacement) {
+ case SAME_LINE:
+ spaces(spaceBeforeLeftBrace ? 1 : 0, tokens.offset() < startOffset);
+ accept(LBRACE);
+ indent = lastIndent + indentSize;
+ break;
+ case NEW_LINE:
+ newline();
+ accept(LBRACE);
+ indent = lastIndent + indentSize;
+ break;
+ case NEW_LINE_HALF_INDENTED:
+ int oldLast = lastIndent;
+ indent = lastIndent + (indentSize >> 1);
+ halfIndent = indent;
+ newline();
+ accept(LBRACE);
+ indent = oldLast + indentSize;
+ break;
+ case NEW_LINE_INDENTED:
+ indent = lastIndent + indentSize;
+ halfIndent = indent;
+ newline();
+ accept(LBRACE);
+ break;
+ }
+ }
+
@Override
public Boolean visitMethod(MethodTree node, Void p) {
boolean old = continuationIndent;
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
index 092df1c..361b681 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/Reindenter.java
@@ -40,6 +40,7 @@ import com.sun.source.tree.SynchronizedTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.tree.TryTree;
+import com.sun.source.tree.TypeParameterTree;
import com.sun.source.tree.VariableTree;
import com.sun.source.tree.WhileLoopTree;
import com.sun.source.util.SourcePositions;
@@ -69,6 +70,7 @@ import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
+import javax.lang.model.element.Modifier;
import org.netbeans.api.java.lexer.JavaTokenId;
import org.netbeans.api.java.source.CodeStyle;
import org.netbeans.api.lexer.TokenHierarchy;
@@ -815,6 +817,9 @@ public class Reindenter implements IndentTask {
if (last.getKind().toString().equals(TreeShims.SWITCH_EXPRESSION)) {
currentIndent = getSwitchIndent(startOffset, endOffset,nextTokenId,lastPos,currentIndent) ;
}
+ else if (last.getKind().toString().equals(TreeShims.RECORD)) {
+ currentIndent = getRecordIndent(startOffset, endOffset, nextTokenId, lastPos, currentIndent);
+ }
else currentIndent = getContinuationIndent(path, currentIndent);
break;
}
@@ -896,6 +901,104 @@ public class Reindenter implements IndentTask {
return currentIndent;
}
+ private int getRecordIndent(int startOffset, int endOffset, JavaTokenId nextTokenId, int lastPos, int currentIndent) throws BadLocationException {
+ LinkedList<? extends Tree> path = getPath(startOffset);
+ Tree last = path.getFirst();
+ TokenSequence<JavaTokenId> token = findFirstNonWhitespaceToken(startOffset, endOffset);
+ nextTokenId = token != null ? token.token().id() : null;
+ if (nextTokenId != null && nextTokenId == JavaTokenId.RBRACE) {
+ if (isLeftBraceOnNewLine(lastPos, startOffset)) {
+ switch (cs.getClassDeclBracePlacement()) {
+ case NEW_LINE_INDENTED:
+ currentIndent += cs.getIndentSize();
+ break;
+ case NEW_LINE_HALF_INDENTED:
+ currentIndent += (cs.getIndentSize() / 2);
+ break;
+ }
+ }
+ } else {
+
+ token = findFirstNonWhitespaceToken(startOffset, lastPos);
+ JavaTokenId prevTokenId = token != null ? token.token().id() : null;
+ if (prevTokenId != null) {
+ switch (prevTokenId) {
+ case LBRACE:
+ if (path.size() > 1 && path.get(1).getKind() == Kind.NEW_CLASS && isLeftBraceOnNewLine(lastPos, startOffset)) {
+ switch (cs.getClassDeclBracePlacement()) {
+ case SAME_LINE:
+ case NEW_LINE:
+ currentIndent += cs.getIndentSize();
+ break;
+ case NEW_LINE_HALF_INDENTED:
+ currentIndent += (cs.getIndentSize() - cs.getIndentSize() / 2);
+ break;
+ }
+ } else {
+ currentIndent += cs.indentTopLevelClassMembers() ? cs.getIndentSize() : 0;
+ }
+ break;
+ case COMMA:
+ List<? extends Tree> implClauses = ((ClassTree) last).getImplementsClause();
+ if (!implClauses.isEmpty() && getStartPosition(implClauses.get(0)) < token.offset()) {
+ currentIndent = getMultilineIndent(implClauses, path, token.offset(), currentIndent, cs.alignMultilineImplements(), true);
+ break;
+ }
+ List<? extends Tree> members = ((ClassTree) last).getMembers();
+ if (!members.isEmpty() && getStartPosition(members.get(0)) < token.offset()) {
+ currentIndent = getMultilineIndent(members, path, token.offset(), currentIndent, cs.alignMultilineMethodParams(), true);
+ break;
+ }
+ List<? extends TypeParameterTree> typeParams = ((ClassTree) last).getTypeParameters();
+ if (!typeParams.isEmpty() && getStartPosition(typeParams.get(0)) < token.offset()) {
+ currentIndent = getMultilineIndent(typeParams, path, token.offset(), currentIndent, cs.alignMultilineMethodParams(), true);
+ break;
+ }
+ break;
+ case IDENTIFIER:
+ case GT:
+ case GTGT:
+ case GTGTGT:
+ case RPAREN:
+ if (nextTokenId != null && nextTokenId == JavaTokenId.LBRACE) {
+ switch (cs.getClassDeclBracePlacement()) {
+ case NEW_LINE_INDENTED:
+ currentIndent += cs.getIndentSize();
+ break;
+ case NEW_LINE_HALF_INDENTED:
+ currentIndent += (cs.getIndentSize() / 2);
+ break;
+ }
+ } else {
+ currentIndent += cs.getContinuationIndentSize();
+ }
+ break;
+
+ default:
+ Tree t = null;
+ for (Tree member : ((ClassTree) last).getMembers()) {
+
+ if (member.getKind() == Tree.Kind.VARIABLE && !((VariableTree) member).getModifiers().getFlags().contains(Modifier.STATIC)) {
+ continue;
+ }
+ if (getEndPosition(member) > startOffset) {
+ break;
+ }
+ t = member;
+ }
+ if (t != null) {
+ int i = getCurrentIndent(t, path);
+ currentIndent = i < 0 ? currentIndent + (cs.indentTopLevelClassMembers() ? cs.getIndentSize() : 0) : i;
+ return currentIndent;
+ }
+
+ currentIndent += cs.getContinuationIndentSize();
+ }
+ }
+ }
+ return currentIndent;
+ }
+
private int getStartPosition(Tree last) {
return (int) sp.getStartPosition(cut, last);
}
diff --git a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
index fa1fd2e..7939666 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java
@@ -5124,6 +5124,108 @@ public class FormatingTest extends NbTestCase {
reformat(doc, content, golden);
}
+ public void testRecord1() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_14, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + "public record g3<T extends Object>() implements Cloneable{\n"
+ + "public g3 {\n"
+ + "System.out.println(\"hello\");\n"
+ + "}}}";
+
+ String golden
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public record g3<T extends Object>() implements Cloneable {\n\n"
+ + " public g3 {\n"
+ + " System.out.println(\"hello\");\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+ }
+
+ public void testRecord2() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_14, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n"
+ + "public record g3<T extends Object>() {static int r =10;\n"
+ + "public g3 {\n"
+ + "System.out.println(\"hello\");\n"
+ + "}"
+ + "static{}"
+ + "}}";
+
+ String golden
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public record g3<T extends Object>() {\n\n"
+ + " static int r = 10;\n\n"
+ + " public g3 {\n"
+ + " System.out.println(\"hello\");\n"
+ + " }\n\n"
+ + " static {\n"
+ + " }\n"
+ + " }\n"
+ + "}\n";
+ Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
+ reformat(doc, content, golden);
+ }
+
+ public void testRecord3() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14"); //NOI18N
+ } catch (IllegalArgumentException ex) {
+ //OK, no RELEASE_14, skip test
+ return;
+ }
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile, "");
+ FileObject testSourceFO = FileUtil.toFileObject(testFile);
+ DataObject testSourceDO = DataObject.find(testSourceFO);
+ EditorCookie ec = (EditorCookie) testSourceDO.getCookie(EditorCookie.class);
+ final Document doc = ec.openDocument();
+ doc.putProperty(Language.class, JavaTokenId.language());
+ String content
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + "public record g3(){}}";
+
+ String golden
+ = "package hierbas.del.litoral;\n\n"
+ + "public class Test {\n\n"
+ + " public record g3() {\n"
+ + " }\n"
+ + "}\n";
+ reformat(doc, content, golden);
+ }
+
private void reformat(Document doc, String content, String golden) throws Exception {
reformat(doc, content, golden, 0, content.length());
}
diff --git a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/ReindenterTest.java b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/ReindenterTest.java
index 93a059a..e792883 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/ReindenterTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/save/ReindenterTest.java
@@ -1976,6 +1976,95 @@ public class ReindenterTest extends NbTestCase {
performSpanIndentationTest("package t;\npublic class T {\n|private final String s = \"\"\"\n1\n 2\n 3\n\"\"\";|\n}\n",
"package t;\npublic class T {\n private final String s = \"\"\"\n 1\n 2\n 3\n \"\"\";\n}\n");
}
+
+ public void testLineIndentationBeforeRecord() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ performLineIndentationTest("package t;\n| public record T() {\n}\n",
+ "package t;\npublic record T() {\n}\n");
+ }
+
+ public void testNewLineIndentationBeforeRecodBody() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ performNewLineIndentationTest("package t;\npublic record T()|{\n}\n",
+ "package t;\npublic record T()\n{\n}\n");
+ }
+
+ public void testLineIndentationBeforeHalfIndentedRecordBody() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
+ preferences.put("classDeclBracePlacement", CodeStyle.BracePlacement.NEW_LINE_HALF_INDENTED.name());
+ try {
+ performLineIndentationTest("package t;\npublic record T()\n|{\n}\n",
+ "package t;\npublic record T()\n {\n}\n");
+ } finally {
+ preferences.remove("classDeclBracePlacement");
+ }
+ }
+
+ public void testNewLineIndentationInsideRecord() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ performNewLineIndentationTest("package t;\npublic record T() {|\n}\n",
+ "package t;\npublic record T() {\n \n}\n");
+ }
+
+ public void testNewLineIndentationBeforeEmptyRecordEnd() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ performNewLineIndentationTest("package t;\npublic record T() {|}\n",
+ "package t;\npublic record T() {\n}\n");
+ }
+
+ public void testLineIndentationBeforeEmptyRecordEnd() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ performLineIndentationTest("package t;\npublic record T() {\n|}\n",
+ "package t;\npublic record T() {\n}\n");
+ }
+
+ public void testLineIndentationBeforeEmptyHalfIndentedRecordEnd() throws Exception {
+ try {
+ SourceVersion.valueOf("RELEASE_14");
+ } catch (IllegalArgumentException ex) {
+ //OK, skip test:
+ return;
+ }
+ Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class);
+ preferences.put("classDeclBracePlacement", CodeStyle.BracePlacement.NEW_LINE_HALF_INDENTED.name());
+ try {
+ performLineIndentationTest("package t;\npublic record T()\n {\n| }\n",
+ "package t;\npublic record T()\n {\n }\n");
+ } finally {
+ preferences.remove("classDeclBracePlacement");
+ }
+ }
private void performNewLineIndentationTest(String code, String golden) throws Exception {
int pos = code.indexOf('|');
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists