@@ -36,6 +36,29 @@ export const customTypesMap = {
3636 }`
3737} ;
3838
39+ function replaceAll ( source : string , searchValue : string , replaceValue : string ) : string {
40+ let result : string | undefined =
41+ ( source as string & { replaceAll : typeof source . replace } ) . replaceAll ?.( searchValue , replaceValue ) ;
42+
43+ if ( result !== undefined ) {
44+ return result ;
45+ }
46+
47+ result = "" ;
48+ const searchLength = searchValue . length ;
49+ while ( true ) {
50+ const index = source . indexOf ( searchValue ) ;
51+ if ( index < 0 ) {
52+ break ;
53+ }
54+ result += source . slice ( 0 , index ) ;
55+ result += replaceValue ;
56+ source = source . slice ( index + searchLength ) ;
57+ }
58+ result += source ;
59+ return result ;
60+ }
61+
3962export interface PostExecAction {
4063 readonly success : boolean ;
4164 requestId : number ;
@@ -115,23 +138,24 @@ export function createLoggerWritingToConsole(host: TestServerHost): Logger {
115138 } , host ) ;
116139}
117140
118- function sanitizeLog ( s : string ) {
119- return s . replace ( / E l a p s e d : : ? \s * \d + (?: \. \d + ) ? m s / g, "Elapsed:: *ms" )
120- . replace ( / \" u p d a t e G r a p h D u r a t i o n M s \" \: \s * \d + (?: \. \d + ) ? / g, `"updateGraphDurationMs": *` )
121- . replace ( / \" c r e a t e A u t o I m p o r t P r o v i d e r P r o g r a m D u r a t i o n M s \" \: \s * \d + (?: \. \d + ) ? / g, `"createAutoImportProviderProgramDurationMs": *` )
122- . replace ( versionRegExp , `FakeVersion` )
123- . replace ( / g e t C o m p l e t i o n D a t a : G e t c u r r e n t t o k e n : \d + (?: \. \d + ) ? / g, `getCompletionData: Get current token: *` )
124- . replace ( / g e t C o m p l e t i o n D a t a : I s i n s i d e c o m m e n t : \d + (?: \. \d + ) ? / g, `getCompletionData: Is inside comment: *` )
125- . replace ( / g e t C o m p l e t i o n D a t a : G e t p r e v i o u s t o k e n : \d + (?: \. \d + ) ? / g, `getCompletionData: Get previous token: *` )
126- . replace ( / g e t C o m p l e t i o n s A t P o s i t i o n : i s C o m p l e t i o n L i s t B l o c k e r : \d + (?: \. \d + ) ? / g, `getCompletionsAtPosition: isCompletionListBlocker: *` )
127- . replace ( / g e t C o m p l e t i o n D a t a : S e m a n t i c w o r k : \d + (?: \. \d + ) ? / g, `getCompletionData: Semantic work: *` )
128- . replace ( / g e t C o m p l e t i o n s A t P o s i t i o n : g e t C o m p l e t i o n E n t r i e s F r o m S y m b o l s : \d + (?: \. \d + ) ? / g, `getCompletionsAtPosition: getCompletionEntriesFromSymbols: *` )
129- . replace ( / f o r E a c h E x t e r n a l M o d u l e T o I m p o r t F r o m a u t o I m p o r t P r o v i d e r : \d + (?: \. \d + ) ? / g, `forEachExternalModuleToImportFrom autoImportProvider: *` )
130- . replace ( / g e t E x p o r t I n f o M a p : d o n e i n \d + (?: \. \d + ) ? / g, `getExportInfoMap: done in *` )
131- . replace ( / c o l l e c t A u t o I m p o r t s : \d + (?: \. \d + ) ? / g, `collectAutoImports: *` )
132- . replace ( / c o n t i n u e P r e v i o u s I n c o m p l e t e R e s p o n s e : \d + (?: \. \d + ) ? / g, `continuePreviousIncompleteResponse: *` )
133- . replace ( / d e p e n d e n c i e s i n \d + (?: \. \d + ) ? / g, `dependencies in *` )
134- . replace ( / \" e x p o r t M a p K e y \" \: \s * \" [ _ $ a - z A - Z ] [ _ $ _ $ a - z A - Z 0 - 9 ] * \| \d + \| / g, match => match . replace ( / \| \d + \| / , `|*|` ) ) ;
141+ function sanitizeLog ( s : string ) : string {
142+ s = s . replace ( / E l a p s e d : : ? \s * \d + (?: \. \d + ) ? m s / g, "Elapsed:: *ms" ) ;
143+ s = s . replace ( / \" u p d a t e G r a p h D u r a t i o n M s \" \: \s * \d + (?: \. \d + ) ? / g, `"updateGraphDurationMs": *` ) ;
144+ s = s . replace ( / \" c r e a t e A u t o I m p o r t P r o v i d e r P r o g r a m D u r a t i o n M s \" \: \s * \d + (?: \. \d + ) ? / g, `"createAutoImportProviderProgramDurationMs": *` ) ;
145+ s = replaceAll ( s , ts . version , "FakeVersion" ) ;
146+ s = s . replace ( / g e t C o m p l e t i o n D a t a : G e t c u r r e n t t o k e n : \d + (?: \. \d + ) ? / g, `getCompletionData: Get current token: *` ) ;
147+ s = s . replace ( / g e t C o m p l e t i o n D a t a : I s i n s i d e c o m m e n t : \d + (?: \. \d + ) ? / g, `getCompletionData: Is inside comment: *` ) ;
148+ s = s . replace ( / g e t C o m p l e t i o n D a t a : G e t p r e v i o u s t o k e n : \d + (?: \. \d + ) ? / g, `getCompletionData: Get previous token: *` ) ;
149+ s = s . replace ( / g e t C o m p l e t i o n s A t P o s i t i o n : i s C o m p l e t i o n L i s t B l o c k e r : \d + (?: \. \d + ) ? / g, `getCompletionsAtPosition: isCompletionListBlocker: *` ) ;
150+ s = s . replace ( / g e t C o m p l e t i o n D a t a : S e m a n t i c w o r k : \d + (?: \. \d + ) ? / g, `getCompletionData: Semantic work: *` ) ;
151+ s = s . replace ( / g e t C o m p l e t i o n s A t P o s i t i o n : g e t C o m p l e t i o n E n t r i e s F r o m S y m b o l s : \d + (?: \. \d + ) ? / g, `getCompletionsAtPosition: getCompletionEntriesFromSymbols: *` ) ;
152+ s = s . replace ( / f o r E a c h E x t e r n a l M o d u l e T o I m p o r t F r o m a u t o I m p o r t P r o v i d e r : \d + (?: \. \d + ) ? / g, `forEachExternalModuleToImportFrom autoImportProvider: *` ) ;
153+ s = s . replace ( / g e t E x p o r t I n f o M a p : d o n e i n \d + (?: \. \d + ) ? / g, `getExportInfoMap: done in *` ) ;
154+ s = s . replace ( / c o l l e c t A u t o I m p o r t s : \d + (?: \. \d + ) ? / g, `collectAutoImports: *` ) ;
155+ s = s . replace ( / c o n t i n u e P r e v i o u s I n c o m p l e t e R e s p o n s e : \d + (?: \. \d + ) ? / g, `continuePreviousIncompleteResponse: *` ) ;
156+ s = s . replace ( / d e p e n d e n c i e s i n \d + (?: \. \d + ) ? / g, `dependencies in *` ) ;
157+ s = s . replace ( / \" e x p o r t M a p K e y \" \: \s * \" [ _ $ a - z A - Z ] [ _ $ _ $ a - z A - Z 0 - 9 ] * \| \d + \| / g, match => match . replace ( / \| \d + \| / , `|*|` ) ) ;
158+ return s ;
135159}
136160
137161export function createLoggerWithInMemoryLogs ( host : TestServerHost ) : Logger {
@@ -159,14 +183,22 @@ export function appendAllScriptInfos(session: TestSession) {
159183 session . logger . log ( "" ) ;
160184}
161185
162- const versionRegExp = new RegExp ( ts . version , "g" ) ;
163- const tsMajorMinorVersion = new RegExp ( `@ts${ ts . versionMajorMinor } ` , "g" ) ;
164186function loggerToTypingsInstallerLog ( logger : Logger ) : ts . server . typingsInstaller . Log | undefined {
165187 return logger ?. loggingEnabled ( ) ? {
166188 isEnabled : ts . returnTrue ,
167- writeLine : s => logger . log ( `TI:: [${ nowString ( logger . host ! ) } ] ${ sanitizeLog ( s ) . replace ( versionRegExp , "FakeVersion" )
168- . replace ( tsMajorMinorVersion , `@tsFakeMajor.Minor` )
169- } `) ,
189+ writeLine : s => {
190+ // This is a VERY VERY NAIVE sanitization strategy.
191+ // If a substring containing the exact TypeScript version is found,
192+ // even if it's unrelated to TypeScript itself, then it will be replaced,
193+ // leaving us with two options:
194+ //
195+ // 1. Deal with flip-flopping baselines.
196+ // 2. Change the TypeScript version until no matching substring is found.
197+ //
198+ const initialLog = sanitizeLog ( s ) ;
199+ const pseudoSanitizedLog = replaceAll ( initialLog , `@ts${ ts . versionMajorMinor } ` , `@tsFakeMajor.Minor` ) ;
200+ return logger . log ( `TI:: [${ nowString ( logger . host ! ) } ] ${ pseudoSanitizedLog } ` ) ;
201+ } ,
170202 } : undefined ;
171203}
172204
0 commit comments