@@ -171,23 +171,116 @@ namespace ts {
171
171
return result ;
172
172
}
173
173
174
+ /**
175
+ * Flattens an array containing a mix of array or non-array elements.
176
+ *
177
+ * @param array The array to flatten.
178
+ */
179
+ export function flatten < T > ( array : ( T | T [ ] ) [ ] ) : T [ ] {
180
+ let result : T [ ] ;
181
+ if ( array ) {
182
+ result = [ ] ;
183
+ for ( const v of array ) {
184
+ if ( v ) {
185
+ if ( isArray ( v ) ) {
186
+ addRange ( result , v ) ;
187
+ }
188
+ else {
189
+ result . push ( v ) ;
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ return result ;
196
+ }
197
+
174
198
/**
175
199
* Maps an array. If the mapped value is an array, it is spread into the result.
200
+ *
201
+ * @param array The array to map.
202
+ * @param mapfn The callback used to map the result into one or more values.
176
203
*/
177
- export function flatMap < T , U > ( array : T [ ] , f : ( x : T , i : number ) => U | U [ ] ) : U [ ] {
204
+ export function flatMap < T , U > ( array : T [ ] , mapfn : ( x : T , i : number ) => U | U [ ] ) : U [ ] {
178
205
let result : U [ ] ;
179
206
if ( array ) {
180
207
result = [ ] ;
181
208
for ( let i = 0 ; i < array . length ; i ++ ) {
182
- const v = array [ i ] ;
183
- const ar = f ( v , i ) ;
184
- if ( ar ) {
185
- // We cast to <U> here to leverage the behavior of Array#concat
186
- // which will append a single value here.
187
- result = result . concat ( < U [ ] > ar ) ;
209
+ const v = mapfn ( array [ i ] , i ) ;
210
+ if ( v ) {
211
+ if ( isArray ( v ) ) {
212
+ addRange ( result , v ) ;
213
+ }
214
+ else {
215
+ result . push ( v ) ;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ return result ;
221
+ }
222
+
223
+ /**
224
+ * Computes the first matching span of elements and returns a tuple of the first span
225
+ * and the remaining elements.
226
+ */
227
+ export function span < T > ( array : T [ ] , f : ( x : T , i : number ) => boolean ) : [ T [ ] , T [ ] ] {
228
+ if ( array ) {
229
+ for ( let i = 0 ; i < array . length ; i ++ ) {
230
+ if ( ! f ( array [ i ] , i ) ) {
231
+ return [ array . slice ( 0 , i ) , array . slice ( i ) ] ;
232
+ }
233
+ }
234
+ return [ array . slice ( 0 ) , [ ] ] ;
235
+ }
236
+
237
+ return undefined ;
238
+ }
239
+
240
+ /**
241
+ * Maps contiguous spans of values with the same key.
242
+ *
243
+ * @param array The array to map.
244
+ * @param keyfn A callback used to select the key for an element.
245
+ * @param mapfn A callback used to map a contiguous chunk of values to a single value.
246
+ */
247
+ export function spanMap < T , K , U > ( array : T [ ] , keyfn : ( x : T , i : number ) => K , mapfn : ( chunk : T [ ] , key : K ) => U ) : U [ ] {
248
+ let result : U [ ] ;
249
+ if ( array ) {
250
+ result = [ ] ;
251
+ const len = array . length ;
252
+ let previousKey : K ;
253
+ let key : K ;
254
+ let start = 0 ;
255
+ let pos = 0 ;
256
+ while ( start < len ) {
257
+ while ( pos < len ) {
258
+ const value = array [ pos ] ;
259
+ key = keyfn ( value , pos ) ;
260
+ if ( pos === 0 ) {
261
+ previousKey = key ;
262
+ }
263
+ else if ( key !== previousKey ) {
264
+ break ;
265
+ }
266
+
267
+ pos ++ ;
188
268
}
269
+
270
+ if ( start < pos ) {
271
+ const v = mapfn ( array . slice ( start , pos ) , previousKey ) ;
272
+ if ( v ) {
273
+ result . push ( v ) ;
274
+ }
275
+
276
+ start = pos ;
277
+ }
278
+
279
+ previousKey = key ;
280
+ pos ++ ;
189
281
}
190
282
}
283
+
191
284
return result ;
192
285
}
193
286
@@ -920,8 +1013,9 @@ namespace ts {
920
1013
this . pos = pos ;
921
1014
this . end = end ;
922
1015
this . flags = NodeFlags . None ;
923
- this . transformFlags = undefined ;
924
- this . excludeTransformFlags = undefined ;
1016
+ this . modifierFlagsCache = ModifierFlags . None ;
1017
+ this . transformFlags = TransformFlags . None ;
1018
+ this . excludeTransformFlags = TransformFlags . None ;
925
1019
this . parent = undefined ;
926
1020
this . original = undefined ;
927
1021
}
@@ -942,7 +1036,12 @@ namespace ts {
942
1036
}
943
1037
944
1038
export namespace Debug {
945
- const currentAssertionLevel = AssertionLevel . None ;
1039
+ declare var process : any ;
1040
+ declare var require : any ;
1041
+
1042
+ const currentAssertionLevel = getDevelopmentMode ( ) === "development"
1043
+ ? AssertionLevel . Normal
1044
+ : AssertionLevel . None ;
946
1045
947
1046
export function shouldAssert ( level : AssertionLevel ) : boolean {
948
1047
return currentAssertionLevel >= level ;
@@ -962,6 +1061,17 @@ namespace ts {
962
1061
export function fail ( message ?: string ) : void {
963
1062
Debug . assert ( /*expression*/ false , message ) ;
964
1063
}
1064
+
1065
+ function getDevelopmentMode ( ) {
1066
+ return typeof require !== "undefined"
1067
+ && typeof process !== "undefined"
1068
+ && ! process . browser
1069
+ && process . nextTick
1070
+ && process . env
1071
+ && process . env . NODE_ENV
1072
+ ? String ( process . env . NODE_ENV ) . toLowerCase ( )
1073
+ : undefined ;
1074
+ }
965
1075
}
966
1076
967
1077
export function copyListRemovingItem < T > ( item : T , list : T [ ] ) {
0 commit comments