This is an automated email from the ASF dual-hosted git repository.

tmysik 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 59c49072fe Add the formatting options for the null coalescing oprator 
(`??`)#5011
     new 944c70f14a Merge pull request #5689 from 
junichi11/php-gh-5011-coalescing-operator-formatting
59c49072fe is described below

commit 59c49072fe21063c5bfb403cb18cb02bde6e682b
Author: Junichi Yamamoto <[email protected]>
AuthorDate: Tue Mar 21 13:47:30 2023 +0900

    Add the formatting options for the null coalescing oprator (`??`)#5011
    
    - https://github.com/apache/netbeans/issues/5011
    - Add options
    - Add/Move unit tests
    - Update the preview files
---
 .../modules/php/editor/indent/CodeStyle.java       |  9 +++++
 .../modules/php/editor/indent/FmtOptions.java      |  4 ++
 .../modules/php/editor/indent/FormatToken.java     |  2 +
 .../modules/php/editor/indent/FormatVisitor.java   | 30 ++++++++++++++-
 .../modules/php/editor/indent/TokenFormatter.java  | 19 ++++++++++
 .../modules/php/editor/indent/ui/Bundle.properties |  4 ++
 .../modules/php/editor/indent/ui/FmtSpaces.java    |  1 +
 .../modules/php/editor/indent/ui/FmtWrapping.form  | 40 ++++++++++++++++++++
 .../modules/php/editor/indent/ui/FmtWrapping.java  | 23 ++++++++++-
 .../modules/php/editor/indent/ui/Spaces.php        |  4 ++
 .../modules/php/editor/indent/ui/Wrapping.php      |  4 ++
 ...rnaryOp09.php => spaceAroundCoalescingOp01.php} |  0
 ...ted => spaceAroundCoalescingOp01.php.formatted} |  0
 ...rnaryOp10.php => spaceAroundCoalescingOp02.php} |  0
 ...ted => spaceAroundCoalescingOp02.php.formatted} |  0
 ...rnaryOp11.php => spaceAroundCoalescingOp03.php} |  0
 ...ted => spaceAroundCoalescingOp03.php.formatted} |  0
 ...rnaryOp12.php => spaceAroundCoalescingOp04.php} |  0
 ...ted => spaceAroundCoalescingOp04.php.formatted} |  0
 .../formatting/wrapping/coalescingOp01a.php        | 21 +++++++++++
 .../wrapping/coalescingOp01a.php.formatted         | 22 +++++++++++
 .../formatting/wrapping/coalescingOp01b.php        | 21 +++++++++++
 .../wrapping/coalescingOp01b.php.formatted         | 23 +++++++++++
 .../formatting/wrapping/coalescingOp02a.php        | 22 +++++++++++
 .../wrapping/coalescingOp02a.php.formatted         | 21 +++++++++++
 .../formatting/wrapping/coalescingOp02b.php        | 22 +++++++++++
 .../wrapping/coalescingOp02b.php.formatted         | 21 +++++++++++
 .../formatting/wrapping/coalescingOp03a.php        | 21 +++++++++++
 .../wrapping/coalescingOp03a.php.formatted         | 21 +++++++++++
 .../formatting/wrapping/coalescingOp03b.php        | 21 +++++++++++
 .../wrapping/coalescingOp03b.php.formatted         | 21 +++++++++++
 .../formatting/wrapping/coalescingOp04a.php        | 20 ++++++++++
 .../wrapping/coalescingOp04a.php.formatted         | 22 +++++++++++
 .../formatting/wrapping/coalescingOp04b.php        | 21 +++++++++++
 .../wrapping/coalescingOp04b.php.formatted         | 22 +++++++++++
 .../testfiles/formatting/wrapping/ternaryOp07.php  |  3 --
 .../formatting/wrapping/ternaryOp07.php.formatted  |  5 ---
 .../php/editor/indent/PHPFormatterSpacesTest.java  | 32 ++++++++--------
 .../editor/indent/PHPFormatterWrappingTest.java    | 44 ++++++++++++++++++++--
 39 files changed, 534 insertions(+), 32 deletions(-)

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 7d538b8d9a..b4b3f6d8f5 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
@@ -322,6 +322,10 @@ public final class CodeStyle {
         return preferences.getBoolean(SPACE_AROUND_TERNARY_OPS, 
getDefaultAsBoolean(SPACE_AROUND_TERNARY_OPS));
     }
 
+    public boolean spaceAroundCoalescingOps() {
+        return preferences.getBoolean(SPACE_AROUND_COALESCING_OPS, 
getDefaultAsBoolean(SPACE_AROUND_COALESCING_OPS));
+    }
+
     public boolean spaceAroundKeyValueOps() {
         return preferences.getBoolean(SPACE_AROUND_KEY_VALUE_OPS, 
getDefaultAsBoolean(SPACE_AROUND_KEY_VALUE_OPS));
     }
@@ -685,6 +689,11 @@ public final class CodeStyle {
         return WrapStyle.valueOf(wrap);
     }
 
+    public WrapStyle wrapCoalescingOps() {
+        String wrap = preferences.get(WRAP_COALESCING_OPS, 
getDefaultAsString(WRAP_COALESCING_OPS));
+        return WrapStyle.valueOf(wrap);
+    }
+
     public WrapStyle wrapAssignOps() {
         String wrap = preferences.get(WRAP_ASSIGN_OPS, 
getDefaultAsString(WRAP_ASSIGN_OPS));
         return WrapStyle.valueOf(wrap);
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 fcfbd1b032..c02a5cb3ec 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
@@ -128,6 +128,7 @@ public final class FmtOptions {
     public static final String SPACE_AROUND_UNARY_OPS = "spaceAroundUnaryOps"; 
//NOI18N
     public static final String SPACE_AROUND_BINARY_OPS = 
"spaceAroundBinaryOps"; //NOI18N
     public static final String SPACE_AROUND_TERNARY_OPS = 
"spaceAroundTernaryOps"; //NOI18N
+    public static final String SPACE_AROUND_COALESCING_OPS = 
"spaceAroundCoalescingOps"; //NOI18N
     public static final String SPACE_AROUND_STRING_CONCAT_OPS = 
"spaceAroundStringConcatOps"; //NOI18N
     public static final String SPACE_AROUND_ASSIGN_OPS = 
"spaceAroundAssignOps"; //NOI18N
     public static final String SPACE_AROUND_KEY_VALUE_OPS = 
"spaceAroundKeyValueOps"; //NOI18N
@@ -210,6 +211,7 @@ public final class FmtOptions {
     public static final String WRAP_DO_WHILE_STATEMENT = 
"wrapDoWhileStatement"; //NOI18N
     public static final String WRAP_BINARY_OPS = "wrapBinaryOps"; //NOI18N
     public static final String WRAP_TERNARY_OPS = "wrapTernaryOps"; //NOI18N
+    public static final String WRAP_COALESCING_OPS = "wrapCoalescingOps"; 
//NOI18N
     public static final String WRAP_ASSIGN_OPS = "wrapAssignOps"; //NOI18N
     public static final String WRAP_BLOCK_BRACES = "wrapBlockBraces";  //NOI18N
     public static final String WRAP_GROUP_USE_BRACES = "wrapGroupUseBraces"; 
// NOI18N
@@ -318,6 +320,7 @@ public final class FmtOptions {
             {SPACE_AROUND_UNARY_OPS, FALSE},
             {SPACE_AROUND_BINARY_OPS, TRUE},
             {SPACE_AROUND_TERNARY_OPS, TRUE},
+            {SPACE_AROUND_COALESCING_OPS, TRUE},
             {SPACE_AROUND_STRING_CONCAT_OPS, TRUE},
             {SPACE_AROUND_KEY_VALUE_OPS, TRUE},
             {SPACE_AROUND_ASSIGN_OPS, TRUE},
@@ -400,6 +403,7 @@ public final class FmtOptions {
             {WRAP_DO_WHILE_STATEMENT, WRAP_ALWAYS}, //NOI18N
             {WRAP_BINARY_OPS, WRAP_NEVER}, //NOI18N
             {WRAP_TERNARY_OPS, WRAP_NEVER},
+            {WRAP_COALESCING_OPS, WRAP_NEVER},
             {WRAP_ASSIGN_OPS, WRAP_NEVER},
             {WRAP_BLOCK_BRACES, TRUE},
             {WRAP_GROUP_USE_BRACES, TRUE},
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 2ea0f02fa9..1d9f68b355 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
@@ -57,6 +57,7 @@ public class FormatToken {
         WHITESPACE_BEFORE_BINARY_OP,
         WHITESPACE_AFTER_BINARY_OP,
         WHITESPACE_AROUND_TERNARY_OP,
+        WHITESPACE_AROUND_COALESCING_OP,
         WHITESPACE_WITHIN_SHORT_TERNARY_OP,
         WHITESPACE_BEFORE_ASSIGN_OP,
         WHITESPACE_AFTER_ASSIGN_OP,
@@ -154,6 +155,7 @@ public class FormatToken {
         WHITESPACE_BEFORE_IF_ELSE_STATEMENT,
         WHITESPACE_IN_FOR,
         WHITESPACE_IN_TERNARY_OP,
+        WHITESPACE_IN_COALESCING_OP,
         WHITESPACE_BEFORE_WHILE,
         WHITESPACE_BEFORE_ELSE,
         WHITESPACE_BEFORE_CATCH,
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 b23284d349..151636f1c1 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
@@ -963,9 +963,9 @@ public class FormatVisitor extends DefaultVisitor {
                 if (putContinualIndent) {
                     formatTokens.add(new FormatToken.IndentToken(ts.offset(), 
options.continualIndentSize));
                 }
-                formatTokens.add(new 
FormatToken(FormatToken.Kind.WHITESPACE_IN_TERNARY_OP, ts.offset()));
+                formatTokens.add(new 
FormatToken(getTokenKindForWhiteSpaceIn(operator), ts.offset()));
                 formatTokens.add(new FormatToken(FormatToken.Kind.TEXT, 
ts.offset(), ts.token().text().toString()));
-                formatTokens.add(new 
FormatToken(FormatToken.Kind.WHITESPACE_AROUND_TERNARY_OP, ts.offset() + 
ts.token().length()));
+                formatTokens.add(new 
FormatToken(getTokenKindForWhiteSpaceAround(operator), ts.offset() + 
ts.token().length()));
                 // condition part
                 addAllUntilOffset(node.getIfFalse().getStartOffset());
                 formatTokens.add(new 
FormatToken.UnbreakableSequenceToken(ts.offset(), null, 
FormatToken.Kind.UNBREAKABLE_SEQUENCE_START));
@@ -977,6 +977,32 @@ public class FormatVisitor extends DefaultVisitor {
         }
     }
 
+    private FormatToken.Kind 
getTokenKindForWhiteSpaceIn(ConditionalExpression.OperatorType operatorType) {
+        FormatToken.Kind kind = FormatToken.Kind.WHITESPACE_IN_TERNARY_OP;
+        switch (operatorType) {
+            case COALESCE:
+                kind = FormatToken.Kind.WHITESPACE_IN_COALESCING_OP;
+                break;
+            default:
+                // no-op
+                break;
+        }
+        return kind;
+    }
+
+    private FormatToken.Kind 
getTokenKindForWhiteSpaceAround(ConditionalExpression.OperatorType 
operatorType) {
+        FormatToken.Kind kind = FormatToken.Kind.WHITESPACE_AROUND_TERNARY_OP;
+        switch (operatorType) {
+            case COALESCE:
+                kind = FormatToken.Kind.WHITESPACE_AROUND_COALESCING_OP;
+                break;
+            default:
+                // no-op
+                break;
+        }
+        return kind;
+    }
+
     private void visitConditionalExpression(ConditionalExpression node, 
boolean putContinualIndent) {
         assert node.getIfTrue() != null;
         // "?" part
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 3a93b73014..0966469e51 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
@@ -118,6 +118,7 @@ public class TokenFormatter {
         public boolean spaceAroundUnaryOps;
         public boolean spaceAroundBinaryOps;
         public boolean spaceAroundTernaryOps;
+        public boolean spaceAroundCoalescingOps;
         public boolean spaceAroundAssignOps;
         public boolean spaceAroundKeyValueOps;
         public boolean spaceWithinArrayDeclParens;
@@ -181,6 +182,7 @@ public class TokenFormatter {
         public CodeStyle.WrapStyle wrapDoWhileStatement;
         public CodeStyle.WrapStyle wrapBinaryOps;
         public CodeStyle.WrapStyle wrapTernaryOps;
+        public CodeStyle.WrapStyle wrapCoalescingOps;
         public CodeStyle.WrapStyle wrapAssignOps;
         public boolean wrapBlockBrace;
         public boolean wrapGroupUseBraces;
@@ -278,6 +280,7 @@ public class TokenFormatter {
             spaceAroundUnaryOps = codeStyle.spaceAroundUnaryOps();
             spaceAroundBinaryOps = codeStyle.spaceAroundBinaryOps();
             spaceAroundTernaryOps = codeStyle.spaceAroundTernaryOps();
+            spaceAroundCoalescingOps = codeStyle.spaceAroundCoalescingOps();
             spaceAroundAssignOps = codeStyle.spaceAroundAssignOps();
             spaceAroundKeyValueOps = codeStyle.spaceAroundKeyValueOps();
 
@@ -353,6 +356,7 @@ public class TokenFormatter {
             wrapDoWhileStatement = codeStyle.wrapDoWhileStatement();
             wrapBinaryOps = codeStyle.wrapBinaryOps();
             wrapTernaryOps = codeStyle.wrapTernaryOps();
+            wrapCoalescingOps = codeStyle.wrapCoalescingOps();
             wrapAssignOps = codeStyle.wrapAssignOps();
             wrapBlockBrace = codeStyle.wrapBlockBrace();
             wrapGroupUseBraces = codeStyle.wrapGroupUseBraces();
@@ -1164,6 +1168,9 @@ public class TokenFormatter {
                                     case WHITESPACE_AROUND_TERNARY_OP:
                                         countSpaces = 
docOptions.spaceAroundTernaryOps ? 1 : 0;
                                         break;
+                                    case WHITESPACE_AROUND_COALESCING_OP:
+                                        countSpaces = 
docOptions.spaceAroundCoalescingOps ? 1 : 0;
+                                        break;
                                     case WHITESPACE_WITHIN_SHORT_TERNARY_OP:
                                         countSpaces = 0;
                                         break;
@@ -1623,6 +1630,18 @@ public class TokenFormatter {
                                         newLines = ws.lines;
                                         countSpaces = ws.spaces;
                                         break;
+                                    case WHITESPACE_IN_COALESCING_OP:
+                                        indentRule = true;
+                                        ws = countWSBeforeAStatement(
+                                                docOptions.wrapCoalescingOps,
+                                                
docOptions.spaceAroundCoalescingOps,
+                                                column,
+                                                
countLengthOfNextSequence(formatTokens, index + 1),
+                                                indent,
+                                                
isAfterLineComment(formatTokens, index));
+                                        newLines = ws.lines;
+                                        countSpaces = ws.spaces;
+                                        break;
                                     case WHITESPACE_IN_CHAINED_METHOD_CALLS:
                                         indentRule = true;
                                         switch 
(docOptions.wrapChainedMethodCalls) {
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 db72248e45..2ccb4270b1 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
@@ -80,6 +80,7 @@ LBL_AroundOperators=Around Operators
 LBL_spaceAroundUnaryOps=Unary Operators
 LBL_spaceAroundBinaryOps=Binary Operators
 LBL_spaceAroundTernaryOps=Ternary Operators
+LBL_spaceAroundCoalescingOps=Coalescing Operators
 LBL_spaceAroundAssignOps=Assignment Operators
 LBL_spaceAroundKeyValueOps=Key => Value Operator
 LBL_spaceAroundObjectOps=Object Operator
@@ -446,3 +447,6 @@ 
FmtWrapping.wrapMethodCallArgsAfterLeftParenCheckBox.text_1=Wrap After '('
 FmtWrapping.wrapMethodCallArgsRightParenCheckBox.text=Wrap ')'
 FmtWrapping.wrapForAfterLeftParenCheckBox.text_1=Wrap After '('
 FmtWrapping.wrapForRightParenCheckBox.text=Wrap ')'
+FmtWrapping.coalescingOpsLabel.text=&Coalescing Operators:
+FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleName=Coalescing 
Operators
+FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleDescription=Coalescing
 operators
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtSpaces.java 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtSpaces.java
index 9e3b59d68b..3b02536d31 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtSpaces.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtSpaces.java
@@ -267,6 +267,7 @@ public final class FmtSpaces extends JPanel implements 
TreeCellRenderer, MouseLi
                 new Item(SPACE_AROUND_UNARY_OPS),
                 new Item(SPACE_AROUND_BINARY_OPS),
                 new Item(SPACE_AROUND_TERNARY_OPS),
+                new Item(SPACE_AROUND_COALESCING_OPS),
                 new Item(SPACE_AROUND_STRING_CONCAT_OPS),
                 new Item(SPACE_AROUND_KEY_VALUE_OPS),
                 new Item(SPACE_AROUND_ASSIGN_OPS),
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.form 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.form
index fbd8aa5825..4891bc9594 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.form
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.form
@@ -112,6 +112,7 @@
                                   <Component id="binaryOpsCombo" alignment="0" 
min="-2" max="-2" attributes="0"/>
                                   <Component id="ternaryOpsCombo" 
alignment="0" min="-2" max="-2" attributes="0"/>
                                   <Component id="assignOpsCombo" alignment="0" 
min="-2" max="-2" attributes="0"/>
+                                  <Component id="coalescingOpsCombo" 
alignment="0" min="-2" max="-2" attributes="0"/>
                               </Group>
                           </Group>
                           <Group type="102" attributes="0">
@@ -158,6 +159,7 @@
                                           <Component 
id="wrapForRightParenCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
                                       </Group>
                                   </Group>
+                                  <Component id="coalescingOpsLabel" 
alignment="0" min="-2" max="-2" attributes="0"/>
                               </Group>
                           </Group>
                       </Group>
@@ -256,6 +258,11 @@
                           <Component id="ternaryOpsLabel" alignment="3" 
min="-2" max="-2" attributes="0"/>
                           <Component id="ternaryOpsCombo" alignment="3" 
min="-2" max="-2" attributes="0"/>
                       </Group>
+                      <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="3" attributes="0">
+                          <Component id="coalescingOpsLabel" alignment="3" 
min="-2" max="-2" attributes="0"/>
+                          <Component id="coalescingOpsCombo" alignment="3" 
min="-2" max="-2" attributes="0"/>
+                      </Group>
                       <EmptySpace type="unrelated" min="-2" max="-2" 
attributes="0"/>
                       <Group type="103" groupAlignment="3" attributes="0">
                           <Component id="assignOpsLabel" alignment="3" 
min="-2" max="-2" attributes="0"/>
@@ -792,6 +799,39 @@
                 </Property>
               </AccessibilityProperties>
             </Component>
+            <Component class="javax.swing.JLabel" name="coalescingOpsLabel">
+              <Properties>
+                <Property name="labelFor" type="java.awt.Component" 
editor="org.netbeans.modules.form.ComponentChooserEditor">
+                  <ComponentRef name="coalescingOpsCombo"/>
+                </Property>
+                <Property name="text" type="java.lang.String" 
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString 
bundle="org/netbeans/modules/php/editor/indent/ui/Bundle.properties" 
key="FmtWrapping.coalescingOpsLabel.text" 
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, 
&quot;{key}&quot;)"/>
+                </Property>
+              </Properties>
+              <AccessibilityProperties>
+                <Property name="AccessibleContext.accessibleName" 
type="java.lang.String" 
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString 
bundle="org/netbeans/modules/php/editor/indent/ui/Bundle.properties" 
key="FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleName" 
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, 
&quot;{key}&quot;)"/>
+                </Property>
+                <Property name="AccessibleContext.accessibleDescription" 
type="java.lang.String" 
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+                  <ResourceString 
bundle="org/netbeans/modules/php/editor/indent/ui/Bundle.properties" 
key="FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleDescription" 
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, 
&quot;{key}&quot;)"/>
+                </Property>
+              </AccessibilityProperties>
+            </Component>
+            <Component class="javax.swing.JComboBox" name="coalescingOpsCombo">
+              <Properties>
+                <Property name="model" type="javax.swing.ComboBoxModel" 
editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+                  <StringArray count="4">
+                    <StringItem index="0" value="Item 1"/>
+                    <StringItem index="1" value="Item 2"/>
+                    <StringItem index="2" value="Item 3"/>
+                    <StringItem index="3" value="Item 4"/>
+                  </StringArray>
+                </Property>
+              </Properties>
+              <AuxValues>
+                <AuxValue name="JavaCodeGenerator_TypeParameters" 
type="java.lang.String" value="&lt;String&gt;"/>
+              </AuxValues>
+            </Component>
             <Component class="javax.swing.JLabel" name="assignOpsLabel">
               <Properties>
                 <Property name="labelFor" type="java.awt.Component" 
editor="org.netbeans.modules.form.ComponentChooserEditor">
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.java 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.java
index 8427b7227a..448ec47bd6 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/FmtWrapping.java
@@ -87,6 +87,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
         binaryOpsCombo.addFocusListener(this);
         ternaryOpsCombo.putClientProperty(OPTION_ID, WRAP_TERNARY_OPS);
         ternaryOpsCombo.addFocusListener(this);
+        coalescingOpsCombo.putClientProperty(OPTION_ID, WRAP_COALESCING_OPS);
+        coalescingOpsCombo.addFocusListener(this);
         assignOpsCombo.putClientProperty(OPTION_ID, WRAP_ASSIGN_OPS);
         assignOpsCombo.addFocusListener(this);
         cbOpenCloseBlockBrace.putClientProperty(OPTION_ID, WRAP_BLOCK_BRACES);
@@ -160,6 +162,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
         binaryOpsCombo = new JComboBox();
         ternaryOpsLabel = new JLabel();
         ternaryOpsCombo = new JComboBox();
+        coalescingOpsLabel = new JLabel();
+        coalescingOpsCombo = new JComboBox<>();
         assignOpsLabel = new JLabel();
         assignOpsCombo = new JComboBox();
         cbOpenCloseBlockBrace = new JCheckBox();
@@ -361,6 +365,11 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
 
             ternaryOpsCombo.setModel(new DefaultComboBoxModel(new String[] { 
"Item 1", "Item 2", "Item 3", "Item 4" }));
 
+            coalescingOpsLabel.setLabelFor(coalescingOpsCombo);
+            Mnemonics.setLocalizedText(coalescingOpsLabel, 
NbBundle.getMessage(FmtWrapping.class, "FmtWrapping.coalescingOpsLabel.text")); 
// NOI18N
+
+            coalescingOpsCombo.setModel(new DefaultComboBoxModel<>(new 
String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
+
             assignOpsLabel.setLabelFor(assignOpsCombo);
             Mnemonics.setLocalizedText(assignOpsLabel, 
NbBundle.getMessage(FmtWrapping.class, "LBL_wrp_assignOps")); // NOI18N
 
@@ -424,7 +433,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
                                 .addComponent(doWhileStatementCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)
                                 .addComponent(binaryOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)
                                 .addComponent(ternaryOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)
-                                .addComponent(assignOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)))
+                                .addComponent(assignOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)
+                                .addComponent(coalescingOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE)))
                         .addGroup(panel1Layout.createSequentialGroup()
                             .addContainerGap()
                             
.addGroup(panel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
@@ -462,7 +472,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
                                         
.addComponent(wrapMethodCallArgsRightParenCheckBox)
                                         
.addComponent(wrapMethodParamsKeepParenAndBraceOnSameLineCheckBox)
                                         
.addComponent(wrapForAfterLeftParenCheckBox)
-                                        
.addComponent(wrapForRightParenCheckBox))))))
+                                        
.addComponent(wrapForRightParenCheckBox)))
+                                .addComponent(coalescingOpsLabel))))
                     .addContainerGap(GroupLayout.DEFAULT_SIZE, 
Short.MAX_VALUE))
             );
             
panel1Layout.setVerticalGroup(panel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
@@ -542,6 +553,10 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
                         .addComponent(ternaryOpsLabel)
                         .addComponent(ternaryOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE))
                     .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
+                    
.addGroup(panel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
+                        .addComponent(coalescingOpsLabel)
+                        .addComponent(coalescingOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                     
.addGroup(panel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                         .addComponent(assignOpsLabel)
                         .addComponent(assignOpsCombo, 
GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, 
GroupLayout.PREFERRED_SIZE))
@@ -606,6 +621,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
             
ternaryOpsLabel.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.ternaryOpsLabel.AccessibleContext.accessibleDescription")); // 
NOI18N
             
ternaryOpsCombo.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.ternaryOpsCombo.AccessibleContext.accessibleName")); // NOI18N
             
ternaryOpsCombo.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.ternaryOpsCombo.AccessibleContext.accessibleDescription")); // 
NOI18N
+            
coalescingOpsLabel.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleName")); // NOI18N
+            
coalescingOpsLabel.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.coalescingOpsLabel.AccessibleContext.accessibleDescription")); // 
NOI18N
             
assignOpsLabel.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.assignOpsLabel.AccessibleContext.accessibleName")); // NOI18N
             
assignOpsLabel.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.assignOpsLabel.AccessibleContext.accessibleDescription")); // 
NOI18N
             
assignOpsCombo.getAccessibleContext().setAccessibleName(NbBundle.getMessage(FmtWrapping.class,
 "FmtWrapping.assignOpsCombo.AccessibleContext.accessibleName")); // NOI18N
@@ -642,6 +659,8 @@ public class FmtWrapping extends javax.swing.JPanel 
implements FocusListener {
     private JCheckBox cbStatements;
     private JComboBox chainedMethodCallsCombo;
     private JLabel chainedMethodCallsLabel;
+    private JComboBox<String> coalescingOpsCombo;
+    private JLabel coalescingOpsLabel;
     private JComboBox doWhileStatementCombo;
     private JLabel doWhileStatementLabel;
     private JComboBox extendsImplementsKeywordCombo;
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Spaces.php 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Spaces.php
index 1e9d0f3793..aa7c76110e 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Spaces.php
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Spaces.php
@@ -22,6 +22,10 @@ private ClassA&ClassB $intersectionType;
        $result = $a < $b ? $a : $b;
     }
 
+    public function coalescingOperatorExample(?string $a): string {
+        return $a ?? 'default value';
+    }
+
 public function forExample() {
     for ($i = 1; $i <= 10; $i++) {echo 'Item: '; echo $i;}
 }
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Wrapping.php 
b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Wrapping.php
index 87e94c8f54..cb7ab06172 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Wrapping.php
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/indent/ui/Wrapping.php
@@ -15,6 +15,10 @@ class Example extends Foo implements Bar, Baz {
        $result = $a < $b ? $a : $b;
     }
 
+    public function coalescingOperatorExample(?string $a): string {
+        return $a ?? 'default value';
+    }
+
 public function forExample() {
     for ($i = 1; $i <= 10; $i++) echo 'Item: ';
 }
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp09.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp01.php
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp09.php
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp01.php
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp09.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp01.php.formatted
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp09.php.formatted
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp01.php.formatted
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp10.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp02.php
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp10.php
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp02.php
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp10.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp02.php.formatted
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp10.php.formatted
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp02.php.formatted
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp11.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp03.php
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp11.php
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp03.php
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp11.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp03.php.formatted
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp11.php.formatted
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp03.php.formatted
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp12.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp04.php
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp12.php
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp04.php
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp12.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp04.php.formatted
similarity index 100%
rename from 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundTernaryOp12.php.formatted
rename to 
php/php.editor/test/unit/data/testfiles/formatting/spaces/spaceAroundCoalescingOp04.php.formatted
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php
new file mode 100644
index 0000000000..97baf91cbb
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= $_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php.formatted
new file mode 100644
index 0000000000..be65df880d
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01a.php.formatted
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['user']
+        ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php
new file mode 100644
index 0000000000..7151df8b65
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= $_GET['username']   ??$_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php.formatted
new file mode 100644
index 0000000000..c89861c938
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp01b.php.formatted
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['username']
+        ?? $_GET['user']
+        ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php
new file mode 100644
index 0000000000..c28ad6737c
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username=$_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php.formatted
new file mode 100644
index 0000000000..cf8f24a202
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02a.php.formatted
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['user'] ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php
new file mode 100644
index 0000000000..92fd659695
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= $_GET['username']   ??$_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php.formatted
new file mode 100644
index 0000000000..76ee4597a4
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp02b.php.formatted
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['username'] ?? $_GET['user'] ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php
new file mode 100644
index 0000000000..76dd569b92
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username=      $_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php.formatted
new file mode 100644
index 0000000000..cf8f24a202
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03a.php.formatted
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['user'] ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php
new file mode 100644
index 0000000000..7151df8b65
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= $_GET['username']   ??$_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php.formatted
new file mode 100644
index 0000000000..76ee4597a4
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp03b.php.formatted
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = $_GET['username'] ?? $_GET['user'] ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php
new file mode 100644
index 0000000000..fdb34c9220
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php
@@ -0,0 +1,20 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= 
$_GET['loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_user']??
   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php.formatted
new file mode 100644
index 0000000000..71e4a33075
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04a.php.formatted
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = 
$_GET['loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_user']
+            ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php
new file mode 100644
index 0000000000..cf092cb59e
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+    $username= 
$_GET['loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_username']
   ??$_GET['user']
+            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php.formatted
new file mode 100644
index 0000000000..d3f8926b02
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/coalescingOp04b.php.formatted
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$username = 
$_GET['loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_username']
+            ?? $_GET['user'] ?? 'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php
deleted file mode 100644
index e6b864048e..0000000000
--- 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-    $username= $_GET['username']   ??$_GET['user']
-            ??   'guest';
diff --git 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php.formatted
 
b/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php.formatted
deleted file mode 100644
index ece08dcf89..0000000000
--- 
a/php/php.editor/test/unit/data/testfiles/formatting/wrapping/ternaryOp07.php.formatted
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-
-$username = $_GET['username']
-        ?? $_GET['user']
-        ?? 'guest';
diff --git 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterSpacesTest.java
 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterSpacesTest.java
index 7ba212da07..12d88c6e6d 100644
--- 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterSpacesTest.java
+++ 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterSpacesTest.java
@@ -793,28 +793,28 @@ public class PHPFormatterSpacesTest extends 
PHPFormatterTestBase {
         
reformatFileContents("testfiles/formatting/spaces/spaceAroundTernaryOp08.php", 
options);
     }
 
-    public void testSpacesAroundTernaryOp09() throws Exception {
-        HashMap<String, Object> options = new HashMap<String, 
Object>(FmtOptions.getDefaults());
-        options.put(FmtOptions.SPACE_AROUND_TERNARY_OPS, false);
-        
reformatFileContents("testfiles/formatting/spaces/spaceAroundTernaryOp09.php", 
options);
+    public void testSpacesAroundCoalescingOp01() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.SPACE_AROUND_COALESCING_OPS, false);
+        
reformatFileContents("testfiles/formatting/spaces/spaceAroundCoalescingOp01.php",
 options);
     }
 
-    public void testSpacesAroundTernaryOp10() throws Exception {
-        HashMap<String, Object> options = new HashMap<String, 
Object>(FmtOptions.getDefaults());
-        options.put(FmtOptions.SPACE_AROUND_TERNARY_OPS, true);
-        
reformatFileContents("testfiles/formatting/spaces/spaceAroundTernaryOp10.php", 
options);
+    public void testSpacesAroundCoalescingOp02() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.SPACE_AROUND_COALESCING_OPS, true);
+        
reformatFileContents("testfiles/formatting/spaces/spaceAroundCoalescingOp02.php",
 options);
     }
 
-    public void testSpacesAroundTernaryOp11() throws Exception {
-        HashMap<String, Object> options = new HashMap<String, 
Object>(FmtOptions.getDefaults());
-        options.put(FmtOptions.SPACE_AROUND_TERNARY_OPS, true);
-        
reformatFileContents("testfiles/formatting/spaces/spaceAroundTernaryOp11.php", 
options);
+    public void testSpacesAroundCoalescingOp03() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.SPACE_AROUND_COALESCING_OPS, true);
+        
reformatFileContents("testfiles/formatting/spaces/spaceAroundCoalescingOp03.php",
 options);
     }
 
-    public void testSpacesAroundTernaryOp12() throws Exception {
-        HashMap<String, Object> options = new HashMap<String, 
Object>(FmtOptions.getDefaults());
-        options.put(FmtOptions.SPACE_AROUND_TERNARY_OPS, false);
-        
reformatFileContents("testfiles/formatting/spaces/spaceAroundTernaryOp12.php", 
options);
+    public void testSpacesAroundCoalescingOp04() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.SPACE_AROUND_COALESCING_OPS, false);
+        
reformatFileContents("testfiles/formatting/spaces/spaceAroundCoalescingOp04.php",
 options);
     }
 
     public void testSpacesAroundKeyValue01() throws Exception {
diff --git 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterWrappingTest.java
 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterWrappingTest.java
index 28ac1e0c11..ea17685c41 100644
--- 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterWrappingTest.java
+++ 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/indent/PHPFormatterWrappingTest.java
@@ -656,10 +656,46 @@ public class PHPFormatterWrappingTest extends 
PHPFormatterTestBase {
         reformatFileContents("testfiles/formatting/wrapping/ternaryOp06.php", 
options);
     }
 
-    public void testTernaryOp07() throws Exception {
-        HashMap<String, Object> options = new HashMap<String, 
Object>(FmtOptions.getDefaults());
-        options.put(FmtOptions.WRAP_TERNARY_OPS, 
CodeStyle.WrapStyle.WRAP_ALWAYS);
-        reformatFileContents("testfiles/formatting/wrapping/ternaryOp07.php", 
options);
+    public void testCoalescingOp01a() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_ALWAYS);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp01a.php", 
options);
+    }
+
+    public void testCoalescingOp01b() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_ALWAYS);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp01b.php", 
options);
+    }
+
+    public void testCoalescingOp02a() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_NEVER);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp02a.php", 
options);
+    }
+
+    public void testCoalescingOp02b() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_NEVER);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp02b.php", 
options);
+    }
+
+    public void testCoalescingOp03a() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_IF_LONG);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp03a.php", 
options);
+    }
+
+    public void testCoalescingOp04a() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_IF_LONG);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp04a.php", 
options);
+    }
+
+    public void testCoalescingOp04b() throws Exception {
+        HashMap<String, Object> options = new 
HashMap<>(FmtOptions.getDefaults());
+        options.put(FmtOptions.WRAP_COALESCING_OPS, 
CodeStyle.WrapStyle.WRAP_IF_LONG);
+        
reformatFileContents("testfiles/formatting/wrapping/coalescingOp04b.php", 
options);
     }
 
     public void testIssue189722_01() throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to