@@ -39,7 +39,7 @@ public function preLexComponents(string $input): string
3939 return $ input ;
4040 }
4141
42- $ this ->input = $ input ;
42+ $ this ->input = $ input = str_replace ([ "\r\n" , "\r" ], "\n" , $ input ) ;
4343 $ this ->length = \strlen ($ input );
4444 $ output = '' ;
4545
@@ -126,7 +126,8 @@ public function preLexComponents(string $input): string
126126 // open the default block
127127 if (!empty ($ this ->currentComponents )
128128 && !$ this ->currentComponents [\count ($ this ->currentComponents ) - 1 ]['hasDefaultBlock ' ]) {
129- $ output .= $ this ->addDefaultBlock ();
129+ $ output .= '{% block content %} ' ;
130+ $ this ->currentComponents [\count ($ this ->currentComponents ) - 1 ]['hasDefaultBlock ' ] = true ;
130131 }
131132
132133 $ attributes = $ this ->consumeAttributes ($ componentName );
@@ -182,7 +183,8 @@ public function preLexComponents(string $input): string
182183 && preg_match ('/\S/ ' , $ char )
183184 && !$ this ->check ('{% block ' )
184185 ) {
185- $ output .= $ this ->addDefaultBlock ();
186+ $ this ->currentComponents [\count ($ this ->currentComponents ) - 1 ]['hasDefaultBlock ' ] = true ;
187+ $ output .= '{% block content %} ' ;
186188 }
187189
188190 $ output .= $ char ;
@@ -199,29 +201,14 @@ public function preLexComponents(string $input): string
199201
200202 private function consumeComponentName (?string $ customExceptionMessage = null ): string
201203 {
202- $ start = $ this ->position ;
203- while ($ this ->position < $ this ->length && preg_match ('/[A-Za-z0-9_:@\-.]/ ' , $ this ->input [$ this ->position ])) {
204- ++$ this ->position ;
205- }
204+ if (preg_match ('/\G[A-Za-z0-9_:@\-.]+/ ' , $ this ->input , $ matches , 0 , $ this ->position )) {
205+ $ componentName = $ matches [0 ];
206+ $ this ->position += strlen ($ componentName );
206207
207- $ componentName = substr ($ this ->input , $ start , $ this ->position - $ start );
208-
209- if (empty ($ componentName )) {
210- $ exceptionMessage = $ customExceptionMessage ;
211- if (null == $ exceptionMessage ) {
212- $ exceptionMessage = 'Expected component name when resolving the "<twig:" syntax. ' ;
213- }
214- throw new SyntaxError ($ exceptionMessage , $ this ->line );
208+ return $ componentName ;
215209 }
216210
217- return $ componentName ;
218- }
219-
220- private function consumeAttributeName (string $ componentName ): string
221- {
222- $ message = \sprintf ('Expected attribute name when parsing the "<twig:%s" syntax. ' , $ componentName );
223-
224- return $ this ->consumeComponentName ($ message );
211+ throw new SyntaxError ($ customExceptionMessage ?? 'Expected component name when resolving the "<twig:" syntax. ' , $ this ->line );
225212 }
226213
227214 private function consumeAttributes (string $ componentName ): string
@@ -251,7 +238,9 @@ private function consumeAttributes(string $componentName): string
251238 $ isAttributeDynamic = true ;
252239 }
253240
254- $ key = $ this ->consumeAttributeName ($ componentName );
241+ $ message = \sprintf ('Expected attribute name when parsing the "<twig:%s" syntax. ' , $ componentName );
242+ // was called 'consumeAttributeName'
243+ $ key = $ this ->consumeComponentName ($ message );
255244
256245 // <twig:component someProp> -> someProp: true
257246 if (!$ this ->check ('= ' )) {
@@ -290,10 +279,8 @@ private function consumeAttributes(string $componentName): string
290279 */
291280 private function consume (string $ string ): bool
292281 {
293- $ stringLength = \strlen ($ string );
294- if (substr ($ this ->input , $ this ->position , $ stringLength ) === $ string ) {
295- $ this ->position += $ stringLength ;
296-
282+ if (str_starts_with (substr ($ this ->input , $ this ->position ), $ string )) {
283+ $ this ->position += strlen ($ string );
297284 return true ;
298285 }
299286
@@ -325,31 +312,25 @@ private function consumeChar($validChars = null): string
325312 */
326313 private function consumeUntil (string $ endString ): string
327314 {
328- $ start = $ this ->position ;
329- $ endCharLength = \strlen ($ endString );
330-
331- while ($ this ->position < $ this ->length ) {
332- if (substr ($ this ->input , $ this ->position , $ endCharLength ) === $ endString ) {
333- break ;
334- }
315+ if (false === $ endPosition = strpos ($ this ->input , $ endString , $ this ->position )) {
316+ $ start = $ this ->position ;
317+ $ this ->position = $ this ->length ;
335318
336- if ("\n" === $ this ->input [$ this ->position ]) {
337- ++$ this ->line ;
338- }
339- ++$ this ->position ;
319+ return substr ($ this ->input , $ start );
340320 }
341321
342- return substr ($ this ->input , $ start , $ this ->position - $ start );
322+ $ content = substr ($ this ->input , $ this ->position , $ endPosition - $ this ->position );
323+ $ this ->line += substr_count ($ content , "\n" );
324+ $ this ->position = $ endPosition ;
325+
326+ return $ content ;
343327 }
344328
345329 private function consumeWhitespace (): void
346330 {
347- while ($ this ->position < $ this ->length && preg_match ('/\s/ ' , $ this ->input [$ this ->position ])) {
348- if ("\n" === $ this ->input [$ this ->position ]) {
349- ++$ this ->line ;
350- }
351- ++$ this ->position ;
352- }
331+ $ whitespace = substr ($ this ->input , $ this ->position , strspn ($ this ->input , " \t\n\r\0\x0B" , $ this ->position ));
332+ $ this ->line += substr_count ($ whitespace , "\n" );
333+ $ this ->position += strlen ($ whitespace );
353334 }
354335
355336 /**
@@ -374,18 +355,8 @@ private function expectAndConsumeChar(string $char): void
374355
375356 private function check (string $ chars ): bool
376357 {
377- $ charsLength = \strlen ($ chars );
378- if ($ this ->position + $ charsLength > $ this ->length ) {
379- return false ;
380- }
381-
382- for ($ i = 0 ; $ i < $ charsLength ; ++$ i ) {
383- if ($ this ->input [$ this ->position + $ i ] !== $ chars [$ i ]) {
384- return false ;
385- }
386- }
387-
388- return true ;
358+ return $ this ->position + strlen ($ chars ) <= $ this ->length
359+ && 0 === substr_compare ($ this ->input , $ chars , $ this ->position , strlen ($ chars ));
389360 }
390361
391362 private function consumeBlock (string $ componentName ): string
@@ -409,7 +380,7 @@ private function consumeBlock(string $componentName): string
409380 $ output = "{% block {$ blockName } %} " ;
410381
411382 $ closingTag = '</twig:block> ' ;
412- if (! $ this ->doesStringEventuallyExist ( $ closingTag )) {
383+ if (false === strpos ( $ this ->input , $ closingTag, $ this -> position )) {
413384 throw new SyntaxError ("Expected closing tag ' {$ closingTag }' for block ' {$ blockName }'. " , $ this ->line );
414385 }
415386 $ blockContents = $ this ->consumeUntilEndBlock ();
@@ -448,7 +419,8 @@ private function consumeUntilEndBlock(): string
448419 if (!$ inComment && '{% endblock %} ' === substr ($ this ->input , $ this ->position , 14 )) {
449420 if (1 === $ depth ) {
450421 // in this case, we want to advance ALL the way beyond the endblock
451- $ this ->position += 14 /* strlen('{% endblock %}') */ ;
422+ // strlen('{% endblock %}') = 14
423+ $ this ->position += 14 ;
452424 break ;
453425 } else {
454426 --$ depth ;
@@ -512,18 +484,4 @@ private function consumeAttributeValue(string $quote): string
512484
513485 return implode ('~ ' , $ parts );
514486 }
515-
516- private function doesStringEventuallyExist (string $ needle ): bool
517- {
518- $ remainingString = substr ($ this ->input , $ this ->position );
519-
520- return str_contains ($ remainingString , $ needle );
521- }
522-
523- private function addDefaultBlock (): string
524- {
525- $ this ->currentComponents [\count ($ this ->currentComponents ) - 1 ]['hasDefaultBlock ' ] = true ;
526-
527- return '{% block content %} ' ;
528- }
529487}
0 commit comments