Skip to content

Commit 7b48674

Browse files
authored
Merge pull request #259 from thekid/feature/parameter-default-annotation
Support reflective access to non-constant expressions for parameter defaults
2 parents efa5688 + 69f51b7 commit 7b48674

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

src/main/php/lang/reflect/Parameter.class.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php namespace lang\reflect;
22

3-
use lang\{ElementNotFoundException, ClassLoadingException, ClassNotFoundException, XPClass, Type, TypeUnion};
3+
use lang\{ElementNotFoundException, IllegalStateException, ClassLoadingException, ClassNotFoundException, XPClass, Type, TypeUnion};
44
use util\Objects;
55

66
/**
@@ -160,17 +160,24 @@ public function isVariadic() {
160160
}
161161

162162
/**
163-
* Get default value.
163+
* Get default value. Additionally checks `default` annotation for NULL defaults.
164164
*
165165
* @throws lang.IllegalStateException in case this argument is not optional
166166
* @return var
167167
*/
168168
public function getDefaultValue() {
169169
if ($this->_reflect->isOptional()) {
170-
return $this->_reflect->isDefaultValueAvailable() ? $this->_reflect->getDefaultValue() : null;
170+
if (!$this->_reflect->isDefaultValueAvailable()) return null;
171+
172+
$value= $this->_reflect->getDefaultValue();
173+
if (null === $value) {
174+
$class= strtr($this->_reflect->getDeclaringClass()->getName(), '\\', '.');
175+
return \xp::$meta[$class][1][$this->_details[1]][DETAIL_TARGET_ANNO]['$'.$this->_reflect->getName()]['default'] ?? null;
176+
}
177+
return $value;
171178
}
172179

173-
throw new \lang\IllegalStateException('Parameter "'.$this->_reflect->getName().'" has no default value');
180+
throw new IllegalStateException('Parameter "'.$this->_reflect->getName().'" has no default value');
174181
}
175182

176183
/**

src/test/php/net/xp_framework/unittest/reflection/MethodParametersTest.class.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public function un_annotated_parameter_annotations_are_empty() {
320320
$this->assertEquals([], $this->method('public function fixture($param) { }')->getParameter(0)->getAnnotations());
321321
}
322322

323-
#[Test, Expect(['class' => ElementNotFoundException::class, 'withMessage' => 'Annotation "test" does not exist'])]
323+
#[Test, Expect(class: ElementNotFoundException::class, withMessage: 'Annotation "test" does not exist')]
324324
public function cannot_get_test_annotation_for_un_annotated_parameter() {
325325
$this->method('public function fixture($param) { }')->getParameter(0)->getAnnotation('test');
326326
}
@@ -335,7 +335,7 @@ public function optional_parameter() {
335335
$this->assertTrue($this->method('public function fixture($param= true) { }')->getParameter(0)->isOptional());
336336
}
337337

338-
#[Test, Expect(['class' => IllegalStateException::class, 'withMessage' => 'Parameter "param" has no default value'])]
338+
#[Test, Expect(class: IllegalStateException::class, withMessage: 'Parameter "param" has no default value')]
339339
public function required_parameter_does_not_have_default_value() {
340340
$this->method('public function fixture($param) { }')->getParameter(0)->getDefaultValue();
341341
}
@@ -345,6 +345,19 @@ public function optional_parameters_default_value() {
345345
$this->assertEquals(true, $this->method('public function fixture($param= true) { }')->getParameter(0)->getDefaultValue());
346346
}
347347

348+
#[Test]
349+
public function default_annotation_may_supply_default_value() {
350+
$method= $this->method('public function fixture($param= null) { }');
351+
352+
// Directly modify meta information for this test's purpose
353+
// See https://github.com/xp-framework/compiler/pull/104#issuecomment-791924395
354+
\xp::$meta[$method->getDeclaringClass()->getName()][1][$method->getName()]= [
355+
DETAIL_TARGET_ANNO => ['$param' => ['default' => $this]]
356+
];
357+
358+
$this->assertEquals($this, $method->getParameter(0)->getDefaultValue());
359+
}
360+
348361
#[Test]
349362
public function vararg_parameters_default_value() {
350363
$this->assertEquals(null, $this->method('public function fixture(... $param) { }')->getParameter(0)->getDefaultValue());

0 commit comments

Comments
 (0)