Skip to content

Commit c919687

Browse files
Tweaks
1 parent 9446b1f commit c919687

File tree

6 files changed

+39
-57
lines changed

6 files changed

+39
-57
lines changed

src/Parser/EntryParser.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use GrahamCampbell\ResultType\Error;
1010
use GrahamCampbell\ResultType\Result;
1111
use GrahamCampbell\ResultType\Success;
12-
use RuntimeException;
1312

1413
final class EntryParser
1514
{
@@ -135,7 +134,7 @@ private static function isQuotedName(string $name)
135134
*/
136135
private static function isValidName(string $name)
137136
{
138-
return Regex::match('~\A[a-zA-Z0-9_.]+\z~', $name)->success()->getOrElse(0) === 1;
137+
return Regex::matches('~\A[a-zA-Z0-9_.]+\z~', $name)->success()->getOrElse(false);
139138
}
140139

141140
/**
@@ -156,7 +155,7 @@ private static function parseValue(string $value)
156155
return Success::create(Value::blank());
157156
}
158157

159-
return \array_reduce(Lexer::lex($value), static function (Result $data, string $token) use ($value) {
158+
return \array_reduce(\iterator_to_array(Lexer::lex($value)), static function (Result $data, string $token) use ($value) {
160159
return $data->flatMap(static function (array $data) use ($token, $value) {
161160
return self::processToken($data[1], $token)->mapError(static function (string $err) use ($value) {
162161
return self::getErrorMessage($err, $value);
@@ -170,7 +169,7 @@ private static function parseValue(string $value)
170169
}
171170

172171
/**
173-
* Process the given character.
172+
* Process the given token.
174173
*
175174
* @param int $state
176175
* @param string $token
@@ -242,7 +241,7 @@ private static function processToken(int $state, string $token)
242241
case self::COMMENT_STATE:
243242
return Success::create(['', false, self::COMMENT_STATE]);
244243
default:
245-
throw new RuntimeException('Parser entered invalid state.');
244+
throw new \Error('Parser entered invalid state.');
246245
}
247246
}
248247

src/Parser/Lexer.php

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

55
namespace Dotenv\Parser;
66

7-
use RuntimeException;
8-
97
final class Lexer
108
{
119
/**
@@ -30,39 +28,35 @@ private function __construct()
3028
}
3129

3230
/**
33-
* Convert a value into an array of tokens.
31+
* Convert content into a token stream.
3432
*
3533
* Multibyte string processing is not needed here, and nether is error
3634
* handling, for performance reasons.
3735
*
38-
* @param string $value
36+
* @param string $content
3937
*
40-
* @return string[]
38+
* @return \Generator<string>
4139
*/
42-
public static function lex(string $value)
40+
public static function lex(string $content)
4341
{
4442
static $regex;
4543

4644
if ($regex === null) {
47-
$regex = '(('.implode(')|(', self::PATTERNS).'))A';
45+
$regex = '(('.\implode(')|(', self::PATTERNS).'))A';
4846
}
4947

5048
$tokens = [];
5149

5250
$offset = 0;
5351

54-
while (isset($value[$offset])) {
55-
if (!preg_match($regex, $value, $matches, 0, $offset)) {
56-
throw new RuntimeException(sprintf('Lexer encountered unexpected character [%s].', $value[$offset]));
52+
while (isset($content[$offset])) {
53+
if (!\preg_match($regex, $content, $matches, 0, $offset)) {
54+
throw new \Error(sprintf('Lexer encountered unexpected character [%s].', $content[$offset]));
5755
}
5856

59-
for ($i = 1; $matches[$i] === ''; ++$i);
60-
61-
$tokens[] = $matches[0];
57+
$offset += \strlen($matches[0]);
6258

63-
$offset += strlen($matches[0]);
59+
yield $matches[0];
6460
}
65-
66-
return $tokens;
6761
}
6862
}

src/Parser/Lines.php

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Dotenv\Parser;
66

7+
use Dotenv\Util\Regex;
78
use Dotenv\Util\Str;
89

910
final class Lines
@@ -103,34 +104,11 @@ private static function looksLikeMultilineStop(string $line, bool $started)
103104
return true;
104105
}
105106

106-
return self::getCharPairs(\str_replace('\\\\', '', $line))->map(static function (array $pairs) use ($started) {
107-
$seen = $started ? 0 : 1;
108-
109-
foreach ($pairs as $pair) {
110-
if ($pair[0] !== '\\' && $pair[1] === '"') {
111-
$seen++;
112-
}
113-
}
114-
115-
return $seen > 1;
107+
return Regex::occurences('/(?=([^\\\\]"))/', \str_replace('\\\\', '', $line))->map(static function (int $count) use ($started) {
108+
return $started ? $count > 1 : $count >= 1;
116109
})->success()->getOrElse(false);
117110
}
118111

119-
/**
120-
* Get all pairs of adjacent characters within the line.
121-
*
122-
* @param string $line
123-
*
124-
* @return \GrahamCampbell\ResultType\Result<array{array{string,string|null}},string>
125-
*/
126-
private static function getCharPairs(string $line)
127-
{
128-
return Str::split($line)->map(static function (array $chars) {
129-
/** @var array{array{string,string|null}} */
130-
return \array_map(null, $chars, \array_slice($chars, 1));
131-
});
132-
}
133-
134112
/**
135113
* Determine if the line in the file is a comment or whitespace.
136114
*
@@ -140,12 +118,8 @@ private static function getCharPairs(string $line)
140118
*/
141119
private static function isCommentOrWhitespace(string $line)
142120
{
143-
if (\trim($line) === '') {
144-
return true;
145-
}
146-
147-
$line = \ltrim($line);
121+
$line = \trim($line);
148122

149-
return isset($line[0]) && $line[0] === '#';
123+
return $line === '' || (isset($line[0]) && $line[0] === '#');
150124
}
151125
}

src/Util/Regex.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,27 @@ private function __construct()
3030
* @param string $pattern
3131
* @param string $subject
3232
*
33+
* @return \GrahamCampbell\ResultType\Result<bool,string>
34+
*/
35+
public static function matches(string $pattern, string $subject)
36+
{
37+
return self::pregAndWrap(static function (string $subject) use ($pattern) {
38+
return @\preg_match($pattern, $subject) === 1;
39+
}, $subject);
40+
}
41+
42+
/**
43+
* Perform a preg match all, wrapping up the result.
44+
*
45+
* @param string $pattern
46+
* @param string $subject
47+
*
3348
* @return \GrahamCampbell\ResultType\Result<int,string>
3449
*/
35-
public static function match(string $pattern, string $subject)
50+
public static function occurences(string $pattern, string $subject)
3651
{
3752
return self::pregAndWrap(static function (string $subject) use ($pattern) {
38-
return (int) @\preg_match($pattern, $subject);
53+
return (int) @\preg_match_all($pattern, $subject);
3954
}, $subject);
4055
}
4156

src/Validator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public function allowedRegexValues(string $regex)
145145
{
146146
return $this->assertNullable(
147147
static function (string $value) use ($regex) {
148-
return Regex::match($regex, $value)->success()->getOrElse(0) === 1;
148+
return Regex::matches($regex, $value)->success()->getOrElse(false);
149149
},
150150
\sprintf('does not match "%s"', $regex)
151151
);

tests/Dotenv/Parser/LexerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function provideLexCases()
2020
['FOO bar', ['FOO', ' ', 'bar']],
2121
['FOO\\n()ab', ['FOO', '\\', 'n()ab']],
2222
["FOO\n\n A", ['FOO', "\n\n", ' ', 'A']],
23-
['"VAL"', ['"', 'VAL', '"']],
23+
['"VA=L"', ['"', 'VA=L', '"']],
2424
['\' \'', ['\'', ' ', '\'']],
2525
];
2626
}
@@ -35,6 +35,6 @@ public function provideLexCases()
3535
*/
3636
public function testLex(string $input, array $output)
3737
{
38-
self::assertSame($output, Lexer::lex($input));
38+
self::assertSame($output, \iterator_to_array(Lexer::lex($input)));
3939
}
4040
}

0 commit comments

Comments
 (0)