Skip to content

Commit a44df30

Browse files
committed
Fix
1 parent 9d2ff8b commit a44df30

14 files changed

+101
-27
lines changed

src/Internal/StringLiteralHelper.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44

55
use function addcslashes;
66
use function preg_match;
7-
use function str_contains;
8-
use function strtr;
97
use function sprintf;
8+
use function str_contains;
109

1110
final class StringLiteralHelper
1211
{
1312

1413
public static function escape(string $string): string
1514
{
16-
return addcslashes($string, "\0..\37\177");
15+
return addcslashes($string, "\0..\37\177\\");
1716
}
1817

1918
public static function escapeAndQuoteIfNeeded(string $string): string
@@ -25,11 +24,13 @@ public static function escapeAndQuoteIfNeeded(string $string): string
2524
$escaped = self::escape($string);
2625

2726
if (str_contains($escaped, '\\') || str_contains($escaped, "'")) {
28-
return sprintf('"%s"', strtr($escaped, ['"' => '\\"']));
27+
return ($escaped === addcslashes($string, '\'\\'))
28+
? sprintf("'%s'", $escaped)
29+
: sprintf('"%s"', addcslashes($escaped, '"'));
2930
}
3031

31-
if (preg_match('/[!-\/:-@\[-^`\{-~]/', $escaped) === 1 || preg_match('/\p{Zs}/u', $escaped) === 1) {
32-
return sprintf("'%s'", strtr($escaped, ['\\' => '\\\\']));
32+
if (preg_match('/[!-,.\/:-@[-^`{|}~]/', $escaped) === 1 || preg_match('/\p{Zs}/u', $escaped) === 1) {
33+
return sprintf("'%s'", addcslashes($escaped, "\\'"));
3334
}
3435

3536
return $escaped;
@@ -44,10 +45,12 @@ public static function quote(string $string): string
4445
$escaped = self::escape($string);
4546

4647
if (str_contains($escaped, '\\') || str_contains($escaped, "'")) {
47-
return sprintf('"%s"', strtr($escaped, ['"' => '\\"']));
48+
return ($escaped === addcslashes($string, '\'\\'))
49+
? sprintf("'%s'", $escaped)
50+
: sprintf('"%s"', addcslashes($escaped, '"'));
4851
}
4952

50-
return sprintf("'%s'", strtr($escaped, ['\\' => '\\\\']));
53+
return sprintf("'%s'", addcslashes($escaped, "\\'"));
5154
}
5255

5356
}

src/Type/Constant/ConstantArrayType.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
use function range;
6868
use function sort;
6969
use function sprintf;
70-
use function str_contains;
7170

7271
/**
7372
* @api

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ public function dataCasts(): array
15521552
'(float) $str',
15531553
],
15541554
[
1555-
"array{\0TypesNamespaceCasts\\Foo\0foo: TypesNamespaceCasts\\Foo, \0TypesNamespaceCasts\\Foo\0int: int, \0*\0protectedInt: int, publicInt: int, \0TypesNamespaceCasts\\Bar\0barProperty: TypesNamespaceCasts\\Bar}",
1555+
'array{"\000TypesNamespaceCasts\\\\Foo\000foo": TypesNamespaceCasts\Foo, "\000TypesNamespaceCasts\\\\Foo\000int": int, "\000*\000protectedInt": int, publicInt: int, "\000TypesNamespaceCasts\\\\Bar\000barProperty": TypesNamespaceCasts\Bar}',
15561556
'(array) $foo',
15571557
],
15581558
[

tests/PHPStan/Analyser/data/bug-5081.php

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

tests/PHPStan/Analyser/nsrt/array-combine-php7.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ function withBoolKey(): void
3333
$c = [false, 'red', 'yellow'];
3434
$d = ['avocado', 'apple', 'banana'];
3535

36-
assertType("array{: 'avocado', red: 'apple', yellow: 'banana'}", array_combine($c, $d));
36+
assertType("array{'': 'avocado', red: 'apple', yellow: 'banana'}", array_combine($c, $d));
3737
}
3838

3939
function withFloatKey(): void
4040
{
4141
$a = [1.5, 'red', 'yellow'];
4242
$b = ['avocado', 'apple', 'banana'];
4343

44-
assertType("array{1.5: 'avocado', red: 'apple', yellow: 'banana'}", array_combine($a, $b));
44+
assertType("array{'1.5': 'avocado', red: 'apple', yellow: 'banana'}", array_combine($a, $b));
4545
}
4646

4747
function withIntegerKey(): void

tests/PHPStan/Analyser/nsrt/array-combine-php8.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ function withBoolKey(): void
3333
$c = [false, 'red', 'yellow'];
3434
$d = ['avocado', 'apple', 'banana'];
3535

36-
assertType("array{: 'avocado', red: 'apple', yellow: 'banana'}", array_combine($c, $d));
36+
assertType("array{'': 'avocado', red: 'apple', yellow: 'banana'}", array_combine($c, $d));
3737
}
3838

3939
function withFloatKey(): void
4040
{
4141
$a = [1.5, 'red', 'yellow'];
4242
$b = ['avocado', 'apple', 'banana'];
4343

44-
assertType("array{1.5: 'avocado', red: 'apple', yellow: 'banana'}", array_combine($a, $b));
44+
assertType("array{'1.5': 'avocado', red: 'apple', yellow: 'banana'}", array_combine($a, $b));
4545
}
4646

4747
function withIntegerKey(): void

tests/PHPStan/Analyser/nsrt/array-fill-keys.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ class Baz {}
2626
function withBoolKey() : array
2727
{
2828
assertType("array{1: 'b'}", array_fill_keys([true], 'b'));
29-
assertType("array{: 'b'}", array_fill_keys([false], 'b'));
29+
assertType("array{'': 'b'}", array_fill_keys([false], 'b'));
3030
}
3131

3232
function withFloatKey() : array
3333
{
34-
assertType("array{1.5: 'b'}", array_fill_keys([1.5], 'b'));
34+
assertType("array{'1.5': 'b'}", array_fill_keys([1.5], 'b'));
3535
}
3636

3737
function withIntegerKey() : array

tests/PHPStan/Analyser/nsrt/array-shapes-keys-strings.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class Foo
1717
*/
1818
public function doFoo(array $slash, array $dollar): void
1919
{
20-
assertType('array{namespace/key: string}', $slash);
21-
assertType('array<int, array{$ref: string}>', $dollar);
20+
assertType("array{'namespace/key': string}", $slash);
21+
assertType("array<int, array{'\$ref': string}>", $dollar);
2222
}
2323

2424
}

tests/PHPStan/Analyser/nsrt/bug-11716.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public function parse(string $glue): string
1313
{
1414
$seenGlues = ['|' => false, '&' => false];
1515

16-
assertType("array{|: false, &: false}", $seenGlues);
16+
assertType("array{'|': false, '&': false}", $seenGlues);
1717

1818
if ($glue !== '') {
1919
assertType('non-empty-string', $glue);
@@ -22,13 +22,13 @@ public function parse(string $glue): string
2222
$seenGlues[$glue] = true;
2323

2424
assertType("'&'|'|'", $glue);
25-
assertType('array{|: bool, &: bool}', $seenGlues);
25+
assertType("array{'|': bool, '&': bool}", $seenGlues);
2626
} else {
2727
assertType("''", $glue);
2828
}
2929

3030
assertType("''|'&'|'|'", $glue);
31-
assertType("array{|: bool, &: bool}", $seenGlues);
31+
assertType("array{'|': bool, '&': bool}", $seenGlues);
3232

3333
return array_key_first($seenGlues);
3434
}

tests/PHPStan/Analyser/nsrt/bug-7621-1.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public function unpackShortcut(string $shortcut, array $supportedGroups): array
134134
!array_key_exists($groupOrShortcut, self::SHORTCUTS)
135135
) {
136136
// Nothing
137-
assertType("array{constants: array{'public constants', 'protected constants', 'private constants'}, static properties: array{'public static properties', 'protected static properties', 'private static properties'}, properties: array{'static properties', 'public properties', 'protected properties', 'private properties'}, all public methods: array{'public final methods', 'public static final methods', 'public abstract methods', 'public static abstract methods', 'public static methods', 'public methods'}, all protected methods: array{'protected final methods', 'protected static final methods', 'protected abstract methods', 'protected static abstract methods', 'protected static methods', 'protected methods'}, all private methods: array{'private static methods', 'private methods'}, final methods: array{'public final methods', 'protected final methods', 'public static final methods', 'protected static final methods'}, abstract methods: array{'public abstract methods', 'protected abstract methods', 'public static abstract methods', 'protected static abstract methods'}, static methods: array{'static constructors', 'public static final methods', 'protected static final methods', 'public static abstract methods', 'protected static abstract methods', 'public static methods', 'protected static methods', 'private static methods'}, methods: array{'final methods', 'abstract methods', 'static methods', 'constructor', 'destructor', 'public methods', 'protected methods', 'private methods', 'magic methods'}}", self::SHORTCUTS);
137+
assertType("array{constants: array{'public constants', 'protected constants', 'private constants'}, 'static properties': array{'public static properties', 'protected static properties', 'private static properties'}, properties: array{'static properties', 'public properties', 'protected properties', 'private properties'}, 'all public methods': array{'public final methods', 'public static final methods', 'public abstract methods', 'public static abstract methods', 'public static methods', 'public methods'}, 'all protected methods': array{'protected final methods', 'protected static final methods', 'protected abstract methods', 'protected static abstract methods', 'protected static methods', 'protected methods'}, 'all private methods': array{'private static methods', 'private methods'}, 'final methods': array{'public final methods', 'protected final methods', 'public static final methods', 'protected static final methods'}, 'abstract methods': array{'public abstract methods', 'protected abstract methods', 'public static abstract methods', 'protected static abstract methods'}, 'static methods': array{'static constructors', 'public static final methods', 'protected static final methods', 'public static abstract methods', 'protected static abstract methods', 'public static methods', 'protected static methods', 'private static methods'}, methods: array{'final methods', 'abstract methods', 'static methods', 'constructor', 'destructor', 'public methods', 'protected methods', 'private methods', 'magic methods'}}", self::SHORTCUTS);
138138
assertType("array{'public final methods', 'protected final methods', 'public static final methods', 'protected static final methods'}", self::SHORTCUTS[self::GROUP_SHORTCUT_FINAL_METHODS]);
139139
} else {
140140
$groups = array_merge($groups, $this->unpackShortcut($groupOrShortcut, $supportedGroups));
@@ -146,4 +146,3 @@ public function unpackShortcut(string $shortcut, array $supportedGroups): array
146146
}
147147

148148
}
149-

0 commit comments

Comments
 (0)