From 27a1f786080a36c77972a344fd93b597cfcacff3 Mon Sep 17 00:00:00 2001
From: USAMI Kenta <tadsan@zonu.me>
Date: Wed, 19 Jun 2019 01:32:49 +0900
Subject: [PATCH 1/2] Add php-class face for highlighting class name

---
 php-face.el | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/php-face.el b/php-face.el
index 75bdc81c..4230baeb 100644
--- a/php-face.el
+++ b/php-face.el
@@ -101,6 +101,11 @@
   :group 'php-faces
   :tag "PHP Type")
 
+(defface php-class '((t (:inherit font-lock-type-face)))
+  "PHP Mode face used to highlight class."
+  :group 'php-faces
+  :tag "PHP Class")
+
 (defface php-constant '((t (:inherit font-lock-constant-face)))
   "PHP Mode face used to highlight constants."
   :group 'php-faces

From 7ca814e7ed48e8a7a98afadf3eda2ecd8d2f2051 Mon Sep 17 00:00:00 2001
From: USAMI Kenta <tadsan@zonu.me>
Date: Wed, 19 Jun 2019 02:29:29 +0900
Subject: [PATCH 2/2] Add highlight class name in typed property

---
 php-mode-test.el                   |  7 +--
 php-mode.el                        |  9 +++-
 tests/7.4/typed-property.php       | 20 ++++++++
 tests/7.4/typed-property.php.faces | 78 ++++++++++++++++++++++++++++++
 4 files changed, 110 insertions(+), 4 deletions(-)
 create mode 100644 tests/7.4/typed-property.php
 create mode 100644 tests/7.4/typed-property.php.faces

diff --git a/php-mode-test.el b/php-mode-test.el
index 1a9177d6..6cd259f7 100644
--- a/php-mode-test.el
+++ b/php-mode-test.el
@@ -662,9 +662,10 @@ Meant for `php-mode-test-issue-503'."
     (goto-char (point-min))
     (should (eq (php-mode-test-in-function-p nil) nil))))
 
-(ert-deftest php-mode-test-php74-arrow-fn ()
-  "Test highlighting arrow funcsion (short closure syntax) added in PHP 7.4."
-  (with-php-mode-test ("7.4/arrow-function.php" :faces t)))
+(ert-deftest php-mode-test-php74 ()
+  "Test highlighting language constructs added in PHP 7.4."
+  (with-php-mode-test ("7.4/arrow-function.php" :faces t))
+  (with-php-mode-test ("7.4/typed-property.php" :faces t)))
 
 (ert-deftest php-mode-test-lang ()
   "Test highlighting for language constructs."
diff --git a/php-mode.el b/php-mode.el
index a339e17f..07edc7ea 100644
--- a/php-mode.el
+++ b/php-mode.el
@@ -1464,7 +1464,14 @@ a completion list."
      ;; namespaces
      ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)[^:a-zA-Z0-9_\\\\]" 1 'font-lock-type-face)
      ("\\(\\([a-zA-Z0-9_]+\\\\\\)+[a-zA-Z0-9_]+\\|\\(\\\\[a-zA-Z0-9_]+\\)+\\)::" 1 'php-constant)
-
+     (,(eval-when-compile
+         (rx bol (* (syntax whitespace))
+             (or "private" "protected" "public")
+             (+ (syntax whitespace))
+             (group (? "?") (+ (or "\\" (syntax word) (syntax symbol))))
+             (+ (syntax whitespace))
+             (: "$" (+ (or (syntax word) (syntax symbol))))))
+      1 'php-class)
      ;; Support the ::class constant in PHP5.6
      ("\\sw+\\(::\\)\\(class\\)\\b" (1 'php-paamayim-nekudotayim) (2 'php-magical-constant))
 
diff --git a/tests/7.4/typed-property.php b/tests/7.4/typed-property.php
new file mode 100644
index 00000000..288defbe
--- /dev/null
+++ b/tests/7.4/typed-property.php
@@ -0,0 +1,20 @@
+<?php
+
+class Typed
+{
+    private ?string $string;
+
+    private Hoge $hoge;
+
+    public function __construct($var = null)
+    {
+        $this->string = $var;
+    }
+
+    public function print()
+    {
+        var_dump($this->string);
+    }
+}
+
+(new Typed)->print();
diff --git a/tests/7.4/typed-property.php.faces b/tests/7.4/typed-property.php.faces
new file mode 100644
index 00000000..18135538
--- /dev/null
+++ b/tests/7.4/typed-property.php.faces
@@ -0,0 +1,78 @@
+;; -*- mode: emacs-lisp -*-
+(("<?php" . php-php-tag)
+ ("
+
+")
+ ("class" . php-keyword)
+ (" ")
+ ("Typed" . font-lock-type-face)
+ ("
+{
+    ")
+ ("private" . php-keyword)
+ (" ")
+ ("?string" . php-class)
+ (" ")
+ ("$" . php-variable-sigil)
+ ("string" . php-variable-name)
+ (";
+
+    ")
+ ("private" . php-keyword)
+ (" ")
+ ("Hoge" . php-class)
+ (" ")
+ ("$" . php-variable-sigil)
+ ("hoge" . php-variable-name)
+ (";
+
+    ")
+ ("public" . php-keyword)
+ (" ")
+ ("function" . php-keyword)
+ (" ")
+ ("__construct" . php-function-name)
+ ("(")
+ ("$" . php-variable-sigil)
+ ("var" . php-variable-name)
+ (" = ")
+ ("null" . php-constant)
+ (")
+    {
+        ")
+ ("$" . php-$this-sigil)
+ ("this" . php-$this)
+ ("->" . php-object-op)
+ ("string" . php-property-name)
+ (" = ")
+ ("$" . php-variable-sigil)
+ ("var" . php-variable-name)
+ (";
+    }
+
+    ")
+ ("public" . php-keyword)
+ (" ")
+ ("function" . php-keyword)
+ (" ")
+ ("print" . php-function-name)
+ ("()
+    {
+        var_dump(")
+ ("$" . php-$this-sigil)
+ ("this" . php-$this)
+ ("->" . php-object-op)
+ ("string" . php-property-name)
+ (");
+    }
+}
+
+(")
+ ("new" . php-keyword)
+ (" ")
+ ("Typed" . font-lock-type-face)
+ (")")
+ ("->" . php-object-op)
+ ("print" . php-method-call)
+ ("();
+"))