Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PHP 8.4 property-hooks #797

Merged
merged 1 commit into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lisp/php-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,9 @@ for \\[find-tag] (which see)."
;; Not operator (!) is defined in "before cc-mode" section above.
("\\(&&\\|||\\)" 1 'php-logical-op)
;; string interpolation ("$var, ${var}, {$var}")
(php-mode--string-interpolated-variable-font-lock-find 0 nil)))
(php-mode--string-interpolated-variable-font-lock-find 0 nil)
(,(rx symbol-start (group (or "get" "set")) (+ (syntax whitespace)) (or "{" "=>"))
1 'php-builtin)))
"Detailed highlighting for PHP Mode.")

(defvar php-font-lock-keywords php-font-lock-keywords-3
Expand Down
33 changes: 33 additions & 0 deletions tests/8.4/property-hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

class Person
{
// A "virtual" property. It may not be set explicitly.
public string $fullName {
get => $this->firstName . ' ' . $this->lastName;
}

// All write operations go through this hook, and the result is what is written.
// Read access happens normally.
public string $firstName {
set => ucfirst(strtolower($value));
}

// All write operations go through this hook, which has to write to the backing value itself.
// Read access happens normally.
public string $lastName {
set {
if (strlen($value) < 2) {
throw new \InvalidArgumentException('Too short');
}
$this->lastName = $value;
}
}
}

$p = new Person();

$p->firstName = 'peter';
print $p->firstName; // Prints "Peter"
$p->lastName = 'Peterson';
print $p->fullName; // Prints "Peter Peterson"
146 changes: 146 additions & 0 deletions tests/8.4/property-hooks.php.faces
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
;; -*- mode: emacs-lisp -*-
(("<?php" . php-php-tag)
("\n\n")
("class" . php-class-declaration)
(" ")
("Person" . font-lock-type-face)
("\n{\n ")
("// " . font-lock-comment-delimiter-face)
("A \"virtual\" property. It may not be set explicitly.\n" . font-lock-comment-face)
(" ")
("public" . php-keyword)
(" ")
("string" . php-class)
(" ")
("$" . php-variable-sigil)
("fullName" . php-variable-name)
(" {\n ")
("get" . php-builtin)
(" ")
("=" . php-assignment-op)
(">" . php-comparison-op)
(" ")
("$" . php-this-sigil)
("this" . php-this)
("->" . php-object-op)
("firstName" . php-property-name)
(" . ")
("' '" . php-string)
(" . ")
("$" . php-this-sigil)
("this" . php-this)
("->" . php-object-op)
("lastName" . php-property-name)
(";\n }\n\n ")
("// " . font-lock-comment-delimiter-face)
("All write operations go through this hook, and the result is what is written.\n" . font-lock-comment-face)
(" ")
("// " . font-lock-comment-delimiter-face)
("Read access happens normally.\n" . font-lock-comment-face)
(" ")
("public" . php-keyword)
(" ")
("string" . php-class)
(" ")
("$" . php-variable-sigil)
("firstName" . php-variable-name)
(" {\n ")
("set" . php-builtin)
(" ")
("=" . php-assignment-op)
(">" . php-comparison-op)
(" ")
("ucfirst" . php-function-call-traditional)
("(")
("strtolower" . php-function-call-traditional)
("(")
("$" . php-variable-sigil)
("value" . php-variable-name)
("));\n }\n\n ")
("// " . font-lock-comment-delimiter-face)
("All write operations go through this hook, which has to write to the backing value itself.\n" . font-lock-comment-face)
(" ")
("// " . font-lock-comment-delimiter-face)
("Read access happens normally.\n" . font-lock-comment-face)
(" ")
("public" . php-keyword)
(" ")
("string" . php-class)
(" ")
("$" . php-variable-sigil)
("lastName" . php-variable-name)
(" {\n ")
("set" . php-builtin)
(" {\n ")
("if" . php-keyword)
(" (")
("strlen" . php-function-call-traditional)
("(")
("$" . php-variable-sigil)
("value" . php-variable-name)
(") ")
("<" . php-comparison-op)
(" 2) {\n ")
("throw" . php-keyword)
(" ")
("new" . php-keyword)
(" ")
("\\InvalidArgumentException" . font-lock-type-face)
("(")
("'Too short'" . php-string)
(");\n }\n ")
("$" . php-this-sigil)
("this" . php-this)
("->" . php-object-op)
("lastName" . php-property-name)
(" ")
("=" . php-assignment-op)
(" ")
("$" . php-variable-sigil)
("value" . php-variable-name)
(";\n }\n }\n}\n\n")
("$" . php-variable-sigil)
("p" . php-variable-name)
(" ")
("=" . php-assignment-op)
(" ")
("new" . php-keyword)
(" ")
("Person" . font-lock-type-face)
("();\n\n")
("$" . php-variable-sigil)
("p" . php-variable-name)
("->" . php-object-op)
("firstName" . php-property-name)
(" ")
("=" . php-assignment-op)
(" ")
("'peter'" . php-string)
(";\n")
("print" . php-keyword)
(" ")
("$" . php-variable-sigil)
("p" . php-variable-name)
("->" . php-object-op)
("firstName" . php-property-name)
("; ")
("// " . font-lock-comment-delimiter-face)
("Prints \"Peter\"\n" . font-lock-comment-face)
("$" . php-variable-sigil)
("p" . php-variable-name)
("->" . php-object-op)
("lastName" . php-property-name)
(" ")
("=" . php-assignment-op)
(" ")
("'Peterson'" . php-string)
(";\n")
("print" . php-keyword)
(" ")
("$" . php-variable-sigil)
("p" . php-variable-name)
("->" . php-object-op)
("fullName" . php-property-name)
("; ")
("// " . font-lock-comment-delimiter-face)
("Prints \"Peter Peterson\"\n" . font-lock-comment-face))
8 changes: 6 additions & 2 deletions tests/php-mode-test.el
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
;;; php-mode-test.el --- Tests for php-mode
;;; php-mode-test.el --- Tests for php-mode -*- lexical-binding: t -*-

;; Copyright (C) 2018-2019 Friends of Emacs-PHP development
;; Copyright (C) 2018-2024 Friends of Emacs-PHP development
;; Copyright (C) 2013 Daniel Hackney
;; 2014, 2015 Eric James Michael Ritz

Expand Down Expand Up @@ -669,6 +669,10 @@ Meant for `php-mode-test-issue-503'."
(with-php-mode-test ("8.1/enum.php" :faces t))
(with-php-mode-test ("8.1/readonly.php" :faces t)))

(ert-deftest php-mode-test-php84 ()
"Test highlighting language constructs added in PHP 8.4."
(with-php-mode-test ("8.4/property-hooks.php" :faces t)))

(ert-deftest php-mode-test-lang ()
"Test highlighting for language constructs."
(with-php-mode-test ("lang/class/anonymous-class.php" :indent t :magic t :faces t))
Expand Down
Loading