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 asymmetric visibility #182

Closed
thekid opened this issue Aug 24, 2024 · 7 comments
Closed

Support asymmetric visibility #182

thekid opened this issue Aug 24, 2024 · 7 comments

Comments

@thekid
Copy link
Member

thekid commented Aug 24, 2024

Add support for https://wiki.php.net/rfc/asymmetric-visibility-v2

Example

In a nutshell:

class Person {
  public private(set) string $name= 'Test';
}
 
$person= new Person();
echo $person->name;       // OK
$person->name= 'Changed'; // Visibility error

RFC status: Accepted

Quoting https://externals.io/message/124622#124838:

The final result is 24 Yes, 7 No, for a total of 77.4% in favor.

The RFC has passed. Thanks everyone for your participation and input. Ilija will get the PR merged soonish.

Rewriting

To support this in lower PHP versions, we will need to rewrite this to virtual properties, much like readonly support was implemented in #124, along the lines of the following:

class Person {
  private $_name;
  
  public function __get($name) {
    if ('name' === $name) return $this->_name;
  }

  public function __set($name, $value) {
    if ('name' === $name) {
       $caller= debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1];
       $scope= $caller['class'] ?? null;

       // For private, just compare; for protected, use instanceof
       if (__CLASS__ !== $scope) {
         $from= $scope ? 'scope '.$scope : 'global scope';
         throw new Error('Cannot access private '.__CLASS__.'::$'.$name.' from '.$from);
       }

       $this->_name= $value;
    }
  }
}

$person= new Person();
echo $person->name;       // OK, triggers __get('name')
$person->name= 'Changed'; // Visibility error, triggers __set('name', 'Changed') from scope NULL

See also

@thekid
Copy link
Member Author

thekid commented Aug 26, 2024

@thekid
Copy link
Member Author

thekid commented Aug 27, 2024

@thekid thekid closed this as completed Aug 27, 2024
@thekid
Copy link
Member Author

thekid commented Aug 27, 2024

Once the PR is merged and built into GitHub Actions's 8.4 build, we can remove the featzre availability checks from the PHP 8.4 emitter using the following patch:

diff --git a/src/main/php/lang/ast/emit/PHP84.class.php b/src/main/php/lang/ast/emit/PHP84.class.php
index a23910d..71379f3 100755
--- a/src/main/php/lang/ast/emit/PHP84.class.php
+++ b/src/main/php/lang/ast/emit/PHP84.class.php
@@ -1,6 +1,5 @@
 <?php namespace lang\ast\emit;
 
-use ReflectionProperty;
 use lang\ast\types\{
   IsArray,
   IsFunction,
@@ -20,10 +19,6 @@ use lang\ast\types\{
  */
 class PHP84 extends PHP {
   use RewriteBlockLambdaExpressions;
-  use PropertyHooks, AsymmetricVisibility {
-    PropertyHooks::emitProperty as emitPropertyHooks;
-    AsymmetricVisibility::emitProperty as emitAsymmetricVisibility;
-  }
 
   public $targetVersion= 80400;
 
@@ -58,25 +53,4 @@ class PHP84 extends PHP {
       IsGeneric::class      => function($t) { return null; }
     ];
   }
-
-  protected function emitProperty($result, $property) {
-    static $asymmetric= null;
-    static $hooks= null;
-
-    // TODO Remove once https://github.com/php/php-src/pull/15063 and
-    // https://github.com/php/php-src/pull/13455 are merged
-    if (
-      !($asymmetric ?? $asymmetric= method_exists(ReflectionProperty::class, 'isPrivateSet')) &&
-      array_intersect($property->modifiers, ['private(set)', 'protected(set)', 'public(set)'])
-    ) {
-      return $this->emitAsymmetricVisibility($result, $property);
-    } else if (
-      !($hooks ?? $hooks= method_exists(ReflectionProperty::class, 'getHooks')) &&
-      $property->hooks
-    ) {
-      return $this->emitPropertyHooks($result, $property);
-    }
-
-    parent::emitProperty($result, $property);
-  }
 }
\ No newline at end of file

@thekid thekid moved this to Done in PHP 8.4 adaption Aug 27, 2024
@thekid thekid moved this from Done to In Progress in PHP 8.4 adaption Aug 27, 2024
@thekid
Copy link
Member Author

thekid commented Aug 31, 2024

Merged in php/php-src@8df557a

@thekid
Copy link
Member Author

thekid commented Aug 31, 2024

PHP 8.4 on Ubuntu is not yet up-to-date with current GIT, see https://github.com/xp-framework/compiler/actions/runs/10643910513/job/29508056545.

@thekid
Copy link
Member Author

thekid commented Aug 31, 2024

PHP 8.4 emitter released in https://github.com/xp-framework/compiler/releases/tag/v9.3.0

@thekid thekid moved this from In Progress to Done in PHP 8.4 adaption Aug 31, 2024
@thekid
Copy link
Member Author

thekid commented Sep 7, 2024

See thekid/dialog#61

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

1 participant