Merge pull request #14587 from samuelsov/lab1058
[civicrm-core.git] / CRM / Core / CodeGen / Util / ArraySyntaxConverter.php
CommitLineData
c3fc2621
CW
1<?php
2
3/**
4 * Class CRM_Core_CodeGen_Util_ArraySyntaxConverter
5 *
6 * @link https://github.com/thomasbachem/php-short-array-syntax-converter
7 *
8 * @license http://www.gnu.org/licenses/lgpl.html
9 * @author Thomas Bachem <mail@thomasbachem.com>
10 */
11class CRM_Core_CodeGen_Util_ArraySyntaxConverter {
12
13 /**
14 * @param string $code
15 * @return string
16 */
17 public static function convert($code) {
18 $tokens = token_get_all($code);
19
20 // - - - - - PARSE CODE - - - - -
be2fb01f 21 $replacements = [];
c3fc2621
CW
22 $offset = 0;
23 for ($i = 0; $i < count($tokens); ++$i) {
24 // Keep track of the current byte offset in the source code
25 $offset += strlen(is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i]);
26 // T_ARRAY could either mean the "array(...)" syntax we're looking for
27 // or a type hinting statement ("function(array $foo) { ... }")
28 if (is_array($tokens[$i]) && $tokens[$i][0] === T_ARRAY) {
29 // Look for a subsequent opening bracket ("(") to be sure we're actually
30 // looking at an "array(...)" statement
31 $isArraySyntax = FALSE;
32 $subOffset = $offset;
33 for ($j = $i + 1; $j < count($tokens); ++$j) {
34 $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]);
35 if (is_string($tokens[$j]) && $tokens[$j] == '(') {
36 $isArraySyntax = TRUE;
37 break;
38 }
39 elseif (!is_array($tokens[$j]) || $tokens[$j][0] !== T_WHITESPACE) {
40 $isArraySyntax = FALSE;
41 break;
42 }
43 }
44 if ($isArraySyntax) {
45 // Replace "array" and the opening bracket (including preceeding whitespace) with "["
be2fb01f 46 $replacements[] = [
c3fc2621
CW
47 'start' => $offset - strlen($tokens[$i][1]),
48 'end' => $subOffset,
49 'string' => '[',
be2fb01f 50 ];
c3fc2621
CW
51 // Look for matching closing bracket (")")
52 $subOffset = $offset;
53 $openBracketsCount = 0;
54 for ($j = $i + 1; $j < count($tokens); ++$j) {
55 $subOffset += strlen(is_array($tokens[$j]) ? $tokens[$j][1] : $tokens[$j]);
56 if (is_string($tokens[$j]) && $tokens[$j] == '(') {
57 ++$openBracketsCount;
58 }
59 elseif (is_string($tokens[$j]) && $tokens[$j] == ')') {
60 --$openBracketsCount;
61 if ($openBracketsCount == 0) {
62 // Replace ")" with "]"
be2fb01f 63 $replacements[] = [
c3fc2621
CW
64 'start' => $subOffset - 1,
65 'end' => $subOffset,
66 'string' => ']',
be2fb01f 67 ];
c3fc2621
CW
68 break;
69 }
70 }
71 }
72 }
73 }
74 }
75
76 // - - - - - UPDATE CODE - - - - -
77 // Apply the replacements to the source code
78 $offsetChange = 0;
79 foreach ($replacements as $replacement) {
80 $code = substr_replace(
81 $code,
82 $replacement['string'],
83 $replacement['start'] + $offsetChange,
84 $replacement['end'] - $replacement['start']
85 );
86 $offsetChange += strlen($replacement['string']) - ($replacement['end'] - $replacement['start']);
87 }
88
89 return $code;
90 }
91
92}