Fix ambiguous annotation values by checking an additional flag #27
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
For BC reasons,
xp::$meta
contains annotation values as follows:#[Test]
null
#[Author('Timm')]
'Timm'
#[Values(1, 2)]
[1, 2]
(See https://github.com/xp-framework/compiler/blob/v8.8.0/src/main/php/lang/ast/emit/php/XpMeta.class.php#L27 and following)
However, this is a problem when the first argument is an array or NULL, as the following become ambiguous:
#[Values([1, 2])]
[1, 2]
#[Values(1, 2)]
[1, 2]
#[Values(null)]
null
#[Values]
null
For the values logic currently in use, this is not a problem. However, when using
newInstance()
with annotation classes, the desired outcomes are different from reality:The first syntax currently invokes the constructor with
$list= 1
and an excess argument which is silently dropped, causing type checker errors - as now we're using the arguments logic! Even wors, when using#[Values(['test'])]
, instead of yielding the value test, a method named test is located on the given type, which is completely unintuitive behavior!This pull request changes reflection code to check for an additional flag for the exactly one argument case, check it and wrap the meta value in an array, resolving the ambiguity, but retaining backwards compatibility:
#[Values([1, 2])]
[1, 2]
[[1, 2]]
🆕#[Values(1, 2)]
[1, 2]
[1, 2]
#[Values(null)]
null
[null]
🆕#[Values]
null
[]
#[Values(1)]
1
[1]
(unchanged!)The last row is unchanged because of how the
(array)
cast works on scalar values!Dependencies
For this to work end-to-end a small change to XP Compiler is required:
Outlook
This implementation goes around several corners to be free of BC breaks. With the removal of reflection from XP core suggested in xp-framework/rfc#338, we also have the chance of redefining how
xp::$meta
is to be used.