1
1
/* @internal */
2
2
namespace ts {
3
+ export enum LogLevel {
4
+ Off ,
5
+ Error ,
6
+ Warning ,
7
+ Info ,
8
+ Verbose
9
+ }
10
+
11
+ export interface LoggingHost {
12
+ log ( level : LogLevel , s : string ) : void ;
13
+ }
14
+
15
+ export interface DeprecationOptions {
16
+ message ?: string ;
17
+ error ?: boolean ;
18
+ since ?: Version | string ;
19
+ warnAfter ?: Version | string ;
20
+ errorAfter ?: Version | string ;
21
+ typeScriptVersion ?: Version | string ;
22
+ }
23
+
3
24
export namespace Debug {
25
+ let typeScriptVersion : Version | undefined ;
26
+
4
27
/* eslint-disable prefer-const */
5
28
export let currentAssertionLevel = AssertionLevel . None ;
29
+ export let currentLogLevel = LogLevel . Warning ;
6
30
export let isDebugging = false ;
31
+ export let loggingHost : LoggingHost | undefined ;
7
32
/* eslint-enable prefer-const */
8
33
34
+ export function getTypeScriptVersion ( ) {
35
+ return typeScriptVersion ?? ( typeScriptVersion = new Version ( version ) ) ;
36
+ }
37
+
38
+ export function shouldLog ( level : LogLevel ) : boolean {
39
+ return currentLogLevel <= level ;
40
+ }
41
+
42
+ function logMessage ( level : LogLevel , s : string ) : void {
43
+ if ( loggingHost && shouldLog ( level ) ) {
44
+ loggingHost . log ( level , s ) ;
45
+ }
46
+ }
47
+
48
+ export function log ( s : string ) : void {
49
+ logMessage ( LogLevel . Info , s ) ;
50
+ }
51
+
52
+ export namespace log {
53
+ export function error ( s : string ) : void {
54
+ logMessage ( LogLevel . Error , s ) ;
55
+ }
56
+
57
+ export function warn ( s : string ) : void {
58
+ logMessage ( LogLevel . Warning , s ) ;
59
+ }
60
+
61
+ export function log ( s : string ) : void {
62
+ logMessage ( LogLevel . Info , s ) ;
63
+ }
64
+
65
+ export function trace ( s : string ) : void {
66
+ logMessage ( LogLevel . Verbose , s ) ;
67
+ }
68
+ }
69
+
9
70
export function shouldAssert ( level : AssertionLevel ) : boolean {
10
71
return currentAssertionLevel >= level ;
11
72
}
@@ -295,7 +356,7 @@ namespace ts {
295
356
if ( nodeIsSynthesized ( this ) ) return "" ;
296
357
const parseNode = getParseTreeNode ( this ) ;
297
358
const sourceFile = parseNode && getSourceFileOfNode ( parseNode ) ;
298
- return sourceFile ? getSourceTextOfNodeFromSourceFile ( sourceFile , parseNode , includeTrivia ) : "" ;
359
+ return sourceFile ? getSourceTextOfNodeFromSourceFile ( sourceFile , parseNode ! , includeTrivia ) : "" ;
299
360
}
300
361
}
301
362
} ) ;
@@ -320,5 +381,92 @@ namespace ts {
320
381
isDebugInfoEnabled = true ;
321
382
}
322
383
384
+ function formatDeprecationMessage ( name : string , error : boolean | undefined , errorAfter : Version | undefined , since : Version | undefined , message : string | undefined ) {
385
+ let deprecationMessage = error ? "DeprecationError: " : "DeprecationWarning: " ;
386
+ deprecationMessage += `'${ name } ' ` ;
387
+ deprecationMessage += since ? `has been deprecated since v${ since } ` : "is deprecated" ;
388
+ deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${ errorAfter } .` : "." ;
389
+ deprecationMessage += message ? ` ${ formatStringFromArgs ( message , [ name ] , 0 ) } ` : "" ;
390
+ return deprecationMessage ;
391
+ }
392
+
393
+ function createErrorDeprecation ( name : string , errorAfter : Version | undefined , since : Version | undefined , message : string | undefined ) {
394
+ const deprecationMessage = formatDeprecationMessage ( name , /*error*/ true , errorAfter , since , message ) ;
395
+ return ( ) => {
396
+ throw new TypeError ( deprecationMessage ) ;
397
+ } ;
398
+ }
399
+
400
+ function createWarningDeprecation ( name : string , errorAfter : Version | undefined , since : Version | undefined , message : string | undefined ) {
401
+ let hasWrittenDeprecation = false ;
402
+ return ( ) => {
403
+ if ( ! hasWrittenDeprecation ) {
404
+ log . warn ( formatDeprecationMessage ( name , /*error*/ false , errorAfter , since , message ) ) ;
405
+ hasWrittenDeprecation = true ;
406
+ }
407
+ } ;
408
+ }
409
+
410
+ function createDeprecation ( name : string , options : DeprecationOptions & { error : true } ) : ( ) => never ;
411
+ function createDeprecation ( name : string , options ?: DeprecationOptions ) : ( ) => void ;
412
+ function createDeprecation ( name : string , options : DeprecationOptions = { } ) {
413
+ const version = typeof options . typeScriptVersion === "string" ? new Version ( options . typeScriptVersion ) : options . typeScriptVersion ?? getTypeScriptVersion ( ) ;
414
+ const errorAfter = typeof options . errorAfter === "string" ? new Version ( options . errorAfter ) : options . errorAfter ;
415
+ const warnAfter = typeof options . warnAfter === "string" ? new Version ( options . warnAfter ) : options . warnAfter ;
416
+ const since = typeof options . since === "string" ? new Version ( options . since ) : options . since ?? warnAfter ;
417
+ const error = options . error || errorAfter && version . compareTo ( errorAfter ) <= 0 ;
418
+ const warn = ! warnAfter || version . compareTo ( warnAfter ) >= 0 ;
419
+ return error ? createErrorDeprecation ( name , errorAfter , since , options . message ) :
420
+ warn ? createWarningDeprecation ( name , errorAfter , since , options . message ) :
421
+ noop ;
422
+ }
423
+
424
+ function wrapFunction < F extends ( ...args : any [ ] ) => any > ( deprecation : ( ) => void , func : F ) : F {
425
+ return function ( this : unknown ) {
426
+ deprecation ( ) ;
427
+ return func . apply ( this , arguments ) ;
428
+ } as F ;
429
+ }
430
+
431
+ function wrapAccessor ( deprecation : ( ) => void , desc : PropertyDescriptor ) {
432
+ if ( desc . configurable ) {
433
+ const newDesc : PropertyDescriptor = { ...desc , enumerable : false } ;
434
+ if ( desc . get ) newDesc . get = wrapFunction ( deprecation , desc . get ) ;
435
+ if ( desc . set ) newDesc . set = wrapFunction ( deprecation , desc . set ) ;
436
+ return newDesc ;
437
+ }
438
+ }
439
+
440
+ function wrapValue ( deprecation : ( ) => void , desc : PropertyDescriptor ) {
441
+ if ( typeof desc . value === "function" && ( desc . configurable || desc . writable ) ) {
442
+ const newDesc : PropertyDescriptor = { ...desc } ;
443
+ if ( desc . configurable ) {
444
+ desc . enumerable = false ;
445
+ }
446
+ newDesc . value = wrapFunction ( deprecation , newDesc . value ) ;
447
+ return newDesc ;
448
+ }
449
+ }
450
+
451
+ export function deprecateExport < T , K extends Extract < MatchingKeys < T , ( ...args : any [ ] ) => any > , string > > ( ns : T , key : K , options ?: DeprecationOptions ) {
452
+ const desc = Object . getOwnPropertyDescriptor ( ns , key ) ;
453
+ if ( ! desc ) return ;
454
+ const deprecation = createDeprecation ( key , options ) ;
455
+ const newDesc = desc . get || desc . set ? wrapAccessor ( deprecation , desc ) : wrapValue ( deprecation , desc ) ;
456
+ if ( newDesc ) {
457
+ Object . defineProperty ( ns , key , newDesc ) ;
458
+ }
459
+ }
460
+
461
+ export function deprecateExports < T , K extends Extract < MatchingKeys < T , ( ...args : any [ ] ) => any > , string > > ( object : T , keys : readonly K [ ] , options ?: DeprecationOptions ) {
462
+ for ( const key of keys ) {
463
+ deprecateExport ( object , key , options ) ;
464
+ }
465
+ }
466
+
467
+ export function deprecateFunction < F extends ( ...args : any [ ] ) => any > ( func : F , options ?: DeprecationOptions ) : F {
468
+ const deprecation = createDeprecation ( getFunctionName ( func ) , options ) ;
469
+ return wrapFunction ( deprecation , func ) ;
470
+ }
323
471
}
324
472
}
0 commit comments