@@ -11,37 +11,16 @@ export function findInjectionIndexAfterDirectives(userCode: string): number {
1111 let lastDirectiveEndIndex : number | undefined ;
1212
1313 while ( index < userCode . length ) {
14- const scanStartIndex = index ;
15-
16- // Comments can appear between directive prologue entries, so keep scanning until we reach the next statement.
17- while ( index < userCode . length ) {
18- const char = userCode [ index ] ;
19-
20- if ( char && / \s / . test ( char ) ) {
21- index += 1 ;
22- continue ;
23- }
24-
25- if ( userCode . startsWith ( '//' , index ) ) {
26- const newlineIndex = userCode . indexOf ( '\n' , index + 2 ) ;
27- index = newlineIndex === - 1 ? userCode . length : newlineIndex + 1 ;
28- continue ;
29- }
30-
31- if ( userCode . startsWith ( '/*' , index ) ) {
32- const commentEndIndex = userCode . indexOf ( '*/' , index + 2 ) ;
33- if ( commentEndIndex === - 1 ) {
34- return lastDirectiveEndIndex ?? scanStartIndex ;
35- }
36-
37- index = commentEndIndex + 2 ;
38- continue ;
39- }
14+ const statementStartIndex = skipWhitespaceAndComments ( userCode , index ) ;
15+ if ( statementStartIndex === undefined ) {
16+ return lastDirectiveEndIndex ?? 0 ;
17+ }
4018
41- break ;
19+ index = statementStartIndex ;
20+ if ( statementStartIndex === userCode . length ) {
21+ return lastDirectiveEndIndex ?? statementStartIndex ;
4222 }
4323
44- const statementStartIndex = index ;
4524 const quote = userCode [ statementStartIndex ] ;
4625 if ( quote !== '"' && quote !== "'" ) {
4726 return lastDirectiveEndIndex ?? statementStartIndex ;
@@ -52,53 +31,49 @@ export function findInjectionIndexAfterDirectives(userCode: string): number {
5231 return lastDirectiveEndIndex ?? statementStartIndex ;
5332 }
5433
55- let statementEndIndex = stringEndIndex ;
56-
57- // Only a bare string literal followed by a statement terminator counts as a directive.
58- while ( statementEndIndex < userCode . length ) {
59- const char = userCode [ statementEndIndex ] ;
34+ const statementEndIndex = findDirectiveTerminator ( userCode , stringEndIndex ) ;
35+ if ( statementEndIndex === undefined ) {
36+ return lastDirectiveEndIndex ?? statementStartIndex ;
37+ }
6038
61- if ( char === ';' ) {
62- statementEndIndex += 1 ;
63- break ;
64- }
39+ index = statementEndIndex ;
40+ lastDirectiveEndIndex = statementEndIndex ;
41+ }
6542
66- if ( char === '\n' || char === '\r' || char === '}' ) {
67- break ;
68- }
43+ return lastDirectiveEndIndex ?? index ;
44+ }
6945
70- if ( char && / \s / . test ( char ) ) {
71- statementEndIndex += 1 ;
72- continue ;
73- }
46+ function skipWhitespaceAndComments ( userCode : string , startIndex : number ) : number | undefined {
47+ let index = startIndex ;
7448
75- if ( userCode . startsWith ( '//' , statementEndIndex ) ) {
76- break ;
77- }
49+ while ( index < userCode . length ) {
50+ const char = userCode [ index ] ;
7851
79- if ( userCode . startsWith ( '/*' , statementEndIndex ) ) {
80- const commentEndIndex = userCode . indexOf ( '*/' , statementEndIndex + 2 ) ;
81- if ( commentEndIndex === - 1 ) {
82- return lastDirectiveEndIndex ?? statementStartIndex ;
83- }
52+ if ( char && / \s / . test ( char ) ) {
53+ index += 1 ;
54+ continue ;
55+ }
8456
85- const comment = userCode . slice ( statementEndIndex + 2 , commentEndIndex ) ;
86- if ( comment . includes ( '\n' ) || comment . includes ( '\r' ) ) {
87- break ;
88- }
57+ if ( userCode . startsWith ( '//' , index ) ) {
58+ const newlineIndex = userCode . indexOf ( '\n' , index + 2 ) ;
59+ index = newlineIndex === - 1 ? userCode . length : newlineIndex + 1 ;
60+ continue ;
61+ }
8962
90- statementEndIndex = commentEndIndex + 2 ;
91- continue ;
63+ if ( userCode . startsWith ( '/*' , index ) ) {
64+ const commentEndIndex = userCode . indexOf ( '*/' , index + 2 ) ;
65+ if ( commentEndIndex === - 1 ) {
66+ return undefined ;
9267 }
9368
94- return lastDirectiveEndIndex ?? statementStartIndex ;
69+ index = commentEndIndex + 2 ;
70+ continue ;
9571 }
9672
97- index = statementEndIndex ;
98- lastDirectiveEndIndex = statementEndIndex ;
73+ break ;
9974 }
10075
101- return lastDirectiveEndIndex ?? index ;
76+ return index ;
10277}
10378
10479function findStringLiteralEnd ( userCode : string , startIndex : number ) : number | undefined {
@@ -127,6 +102,51 @@ function findStringLiteralEnd(userCode: string, startIndex: number): number | un
127102 return undefined ;
128103}
129104
105+ function findDirectiveTerminator ( userCode : string , startIndex : number ) : number | undefined {
106+ let index = startIndex ;
107+
108+ // Only a bare string literal followed by a statement terminator counts as a directive.
109+ while ( index < userCode . length ) {
110+ const char = userCode [ index ] ;
111+
112+ if ( char === ';' ) {
113+ return index + 1 ;
114+ }
115+
116+ if ( char === '\n' || char === '\r' || char === '}' ) {
117+ return index ;
118+ }
119+
120+ if ( char && / \s / . test ( char ) ) {
121+ index += 1 ;
122+ continue ;
123+ }
124+
125+ if ( userCode . startsWith ( '//' , index ) ) {
126+ return index ;
127+ }
128+
129+ if ( userCode . startsWith ( '/*' , index ) ) {
130+ const commentEndIndex = userCode . indexOf ( '*/' , index + 2 ) ;
131+ if ( commentEndIndex === - 1 ) {
132+ return undefined ;
133+ }
134+
135+ const comment = userCode . slice ( index + 2 , commentEndIndex ) ;
136+ if ( comment . includes ( '\n' ) || comment . includes ( '\r' ) ) {
137+ return index ;
138+ }
139+
140+ index = commentEndIndex + 2 ;
141+ continue ;
142+ }
143+
144+ return undefined ;
145+ }
146+
147+ return index ;
148+ }
149+
130150/**
131151 * Set values on the global/window object at the start of a module.
132152 *
0 commit comments