From 161f65c97dd8d9dade357bb3621453bd81a5ec68 Mon Sep 17 00:00:00 2001 From: Junichi Yamamoto Date: Fri, 15 Sep 2023 14:44:56 +0900 Subject: [PATCH] Add "After Use Trait" to the formatting options #4685 - https://github.com/apache/netbeans/issues/4685 - Add "After Use Trait" option - Add unit tests --- .../modules/php/editor/indent/CodeStyle.java | 4 + .../modules/php/editor/indent/FmtOptions.java | 2 + .../php/editor/indent/FormatToken.java | 1 + .../php/editor/indent/FormatVisitor.java | 11 +++ .../php/editor/indent/TokenFormatter.java | 6 ++ .../php/editor/indent/ui/Bundle.properties | 2 + .../php/editor/indent/ui/FmtBlankLines.form | 78 +++++++++++-------- .../php/editor/indent/ui/FmtBlankLines.java | 71 ++++++++++------- .../blankLines/AfterUseTrait_01.php | 52 +++++++++++++ ...estAfterUseTraitHasBlankLine_01a.formatted | 57 ++++++++++++++ ...estAfterUseTraitHasBlankLine_01b.formatted | 62 +++++++++++++++ ...testAfterUseTraitNoBlankLine_01a.formatted | 55 +++++++++++++ ...testAfterUseTraitNoBlankLine_01b.formatted | 62 +++++++++++++++ .../indent/PHPFormatterBlankLinesTest.java | 40 ++++++++++ 14 files changed, 443 insertions(+), 60 deletions(-) create mode 100644 php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php create mode 100644 php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php.testAfterUseTraitHasBlankLine_01a.formatted create mode 100644 php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php.testAfterUseTraitHasBlankLine_01b.formatted create mode 100644 php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php.testAfterUseTraitNoBlankLine_01a.formatted create mode 100644 php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php.testAfterUseTraitNoBlankLine_01b.formatted diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/CodeStyle.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/CodeStyle.java index a1ba761f73a5..885c6ff243b6 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/CodeStyle.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/CodeStyle.java @@ -172,6 +172,10 @@ public int getBlankLinesBeforeUseTrait() { return preferences.getInt(BLANK_LINES_BEFORE_USE_TRAIT, getDefaultAsInt(BLANK_LINES_BEFORE_USE_TRAIT)); } + public int getBlankLinesAfterUseTrait() { + return preferences.getInt(BLANK_LINES_AFTER_USE_TRAIT, getDefaultAsInt(BLANK_LINES_AFTER_USE_TRAIT)); + } + public int getBlankLinesAfterUse() { return preferences.getInt(BLANK_LINES_AFTER_USE, getDefaultAsInt(BLANK_LINES_AFTER_USE)); } diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FmtOptions.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FmtOptions.java index 24d05c20a426..5ba623e44ac6 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FmtOptions.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FmtOptions.java @@ -94,6 +94,7 @@ public final class FmtOptions { public static final String BLANK_LINES_AFTER_NAMESPACE = "blankLinesAfterNamespace"; //NOI18N public static final String BLANK_LINES_BEFORE_USE = "blankLinesBeforeUse"; //NOI18N public static final String BLANK_LINES_BEFORE_USE_TRAIT = "blankLinesBeforeUseTrait"; //NOI18N + public static final String BLANK_LINES_AFTER_USE_TRAIT = "blankLinesAfterUseTrait"; //NOI18N public static final String BLANK_LINES_AFTER_USE = "blankLinesAfterUse"; //NOI18N public static final String BLANK_LINES_BETWEEN_USE_TYPES = "blankLinesBetweenUseType"; //NOI18N public static final String BLANK_LINES_BEFORE_CLASS = "blankLinesBeforeClass"; //NOI18N @@ -289,6 +290,7 @@ private static void createDefaults() { {BLANK_LINES_AFTER_NAMESPACE, "1"}, //NOI18N {BLANK_LINES_BEFORE_USE, "1"}, //NOI18N {BLANK_LINES_BEFORE_USE_TRAIT, "1"}, //NOI18N + {BLANK_LINES_AFTER_USE_TRAIT, "1"}, //NOI18N {BLANK_LINES_AFTER_USE, "1"}, //NOI18N {BLANK_LINES_BETWEEN_USE_TYPES, "0"}, //NOI18N {BLANK_LINES_BEFORE_CLASS, "1"}, //NOI18N diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatToken.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatToken.java index 4f464a826f44..ec0d6cda7f16 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatToken.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatToken.java @@ -103,6 +103,7 @@ public enum Kind { WHITESPACE_BEFORE_OTHER_RIGHT_BRACE, WHITESPACE_BEFORE_USES_PART, WHITESPACE_BEFORE_USE_TRAIT, + WHITESPACE_AFTER_USE_TRAIT, WHITESPACE_BEFORE_USE_TRAIT_PART, WHITESPACE_BEFORE_USE_TRAIT_BODY_LEFT_BRACE, WHITESPACE_BEFORE_USE_TRAIT_BODY_RIGHT_BRACE, diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatVisitor.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatVisitor.java index 00a727a56e9e..c03939e031a0 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatVisitor.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatVisitor.java @@ -2362,7 +2362,18 @@ && isFirstUseTraitStatementInBlock(path.get(1), node)) { } includeWSBeforePHPDoc = true; isFirstUseTraitStatementPart = true; + Block block = (Block) path.get(1); + int index = 0; + List statements = block.getStatements(); super.visit(node); + while (index < statements.size() && statements.get(index).getStartOffset() < node.getStartOffset()) { + index++; + } + if (index == statements.size() - 1 + || ((index < statements.size() - 1) && !(statements.get(index + 1) instanceof UseTraitStatement))) { + addRestOfLine(); + formatTokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_USE_TRAIT, ts.offset() + ts.token().length())); + } } @Override diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/TokenFormatter.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/TokenFormatter.java index 0d4e9a41a96f..c8ac89f81796 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/TokenFormatter.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/TokenFormatter.java @@ -152,6 +152,7 @@ protected static class DocumentOptions { public int blankLinesAfterNamespace; public int blankLinesBeforeUse; public int blankLinesBeforeUseTrait; + public int blankLinesAfterUseTrait; public int blankLinesAfterUse; public int blankLinesBetweenUseTypes; public int blankLinesBeforeClass; @@ -320,6 +321,7 @@ public DocumentOptions(BaseDocument doc) { blankLinesAfterNamespace = codeStyle.getBlankLinesAfterNamespace(); blankLinesBeforeUse = codeStyle.getBlankLinesBeforeUse(); blankLinesBeforeUseTrait = codeStyle.getBlankLinesBeforeUseTrait(); + blankLinesAfterUseTrait = codeStyle.getBlankLinesAfterUseTrait(); blankLinesAfterUse = codeStyle.getBlankLinesAfterUse(); blankLinesBetweenUseTypes = codeStyle.getBlankLinesBetweenUseTypes(); blankLinesBeforeClass = codeStyle.getBlankLinesBeforeClass(); @@ -873,6 +875,10 @@ public void run() { indentRule = true; newLines = docOptions.blankLinesBeforeUseTrait + 1; break; + case WHITESPACE_AFTER_USE_TRAIT: + indentRule = true; + newLines = docOptions.blankLinesAfterUseTrait + 1; + break; case WHITESPACE_BEFORE_USE_TRAIT_PART: indentRule = true; if (formatTokens.get(index - 1).getId() == FormatToken.Kind.ANCHOR) { diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Bundle.properties b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Bundle.properties index 60f568d079eb..328edd2866db 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Bundle.properties +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Bundle.properties @@ -456,3 +456,5 @@ FmtBlankLines.betweenUseTypesField.text= FmtBlankLines.endOfFileCheckBox.text=En&d of File FmtUses.putInPSR12OrderCheckBox.text=Put in PSR-12 &Order FmtUses.keepExistingUseTypeOrderCheckBox.text=&Keep Existing Order of Use Types(types, functions, constants) If Possible +FmtBlankLines.afterUseTraitLabel.text=After U&se Trait: +FmtBlankLines.afterUseTraitTextField.text= diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.form b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.form index bf1de5ceda51..8485967c6a11 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.form +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.form @@ -116,42 +116,39 @@ + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + @@ -261,6 +258,11 @@ + + + + + @@ -816,6 +818,20 @@ + + + + + + + + + + + + + + diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.java b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.java index a820aa09b143..8f76fd205ca4 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtBlankLines.java @@ -60,6 +60,7 @@ public FmtBlankLines() { aUseField.putClientProperty(OPTION_ID, BLANK_LINES_AFTER_USE); betweenUseTypesField.putClientProperty(OPTION_ID, BLANK_LINES_BETWEEN_USE_TYPES); bUseTraitField.putClientProperty(OPTION_ID, BLANK_LINES_BEFORE_USE_TRAIT); + afterUseTraitTextField.putClientProperty(OPTION_ID, BLANK_LINES_AFTER_USE_TRAIT); bClassField.putClientProperty(OPTION_ID, BLANK_LINES_BEFORE_CLASS); aClassField.putClientProperty(OPTION_ID, BLANK_LINES_AFTER_CLASS); aClassHeaderField.putClientProperty(OPTION_ID, BLANK_LINES_AFTER_CLASS_HEADER); @@ -83,6 +84,7 @@ public FmtBlankLines() { aUseField.addKeyListener(new NumericKeyListener()); betweenUseTypesField.addKeyListener(new NumericKeyListener()); bUseTraitField.addKeyListener(new NumericKeyListener()); + afterUseTraitTextField.addKeyListener(new NumericKeyListener()); bClassField.addKeyListener(new NumericKeyListener()); aClassField.addKeyListener(new NumericKeyListener()); bClassEndField.addKeyListener(new NumericKeyListener()); @@ -164,6 +166,8 @@ private void initComponents() { betweenUseTypesLabel = new JLabel(); betweenUseTypesField = new JTextField(); endOfFileCheckBox = new JCheckBox(); + afterUseTraitLabel = new JLabel(); + afterUseTraitTextField = new JTextField(); setName(NbBundle.getMessage(FmtBlankLines.class, "LBL_BlankLines")); // NOI18N setOpaque(false); @@ -270,6 +274,10 @@ private void initComponents() { Mnemonics.setLocalizedText(endOfFileCheckBox, NbBundle.getMessage(FmtBlankLines.class, "FmtBlankLines.endOfFileCheckBox.text")); // NOI18N + Mnemonics.setLocalizedText(afterUseTraitLabel, NbBundle.getMessage(FmtBlankLines.class, "FmtBlankLines.afterUseTraitLabel.text")); // NOI18N + + afterUseTraitTextField.setText(NbBundle.getMessage(FmtBlankLines.class, "FmtBlankLines.afterUseTraitTextField.text")); // NOI18N + GroupLayout jPanel1Layout = new GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) @@ -298,36 +306,35 @@ private void initComponents() { .addComponent(aNamespaceLabel) .addComponent(bNamespaceLabel) .addComponent(bUseTraitLabel) - .addComponent(maxPreservedBlankLabel)) + .addComponent(maxPreservedBlankLabel) + .addComponent(afterUseTraitLabel)) + .addGap(12, 12, 12) .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(12, 12, 12) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING, false) - .addComponent(aMethodsField, GroupLayout.Alignment.LEADING) - .addComponent(bMethodsField, GroupLayout.Alignment.LEADING) - .addComponent(aFieldsField, GroupLayout.Alignment.LEADING) - .addComponent(bFunctionEndField, GroupLayout.Alignment.LEADING) - .addComponent(betweenFields, GroupLayout.Alignment.LEADING) - .addComponent(bFieldsField, GroupLayout.Alignment.LEADING) - .addComponent(aClassField, GroupLayout.Alignment.LEADING) - .addComponent(bClassEndField, GroupLayout.Alignment.LEADING) - .addComponent(aClassHeaderField, GroupLayout.Alignment.LEADING) - .addComponent(bClassField, GroupLayout.Alignment.LEADING) - .addComponent(aUseField, GroupLayout.Alignment.LEADING) - .addComponent(bUseField, GroupLayout.Alignment.LEADING) - .addComponent(aNamespaceField, GroupLayout.Alignment.LEADING) - .addComponent(bNamespaceField, GroupLayout.Alignment.LEADING) - .addComponent(betweenUseTypesField, GroupLayout.Alignment.LEADING)) - .addComponent(aOpenPHPTagField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(bClosePHPTagField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(aOpenPHPTagHTMLField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))) - .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) - .addComponent(maxPreservedBlankField) - .addComponent(bUseTraitField))))) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.TRAILING, false) + .addComponent(aMethodsField, GroupLayout.Alignment.LEADING) + .addComponent(bMethodsField, GroupLayout.Alignment.LEADING) + .addComponent(aFieldsField, GroupLayout.Alignment.LEADING) + .addComponent(bFunctionEndField, GroupLayout.Alignment.LEADING) + .addComponent(betweenFields, GroupLayout.Alignment.LEADING) + .addComponent(bFieldsField, GroupLayout.Alignment.LEADING) + .addComponent(aClassField, GroupLayout.Alignment.LEADING) + .addComponent(bClassEndField, GroupLayout.Alignment.LEADING) + .addComponent(aClassHeaderField, GroupLayout.Alignment.LEADING) + .addComponent(bClassField, GroupLayout.Alignment.LEADING) + .addComponent(aUseField, GroupLayout.Alignment.LEADING) + .addComponent(bUseField, GroupLayout.Alignment.LEADING) + .addComponent(aNamespaceField, GroupLayout.Alignment.LEADING) + .addComponent(bNamespaceField, GroupLayout.Alignment.LEADING) + .addComponent(betweenUseTypesField, GroupLayout.Alignment.LEADING)) + .addComponent(aOpenPHPTagField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(bClosePHPTagField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(aOpenPHPTagHTMLField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))) + .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING, false) + .addComponent(maxPreservedBlankField) + .addComponent(bUseTraitField) + .addComponent(afterUseTraitTextField)))) .addComponent(cbGroupFields, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(betweenUseTypesLabel) .addComponent(endOfFileCheckBox)) @@ -415,6 +422,10 @@ private void initComponents() { .addComponent(bUseTraitField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(bUseTraitLabel)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(afterUseTraitLabel) + .addComponent(afterUseTraitTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(maxPreservedBlankLabel) .addComponent(maxPreservedBlankField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) @@ -512,6 +523,8 @@ private void initComponents() { private JLabel aOpenPHPTagLebel; private JTextField aUseField; private JLabel aUseLabel; + private JLabel afterUseTraitLabel; + private JTextField afterUseTraitTextField; private JTextField bClassEndField; private JLabel bClassEndLabel; private JTextField bClassField; diff --git a/php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php b/php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php new file mode 100644 index 000000000000..c389fa74a730 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/formatting/blankLines/AfterUseTrait_01.php @@ -0,0 +1,52 @@ + options = new HashMap<>(FmtOptions.getDefaults()); + options.put(FmtOptions.BLANK_LINES_AFTER_USE_TRAIT, 1); + options.put(FmtOptions.BLANK_LINES_BEFORE_USE_TRAIT, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_FIELDS, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_FUNCTION, 0); + reformatFileContents("testfiles/formatting/blankLines/AfterUseTrait_01.php", options, false, true); + } + + public void testAfterUseTraitHasBlankLine_01b() throws Exception { + // GH-4685 + HashMap options = new HashMap<>(FmtOptions.getDefaults()); + options.put(FmtOptions.BLANK_LINES_AFTER_USE_TRAIT, 1); + options.put(FmtOptions.BLANK_LINES_BEFORE_USE_TRAIT,1); + options.put(FmtOptions.BLANK_LINES_BEFORE_FIELDS, 1); + options.put(FmtOptions.BLANK_LINES_BEFORE_FUNCTION, 1); + reformatFileContents("testfiles/formatting/blankLines/AfterUseTrait_01.php", options, false, true); + } + + public void testAfterUseTraitNoBlankLine_01a() throws Exception { + // GH-4685 + HashMap options = new HashMap<>(FmtOptions.getDefaults()); + options.put(FmtOptions.BLANK_LINES_AFTER_USE_TRAIT, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_USE_TRAIT, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_FIELDS, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_FUNCTION, 0); + reformatFileContents("testfiles/formatting/blankLines/AfterUseTrait_01.php", options, false, true); + } + + public void testAfterUseTraitNoBlankLine_01b() throws Exception { + // GH-4685 + HashMap options = new HashMap<>(FmtOptions.getDefaults()); + options.put(FmtOptions.BLANK_LINES_AFTER_USE_TRAIT, 0); + options.put(FmtOptions.BLANK_LINES_BEFORE_USE_TRAIT, 1); + options.put(FmtOptions.BLANK_LINES_BEFORE_FIELDS, 1); + options.put(FmtOptions.BLANK_LINES_BEFORE_FUNCTION, 1); + reformatFileContents("testfiles/formatting/blankLines/AfterUseTrait_01.php", options, false, true); + } + }