@@ -43,7 +43,6 @@ import { idof } from "./builtins";
4343 }
4444
4545 @operator ( "[]" ) charAt ( pos : i32 ) : String {
46- assert ( this !== null ) ;
4746 if ( < u32 > pos >= < u32 > this . length ) return changetype < String > ( "" ) ;
4847 var out = __alloc ( 2 , idof < String > ( ) ) ;
4948 store < u16 > ( out , load < u16 > ( changetype < usize > ( this ) + ( < usize > pos << 1 ) ) ) ;
@@ -81,7 +80,6 @@ import { idof } from "./builtins";
8180 }
8281
8382 endsWith ( search : String , end : i32 = String . MAX_LENGTH ) : bool {
84- assert ( this !== null ) ;
8583 if ( search === null ) return false ;
8684 end = min ( max ( end , 0 ) , this . length ) ;
8785 var searchLength = < isize > search . length ;
@@ -169,7 +167,6 @@ import { idof } from "./builtins";
169167 }
170168
171169 startsWith ( search : String , start : i32 = 0 ) : bool {
172- assert ( this !== null ) ;
173170 if ( search === null ) search = changetype < String > ( "null" ) ;
174171 var len = < isize > this . length ;
175172 var searchStart = min ( max ( < isize > start , 0 ) , len ) ;
@@ -180,7 +177,6 @@ import { idof } from "./builtins";
180177 }
181178
182179 substr ( start : i32 , length : i32 = i32 . MAX_VALUE ) : String { // legacy
183- assert ( this !== null ) ;
184180 var intStart : isize = start ;
185181 var end : isize = length ;
186182 var size : isize = this . length ;
@@ -193,7 +189,6 @@ import { idof } from "./builtins";
193189 }
194190
195191 substring ( start : i32 , end : i32 = i32 . MAX_VALUE ) : String {
196- assert ( this !== null ) ;
197192 var len : isize = this . length ;
198193 var finalStart = min < isize > ( max ( start , 0 ) , len ) ;
199194 var finalEnd = min < isize > ( max ( end , 0 ) , len ) ;
@@ -208,7 +203,6 @@ import { idof } from "./builtins";
208203 }
209204
210205 trim ( ) : String {
211- assert ( this !== null ) ;
212206 var length = this . length ;
213207 var size : usize = length << 1 ;
214208 while (
@@ -246,7 +240,6 @@ import { idof } from "./builtins";
246240 }
247241
248242 trimStart ( ) : String {
249- assert ( this !== null ) ;
250243 var size = < usize > this . length << 1 ;
251244 var offset : usize = 0 ;
252245 while (
@@ -266,7 +259,6 @@ import { idof } from "./builtins";
266259 }
267260
268261 trimEnd ( ) : String {
269- assert ( this !== null ) ;
270262 var originalSize = < usize > this . length << 1 ;
271263 var size = originalSize ;
272264 while (
@@ -285,7 +277,6 @@ import { idof } from "./builtins";
285277 }
286278
287279 padStart ( length : i32 , pad : string = " " ) : String {
288- assert ( this !== null ) ;
289280 var thisSize = < usize > this . length << 1 ;
290281 var targetSize = < usize > length << 1 ;
291282 var padSize = < usize > pad . length << 1 ;
@@ -306,7 +297,6 @@ import { idof } from "./builtins";
306297 }
307298
308299 padEnd ( length : i32 , pad : string = " " ) : String {
309- assert ( this !== null ) ;
310300 var thisSize = < usize > this . length << 1 ;
311301 var targetSize = < usize > length << 1 ;
312302 var padSize = < usize > pad . length << 1 ;
@@ -327,7 +317,6 @@ import { idof } from "./builtins";
327317 }
328318
329319 repeat ( count : i32 = 0 ) : String {
330- assert ( this !== null ) ;
331320 var length = this . length ;
332321
333322 // Most browsers can't handle strings 1 << 28 chars or longer
@@ -342,8 +331,121 @@ import { idof } from "./builtins";
342331 return changetype < String > ( out ) ; // retains
343332 }
344333
334+ replace ( search : String , replacement : String ) : String {
335+ var len : usize = this . length ;
336+ var slen : usize = search . length ;
337+ if ( len <= slen ) {
338+ return len < slen ? this : select < String > ( replacement , this , search == this ) ;
339+ }
340+ var index : isize = this . indexOf ( search ) ;
341+ if ( ~ index ) {
342+ let rlen : usize = replacement . length ;
343+ len -= slen ;
344+ let olen = len + rlen ;
345+ if ( olen ) {
346+ let out = __alloc ( olen << 1 , idof < String > ( ) ) ;
347+ memory . copy ( out , changetype < usize > ( this ) , index << 1 ) ;
348+ memory . copy (
349+ out + ( index << 1 ) ,
350+ changetype < usize > ( replacement ) ,
351+ rlen << 1
352+ ) ;
353+ memory . copy (
354+ out + ( ( index + rlen ) << 1 ) ,
355+ changetype < usize > ( this ) + ( ( index + slen ) << 1 ) ,
356+ ( len - index ) << 1
357+ ) ;
358+ return changetype < String > ( out ) ;
359+ }
360+ }
361+ return this ;
362+ }
363+
364+ replaceAll ( search : String , replacement : String ) : String {
365+ var len : usize = this . length ;
366+ var slen : usize = search . length ;
367+ if ( len <= slen ) {
368+ return len < slen ? this : select < String > ( replacement , this , search == this ) ;
369+ }
370+ var rlen : usize = replacement . length ;
371+ if ( ! slen ) {
372+ if ( ! rlen ) return this ;
373+ // Special case: 'abc'.replaceAll('', '-') -> '-a-b-c-'
374+ let out = __alloc ( ( len + ( len + 1 ) * rlen ) << 1 , idof < String > ( ) ) ;
375+ memory . copy ( out , changetype < usize > ( replacement ) , rlen << 1 ) ;
376+ let offset = rlen ;
377+ for ( let i : usize = 0 ; i < len ; ++ i ) {
378+ store < u16 > (
379+ changetype < usize > ( out ) + ( offset ++ << 1 ) ,
380+ load < u16 > ( changetype < usize > ( this ) + ( i << 1 ) )
381+ ) ;
382+ memory . copy (
383+ out + ( offset << 1 ) ,
384+ changetype < usize > ( replacement ) ,
385+ rlen << 1
386+ ) ;
387+ offset += rlen ;
388+ }
389+ return changetype < String > ( out ) ;
390+ }
391+ var prev : isize = 0 , next : isize = 0 ;
392+ if ( slen == rlen ) {
393+ // Fast path when search and replacement have same length
394+ let size = len << 1 ;
395+ let out = __alloc ( size , idof < String > ( ) ) ;
396+ memory . copy ( out , changetype < usize > ( this ) , size ) ;
397+ while ( ~ ( next = < isize > this . indexOf ( search , < i32 > prev ) ) ) {
398+ memory . copy ( out + ( next << 1 ) , changetype < usize > ( replacement ) , rlen << 1 ) ;
399+ prev = next + slen ;
400+ }
401+ return changetype < String > ( out ) ;
402+ }
403+ var out : usize = 0 , offset : usize = 0 , resLen = len ;
404+ while ( ~ ( next = < isize > this . indexOf ( search , < i32 > prev ) ) ) {
405+ if ( ! out ) out = __alloc ( len << 1 , idof < String > ( ) ) ;
406+ if ( offset > resLen ) {
407+ let newLength = resLen << 1 ;
408+ out = __realloc ( out , newLength << 1 ) ;
409+ resLen = newLength ;
410+ }
411+ let chunk = next - prev ;
412+ memory . copy (
413+ out + ( offset << 1 ) ,
414+ changetype < usize > ( this ) + ( prev << 1 ) ,
415+ chunk << 1
416+ ) ;
417+ offset += chunk ;
418+ memory . copy (
419+ out + ( offset << 1 ) ,
420+ changetype < usize > ( replacement ) ,
421+ rlen << 1
422+ ) ;
423+ offset += rlen ;
424+ prev = next + slen ;
425+ }
426+ if ( offset ) {
427+ if ( offset > resLen ) {
428+ let newLength = resLen << 1 ;
429+ out = __realloc ( out , newLength << 1 ) ;
430+ resLen = newLength ;
431+ }
432+ let rest = len - prev ;
433+ if ( rest ) {
434+ memory . copy (
435+ out + ( offset << 1 ) ,
436+ changetype < usize > ( this ) + ( prev << 1 ) ,
437+ rest << 1
438+ ) ;
439+ }
440+ rest += offset ;
441+ if ( resLen > rest ) out = __realloc ( out , rest << 1 ) ;
442+ return changetype < String > ( out ) ;
443+ }
444+ return this ;
445+ }
446+
345447 slice ( start : i32 , end : i32 = i32 . MAX_VALUE ) : String {
346- var len = this . length ;
448+ var len = this . length ;
347449 start = start < 0 ? max ( start + len , 0 ) : min ( start , len ) ;
348450 end = end < 0 ? max ( end + len , 0 ) : min ( end , len ) ;
349451 len = end - start ;
@@ -354,7 +456,6 @@ import { idof } from "./builtins";
354456 }
355457
356458 split ( separator : String | null = null , limit : i32 = i32 . MAX_VALUE ) : String [ ] {
357- assert ( this !== null ) ;
358459 if ( ! limit ) return changetype < Array < String > > ( __allocArray ( 0 , alignof < String > ( ) , idof < Array < String > > ( ) ) ) ; // retains
359460 if ( separator === null ) return < String [ ] > [ this ] ;
360461 var length : isize = this . length ;
@@ -380,7 +481,7 @@ import { idof } from "./builtins";
380481 }
381482 var result = changetype < Array < String > > ( __allocArray ( 0 , alignof < String > ( ) , idof < Array < String > > ( ) ) ) ; // retains
382483 var end = 0 , start = 0 , i = 0 ;
383- while ( ( end = this . indexOf ( separator , start ) ) != - 1 ) {
484+ while ( ~ ( end = this . indexOf ( separator , start ) ) ) {
384485 let len = end - start ;
385486 if ( len > 0 ) {
386487 let out = __alloc ( < usize > len << 1 , idof < String > ( ) ) ;
0 commit comments