You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by tm...@apache.org on 2020/08/06 11:14:35 UTC

[netbeans] branch php80-support updated: [NETBEANS-4443] PHP 8.0 Support: Allow ::class on objects part

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

tmysik pushed a commit to branch php80-support
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/php80-support by this push:
     new 6141e51  [NETBEANS-4443] PHP 8.0 Support: Allow ::class on objects part
     new f579054  Merge pull request #2295 from junichi11/php80-class-name-literal-on-object
6141e51 is described below

commit 6141e51285bc4cbee4c8c476fabcd8d2c676fa14
Author: Junichi Yamamoto <ju...@apache.org>
AuthorDate: Sun Jul 26 20:22:24 2020 +0900

    [NETBEANS-4443] PHP 8.0 Support: Allow ::class on objects part
    
    - https://wiki.php.net/rfc/class_name_literal_on_object
    - Fix code completion for `::class`
    - Fix unit tests for CC
    - Add unit tests for the parser
    - Fix the `PHP80UnhandledError`
---
 .../php/editor/completion/PHPCodeCompletion.java   |  20 +-
 .../parser/astnodes/StaticConstantAccess.java      |   8 +-
 .../editor/verification/PHP80UnhandledError.java   |  24 +
 .../parser/php80/classNameLiteralOnObjects_01.pass | 998 +++++++++++++++++++++
 ...1859_02.php.testNamespaceFunction_02.completion |   1 +
 .../nb4185/nb4185.php.testReturnSelf_03.completion |   1 +
 .../nb4185/nb4185.php.testReturnSelf_05.completion |   1 +
 .../nb4185/nb4185.php.testReturnSelf_06.completion |   1 +
 .../nb4185.php.testReturnStatic_03.completion      |   1 +
 .../nb4185.php.testReturnStatic_05.completion      |   1 +
 .../nb4185.php.testReturnStatic_06.completion      |   1 +
 .../nb4185/nb4185.php.testReturnThis_02.completion |   1 +
 .../lib/nb501/nb501.php.testNb501_03a.completion   |   1 +
 ...ax01.php.testUniformVariableSyntax01.completion |   1 +
 ...x03.php.testUniformVariableSyntax03b.completion |   1 +
 ...x03.php.testUniformVariableSyntax03c.completion |   1 +
 ...x03.php.testUniformVariableSyntax03d.completion |   1 +
 ...hp.testUVSNestedStaticFieldAccess_03.completion |   1 +
 ...hp.testUVSNestedStaticFieldAccess_04.completion |   1 +
 .../classNameLiteralOnObjects.php                  |  56 ++
 ...php.testClassNameLiteralOnObjects_01.completion |   4 +
 ...php.testClassNameLiteralOnObjects_02.completion |   4 +
 ...php.testClassNameLiteralOnObjects_03.completion |   4 +
 ...php.testClassNameLiteralOnObjects_04.completion |   4 +
 ...php.testClassNameLiteralOnObjects_05.completion |   4 +
 ...php.testClassNameLiteralOnObjects_06.completion |   4 +
 ...hp.testClassNameLiteralOnObjects_07.completion} |   3 +-
 ...icAccessFromEnclosedExtendedInstance.completion |   1 +
 ...testStaticAccessFromEnclosedInstance.completion |   1 +
 ...testStaticAccessFromExtendedInstance.completion |   1 +
 ...527.php.testStaticAccessFromInstance.completion |   1 +
 ...hp.testStaticAccessFromInstanceArray.completion |   1 +
 ...e240527.php.testStaticAccessFromThis.completion |   1 +
 .../issue269108.php.testReturnSelf_03.completion   |   1 +
 .../issue269108.php.testReturnSelf_05.completion   |   1 +
 .../issue269108.php.testReturnSelf_06.completion   |   1 +
 .../issue269108.php.testReturnStatic_03.completion |   1 +
 .../issue269108.php.testReturnStatic_05.completion |   1 +
 .../issue269108.php.testReturnStatic_06.completion |   1 +
 .../issue269108.php.testReturnThis_02.completion   |   1 +
 .../parser/php80/classNameLiteralOnObjects_01.php  |  61 ++
 .../php80/classNameLiteralOnObjects_01.php.errors  |   1 +
 .../editor/completion/PHP80CodeCompletionTest.java |  29 +
 .../completion/PHPCodeCompletion262141UVSTest.java |   1 -
 .../php/editor/parser/ASTPHP5ParserTest.java       |   4 +
 .../php/editor/parser/PhpParserErrorTest.java      |   4 +
 46 files changed, 1240 insertions(+), 21 deletions(-)

diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion.java b/php/php.editor/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion.java
index fa3fef8..da63612 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion.java
@@ -1291,18 +1291,16 @@ public class PHPCodeCompletion implements CodeCompletionHandler2 {
                         }
                     }
                     if (staticContext) {
-                        boolean isDynamicAccess = isDynamicAccess(varName);
                         Set<TypeConstantElement> magicConstants = constantsFilter.filter(request.index.getAccessibleMagicConstants(typeScope));
                         for (TypeConstantElement magicConstant : magicConstants) {
                             if (CancelSupport.getDefault().isCancelled()) {
                                 return;
                             }
                             if (magicConstant != null) {
-                                // dynamic class names are not allowed in complie-time
-                                // e.g. $instance::class, create()::class
-                                if ("class".equals(magicConstant.getName()) && isDynamicAccess) { // NOI18N
-                                    continue;
-                                }
+                                // NETBEANS-4443
+                                // PHP 8.0 allows ::class on objects (e.g. $instance::class, create()::class)
+                                // so don't restrict dynamic access any more
+                                // https://wiki.php.net/rfc/class_name_literal_on_object
                                 completionResult.add(PHPCompletionItem.TypeConstantItem.getItem(magicConstant, request));
                             }
                         }
@@ -1312,16 +1310,6 @@ public class PHPCodeCompletion implements CodeCompletionHandler2 {
         }
     }
 
-    private static boolean isDynamicAccess(CharSequence varName) {
-        if (varName != null) {
-            return varName.charAt(0) == '$'
-                    || varName.charAt(0) == ']' // array
-                    || varName.charAt(0) == '}'
-                    || varName.charAt(0) == ')';
-        }
-        return false;
-    }
-
     private void autoCompleteClassConstants(final PHPCompletionResult completionResult, final PHPCompletionItem.CompletionRequest request) {
         // NETBANS-1855
         // complete access prefix i.e. add "self::" to the top of constant names
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/parser/astnodes/StaticConstantAccess.java b/php/php.editor/src/org/netbeans/modules/php/editor/parser/astnodes/StaticConstantAccess.java
index c4bb857..c0dd664 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/parser/astnodes/StaticConstantAccess.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/parser/astnodes/StaticConstantAccess.java
@@ -19,9 +19,13 @@
 package org.netbeans.modules.php.editor.parser.astnodes;
 
 /**
- * Represents a constant class access
- * <pre>e.g.<pre> MyClass::CONST
+ * Represents a constant class access.
+ *
+ * e.g.
+ * <pre>
+ * MyClass::CONST
  * MyClass::CONSTANT[0]
+ * </pre>
  */
 public class StaticConstantAccess extends StaticDispatch {
 
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/verification/PHP80UnhandledError.java b/php/php.editor/src/org/netbeans/modules/php/editor/verification/PHP80UnhandledError.java
index 95c186e..8d871f6 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/verification/PHP80UnhandledError.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/verification/PHP80UnhandledError.java
@@ -42,8 +42,11 @@ import org.netbeans.modules.php.editor.parser.astnodes.Expression;
 import org.netbeans.modules.php.editor.parser.astnodes.ExpressionStatement;
 import org.netbeans.modules.php.editor.parser.astnodes.FormalParameter;
 import org.netbeans.modules.php.editor.parser.astnodes.FunctionDeclaration;
+import org.netbeans.modules.php.editor.parser.astnodes.Identifier;
 import org.netbeans.modules.php.editor.parser.astnodes.LambdaFunctionDeclaration;
 import org.netbeans.modules.php.editor.parser.astnodes.ThrowExpression;
+import org.netbeans.modules.php.editor.parser.astnodes.NamespaceName;
+import org.netbeans.modules.php.editor.parser.astnodes.StaticConstantAccess;
 import org.netbeans.modules.php.editor.parser.astnodes.visitors.DefaultVisitor;
 import org.openide.filesystems.FileObject;
 import org.openide.util.NbBundle;
@@ -140,6 +143,15 @@ public final class PHP80UnhandledError extends UnhandledErrorRule {
             super.visit(node);
         }
 
+        @Override
+        public void visit(StaticConstantAccess node) {
+            if (CancelSupport.getDefault().isCancelled()) {
+                return;
+            }
+            checkClassNameLiteralOnObject(node);
+            super.visit(node);
+        }
+
         private void addLastParam(List<FormalParameter> parameters) {
             if (!parameters.isEmpty()) {
                 lastParams.add(parameters.get(parameters.size() - 1));
@@ -218,6 +230,18 @@ public final class PHP80UnhandledError extends UnhandledErrorRule {
             }
         }
 
+        private void checkClassNameLiteralOnObject(StaticConstantAccess node) {
+            if ("class".equals(node.getConstantName().getName())) { // NOI18N
+                Expression dispatcher = node.getDispatcher();
+                if (!(dispatcher instanceof NamespaceName)
+                        && !(dispatcher instanceof Identifier)) {
+                    // other than namespacename(e.g. \Foo\Bar::class) and identifier(e.g. Foo::class)
+                    // i.e. in case of dinamic class name (e.g. $object::class, create()::class)
+                    createError(node);
+                }
+            }
+        }
+
         private void createError(ASTNode node) {
             createError(node.getStartOffset(), node.getEndOffset());
         }
diff --git a/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest/parser/php80/classNameLiteralOnObjects_01.pass b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest/parser/php80/classNameLiteralOnObjects_01.pass
new file mode 100644
index 0000000..88e4667
--- /dev/null
+++ b/php/php.editor/test/unit/data/goldenfiles/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest/parser/php80/classNameLiteralOnObjects_01.pass
@@ -0,0 +1,998 @@
+<testresult testFile='classNameLiteralOnObjects_01.php'>
+    <scanner>
+        <token id='T_VARIABLE' start='909' end='918'>
+            <text>$stdClass</text>
+        </token>
+        <token id='T_EQUAL' start='919' end='920'>
+            <text>=</text>
+        </token>
+        <token id='T_NEW' start='921' end='924'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='925' end='933'>
+            <text>stdClass</text>
+        </token>
+        <token id='T_SEMICOLON' start='933' end='934'>
+            <text>;</text>
+        </token>
+        <token id='T_STRING' start='935' end='943'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='943' end='944'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='944' end='953'>
+            <text>$stdClass</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='953' end='955'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='955' end='960'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='960' end='961'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='961' end='962'>
+            <text>;</text>
+        </token>
+        <token id='T_VARIABLE' start='963' end='973'>
+            <text>$reference</text>
+        </token>
+        <token id='T_EQUAL' start='974' end='975'>
+            <text>=</text>
+        </token>
+        <token id='T_REFERENCE' start='975' end='976'>
+            <text>&amp;</text>
+        </token>
+        <token id='T_VARIABLE' start='977' end='986'>
+            <text>$stdClass</text>
+        </token>
+        <token id='T_SEMICOLON' start='986' end='987'>
+            <text>;</text>
+        </token>
+        <token id='T_STRING' start='988' end='996'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='996' end='997'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='997' end='1007'>
+            <text>$reference</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1007' end='1009'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1009' end='1014'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1014' end='1015'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1015' end='1016'>
+            <text>;</text>
+        </token>
+        <token id='T_STRING' start='1017' end='1025'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1025' end='1026'>
+            <text>(</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1026' end='1027'>
+            <text>(</text>
+        </token>
+        <token id='T_NEW' start='1027' end='1030'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='1031' end='1039'>
+            <text>stdClass</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1039' end='1040'>
+            <text>)</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1040' end='1042'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1042' end='1047'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1047' end='1048'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1048' end='1049'>
+            <text>;</text>
+        </token>
+        <token id='T_STRING' start='1050' end='1058'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1058' end='1059'>
+            <text>(</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1059' end='1060'>
+            <text>(</text>
+        </token>
+        <token id='T_CLONE' start='1060' end='1065'>
+            <text>clone</text>
+        </token>
+        <token id='T_NEW' start='1066' end='1069'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='1070' end='1074'>
+            <text>Test</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1074' end='1075'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1075' end='1076'>
+            <text>)</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1076' end='1077'>
+            <text>)</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1077' end='1079'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1079' end='1084'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1084' end='1085'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1085' end='1086'>
+            <text>;</text>
+        </token>
+        <token id='T_FUNCTION' start='1088' end='1096'>
+            <text>function</text>
+        </token>
+        <token id='T_STRING' start='1097' end='1101'>
+            <text>test</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1101' end='1102'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1102' end='1103'>
+            <text>)</text>
+        </token>
+        <token id='T_NEKUDOTAIM' start='1103' end='1104'>
+            <text>:</text>
+        </token>
+        <token id='T_STRING' start='1105' end='1113'>
+            <text>stdClass</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1114' end='1115'>
+            <text>{</text>
+        </token>
+        <token id='T_RETURN' start='1120' end='1126'>
+            <text>return</text>
+        </token>
+        <token id='T_NEW' start='1127' end='1130'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='1131' end='1139'>
+            <text>stdClass</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1139' end='1140'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1140' end='1141'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1141' end='1142'>
+            <text>;</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1143' end='1144'>
+            <text>}</text>
+        </token>
+        <token id='T_STRING' start='1146' end='1154'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1154' end='1155'>
+            <text>(</text>
+        </token>
+        <token id='T_STRING' start='1155' end='1159'>
+            <text>test</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1159' end='1160'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1160' end='1161'>
+            <text>)</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1161' end='1163'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1163' end='1168'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1168' end='1169'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1169' end='1170'>
+            <text>;</text>
+        </token>
+        <token id='T_CLASS' start='1172' end='1177'>
+            <text>class</text>
+        </token>
+        <token id='T_STRING' start='1178' end='1182'>
+            <text>Test</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1183' end='1184'>
+            <text>{</text>
+        </token>
+        <token id='T_PUBLIC' start='1189' end='1195'>
+            <text>public</text>
+        </token>
+        <token id='T_FUNCTION' start='1196' end='1204'>
+            <text>function</text>
+        </token>
+        <token id='T_STRING' start='1205' end='1218'>
+            <text>noReturnTypes</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1218' end='1219'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1219' end='1220'>
+            <text>)</text>
+        </token>
+        <token id='T_NEKUDOTAIM' start='1220' end='1221'>
+            <text>:</text>
+        </token>
+        <token id='T_STRING' start='1222' end='1226'>
+            <text>void</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1227' end='1228'>
+            <text>{</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1233' end='1234'>
+            <text>}</text>
+        </token>
+        <token id='T_PUBLIC' start='1240' end='1246'>
+            <text>public</text>
+        </token>
+        <token id='T_FUNCTION' start='1247' end='1255'>
+            <text>function</text>
+        </token>
+        <token id='T_STRING' start='1256' end='1267'>
+            <text>newInstance</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1267' end='1268'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1268' end='1269'>
+            <text>)</text>
+        </token>
+        <token id='T_NEKUDOTAIM' start='1269' end='1270'>
+            <text>:</text>
+        </token>
+        <token id='T_STRING' start='1271' end='1275'>
+            <text>Test</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1276' end='1277'>
+            <text>{</text>
+        </token>
+        <token id='T_RETURN' start='1286' end='1292'>
+            <text>return</text>
+        </token>
+        <token id='T_VARIABLE' start='1293' end='1298'>
+            <text>$this</text>
+        </token>
+        <token id='T_SEMICOLON' start='1298' end='1299'>
+            <text>;</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1304' end='1305'>
+            <text>}</text>
+        </token>
+        <token id='T_PUBLIC' start='1311' end='1317'>
+            <text>public</text>
+        </token>
+        <token id='T_FUNCTION' start='1318' end='1326'>
+            <text>function</text>
+        </token>
+        <token id='T_STRING' start='1327' end='1335'>
+            <text>withThis</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1335' end='1336'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1336' end='1337'>
+            <text>)</text>
+        </token>
+        <token id='T_NEKUDOTAIM' start='1337' end='1338'>
+            <text>:</text>
+        </token>
+        <token id='T_STRING' start='1339' end='1343'>
+            <text>void</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1344' end='1345'>
+            <text>{</text>
+        </token>
+        <token id='T_STRING' start='1354' end='1362'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1362' end='1363'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='1363' end='1368'>
+            <text>$this</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1368' end='1370'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1370' end='1375'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1375' end='1376'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1376' end='1377'>
+            <text>;</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1382' end='1383'>
+            <text>}</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1384' end='1385'>
+            <text>}</text>
+        </token>
+        <token id='T_VARIABLE' start='1387' end='1392'>
+            <text>$test</text>
+        </token>
+        <token id='T_EQUAL' start='1393' end='1394'>
+            <text>=</text>
+        </token>
+        <token id='T_NEW' start='1395' end='1398'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='1399' end='1403'>
+            <text>Test</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1403' end='1404'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1404' end='1405'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1405' end='1406'>
+            <text>;</text>
+        </token>
+        <token id='T_TRY' start='1407' end='1410'>
+            <text>try</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1411' end='1412'>
+            <text>{</text>
+        </token>
+        <token id='T_STRING' start='1417' end='1425'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1425' end='1426'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='1426' end='1431'>
+            <text>$test</text>
+        </token>
+        <token id='T_OBJECT_OPERATOR' start='1431' end='1433'>
+            <text>-&gt;</text>
+        </token>
+        <token id='T_STRING' start='1433' end='1446'>
+            <text>noReturnTypes</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1446' end='1447'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1447' end='1448'>
+            <text>)</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1448' end='1450'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1450' end='1455'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1455' end='1456'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1456' end='1457'>
+            <text>;</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1472' end='1473'>
+            <text>}</text>
+        </token>
+        <token id='T_CATCH' start='1474' end='1479'>
+            <text>catch</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1480' end='1481'>
+            <text>(</text>
+        </token>
+        <token id='T_STRING' start='1481' end='1490'>
+            <text>TypeError</text>
+        </token>
+        <token id='T_VARIABLE' start='1491' end='1494'>
+            <text>$ex</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1494' end='1495'>
+            <text>)</text>
+        </token>
+        <token id='T_CURLY_OPEN' start='1496' end='1497'>
+            <text>{</text>
+        </token>
+        <token id='T_ECHO' start='1502' end='1506'>
+            <text>echo</text>
+        </token>
+        <token id='T_VARIABLE' start='1507' end='1510'>
+            <text>$ex</text>
+        </token>
+        <token id='T_OBJECT_OPERATOR' start='1510' end='1512'>
+            <text>-&gt;</text>
+        </token>
+        <token id='T_STRING' start='1512' end='1522'>
+            <text>getMessage</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1522' end='1523'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1523' end='1524'>
+            <text>)</text>
+        </token>
+        <token id='T_NEKUDA' start='1525' end='1526'>
+            <text>.</text>
+        </token>
+        <token id='T_STRING' start='1527' end='1534'>
+            <text>PHP_EOL</text>
+        </token>
+        <token id='T_SEMICOLON' start='1534' end='1535'>
+            <text>;</text>
+        </token>
+        <token id='T_CURLY_CLOSE' start='1536' end='1537'>
+            <text>}</text>
+        </token>
+        <token id='T_STRING' start='1539' end='1547'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1547' end='1548'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='1548' end='1553'>
+            <text>$test</text>
+        </token>
+        <token id='T_OBJECT_OPERATOR' start='1553' end='1555'>
+            <text>-&gt;</text>
+        </token>
+        <token id='T_STRING' start='1555' end='1566'>
+            <text>newInstance</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1566' end='1567'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1567' end='1568'>
+            <text>)</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1568' end='1570'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1570' end='1575'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1575' end='1576'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1576' end='1577'>
+            <text>;</text>
+        </token>
+        <token id='T_VARIABLE' start='1579' end='1585'>
+            <text>$array</text>
+        </token>
+        <token id='T_OPEN_RECT' start='1585' end='1586'>
+            <text>[</text>
+        </token>
+        <token id='T_LNUMBER' start='1586' end='1587'>
+            <text>0</text>
+        </token>
+        <token id='T_CLOSE_RECT' start='1587' end='1588'>
+            <text>]</text>
+        </token>
+        <token id='T_EQUAL' start='1589' end='1590'>
+            <text>=</text>
+        </token>
+        <token id='T_NEW' start='1591' end='1594'>
+            <text>new</text>
+        </token>
+        <token id='T_STRING' start='1595' end='1599'>
+            <text>Test</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1599' end='1600'>
+            <text>(</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1600' end='1601'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1601' end='1602'>
+            <text>;</text>
+        </token>
+        <token id='T_STRING' start='1603' end='1611'>
+            <text>var_dump</text>
+        </token>
+        <token id='T_OPEN_PARENTHESE' start='1611' end='1612'>
+            <text>(</text>
+        </token>
+        <token id='T_VARIABLE' start='1612' end='1618'>
+            <text>$array</text>
+        </token>
+        <token id='T_OPEN_RECT' start='1618' end='1619'>
+            <text>[</text>
+        </token>
+        <token id='T_LNUMBER' start='1619' end='1620'>
+            <text>0</text>
+        </token>
+        <token id='T_CLOSE_RECT' start='1620' end='1621'>
+            <text>]</text>
+        </token>
+        <token id='T_PAAMAYIM_NEKUDOTAYIM' start='1621' end='1623'>
+            <text>::</text>
+        </token>
+        <token id='T_CLASS' start='1623' end='1628'>
+            <text>class</text>
+        </token>
+        <token id='T_CLOSE_PARENTHESE' start='1628' end='1629'>
+            <text>)</text>
+        </token>
+        <token id='T_SEMICOLON' start='1629' end='1630'>
+            <text>;</text>
+        </token>
+        <token id='EOF' start='1631' end='1631'>
+            <text></text>
+        </token>
+    </scanner>
+    <Program start='0' end='1631'>
+        <Comments>
+            <Comment start='6' end='813' commentType='multiLine'/>
+            <Comment start='815' end='851' commentType='singleLine'/>
+            <Comment start='851' end='908' commentType='singleLine'/>
+            <Comment start='1458' end='1472' commentType='singleLine'/>
+            <Comment start='6' end='813' commentType='multiLine'/>
+            <Comment start='815' end='851' commentType='singleLine'/>
+            <Comment start='851' end='908' commentType='singleLine'/>
+            <Comment start='1458' end='1472' commentType='singleLine'/>
+        </Comments>
+        <Statements>
+            <ExpressionStatement start='909' end='934'>
+                <Assignment start='909' end='933' operator='EQUAL'>
+                    <Variable start='909' end='918' isDollared='true'>
+                        <Identifier start='910' end='918' name='stdClass'/>
+                    </Variable>
+                    <ClassInstanceCreation start='921' end='933' anonymous='false'>
+                        <ClassName start='925' end='933'>
+                            <NamespaceName start='925' end='933' isCurrent='false' isGlobal='false'>
+                                <Identifier start='925' end='933' name='stdClass'/>
+                            </NamespaceName>
+                        </ClassName>
+                        <Parameters>
+                        </Parameters>
+                    </ClassInstanceCreation>
+                </Assignment>
+            </ExpressionStatement>
+            <ExpressionStatement start='935' end='962'>
+                <FunctionInvocation start='935' end='961'>
+                    <FucntionName start='935' end='943'>
+                        <NamespaceName start='935' end='943' isCurrent='false' isGlobal='false'>
+                            <Identifier start='935' end='943' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='944' end='960'>
+                            <Variable start='944' end='953' isDollared='true'>
+                                <Identifier start='945' end='953' name='stdClass'/>
+                            </Variable>
+                            <Constant>
+                                <Identifier start='955' end='960' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='955' end='960' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <ExpressionStatement start='963' end='987'>
+                <Assignment start='963' end='986' operator='EQUAL'>
+                    <Variable start='963' end='973' isDollared='true'>
+                        <Identifier start='964' end='973' name='reference'/>
+                    </Variable>
+                    <Reference start='975' end='986'>
+                        <Variable start='977' end='986' isDollared='true'>
+                            <Identifier start='978' end='986' name='stdClass'/>
+                        </Variable>
+                    </Reference>
+                </Assignment>
+            </ExpressionStatement>
+            <ExpressionStatement start='988' end='1016'>
+                <FunctionInvocation start='988' end='1015'>
+                    <FucntionName start='988' end='996'>
+                        <NamespaceName start='988' end='996' isCurrent='false' isGlobal='false'>
+                            <Identifier start='988' end='996' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='997' end='1014'>
+                            <Variable start='997' end='1007' isDollared='true'>
+                                <Identifier start='998' end='1007' name='reference'/>
+                            </Variable>
+                            <Constant>
+                                <Identifier start='1009' end='1014' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1009' end='1014' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <ExpressionStatement start='1017' end='1049'>
+                <FunctionInvocation start='1017' end='1048'>
+                    <FucntionName start='1017' end='1025'>
+                        <NamespaceName start='1017' end='1025' isCurrent='false' isGlobal='false'>
+                            <Identifier start='1017' end='1025' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='1026' end='1047'>
+                            <AnonymousObjectVariable start='1026' end='1040'>
+                                <ClassInstanceCreation start='1027' end='1039' anonymous='false'>
+                                    <ClassName start='1031' end='1039'>
+                                        <NamespaceName start='1031' end='1039' isCurrent='false' isGlobal='false'>
+                                            <Identifier start='1031' end='1039' name='stdClass'/>
+                                        </NamespaceName>
+                                    </ClassName>
+                                    <Parameters>
+                                    </Parameters>
+                                </ClassInstanceCreation>
+                            </AnonymousObjectVariable>
+                            <Constant>
+                                <Identifier start='1042' end='1047' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1042' end='1047' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <ExpressionStatement start='1050' end='1086'>
+                <FunctionInvocation start='1050' end='1085'>
+                    <FucntionName start='1050' end='1058'>
+                        <NamespaceName start='1050' end='1058' isCurrent='false' isGlobal='false'>
+                            <Identifier start='1050' end='1058' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='1059' end='1084'>
+                            <AnonymousObjectVariable start='1059' end='1077'>
+                                <CloneExpression start='1060' end='1076'>
+                                    <ClassInstanceCreation start='1066' end='1076' anonymous='false'>
+                                        <ClassName start='1070' end='1074'>
+                                            <NamespaceName start='1070' end='1074' isCurrent='false' isGlobal='false'>
+                                                <Identifier start='1070' end='1074' name='Test'/>
+                                            </NamespaceName>
+                                        </ClassName>
+                                        <Parameters>
+                                        </Parameters>
+                                    </ClassInstanceCreation>
+                                </CloneExpression>
+                            </AnonymousObjectVariable>
+                            <Constant>
+                                <Identifier start='1079' end='1084' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1079' end='1084' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <FunctionDeclaration start='1088' end='1144' isReference='false'>
+                <Identifier start='1097' end='1101' name='test'/>
+                <FormalParameters>
+                </FormalParameters>
+                <NamespaceName start='1105' end='1113' isCurrent='false' isGlobal='false'>
+                    <Identifier start='1105' end='1113' name='stdClass'/>
+                </NamespaceName>
+                <Block start='1114' end='1144' isCurly='true'>
+                    <ReturnStatement start='1120' end='1142'>
+                        <ClassInstanceCreation start='1127' end='1141' anonymous='false'>
+                            <ClassName start='1131' end='1139'>
+                                <NamespaceName start='1131' end='1139' isCurrent='false' isGlobal='false'>
+                                    <Identifier start='1131' end='1139' name='stdClass'/>
+                                </NamespaceName>
+                            </ClassName>
+                            <Parameters>
+                            </Parameters>
+                        </ClassInstanceCreation>
+                    </ReturnStatement>
+                </Block>
+            </FunctionDeclaration>
+            <ExpressionStatement start='1146' end='1170'>
+                <FunctionInvocation start='1146' end='1169'>
+                    <FucntionName start='1146' end='1154'>
+                        <NamespaceName start='1146' end='1154' isCurrent='false' isGlobal='false'>
+                            <Identifier start='1146' end='1154' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='1155' end='1168'>
+                            <FunctionInvocation start='1155' end='1161'>
+                                <FucntionName start='1155' end='1159'>
+                                    <NamespaceName start='1155' end='1159' isCurrent='false' isGlobal='false'>
+                                        <Identifier start='1155' end='1159' name='test'/>
+                                    </NamespaceName>
+                                </FucntionName>
+                                <Parameters>
+                                </Parameters>
+                            </FunctionInvocation>
+                            <Constant>
+                                <Identifier start='1163' end='1168' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1163' end='1168' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <ClassDeclaration start='1172' end='1385' modifier='NONE'>
+                <ClassName>
+                    <Identifier start='1178' end='1182' name='Test'/>
+                </ClassName>
+                <SuperClassName>
+                </SuperClassName>
+                <Interfaces>
+                </Interfaces>
+                <Block start='1183' end='1385' isCurly='true'>
+                    <MethodDeclaration start='1189' end='1234' modifiers='public'>
+                        <FunctionDeclaration start='1196' end='1234' isReference='false'>
+                            <Identifier start='1205' end='1218' name='noReturnTypes'/>
+                            <FormalParameters>
+                            </FormalParameters>
+                            <NamespaceName start='1222' end='1226' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1222' end='1226' name='void'/>
+                            </NamespaceName>
+                            <Block start='1227' end='1234' isCurly='true'>
+                            </Block>
+                        </FunctionDeclaration>
+                    </MethodDeclaration>
+                    <MethodDeclaration start='1240' end='1305' modifiers='public'>
+                        <FunctionDeclaration start='1247' end='1305' isReference='false'>
+                            <Identifier start='1256' end='1267' name='newInstance'/>
+                            <FormalParameters>
+                            </FormalParameters>
+                            <NamespaceName start='1271' end='1275' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1271' end='1275' name='Test'/>
+                            </NamespaceName>
+                            <Block start='1276' end='1305' isCurly='true'>
+                                <ReturnStatement start='1286' end='1299'>
+                                    <Variable start='1293' end='1298' isDollared='true'>
+                                        <Identifier start='1294' end='1298' name='this'/>
+                                    </Variable>
+                                </ReturnStatement>
+                            </Block>
+                        </FunctionDeclaration>
+                    </MethodDeclaration>
+                    <MethodDeclaration start='1311' end='1383' modifiers='public'>
+                        <FunctionDeclaration start='1318' end='1383' isReference='false'>
+                            <Identifier start='1327' end='1335' name='withThis'/>
+                            <FormalParameters>
+                            </FormalParameters>
+                            <NamespaceName start='1339' end='1343' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1339' end='1343' name='void'/>
+                            </NamespaceName>
+                            <Block start='1344' end='1383' isCurly='true'>
+                                <ExpressionStatement start='1354' end='1377'>
+                                    <FunctionInvocation start='1354' end='1376'>
+                                        <FucntionName start='1354' end='1362'>
+                                            <NamespaceName start='1354' end='1362' isCurrent='false' isGlobal='false'>
+                                                <Identifier start='1354' end='1362' name='var_dump'/>
+                                            </NamespaceName>
+                                        </FucntionName>
+                                        <Parameters>
+                                            <StaticConstantAccess start='1363' end='1375'>
+                                                <Variable start='1363' end='1368' isDollared='true'>
+                                                    <Identifier start='1364' end='1368' name='this'/>
+                                                </Variable>
+                                                <Constant>
+                                                    <Identifier start='1370' end='1375' name='class'/>
+                                                </Constant>
+                                                <Member>
+                                                    <Identifier start='1370' end='1375' name='class'/>
+                                                </Member>
+                                            </StaticConstantAccess>
+                                        </Parameters>
+                                    </FunctionInvocation>
+                                </ExpressionStatement>
+                            </Block>
+                        </FunctionDeclaration>
+                    </MethodDeclaration>
+                </Block>
+            </ClassDeclaration>
+            <ExpressionStatement start='1387' end='1406'>
+                <Assignment start='1387' end='1405' operator='EQUAL'>
+                    <Variable start='1387' end='1392' isDollared='true'>
+                        <Identifier start='1388' end='1392' name='test'/>
+                    </Variable>
+                    <ClassInstanceCreation start='1395' end='1405' anonymous='false'>
+                        <ClassName start='1399' end='1403'>
+                            <NamespaceName start='1399' end='1403' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1399' end='1403' name='Test'/>
+                            </NamespaceName>
+                        </ClassName>
+                        <Parameters>
+                        </Parameters>
+                    </ClassInstanceCreation>
+                </Assignment>
+            </ExpressionStatement>
+            <TryStatement start='1407' end='1537'>
+                <CatchClauses>
+                    <CatchClause start='1474' end='1537'>
+                        <ClassNames>
+                            <NamespaceName start='1481' end='1490' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1481' end='1490' name='TypeError'/>
+                            </NamespaceName>
+                        </ClassNames>
+                        <Variable start='1491' end='1494' isDollared='true'>
+                            <Identifier start='1492' end='1494' name='ex'/>
+                        </Variable>
+                        <Block start='1496' end='1537' isCurly='true'>
+                            <EchoStatement start='1502' end='1535'>
+                                <InfixExpression start='1507' end='1534' operator='CONCAT'>
+                                    <MethodInvocation start='1507' end='1524'>
+                                        <Variable start='1507' end='1510' isDollared='true'>
+                                            <Identifier start='1508' end='1510' name='ex'/>
+                                        </Variable>
+                                        <Method>
+                                            <FunctionInvocation start='1512' end='1524'>
+                                                <FucntionName start='1512' end='1522'>
+                                                    <Variable start='1512' end='1522' isDollared='false'>
+                                                        <Identifier start='1512' end='1522' name='getMessage'/>
+                                                    </Variable>
+                                                </FucntionName>
+                                                <Parameters>
+                                                </Parameters>
+                                            </FunctionInvocation>
+                                        </Method>
+                                    </MethodInvocation>
+                                    <NamespaceName start='1527' end='1534' isCurrent='false' isGlobal='false'>
+                                        <Identifier start='1527' end='1534' name='PHP_EOL'/>
+                                    </NamespaceName>
+                                </InfixExpression>
+                            </EchoStatement>
+                        </Block>
+                    </CatchClause>
+                </CatchClauses>
+                <Block start='1411' end='1473' isCurly='true'>
+                    <ExpressionStatement start='1417' end='1457'>
+                        <FunctionInvocation start='1417' end='1456'>
+                            <FucntionName start='1417' end='1425'>
+                                <NamespaceName start='1417' end='1425' isCurrent='false' isGlobal='false'>
+                                    <Identifier start='1417' end='1425' name='var_dump'/>
+                                </NamespaceName>
+                            </FucntionName>
+                            <Parameters>
+                                <StaticConstantAccess start='1426' end='1455'>
+                                    <MethodInvocation start='1426' end='1448'>
+                                        <Variable start='1426' end='1431' isDollared='true'>
+                                            <Identifier start='1427' end='1431' name='test'/>
+                                        </Variable>
+                                        <Method>
+                                            <FunctionInvocation start='1433' end='1448'>
+                                                <FucntionName start='1433' end='1446'>
+                                                    <Variable start='1433' end='1446' isDollared='false'>
+                                                        <Identifier start='1433' end='1446' name='noReturnTypes'/>
+                                                    </Variable>
+                                                </FucntionName>
+                                                <Parameters>
+                                                </Parameters>
+                                            </FunctionInvocation>
+                                        </Method>
+                                    </MethodInvocation>
+                                    <Constant>
+                                        <Identifier start='1450' end='1455' name='class'/>
+                                    </Constant>
+                                    <Member>
+                                        <Identifier start='1450' end='1455' name='class'/>
+                                    </Member>
+                                </StaticConstantAccess>
+                            </Parameters>
+                        </FunctionInvocation>
+                    </ExpressionStatement>
+                </Block>
+            </TryStatement>
+            <ExpressionStatement start='1539' end='1577'>
+                <FunctionInvocation start='1539' end='1576'>
+                    <FucntionName start='1539' end='1547'>
+                        <NamespaceName start='1539' end='1547' isCurrent='false' isGlobal='false'>
+                            <Identifier start='1539' end='1547' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='1548' end='1575'>
+                            <MethodInvocation start='1548' end='1568'>
+                                <Variable start='1548' end='1553' isDollared='true'>
+                                    <Identifier start='1549' end='1553' name='test'/>
+                                </Variable>
+                                <Method>
+                                    <FunctionInvocation start='1555' end='1568'>
+                                        <FucntionName start='1555' end='1566'>
+                                            <Variable start='1555' end='1566' isDollared='false'>
+                                                <Identifier start='1555' end='1566' name='newInstance'/>
+                                            </Variable>
+                                        </FucntionName>
+                                        <Parameters>
+                                        </Parameters>
+                                    </FunctionInvocation>
+                                </Method>
+                            </MethodInvocation>
+                            <Constant>
+                                <Identifier start='1570' end='1575' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1570' end='1575' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+            <ExpressionStatement start='1579' end='1602'>
+                <Assignment start='1579' end='1601' operator='EQUAL'>
+                    <ArrayAccess start='1579' end='1588' type='VARIABLE_ARRAY' isDollared='false'>
+                        <ArrayDimension start='1585' end='1588'>
+                            <Index>
+                                <Scalar start='1586' end='1587' type='INT' value='0'/>
+                            </Index>
+                        </ArrayDimension>
+                        <Name>
+                            <Variable start='1579' end='1585' isDollared='true'>
+                                <Identifier start='1580' end='1585' name='array'/>
+                            </Variable>
+                        </Name>
+                    </ArrayAccess>
+                    <ClassInstanceCreation start='1591' end='1601' anonymous='false'>
+                        <ClassName start='1595' end='1599'>
+                            <NamespaceName start='1595' end='1599' isCurrent='false' isGlobal='false'>
+                                <Identifier start='1595' end='1599' name='Test'/>
+                            </NamespaceName>
+                        </ClassName>
+                        <Parameters>
+                        </Parameters>
+                    </ClassInstanceCreation>
+                </Assignment>
+            </ExpressionStatement>
+            <ExpressionStatement start='1603' end='1630'>
+                <FunctionInvocation start='1603' end='1629'>
+                    <FucntionName start='1603' end='1611'>
+                        <NamespaceName start='1603' end='1611' isCurrent='false' isGlobal='false'>
+                            <Identifier start='1603' end='1611' name='var_dump'/>
+                        </NamespaceName>
+                    </FucntionName>
+                    <Parameters>
+                        <StaticConstantAccess start='1612' end='1628'>
+                            <ArrayAccess start='1612' end='1621' type='VARIABLE_ARRAY' isDollared='false'>
+                                <ArrayDimension start='1618' end='1621'>
+                                    <Index>
+                                        <Scalar start='1619' end='1620' type='INT' value='0'/>
+                                    </Index>
+                                </ArrayDimension>
+                                <Name>
+                                    <Variable start='1612' end='1618' isDollared='true'>
+                                        <Identifier start='1613' end='1618' name='array'/>
+                                    </Variable>
+                                </Name>
+                            </ArrayAccess>
+                            <Constant>
+                                <Identifier start='1623' end='1628' name='class'/>
+                            </Constant>
+                            <Member>
+                                <Identifier start='1623' end='1628' name='class'/>
+                            </Member>
+                        </StaticConstantAccess>
+                    </Parameters>
+                </FunctionInvocation>
+            </ExpressionStatement>
+        </Statements>
+    </Program>
+</testresult>
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb1859/nb1859_02.php.testNamespaceFunction_02.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb1859/nb1859_02.php.testNamespaceFunction_02.completion
index 2c9d305..7300af3 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb1859/nb1859_02.php.testNamespaceFunction_02.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb1859/nb1859_02.php.testNamespaceFunction_02.completion
@@ -4,3 +4,4 @@ echo \TestNamespace\newTestClass()::|
 ------------------------------------
 METHOD     staticTest()                    [STATIC]   \TestNamespace\TestClass
 VARIABLE   ? $staticTest                   [STATIC]   \TestNamespace\TestClass
+CONSTANT   class \TestNamespace\TestClass  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_03.completion
index e916867..9d37490 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_03.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_03.completion
@@ -4,3 +4,4 @@ echo B::staticReturnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_05.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_05.completion
index f1516a0..54d6221 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_05.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_05.completion
@@ -4,3 +4,4 @@ echo $b::staticReturnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_06.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_06.completion
index 56e37f4..cf6fcdf 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_06.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnSelf_06.completion
@@ -4,3 +4,4 @@ echo $b->returnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_03.completion
index f4619fb..9027f69 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_03.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_03.completion
@@ -5,3 +5,4 @@ METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
+CONSTANT   class \B                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_05.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_05.completion
index 35c6703..892432a 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_05.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_05.completion
@@ -5,3 +5,4 @@ METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
+CONSTANT   class \B                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_06.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_06.completion
index 94287ff..6dbd1bd 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_06.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnStatic_06.completion
@@ -5,3 +5,4 @@ METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
+CONSTANT   class \B                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnThis_02.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnThis_02.completion
index 6f7202f..3013563 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnThis_02.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb4185/nb4185.php.testReturnThis_02.completion
@@ -5,3 +5,4 @@ METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
+CONSTANT   class \B                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb501/nb501.php.testNb501_03a.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb501/nb501.php.testNb501_03a.completion
index ba316b8..0c85618 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/nb501/nb501.php.testNb501_03a.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb501/nb501.php.testNb501_03a.completion
@@ -2,3 +2,4 @@ Code completion result for source line:
 (clone Example::getDefault())::|getDefault()->testMethod(); // test3
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
 METHOD     getDefault()                    [STATIC]   Example
+CONSTANT   class \Example                  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion
index 7c8aecc..2e143ae 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion
@@ -2,3 +2,4 @@ Code completion result for source line:
 fnc()->getNumbers()::|MAX;
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
 CONSTANT   MAX 100                         [PUBLIC]   Numbers
+CONSTANT   class \Numbers                  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03b.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03b.completion
index bf0a665..8428ef0 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03b.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03b.completion
@@ -2,3 +2,4 @@ Code completion result for source line:
 UVS3::myStatic3()::|myStatic2()::myStatic1()::MAX;
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
 METHOD     myStatic2()                     [STATIC]   UVS2
+CONSTANT   class \UVS2                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03c.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03c.completion
index 8a292b1..f49fb33 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03c.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03c.completion
@@ -4,3 +4,4 @@ UVS3::myStatic3()::myStatic2()::|myStatic1()::MAX;
 METHOD     myStatic1()                     [STATIC]   UVS1
 VARIABLE   UVS1 $INSTANCE                  [STATIC]   UVS1
 CONSTANT   MAX 99                          [PUBLIC]   UVS1
+CONSTANT   class \UVS1                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03d.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03d.completion
index 5b72abe..32da7f9 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03d.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax03.php.testUniformVariableSyntax03d.completion
@@ -4,3 +4,4 @@ UVS3::myStatic3()::myStatic2()::myStatic1()::|MAX;
 METHOD     myStatic1()                     [STATIC]   UVS1
 VARIABLE   UVS1 $INSTANCE                  [STATIC]   UVS1
 CONSTANT   MAX 99                          [PUBLIC]   UVS1
+CONSTANT   class \UVS1                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_03.completion
index 0fa66cb..8edac49 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_03.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_03.completion
@@ -3,3 +3,4 @@ UVS1::$INSTANCE2::$INSTANCE3::|MAX;
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
 VARIABLE   UVS1 $INSTANCE1                 [STATIC]   UVS3
 CONSTANT   MAX 101                         [PUBLIC]   UVS3
+CONSTANT   class \UVS3                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_04.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_04.completion
index 7a5276e..945036f 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_04.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php.testUVSNestedStaticFieldAccess_04.completion
@@ -3,3 +3,4 @@ test()::|$INSTANCE1::$INSTANCE2::MAX;
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
 VARIABLE   UVS1 $INSTANCE1                 [STATIC]   UVS3
 CONSTANT   MAX 101                         [PUBLIC]   UVS3
+CONSTANT   class \UVS3                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php
new file mode 100644
index 0000000..1b695ed
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php
@@ -0,0 +1,56 @@
+<?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.
+ */
+
+// PHP 8.0 Allow ::class on objects
+// https://wiki.php.net/rfc/class_name_literal_on_object
+
+class Test
+{
+    public function noReturnTypes(): void {
+    }
+
+    public function newInstance(): Test {
+        return $this;
+    }
+
+    public function withThis(): void {
+        var_dump($this::class); // test6
+    }
+}
+
+$test = new Test;
+var_dump($test::class); // test1
+$reference =& $test;
+var_dump($reference::class); // test2
+var_dump((new Test)::class); // test3
+
+function test(): Test {
+    return new Test();
+}
+
+var_dump(test()::class); // test4
+
+var_dump($test->newInstance()::class); // test5
+
+try {
+    var_dump($test->noReturnTypes()::class); // test7 Type Error
+} catch (TypeError $ex) {
+    echo $ex->getMessage() . PHP_EOL;
+}
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_01.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_01.completion
new file mode 100644
index 0000000..ec911c0
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_01.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump($test::|class); // test1
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_02.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_02.completion
new file mode 100644
index 0000000..0b2b1d5
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_02.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump($reference::cl|ass); // test2
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_03.completion
new file mode 100644
index 0000000..6433020
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_03.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump((new Test)::|class); // test3
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_04.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_04.completion
new file mode 100644
index 0000000..1eaa71d
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_04.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump(test()::|class); // test4
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_05.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_05.completion
new file mode 100644
index 0000000..693f3de
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_05.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump($test->newInstance()::c|lass); // test5
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_06.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_06.completion
new file mode 100644
index 0000000..a5dd039
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_06.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+var_dump($this::|class); // test6
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+CONSTANT   class \Test                     [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_07.completion
similarity index 53%
copy from php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion
copy to php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_07.completion
index 7c8aecc..75848fa 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/php70/base/uniformVariableSyntax01.php.testUniformVariableSyntax01.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/php80/testClassNameLiteralOnObjects/classNameLiteralOnObjects.php.testClassNameLiteralOnObjects_07.completion
@@ -1,4 +1,3 @@
 Code completion result for source line:
-fnc()->getNumbers()::|MAX;
+var_dump($test->noReturnTypes()::|class); // test7 Type Error
 (QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
-CONSTANT   MAX 100                         [PUBLIC]   Numbers
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedExtendedInstance.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedExtendedInstance.completion
index 8dd922f..3968e88 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedExtendedInstance.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedExtendedInstance.completion
@@ -20,3 +20,4 @@ VARIABLE   ? $publicStaticExField          [STATIC]   ExClass
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_EX 'CONSTANT_EX'       [PUBLIC]   ExClass
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \ExClass                  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedInstance.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedInstance.completion
index 496539b..7e5385a 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedInstance.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromEnclosedInstance.completion
@@ -8,3 +8,4 @@ VARIABLE   ? $privateStaticSAField         [PRIVATE,  StaticAccessTest
 VARIABLE   ? $protectedStaticSAField       [PROTECTE  StaticAccessTest
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \StaticAccessTest         [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromExtendedInstance.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromExtendedInstance.completion
index 2d0c8b8..9c84940 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromExtendedInstance.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromExtendedInstance.completion
@@ -10,3 +10,4 @@ VARIABLE   ? $publicStaticExField          [STATIC]   ExClass
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_EX 'CONSTANT_EX'       [PUBLIC]   ExClass
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \ExClass                  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstance.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstance.completion
index 23a1dff..8c75c53 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstance.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstance.completion
@@ -4,3 +4,4 @@ $staticAccessTest::|publicStaticSAMethod(); // test
 METHOD     publicStaticSAMethod()          [STATIC]   StaticAccessTest
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \StaticAccessTest         [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstanceArray.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstanceArray.completion
index ae24a07..a331c94 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstanceArray.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromInstanceArray.completion
@@ -4,3 +4,4 @@ $staticAccessTestArray[0]::|publicStaticSAMethod(); // test
 METHOD     publicStaticSAMethod()          [STATIC]   StaticAccessTest
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \StaticAccessTest         [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromThis.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromThis.completion
index 74990ef..8124cb7 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromThis.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests240527/issue240527.php.testStaticAccessFromThis.completion
@@ -20,3 +20,4 @@ VARIABLE   ? $publicStaticExField          [STATIC]   ExClass
 VARIABLE   ? $publicStaticSAField          [STATIC]   StaticAccessTest
 CONSTANT   CONSTANT_EX 'CONSTANT_EX'       [PUBLIC]   ExClass
 CONSTANT   CONSTANT_SA 'CONSTANT_SA'       [PUBLIC]   StaticAccessTest
+CONSTANT   class \ExClass                  [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_03.completion
index eebc15d..4acc1c6 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_03.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_03.completion
@@ -4,3 +4,4 @@ echo C::staticReturnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_05.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_05.completion
index 0334565..e257687 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_05.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_05.completion
@@ -4,3 +4,4 @@ echo $c::staticReturnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_06.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_06.completion
index a4f32ca..eb3aabe 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_06.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnSelf_06.completion
@@ -4,3 +4,4 @@ echo $c->returnSelf()::|staticTestA() . PHP_EOL; // staticTestA (PHP7)
 METHOD     staticReturnSelf()              [STATIC]   A
 METHOD     staticReturnStatic()            [STATIC]   A
 METHOD     staticTestA()                   [STATIC]   A
+CONSTANT   class \A                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_03.completion
index 4aa85c9..b60d029 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_03.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_03.completion
@@ -6,3 +6,4 @@ METHOD     staticReturnStatic()            [STATIC]   B
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
 METHOD     staticTestC()                   [STATIC]   C
+CONSTANT   class \C                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_05.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_05.completion
index c8bc041..9263749 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_05.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_05.completion
@@ -6,3 +6,4 @@ METHOD     staticReturnStatic()            [STATIC]   B
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
 METHOD     staticTestC()                   [STATIC]   C
+CONSTANT   class \C                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_06.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_06.completion
index 3657dbe..e1de84a 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_06.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnStatic_06.completion
@@ -6,3 +6,4 @@ METHOD     staticReturnStatic()            [STATIC]   B
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
 METHOD     staticTestC()                   [STATIC]   C
+CONSTANT   class \C                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnThis_02.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnThis_02.completion
index 77dee59..d352c23 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnThis_02.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests269108/issue269108.php.testReturnThis_02.completion
@@ -6,3 +6,4 @@ METHOD     staticReturnStatic()            [STATIC]   B
 METHOD     staticTestA()                   [STATIC]   A
 METHOD     staticTestB()                   [STATIC]   B
 METHOD     staticTestC()                   [STATIC]   C
+CONSTANT   class \C                        [PUBLIC]   Magic Constant
diff --git a/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php b/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php
new file mode 100644
index 0000000..2eebf42
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php
@@ -0,0 +1,61 @@
+<?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.
+ */
+
+// PHP 8.0 Allow ::class on objects
+// https://wiki.php.net/rfc/class_name_literal_on_object
+
+$stdClass = new stdClass;
+var_dump($stdClass::class);
+$reference =& $stdClass;
+var_dump($reference::class);
+var_dump((new stdClass)::class);
+var_dump((clone new Test())::class);
+
+function test(): stdClass {
+    return new stdClass();
+}
+
+var_dump(test()::class);
+
+class Test
+{
+    public function noReturnTypes(): void {
+    }
+
+    public function newInstance(): Test {
+        return $this;
+    }
+
+    public function withThis(): void {
+        var_dump($this::class);
+    }
+}
+
+$test = new Test();
+try {
+    var_dump($test->noReturnTypes()::class); // Type Error
+} catch (TypeError $ex) {
+    echo $ex->getMessage() . PHP_EOL;
+}
+
+var_dump($test->newInstance()::class);
+
+$array[0] = new Test();
+var_dump($array[0]::class);
diff --git a/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php.errors b/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php.errors
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/parser/php80/classNameLiteralOnObjects_01.php.errors
@@ -0,0 +1 @@
+
diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHP80CodeCompletionTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHP80CodeCompletionTest.java
index 53c2fbf..c992cd7 100644
--- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHP80CodeCompletionTest.java
+++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHP80CodeCompletionTest.java
@@ -80,4 +80,33 @@ public class PHP80CodeCompletionTest extends PHPCodeCompletionTestBase {
         checkCompletion(getTestPath("nonCapturingCatches"), "} catch (^) { // test4", false);
     }
 
+    // Allow ::class on Objects
+    public void testClassNameLiteralOnObjects_01() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump($test::^class);", false);
+    }
+
+    public void testClassNameLiteralOnObjects_02() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump($reference::cl^ass);", false);
+    }
+
+    public void testClassNameLiteralOnObjects_03() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump((new Test)::^class);", false);
+    }
+
+    public void testClassNameLiteralOnObjects_04() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump(test()::^class);", false);
+    }
+
+    public void testClassNameLiteralOnObjects_05() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump($test->newInstance()::c^lass)", false);
+    }
+
+    public void testClassNameLiteralOnObjects_06() throws Exception {
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump($this::^class);", false);
+    }
+
+    public void testClassNameLiteralOnObjects_07() throws Exception {
+        // No completion items
+        checkCompletion(getTestPath("classNameLiteralOnObjects"), "var_dump($test->noReturnTypes()::^class)", false);
+    }
 }
diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion262141UVSTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion262141UVSTest.java
index a0597f5..1bcdb5c 100644
--- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion262141UVSTest.java
+++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletion262141UVSTest.java
@@ -58,7 +58,6 @@ public class PHPCodeCompletion262141UVSTest extends PHPCodeCompletionTestBase {
     }
 
     public void testUVSNestedStaticFieldAccess_04() throws Exception {
-        // no "class" magic constant
         checkCompletion("testfiles/completion/lib/php70/uniformVariableSyntax/testUVSNestedStaticFieldAccess.php", "test()::^$INSTANCE1::$INSTANCE2::MAX;", false);
     }
 
diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest.java
index 1cbd8d1..6359649 100644
--- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest.java
+++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/ASTPHP5ParserTest.java
@@ -1139,6 +1139,10 @@ public class ASTPHP5ParserTest extends ParserTestBase {
         performTest("parser/php80/throwExpression_01");
     }
 
+    public void testClassNameLiteralOnObjects_01() throws Exception {
+        performTest("parser/php80/classNameLiteralOnObjects_01");
+    }
+
     @Override
     protected String getTestResult(String filename) throws Exception {
         // the same <Comment /> is shown twice becase the scanner is used twice
diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/PhpParserErrorTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/PhpParserErrorTest.java
index 5b9ad9e..e5694cc 100644
--- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/PhpParserErrorTest.java
+++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/parser/PhpParserErrorTest.java
@@ -1066,4 +1066,8 @@ public class PhpParserErrorTest extends PHPTestBase {
         checkErrors("testfiles/parser/php80/throwExpression_01.php");
     }
 
+    public void testClassNameLiteralOnObjects_01() throws Exception {
+        checkErrors("testfiles/parser/php80/classNameLiteralOnObjects_01.php");
+    }
+
 }


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

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