Skip to content

Commit 6bc9601

Browse files
authored
Add Arr::convertToShortSyntax() (#2)
1 parent 1367a02 commit 6bc9601

File tree

12 files changed

+182
-10
lines changed

12 files changed

+182
-10
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ yarn-error.log
5959
/.phpunit.cache
6060
.phpunit.result.cache
6161
/--cache-directory/*
62+
tests/test_files/array_short_syntax_test/*
63+
tests/test_files/hash_test/*
6264

6365
##################################
6466
######## Legacy Laravel ########

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/php.xml

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/stdlib.iml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"EncoreDigitalGroup\\StdLib\\": "src/"
3535
},
3636
"files": [
37+
"src/ObjectHelpers/arr_helpers.php",
3738
"src/ObjectHelpers/dir_helpers.php",
3839
"src/ObjectHelpers/file_helpers.php",
3940
"src/ObjectHelpers/num_helpers.php",

phpstan.neon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ parameters:
66
paths:
77
- src
88
reportUnmatchedIgnoredErrors: false
9-
checkMissingIterableValueType: false
10-
checkGenericClassInNonGenericObjectType: false
119
checkDynamicProperties: false
1210
checkTooWideReturnTypesInProtectedAndPublicMethods: false
1311
ignoreErrors:
12+
- identifier: missingType.generics
13+
- identifier: missingType.iterableValue
1414
- '#PHPDoc tag .+ #'
1515
unused_public:
1616
methods: true

src/ObjectHelpers/arr_helpers.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
use EncoreDigitalGroup\StdLib\Exceptions\ArgumentNullException;
4+
use EncoreDigitalGroup\StdLib\Objects\Arr;
5+
6+
if (!function_exists('arr_to_short_syntax')) {
7+
/**
8+
* @throws ArgumentNullException
9+
*/
10+
function arr_to_short_syntax(array|string $value): array|string
11+
{
12+
return Arr::convertToShortSyntax($value);
13+
}
14+
}

src/Objects/Arr.php

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,112 @@
22

33
namespace EncoreDigitalGroup\StdLib\Objects;
44

5+
use EncoreDigitalGroup\StdLib\Exceptions\ArgumentNullException;
56
use Illuminate\Support\Arr as ArraySupport;
7+
use TypeError;
68

79
/**
810
* @api
911
*
1012
* @internal
11-
*
12-
* @codeCoverageIgnore
1313
*/
1414
class Arr extends ArraySupport
1515
{
16+
public static function convertToShortSyntax(array|string $code): array|string
17+
{
18+
// Regular expression to match long array syntax
19+
$pattern = '/array\s*\(([^()]*(?:(?R)[^()]*)*)\)/m';
20+
21+
// Callback function to replace long array syntax with short array syntax
22+
$callback = function ($matches): string {
23+
// Recursively convert nested arrays
24+
$innerArray = $matches[1];
25+
$convertedInnerArray = self::convertToShortSyntax($innerArray);
26+
27+
// Handle proper formatting of nested arrays
28+
$convertedInnerArray = preg_replace('/\n\s*/', ' ', $convertedInnerArray);
29+
30+
if (!is_string($convertedInnerArray)) {
31+
throw new TypeError(str_concat_space('Expected string, got ', get_type($convertedInnerArray)));
32+
}
33+
34+
return "[\n " . $convertedInnerArray . "\n]";
35+
};
36+
37+
/**
38+
* Replace all instances of long array syntax with short array syntax
39+
*/
40+
$convertedCode = preg_replace_callback($pattern, $callback, $code);
41+
42+
/** Ensure array brackets are properly placed on the same line as the key. This regex searches for an
43+
* opening square bracket '[' followed by one or more whitespace characters '\s+' and replaces it with
44+
* the same opening bracket '[' followed by a new line '\n', ensuring the array's opening bracket appears
45+
* on its own line.
46+
*/
47+
$convertedCode = preg_replace('/\[\s+/', "[\n", $convertedCode ?? '');
48+
49+
/**
50+
* Ensure array brackets are properly placed on the same line as the key (closing brackets). This regex searches
51+
* for a closing square bracket ']' followed by one or more whitespace characters '\s+' and replaces it with just
52+
* the closing bracket ']', ensuring that the array's closing bracket is placed correctly without extra whitespace.
53+
*/
54+
$convertedCode = preg_replace('/\]\s+/', '] ', $convertedCode ?? '');
55+
56+
/**
57+
* Ensure array brackets are properly placed on the same line as the key (opening brackets in nested arrays). This regex
58+
* searches for a comma ',' followed by one or more whitespace characters '\s+' and an opening square bracket '[' and
59+
* replaces it with just a comma ',' followed by a space and an opening bracket '[', ensuring proper spacing between the
60+
* comma and the opening bracket in nested arrays.
61+
*/
62+
$convertedCode = preg_replace('/,\s+\[/', ', [', $convertedCode ?? '');
63+
64+
/**
65+
* Add new lines after commas that are outside of array values. This regex searches for a comma ',' followed by zero or
66+
* more whitespace characters '\s*' and a closing square bracket ']' and replaces it with just a comma ',' followed by a
67+
* new line '\n' and a closing bracket ']', ensuring that a new line is triggered before the closing bracket ']'.
68+
*/
69+
$convertedCode = preg_replace('/,\s*\]/', ",\n]", $convertedCode ?? '');
70+
71+
/**
72+
* Format array keys to ensure brackets are on the same line. This regex matches and captures an opening square bracket '\['
73+
* followed by zero or more whitespace characters '\s*', then captures any characters that are not commas, closing or opening
74+
* square brackets '([^,\]\[]+?)', and finally captures a closing square bracket '\]'. It replaces the matches with the captured
75+
* groups, ensuring the brackets are not separated by whitespace.
76+
*/
77+
$convertedCode = preg_replace('/(\[)\s*([^,\]\[]+?)\s*(\])/', '$1$2$3', $convertedCode ?? '');
78+
79+
/**
80+
* Add new lines after closing brackets of arrays. This regex searches for a closing bracket ']' followed by zero or more whitespace
81+
* characters '\s*' and a comma ',' and replaces it with just the closing bracket ']' followed by a new line '\n', ensuring each array
82+
* element is on a new line.
83+
*/
84+
$convertedCode = preg_replace('/\]\s*,/', "],\n", $convertedCode ?? '');
85+
86+
/**
87+
* Replace every occurrence of a comma ',' in the $convertedCode string with a comma followed by a newline ",\n".
88+
*/
89+
$convertedCode = preg_replace('/,/', ",\n", $convertedCode ?? '');
90+
91+
/**
92+
* Add indentation for nested arrays. This regex searches for a comma ',' followed by zero or more whitespace characters '\s*', a new line
93+
* '\n', zero or more whitespace characters '\s*', and an opening square bracket '[' and replaces it with a comma ',' followed by a new line
94+
* '\n' and indentation ' ' equivalent to four spaces and an opening square bracket '['.
95+
*/
96+
$convertedCode = preg_replace('/,\s*\n\s*\[/', ",\n [", $convertedCode ?? '');
97+
98+
/**
99+
* Add a new line after the closing bracket of the entire array declaration. This regex searches for a closing bracket ']' followed by zero or
100+
* more whitespace characters '\s*' and a semicolon ';' and replaces it with just the closing bracket ']' followed by a semicolon ';' and a new
101+
* line '\n'.
102+
*/
103+
$convertedCode = preg_replace('/\]\s*;/', '];', $convertedCode ?? '');
104+
105+
$convertedCode = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $convertedCode ?? '');
106+
107+
if (is_null($convertedCode) || empty($convertedCode)) {
108+
throw new ArgumentNullException('convertedCode');
109+
}
110+
111+
return $convertedCode;
112+
}
16113
}

tests/Feature/ExampleTest.php

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/Unit/ArrayTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
test('Array converts to short syntax without error', function () {
4+
$longSyntax = require 'tests/test_files/array_short_syntax_test/long_syntax.php';
5+
6+
$longSyntax = var_export($longSyntax, true);
7+
$shortSyntax = arr_to_short_syntax($longSyntax);
8+
9+
$tmp = "<?php\n\nreturn " . $shortSyntax . ";\n";
10+
11+
file_put_contents('tests/test_files/array_short_syntax_test/tmp_short_syntax.php', $tmp);
12+
13+
$shortSyntaxFile = require 'tests/test_files/array_short_syntax_test/short_syntax.php';
14+
$tmpSyntaxFile = require 'tests/test_files/array_short_syntax_test/tmp_short_syntax.php';
15+
16+
$this->assertEquals($shortSyntaxFile, $tmpSyntaxFile);
17+
});

0 commit comments

Comments
 (0)