Conversation
Coverage Report for CI Build 34157484442Coverage increased (+0.5%) to 98.929%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
There was a problem hiding this comment.
💡 Codex Review
larabuilder/src/Visitors/MethodVisitors/AddReturnedArrayItem.php
Lines 52 to 56 in f4b5384
When the requested key already exists, this branch replaces its value without setting the new Modified attribute. Therefore an inline returned array containing more than two items never enters the new pArray() formatting path and remains inline, contrary to the documented rule for modified arrays; mark the containing item or array before returning.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if ($this->hasParentOfType($node, PropertyItem::class) || $isMultiline === true) { | ||
| return '[' . $this->pCommaSeparatedMultiline($node->items, true) . $this->nl . ']'; | ||
| } | ||
|
|
||
| return parent::pExpr_Array($node); | ||
| return ($isMultiline === false) | ||
| ? '[' . $this->pCommaSeparated($node->items) . ']' |
There was a problem hiding this comment.
Preserve long array syntax when reprinting
When an item is appended to a returned array written with array(...), pArray() now forces the entire expression through this override, which always emits square brackets. Consequently, a formatting-only update unexpectedly converts long array syntax to short syntax; select delimiters based on the array's kind attribute or delegate that part to the parent printer.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Short array syntax is the standard in Laravel projects, so the linter rewrites array(...) to [...] on any file it touches anyway. Preserving long syntax here would only postpone an edit the linter makes regardless, so not supporting it is a deliberate choice.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9ffa6c9921
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| $firstItem = $origNodes[0] ?? null; | ||
| $endPos = $firstItem?->getStartTokenPos() ?? $this->origTokens->findRight($pos, ']'); | ||
|
|
||
| return str_contains($this->origTokens->getTokenCode($pos, $endPos, 0), "\n"); |
There was a problem hiding this comment.
Inspect the whole original array for multiline formatting
When a one-item array places its first item on the opening line but its closing bracket on a later line, such as return ['first',\n];, this stops scanning at the first item's start and misses the newline after it. Appending a second item does not satisfy count($nodes) > 2, so the array is marked non-multiline and collapsed onto one line despite the documented rule that an already multiline array stays multiline.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
@artengin I noticed this case as well. I don't think it's critical, though. Looks good for me
protected function getSortableFields(): array
{
return ['id',
];
}VS
protected function getSortableFields(): array
{
return ['id', 'name'];
}| return ['first' => 1, 'second' => 2]; | ||
| } | ||
|
|
||
| protected function getDefaultFilters(): array |
There was a problem hiding this comment.
@artengin It might be worth adding some of the test cases below to explicitly confirm/document the existing behavior. Please take a look.
I added these locally, and everything worked as expected for me.
- Comments associated with array elements are preserved
Before:
protected function getValidationRules(): array
{
return [
// profile
'name' => 'required|string',
'email' => 'required|email',
// address
'city' => 'nullable|string'
];
}After:
protected function getValidationRules(): array
{
return [
// profile
'name' => 'required|string',
'email' => 'required|email',
// address
'city' => 'nullable|string',
'zip' => 'nullable|string',
];
}- Nested arrays preserve their original formatting
Before:
protected function getUserData(): array
{
return [
'name' => 'John',
'settings' => [
'locale' => 'en',
'timezone' => 'UTC',
],
];
}After:
protected function getUserData(): array
{
return [
'name' => 'John',
'settings' => [
'locale' => 'en',
'timezone' => 'UTC',
],
'roles' => ['admin', 'editor'],
];
}- Empty multiline array → append
This is the only case I found where the wasMultiline fallback branch is triggered (findRight(']')), preserving the original multiline array syntax even when adding the first element.
Before:
protected function getExtraFilters(): array
{
return [
];
}After:
protected function getExtraFilters(): array
{
return [
'is_hidden',
];
}|
@artengin The solution in its current form works well for me. I have just one suggestion: Perhaps we could replace Multiline with OriginNode, which is supported by the parent printer out of the box. Please take a look at this alternative approach and let me know what you think. The implementation could then look something like this: protected function pArray(
array $nodes,
array $origNodes,
int &$pos,
int $indentAdjustment,
string $parentNodeClass,
string $subNodeName,
?int $fixup,
): ?string {
$hasModifiedItem = ($parentNodeClass === Array_::class && $subNodeName === 'items')
&& $this->hasModifiedItem($nodes);
return ($hasModifiedItem && !$this->isMultiline($origNodes))
? null
: parent::pArray($nodes, $origNodes, $pos, $indentAdjustment, $parentNodeClass, $subNodeName, $fixup);
}
protected function pExpr_Array(Array_ $node): string
{
if ($this->hasParentOfType($node, PropertyItem::class) || $this->shouldBeMultiline($node)) {
return '[' . $this->pCommaSeparatedMultiline($node->items, true) . $this->nl . ']';
}
return parent::pExpr_Array($node);
}
protected function shouldBeMultiline(Array_ $node): bool
{
return !empty($this->origTokens)
&& $this->hasModifiedItem($node->items)
&& (count($node->items) > 2 || $this->wasMultiline($node->getAttribute(StatementAttributeEnum::OrigNode->value)));
}
protected function wasMultiline(?Array_ $origNode): bool
{
if (empty($origNode)) {
return false;
}
$startPos = $origNode->getStartTokenPos();
$endPos = Arr::get($origNode->items, 0)?->getStartTokenPos() ?? $origNode->getEndTokenPos();
return str_contains($this->origTokens->getTokenCode($startPos, $endPos, 0), "\n");
}The main differences are:
|
refs: #71 (comment)