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

junichi11 pushed a commit to branch php-nb21-features
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit ab297022ed085f8486337bc9803f650350a68caf
Author: Junichi Yamamoto <junich...@apache.org>
AuthorDate: Thu Sep 28 22:48:23 2023 +0900

    PHP 8.2 Support: Disjunctive Normal Form Types (Part 4)
    
    - https://github.com/apache/netbeans/issues/4725
    - https://wiki.php.net/rfc/dnf_types
    - Fix DNF field types for the navigator
---
 .../org/netbeans/modules/php/editor/CodeUtils.java |  1 +
 .../modules/php/editor/csl/NavigatorScanner.java   | 19 ++----
 .../php/editor/model/impl/FieldElementImpl.java    | 11 +---
 .../php/editor/model/impl/ModelVisitor.java        | 75 +++++++++++++++++-----
 .../modules/php/editor/model/impl/Type.java        |  1 +
 .../php/editor/model/impl/VariousUtils.java        | 14 ++++
 .../structure/deprecatedTypedFields.pass           |  8 +--
 .../php82/deprecatedDnfFieldTypes_01.pass          | 23 +++++++
 .../structure/php82/dnfFieldTypes.pass             | 23 +++++++
 .../structure/php82/deprecatedDnfFieldTypes_01.php | 58 +++++++++++++++++
 .../testfiles/structure/php82/dnfFieldTypes.php    | 55 ++++++++++++++++
 .../php/editor/csl/NavigatorDeprecatedTest.java    |  4 ++
 .../modules/php/editor/csl/NavigatorTest.java      |  4 ++
 13 files changed, 252 insertions(+), 44 deletions(-)

diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/CodeUtils.java 
b/php/php.editor/src/org/netbeans/modules/php/editor/CodeUtils.java
index ab54785743..746fecc67a 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/CodeUtils.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/CodeUtils.java
@@ -90,6 +90,7 @@ public final class CodeUtils {
     public static final String ELLIPSIS = "..."; // NOI18N
 
     public static final Pattern WHITE_SPACES_PATTERN = 
Pattern.compile("\\s+"); // NOI18N
+    public static final Pattern SPLIT_TYPES_PATTERN = 
Pattern.compile("[()|&]"); // NOI18N
 
     private static final Logger LOGGER = 
Logger.getLogger(CodeUtils.class.getName());
 
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/csl/NavigatorScanner.java 
b/php/php.editor/src/org/netbeans/modules/php/editor/csl/NavigatorScanner.java
index 3eed34cc26..a03c7c80f5 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/csl/NavigatorScanner.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/csl/NavigatorScanner.java
@@ -481,7 +481,7 @@ public final class NavigatorScanner {
             if (declaredType == null) {
                 return;
             }
-            if (isReturn) {
+            if (isReturn || modelElement instanceof FieldElement) {
                 formatter.appendHtml(FONT_GRAY_COLOR + ":"); // NOI18N
             } else {
                 formatter.appendHtml(FONT_GRAY_COLOR);
@@ -508,7 +508,7 @@ public final class NavigatorScanner {
             if (sb.length() > 0) {
                 processTypeName(sb, modelElement, formatter);
             }
-            if (!isReturn) {
+            if (!isReturn && modelElement instanceof FunctionScope) { // 
parameter
                 formatter.appendText(" "); // NOI18N
             }
             formatter.appendHtml(CLOSE_FONT);
@@ -606,19 +606,8 @@ public final class NavigatorScanner {
             if (field.isDeprecated()) {
                 formatter.deprecated(false);
             }
-            Collection<? extends String> types = field.getDefaultTypeNames();
-            boolean isIntersectionType = field.getDefaultType() != null && 
field.getDefaultType().contains(Type.SEPARATOR_INTERSECTION);
-            if (!types.isEmpty()) {
-                formatter.appendHtml(FONT_GRAY_COLOR + ":"); //NOI18N
-                int i = 0;
-                for (String type : types) {
-                    i++;
-                    if (i > 1) {
-                        
formatter.appendText(Type.getTypeSeparator(isIntersectionType));
-                    }
-                    processTypeName(type, field, formatter);
-                }
-                formatter.appendHtml(CLOSE_FONT);
+            if (StringUtils.hasText(field.getDefaultType())) {
+                processDeclaredType(field, formatter, field.getDefaultType(), 
false);
             }
             return formatter.getText();
         }
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/FieldElementImpl.java
 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/FieldElementImpl.java
index c258cdc3bb..e3d68b1494 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/FieldElementImpl.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/FieldElementImpl.java
@@ -252,16 +252,7 @@ class FieldElementImpl extends ScopeImpl implements 
FieldElement {
 
     @Override
     public Collection<? extends String> getDefaultTypeNames() {
-        Collection<String> retval = Collections.<String>emptyList();
-        if (defaultType != null && defaultType.length() > 0) {
-            retval = new ArrayList<>();
-            for (String typeName : defaultType.split("\\&|\\|")) { //NOI18N
-                if (!VariousUtils.isSemiType(typeName)) {
-                    retval.add(typeName);
-                }
-            }
-        }
-        return retval;
+        return VariousUtils.getAllTypeNames(defaultType);
     }
 
     @CheckForNull
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
index b5ac842240..76cde49e4f 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
@@ -1354,26 +1354,20 @@ public final class ModelVisitor extends 
DefaultTreePathVisitor {
     @Override
     public void visit(PHPDocVarTypeTag node) {
         Scope currentScope = modelBuilder.getCurrentScope();
-        StringBuilder sb = new StringBuilder();
-        StringBuilder fqNames = new StringBuilder();
+        String defaultType = null;
+        String fqType = null;
+        if (isPropertyTag(node)) {
+            defaultType = getDefaultType(node);
+            if (defaultType != null) {
+                fqType = getFqName(defaultType, node, currentScope);
+            }
+        }
         List<? extends PhpDocTypeTagInfo> tagInfos = 
PhpDocTypeTagInfo.create(node, currentScope);
         for (Iterator<? extends PhpDocTypeTagInfo> it = tagInfos.iterator(); 
it.hasNext();) {
             PhpDocTypeTagInfo phpDocTypeTagInfo = it.next();
             if (phpDocTypeTagInfo.getKind().equals(Kind.FIELD) && 
!phpDocTypeTagInfo.getName().isEmpty()) {
-                String typeName = phpDocTypeTagInfo.getTypeName();
-                if (typeName != null) {
-                    if (sb.length() > 0) {
-                        sb.append(SEPARATOR);
-                    }
-                    if (fqNames.length() > 0) {
-                        fqNames.append(SEPARATOR);
-                    }
-                    String qualifiedTypeNames = 
VariousUtils.qualifyTypeNames(typeName, node.getStartOffset(), currentScope);
-                    fqNames.append(qualifiedTypeNames);
-                    sb.append(typeName);
-                }
                 if ((currentScope instanceof ClassScope || currentScope 
instanceof TraitScope) && !it.hasNext()) {
-                    new FieldElementImpl(currentScope, sb.length() > 0 ? 
sb.toString() : null, fqNames.length() > 0 ? fqNames.toString() : null, 
phpDocTypeTagInfo, true);
+                    new FieldElementImpl(currentScope, defaultType, fqType, 
phpDocTypeTagInfo, true);
                 }
             } else if (node.getKind().equals(PHPDocTag.Type.GLOBAL) && 
phpDocTypeTagInfo.getKind().equals(Kind.VARIABLE)) {
                 final String typeName = phpDocTypeTagInfo.getTypeName();
@@ -1398,6 +1392,57 @@ public final class ModelVisitor extends 
DefaultTreePathVisitor {
         super.visit(node);
     }
 
+    private static boolean isPropertyTag(PHPDocVarTypeTag node) {
+        return node.getKind() == PHPDocTag.Type.PROPERTY
+                || node.getKind() == PHPDocTag.Type.PROPERTY_READ
+                || node.getKind() == PHPDocTag.Type.PROPERTY_WRITE
+                || node.getKind() == PHPDocTag.Type.PARAM;
+    }
+
+    private String getDefaultType(PHPDocVarTypeTag node) {
+        // e.g. @property (X&Y)|Z $prop description
+        String[] values = node.getValue().trim().split(" ", 2); // NOI18N
+        if (values[0].startsWith("$") || values.length < 2) { // NOI18N
+            return null;
+        }
+        // e.g. string[]
+        String defaultType = values[0].replace("[]", ""); // NOI18N
+        return defaultType;
+    }
+
+    private String getFqName(String defaultType, PHPDocVarTypeTag node, Scope 
currentScope) {
+        int typeStart = 0;
+        String fqType = null;
+        StringBuilder fqNames = new StringBuilder();
+        for (int i = 0; i < defaultType.length(); i++) {
+            switch (defaultType.charAt(i)) {
+                case '(': // no break
+                case ')': // no break
+                case '|': // no break
+                case '&': // no break
+                case '?':
+                    String type = defaultType.substring(typeStart, i);
+                    if (!type.isEmpty()) {
+                        fqNames.append(VariousUtils.qualifyTypeNames(type, 
node.getStartOffset(), currentScope));
+                    }
+                    fqNames.append(defaultType.charAt(i));
+                    typeStart = i + 1;
+                    break;
+                default:
+                    // noop
+                    break;
+            }
+            if (i == defaultType.length() - 1) {
+                String type = defaultType.substring(typeStart, 
defaultType.length());
+                if (!type.isEmpty()) {
+                    fqNames.append(VariousUtils.qualifyTypeNames(type, 
node.getStartOffset(), currentScope));
+                }
+                fqType = fqNames.length() > 0 ? fqNames.toString() : null;
+            }
+        }
+        return fqType;
+    }
+
     public FileScope getFileScope() {
         return fileScope;
     }
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/Type.java 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/Type.java
index 523e6a56b1..e7bbcc949d 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/Type.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/Type.java
@@ -21,6 +21,7 @@ package org.netbeans.modules.php.editor.model.impl;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.regex.Pattern;
 import org.netbeans.api.annotations.common.NullAllowed;
 import org.netbeans.modules.php.api.util.StringUtils;
 
diff --git 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
index 9c70064b09..3f48d78e32 100644
--- 
a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
+++ 
b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
@@ -2040,6 +2040,20 @@ public final class VariousUtils {
         return typeName != null && 
typeName.contains(PRE_OPERATION_TYPE_DELIMITER);
     }
 
+    public static List<String> getAllTypeNames(String declaredTypes) {
+        if (!StringUtils.hasText(declaredTypes)) {
+            return Collections.emptyList();
+        }
+        List<String> typeNames = new ArrayList<>();
+        // e.g. (X&Y)|Z
+        for (String typeName : 
CodeUtils.SPLIT_TYPES_PATTERN.split(declaredTypes.trim())) {
+            if (!typeName.isEmpty() && !VariousUtils.isSemiType(typeName)) {
+                typeNames.add(typeName);
+            }
+        }
+        return typeNames;
+    }
+
     //~ inner class
     private static class CloneExpressionInfo {
 
diff --git 
a/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/deprecatedTypedFields.pass
 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/deprecatedTypedFields.pass
index 2710b981f1..5be209c5f4 100644
--- 
a/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/deprecatedTypedFields.pass
+++ 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/deprecatedTypedFields.pass
@@ -5,14 +5,14 @@
 |--$nullableTypeField [998, 1015] : 
DEPRECATED{ESCAPED{$nullableTypeField}}<font 
color="#999999">:ESCAPED{?}ESCAPED{string}</font>
 |--$unionTypeField [1084, 1098] : DEPRECATED{ESCAPED{$unionTypeField}}<font 
color="#999999">:ESCAPED{string}ESCAPED{|}ESCAPED{TypedFields}</font>
 |--$intersectionTypeField [1156, 1177] : 
DEPRECATED{ESCAPED{$intersectionTypeField}}<font 
color="#999999">:ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}</font>
-|--$dnfTypeField [1241, 1253] : DEPRECATED{ESCAPED{$dnfTypeField}}<font 
color="#999999">:ESCAPED{(Foo}ESCAPED{&}ESCAPED{Bar)}ESCAPED{&}ESCAPED{Baz}</font>
+|--$dnfTypeField [1241, 1253] : DEPRECATED{ESCAPED{$dnfTypeField}}<font 
color="#999999">:ESCAPED{(}ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}ESCAPED{)}ESCAPED{|}ESCAPED{Baz}</font>
 |--$typedStaticField [1302, 1318] : 
DEPRECATED{ESCAPED{$typedStaticField}}<font color="#999999">:ESCAPED{int}</font>
 |--$multiStaticField1 [1367, 1384] : 
DEPRECATED{ESCAPED{$multiStaticField1}}<font 
color="#999999">:ESCAPED{int}</font>
 |--$multiStaticField2 [1387, 1404] : 
DEPRECATED{ESCAPED{$multiStaticField2}}<font 
color="#999999">:ESCAPED{int}</font>
 |--$nullableTypeStaticField [1457, 1480] : 
DEPRECATED{ESCAPED{$nullableTypeStaticField}}<font 
color="#999999">:ESCAPED{?}ESCAPED{string}</font>
 |--$unionTypeStaticField [1556, 1576] : 
DEPRECATED{ESCAPED{$unionTypeStaticField}}<font 
color="#999999">:ESCAPED{string}ESCAPED{|}ESCAPED{TypedFields}</font>
 |--$intersectionTypeStaticField [1641, 1668] : 
DEPRECATED{ESCAPED{$intersectionTypeStaticField}}<font 
color="#999999">:ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}</font>
-|--$dnfTypeStaticField [1739, 1757] : 
DEPRECATED{ESCAPED{$dnfTypeStaticField}}<font 
color="#999999">:ESCAPED{(Foo}ESCAPED{&}ESCAPED{Bar)}ESCAPED{&}ESCAPED{Baz}</font>
+|--$dnfTypeStaticField [1739, 1757] : 
DEPRECATED{ESCAPED{$dnfTypeStaticField}}<font 
color="#999999">:ESCAPED{(}ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}ESCAPED{)}ESCAPED{|}ESCAPED{Baz}</font>
 |-TypedFieldsTrait [1768, 2712] : ESCAPED{TypedFieldsTrait}
 |--$typedField [1827, 1837] : DEPRECATED{ESCAPED{$typedField}}<font 
color="#999999">:ESCAPED{int}</font>
 |--$multiField1 [1879, 1890] : DEPRECATED{ESCAPED{$multiField1}}<font 
color="#999999">:ESCAPED{int}</font>
@@ -20,11 +20,11 @@
 |--$nullableTypeField [1950, 1967] : 
DEPRECATED{ESCAPED{$nullableTypeField}}<font 
color="#999999">:ESCAPED{?}ESCAPED{string}</font>
 |--$unionTypeField [2036, 2050] : DEPRECATED{ESCAPED{$unionTypeField}}<font 
color="#999999">:ESCAPED{string}ESCAPED{|}ESCAPED{TypedFields}</font>
 |--$intersectionTypeField [2108, 2129] : 
DEPRECATED{ESCAPED{$intersectionTypeField}}<font 
color="#999999">:ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}</font>
-|--$dnfTypeField [2193, 2205] : DEPRECATED{ESCAPED{$dnfTypeField}}<font 
color="#999999">:ESCAPED{(Foo}ESCAPED{&}ESCAPED{Bar)}ESCAPED{&}ESCAPED{Baz}</font>
+|--$dnfTypeField [2193, 2205] : DEPRECATED{ESCAPED{$dnfTypeField}}<font 
color="#999999">:ESCAPED{(}ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}ESCAPED{)}ESCAPED{|}ESCAPED{Baz}</font>
 |--$typedStaticField [2254, 2270] : 
DEPRECATED{ESCAPED{$typedStaticField}}<font color="#999999">:ESCAPED{int}</font>
 |--$multiStaticField1 [2319, 2336] : 
DEPRECATED{ESCAPED{$multiStaticField1}}<font 
color="#999999">:ESCAPED{int}</font>
 |--$multiStaticField2 [2339, 2356] : 
DEPRECATED{ESCAPED{$multiStaticField2}}<font 
color="#999999">:ESCAPED{int}</font>
 |--$nullableTypeStaticField [2409, 2432] : 
DEPRECATED{ESCAPED{$nullableTypeStaticField}}<font 
color="#999999">:ESCAPED{?}ESCAPED{string}</font>
 |--$unionTypeStaticField [2508, 2528] : 
DEPRECATED{ESCAPED{$unionTypeStaticField}}<font 
color="#999999">:ESCAPED{string}ESCAPED{|}ESCAPED{TypedFields}</font>
 |--$intersectionTypeStaticField [2593, 2620] : 
DEPRECATED{ESCAPED{$intersectionTypeStaticField}}<font 
color="#999999">:ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}</font>
-|--$dnfTypeStaticField [2691, 2709] : 
DEPRECATED{ESCAPED{$dnfTypeStaticField}}<font 
color="#999999">:ESCAPED{(Foo}ESCAPED{&}ESCAPED{Bar)}ESCAPED{&}ESCAPED{Baz}</font>
+|--$dnfTypeStaticField [2691, 2709] : 
DEPRECATED{ESCAPED{$dnfTypeStaticField}}<font 
color="#999999">:ESCAPED{(}ESCAPED{Foo}ESCAPED{&}ESCAPED{Bar}ESCAPED{)}ESCAPED{|}ESCAPED{Baz}</font>
diff --git 
a/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/php82/deprecatedDnfFieldTypes_01.pass
 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/php82/deprecatedDnfFieldTypes_01.pass
new file mode 100644
index 0000000000..a01eb0670f
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest/structure/php82/deprecatedDnfFieldTypes_01.pass
@@ -0,0 +1,23 @@
+|-X [820, 824] : ESCAPED{X}
+|-Y [831, 835] : ESCAPED{Y}
+|-Z [842, 846] : ESCAPED{Z}
+|-DeprecatedType [876, 893] : DEPRECATED{ESCAPED{DeprecatedType}}
+|-TestClass [901, 1293] : ESCAPED{TestClass}
+|--$dnfType1 [947, 955] : ESCAPED{$dnfType1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}DEPRECATED{ESCAPED{DeprecatedType}}</font>
+|--$dnfType2 [993, 1001] : ESCAPED{$dnfType2}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{)}ESCAPED{|}ESCAPED{Z}</font>
+|--$phpDocType1 [1067, 1078] : ESCAPED{$phpDocType1}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--__construct [1100, 1291] : ESCAPED{__construct}ESCAPED{(}<font 
color="#999999">DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{
 }</font>ESCAPED{$promotedField1}ESCAPED{, }<font 
color="#999999">ESCAPED{(}ESCAPED{X}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{
 }</font>ESCAPED{$promotedField2}ESCAPED{, }<font color="# [...]
+|--$promotedField1 [1157, 1171] : ESCAPED{$promotedField1}<font 
color="#999999">:DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$promotedField2 [1221, 1235] : ESCAPED{$promotedField2}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|-TestTrait [1301, 1523] : ESCAPED{TestTrait}
+|--$dnfType1 [1354, 1362] : ESCAPED{$dnfType1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{(}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{&}ESCAPED{Test}ESCAPED{)}</font>
+|--$dnfType2 [1406, 1414] : ESCAPED{$dnfType2}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$dnfType3 [1462, 1470] : ESCAPED{$dnfType3}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{(}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$dnfType4 [1512, 1520] : ESCAPED{$dnfType4}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}DEPRECATED{ESCAPED{\DeprecatedType}}ESCAPED{)}ESCAPED{|}ESCAPED{Test}</font>
+|-Properties [1843, 1856] : ESCAPED{Properties}
+|--$prop [1543, 1547] : ESCAPED{$prop}
+|--$prop1 [1595, 1600] : ESCAPED{$prop1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}DEPRECATED{ESCAPED{DeprecatedType}}</font>
+|--$prop2 [1653, 1658] : ESCAPED{$prop2}<font 
color="#999999">:DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$prop3 [1717, 1722] : ESCAPED{$prop3}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{Test}</font>
+|--$prop4 [1777, 1782] : ESCAPED{$prop4}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Test}ESCAPED{)}</font>
+|--$param [1827, 1832] : ESCAPED{$param}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}DEPRECATED{ESCAPED{DeprecatedType}}ESCAPED{)}</font>
diff --git 
a/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorTest/structure/php82/dnfFieldTypes.pass
 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorTest/structure/php82/dnfFieldTypes.pass
new file mode 100644
index 0000000000..e9bf4aa62d
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/csl/NavigatorTest/structure/php82/dnfFieldTypes.pass
@@ -0,0 +1,23 @@
+|-X [820, 824] : ESCAPED{X}
+|-Y [831, 835] : ESCAPED{Y}
+|-Z [842, 846] : ESCAPED{Z}
+|-Test [853, 860] : ESCAPED{Test}
+|-TestClass [868, 1182] : ESCAPED{TestClass}
+|--$dnfType1 [901, 909] : ESCAPED{$dnfType1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{Z}</font>
+|--$dnfType2 [934, 942] : ESCAPED{$dnfType2}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{Z}</font>
+|--$phpDocType1 [995, 1006] : ESCAPED{$phpDocType1}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--__construct [1028, 1180] : ESCAPED{__construct}ESCAPED{(}<font 
color="#999999">ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{
 }</font>ESCAPED{$promotedField1}ESCAPED{, }<font 
color="#999999">ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{
 }</font>ESCAPED{$promotedField2}ESCAPED{, }<font 
color="#999999">ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Z}ES [...]
+|--$promotedField1 [1072, 1086] : ESCAPED{$promotedField1}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$promotedField2 [1123, 1137] : ESCAPED{$promotedField2}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|-TestTrait [1190, 1360] : ESCAPED{TestTrait}
+|--$dnfType1 [1230, 1238] : ESCAPED{$dnfType1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Test}ESCAPED{)}</font>
+|--$dnfType2 [1269, 1277] : ESCAPED{$dnfType2}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{Y}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$dnfType3 [1312, 1320] : ESCAPED{$dnfType3}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$dnfType4 [1349, 1357] : ESCAPED{$dnfType4}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{\Z}ESCAPED{)}ESCAPED{|}ESCAPED{Test}</font>
+|-Properties [1618, 1631] : ESCAPED{Properties}
+|--$prop [1380, 1384] : ESCAPED{$prop}
+|--$prop1 [1422, 1427] : ESCAPED{$prop1}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Y}ESCAPED{)}ESCAPED{|}ESCAPED{Test}</font>
+|--$prop2 [1467, 1472] : ESCAPED{$prop2}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
+|--$prop3 [1518, 1523] : ESCAPED{$prop3}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{Test}</font>
+|--$prop4 [1565, 1570] : ESCAPED{$prop4}<font 
color="#999999">:ESCAPED{(}ESCAPED{X}ESCAPED{&}ESCAPED{Z}ESCAPED{)}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Test}ESCAPED{)}</font>
+|--$param [1602, 1607] : ESCAPED{$param}<font 
color="#999999">:ESCAPED{X}ESCAPED{|}ESCAPED{(}ESCAPED{Y}ESCAPED{&}ESCAPED{Z}ESCAPED{)}</font>
diff --git 
a/php/php.editor/test/unit/data/testfiles/structure/php82/deprecatedDnfFieldTypes_01.php
 
b/php/php.editor/test/unit/data/testfiles/structure/php82/deprecatedDnfFieldTypes_01.php
new file mode 100644
index 0000000000..3931877fd6
--- /dev/null
+++ 
b/php/php.editor/test/unit/data/testfiles/structure/php82/deprecatedDnfFieldTypes_01.php
@@ -0,0 +1,58 @@
+<?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.
+ */
+class X {}
+class Y {}
+class Z {}
+/**
+ * @deprecated
+ */
+class DeprecatedType {}
+
+class TestClass {
+    private (X&Y)|DeprecatedType $dnfType1;
+    private X|(X&DeprecatedType)|Z $dnfType2;
+    /**
+     * @var X|(X&DeprecatedType&Z)
+     */
+    private $phpDocType1;
+    public function __construct(
+            private DeprecatedType|(X&Y&Z) $promotedField1,
+            private (X&DeprecatedType)|(X&Y&Z) $promotedField2,
+            (DeprecatedType&Z)|Z $field,
+    ) {
+    }
+}
+
+trait TestTrait {
+    private (X&Y)|(DeprecatedType&Test) $dnfType1;
+    private (X&Y)|DeprecatedType|(X&Y&Z) $dnfType2;
+    private (X&Y)|(DeprecatedType&Z)|(X&Y&Z) $dnfType3;
+    private X|(Y&\DeprecatedType)|Test $dnfType4;
+}
+
+/**
+ * @property $prop Description
+ * @property (X&Y)|DeprecatedType $prop1 Description
+ * @property-read DeprecatedType|(Y&Z) $prop2 Description
+ * @property-write X|(DeprecatedType&Z)|Test $prop3 Description
+ * @property (X&DeprecatedType)|(Y&Test) $prop4 Description
+ * @param X|(Y&DeprecatedType) $param
+ */
+class Properties {}
diff --git 
a/php/php.editor/test/unit/data/testfiles/structure/php82/dnfFieldTypes.php 
b/php/php.editor/test/unit/data/testfiles/structure/php82/dnfFieldTypes.php
new file mode 100644
index 0000000000..c776a83a22
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/structure/php82/dnfFieldTypes.php
@@ -0,0 +1,55 @@
+<?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.
+ */
+class X {}
+class Y {}
+class Z {}
+class Test {}
+
+class TestClass {
+    private (X&Y)|Z $dnfType1;
+    private X|(X&Y)|Z $dnfType2;
+    /**
+     * @var X|(X&Y&Z)
+     */
+    private $phpDocType1;
+    public function __construct(
+            private X|(X&Y&Z) $promotedField1,
+            private (X&Z)|(X&Y&Z) $promotedField2,
+            (X&Z)|Z $field,
+    ) {
+    }
+}
+
+trait TestTrait {
+    private (X&Y)|(X&Test) $dnfType1;
+    private (X&Y)|Y|(X&Y&Z) $dnfType2;
+    private (X&Y)|(Y&Z)|(X&Y&Z) $dnfType3;
+    private X|(Y&\Z)|Test $dnfType4;
+}
+
+/**
+ * @property $prop Description
+ * @property (X&Y)|Test $prop1 Description
+ * @property-read X|(Y&Z) $prop2 Description
+ * @property-write X|(Y&Z)|Test $prop3 Description
+ * @property (X&Z)|(Y&Test) $prop4 Description
+ * @param X|(Y&Z) $param
+ */
+class Properties {}
diff --git 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest.java
 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest.java
index 165646673b..293c5eb5b1 100644
--- 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest.java
+++ 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorDeprecatedTest.java
@@ -70,6 +70,10 @@ public class NavigatorDeprecatedTest extends 
PhpNavigatorTestBase {
         performTest("structure/php82/deprecatedDnfParameterTypes_01");
     }
 
+    public void testDeprecatedTypesForDNFFieldTypes_01() throws Exception {
+        performTest("structure/php82/deprecatedDnfFieldTypes_01");
+    }
+
     @Override
     protected Map<String, ClassPath> createClassPathsForTest() {
         return Collections.singletonMap(
diff --git 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorTest.java
 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorTest.java
index 0504b8053b..b6970178a6 100644
--- 
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorTest.java
+++ 
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/NavigatorTest.java
@@ -140,4 +140,8 @@ public class NavigatorTest extends PhpNavigatorTestBase {
         performTest("structure/php82/dnfParameterTypes");
     }
 
+    public void testDNFFieldTypes() throws Exception {
+        performTest("structure/php82/dnfFieldTypes");
+    }
+
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

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

Reply via email to