Skip to content

Commit 8373d4c

Browse files
committed
feat(51000): add ignoreDeprecations option
1 parent 5e3fa9b commit 8373d4c

File tree

9,056 files changed

+139002
-990
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

9,056 files changed

+139002
-990
lines changed

src/compiler/commandLineParser.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,15 @@ namespace ts {
13521352
description: Diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files,
13531353
category: Diagnostics.Language_and_Environment,
13541354
defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules,
1355+
},
1356+
{
1357+
name: "ignoreDeprecations",
1358+
type: new Map(getEntries({
1359+
[DeprecationPhaseToVersionMap[DeprecationPhase.Phase1]]: DeprecationPhase.Phase1,
1360+
[DeprecationPhaseToVersionMap[DeprecationPhase.Phase2]]: DeprecationPhase.Phase2,
1361+
[DeprecationPhaseToVersionMap[DeprecationPhase.Phase3]]: DeprecationPhase.Phase3,
1362+
})),
1363+
defaultValueDescription: undefined,
13551364
}
13561365
];
13571366

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4221,6 +4221,18 @@
42214221
"category": "Error",
42224222
"code": 5095
42234223
},
4224+
"Flag '{0}' is deprecated and will stop functioning in TypeScript {1}. Specify 'ignoreDeprecations: \"{2}\"' to silence this error.": {
4225+
"category": "Error",
4226+
"code": 5096
4227+
},
4228+
"Flag '{0}' is deprecated, please remove it from your configuration.": {
4229+
"category": "Error",
4230+
"code": 5097
4231+
},
4232+
"Invalid value for '--ignoreDeprecations'.": {
4233+
"category": "Error",
4234+
"code": 5098
4235+
},
42244236

42254237
"Generates a sourcemap for each corresponding '.d.ts' file.": {
42264238
"category": "Message",

src/compiler/program.ts

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,12 +1021,11 @@ namespace ts {
10211021
* @param configFileParsingDiagnostics - error during config file parsing
10221022
* @returns A 'Program' object.
10231023
*/
1024-
export function createProgram(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[]): Program;
1025-
export function createProgram(rootNamesOrOptions: readonly string[] | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: readonly Diagnostic[]): Program {
1024+
export function createProgram(rootNames: readonly string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: readonly Diagnostic[], typeScriptVersion?: string): Program;
1025+
export function createProgram(rootNamesOrOptions: readonly string[] | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: readonly Diagnostic[], typeScriptVersion?: string): Program {
10261026
const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
10271027
const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
10281028
let { oldProgram } = createProgramOptions;
1029-
10301029
let processingDefaultLibFiles: SourceFile[] | undefined;
10311030
let processingOtherFiles: SourceFile[] | undefined;
10321031
let files: SourceFile[];
@@ -1073,6 +1072,9 @@ namespace ts {
10731072
const supportedExtensions = getSupportedExtensions(options);
10741073
const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
10751074

1075+
let _typeScriptVersion: Version | undefined;
1076+
const _ignoreDeprecations = new Map<DeprecationPhase, Version>();
1077+
10761078
// Map storing if there is emit blocking diagnostics for given input
10771079
const hasEmitBlockingDiagnostics = new Map<string, boolean>();
10781080
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | false | undefined;
@@ -3397,6 +3399,7 @@ namespace ts {
33973399
if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) {
33983400
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
33993401
}
3402+
34003403
if (options.exactOptionalPropertyTypes && !getStrictOptionValue(options, "strictNullChecks")) {
34013404
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "exactOptionalPropertyTypes", "strictNullChecks");
34023405
}
@@ -3439,6 +3442,7 @@ namespace ts {
34393442
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
34403443
}
34413444

3445+
verifyDeprecatedCompilerOptions();
34423446
verifyProjectReferences();
34433447

34443448
// List of collected files is complete; validate exhautiveness if this is a project with a file list
@@ -3701,6 +3705,55 @@ namespace ts {
37013705
}
37023706
}
37033707

3708+
function verifyDeprecatedCompilerOptions() {
3709+
const version = isString(typeScriptVersion) && typeScriptVersion ? new Version(typeScriptVersion) : getTypeScriptVersion();
3710+
if (options.ignoreDeprecations) {
3711+
const ignoreDeprecationsVersion = getIgnoreDeprecationsVersion(options.ignoreDeprecations);
3712+
if (ignoreDeprecationsVersion.compareTo(version) === Comparison.LessThan) {
3713+
createOptionValueDiagnostic("ignoreDeprecations", Diagnostics.Invalid_value_for_ignoreDeprecations);
3714+
}
3715+
if (ignoreDeprecationsVersion.compareTo(version) >= 0) {
3716+
return;
3717+
}
3718+
}
3719+
if (options.target === ScriptTarget.ES3) {
3720+
createDeprecatedDiagnosticForOption(version, "target", "ES3");
3721+
}
3722+
if (options.noImplicitUseStrict) {
3723+
createDeprecatedDiagnosticForOption(version, "noImplicitUseStrict");
3724+
}
3725+
if (options.keyofStringsOnly) {
3726+
createDeprecatedDiagnosticForOption(version, "keyofStringsOnly");
3727+
}
3728+
if (options.suppressExcessPropertyErrors) {
3729+
createDeprecatedDiagnosticForOption(version, "suppressExcessPropertyErrors");
3730+
}
3731+
if (options.suppressImplicitAnyIndexErrors) {
3732+
createDeprecatedDiagnosticForOption(version, "suppressImplicitAnyIndexErrors");
3733+
}
3734+
if (options.noStrictGenericChecks) {
3735+
createDeprecatedDiagnosticForOption(version, "noStrictGenericChecks");
3736+
}
3737+
if (options.charset) {
3738+
createDeprecatedDiagnosticForOption(version, "charset");
3739+
}
3740+
if (options.out) {
3741+
createDeprecatedDiagnosticForOption(version, "out");
3742+
}
3743+
}
3744+
3745+
function createDeprecatedDiagnosticForOption(version: Version, name: string, value?: string) {
3746+
if (version.compareTo(getIgnoreDeprecationsVersion(DeprecationPhase.Phase3)) === Comparison.EqualTo) {
3747+
createDiagnosticForOption(/*onKey*/ !value, name, /*option2*/ undefined, Diagnostics.Flag_0_is_deprecated_please_remove_it_from_your_configuration, value || name);
3748+
}
3749+
else {
3750+
const { major, minor } = version;
3751+
const nextPhase = version.compareTo(getIgnoreDeprecationsVersion(DeprecationPhase.Phase2)) === Comparison.EqualTo ? DeprecationPhase.Phase3 : DeprecationPhase.Phase2;
3752+
createDiagnosticForOption(/*onKey*/ !value, name, /*option2*/ undefined,
3753+
Diagnostics.Flag_0_is_deprecated_and_will_stop_functioning_in_TypeScript_1_Specify_ignoreDeprecations_Colon_2_to_silence_this_error, value || name, DeprecationPhaseToVersionMap[nextPhase], `${major}.${minor}`);
3754+
}
3755+
}
3756+
37043757
function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: (string | number | undefined)[] | undefined): Diagnostic {
37053758
let fileIncludeReasons: DiagnosticMessageChain[] | undefined;
37063759
let relatedInfo: Diagnostic[] | undefined;
@@ -3972,6 +4025,21 @@ namespace ts {
39724025
return _compilerOptionsObjectLiteralSyntax || undefined;
39734026
}
39744027

4028+
function getTypeScriptVersion() {
4029+
if (_typeScriptVersion === undefined) {
4030+
_typeScriptVersion = new Version(versionMajorMinor);
4031+
}
4032+
return _typeScriptVersion;
4033+
}
4034+
4035+
function getIgnoreDeprecationsVersion(phase: DeprecationPhase) {
4036+
let version = _ignoreDeprecations.get(phase);
4037+
if (version === undefined) {
4038+
_ignoreDeprecations.set(phase, version = new Version(DeprecationPhaseToVersionMap[phase]));
4039+
}
4040+
return version;
4041+
}
4042+
39754043
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean {
39764044
const props = getPropertyAssignment(objectLiteral, key1, key2);
39774045
for (const prop of props) {

src/compiler/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6582,6 +6582,7 @@ namespace ts {
65826582
/*@internal*/generateCpuProfile?: string;
65836583
/*@internal*/generateTrace?: string;
65846584
/*@internal*/help?: boolean;
6585+
ignoreDeprecations?: DeprecationPhase;
65856586
importHelpers?: boolean;
65866587
importsNotUsedAsValues?: ImportsNotUsedAsValues;
65876588
/*@internal*/init?: boolean;
@@ -6740,6 +6741,19 @@ namespace ts {
67406741
LineFeed = 1
67416742
}
67426743

6744+
export const enum DeprecationPhase {
6745+
Phase1 = 1,
6746+
Phase2 = 2,
6747+
Phase3 = 3,
6748+
}
6749+
6750+
/* @internal */
6751+
export const DeprecationPhaseToVersionMap = {
6752+
[DeprecationPhase.Phase1]: "5.0",
6753+
[DeprecationPhase.Phase2]: "5.5",
6754+
[DeprecationPhase.Phase3]: "6.0",
6755+
};
6756+
67436757
export interface LineAndCharacter {
67446758
/** 0-based. */
67456759
line: number;

src/harness/compilerImpl.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ namespace compiler {
233233
}
234234
}
235235

236-
export function compileFiles(host: fakes.CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions): CompilationResult {
236+
export function compileFiles(host: fakes.CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions, typeScriptVersion?: string): CompilationResult {
237237
if (compilerOptions.project || !rootFiles || rootFiles.length === 0) {
238238
const project = readProject(host.parseConfigHost, compilerOptions.project, compilerOptions);
239239
if (project) {
@@ -258,10 +258,10 @@ namespace compiler {
258258
// and if the test is running `skipLibCheck` - an indicator that we want the tets to run quickly - skip the before/after error comparison, too
259259
const skipErrorComparison = ts.length(rootFiles) >= 100 || (!!compilerOptions.skipLibCheck && !!compilerOptions.declaration);
260260

261-
const preProgram = !skipErrorComparison ? ts.createProgram(rootFiles || [], { ...compilerOptions, configFile: compilerOptions.configFile, traceResolution: false }, host) : undefined;
261+
const preProgram = !skipErrorComparison ? ts.createProgram(rootFiles || [], { ...compilerOptions, configFile: compilerOptions.configFile, traceResolution: false }, host, /*oldProgram*/ undefined, /*configFileParsingDiagnostics*/ undefined, typeScriptVersion) : undefined;
262262
const preErrors = preProgram && ts.getPreEmitDiagnostics(preProgram);
263263

264-
const program = ts.createProgram(rootFiles || [], compilerOptions, host);
264+
const program = ts.createProgram(rootFiles || [], compilerOptions, host, /*oldProgram*/ undefined, /*configFileParsingDiagnostics*/ undefined, typeScriptVersion);
265265
const emitResult = program.emit();
266266
const postErrors = ts.getPreEmitDiagnostics(program);
267267
const longerErrors = ts.length(preErrors) > postErrors.length ? preErrors : postErrors;

src/harness/harnessIO.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ namespace Harness {
338338
if (value === undefined) {
339339
throw new Error(`Cannot have undefined value for compiler option '${name}'.`);
340340
}
341+
if (name === "typeScriptVersion") {
342+
continue;
343+
}
341344
const option = getCommandLineOption(name);
342345
if (option) {
343346
const errors: ts.Diagnostic[] = [];
@@ -399,17 +402,21 @@ namespace Harness {
399402
currentDirectory = vfs.srcFolder;
400403
}
401404

405+
let typeScriptVersion: string | undefined;
406+
402407
// Parse settings
403408
if (harnessSettings) {
404409
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
410+
if (ts.isString(harnessSettings.typeScriptVersion) && harnessSettings.typeScriptVersion) {
411+
typeScriptVersion = harnessSettings.typeScriptVersion;
412+
}
405413
}
406414
if (options.rootDirs) {
407415
options.rootDirs = ts.map(options.rootDirs, d => ts.getNormalizedAbsolutePath(d, currentDirectory));
408416
}
409417

410418
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : true;
411419
const programFileNames = inputFiles.map(file => file.unitName).filter(fileName => !ts.fileExtensionIs(fileName, ts.Extension.Json));
412-
413420
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
414421
// Treat them as library files, so include them in build, but not in baselines.
415422
if (options.includeBuiltFile) {
@@ -429,7 +436,7 @@ namespace Harness {
429436
fs.apply(symlinks);
430437
}
431438
const host = new fakes.CompilerHost(fs, options);
432-
const result = compiler.compileFiles(host, programFileNames, options);
439+
const result = compiler.compileFiles(host, programFileNames, options, typeScriptVersion);
433440
result.symlinks = symlinks;
434441
return result;
435442
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error TS5096: Flag 'ES3' is deprecated and will stop functioning in TypeScript 5.5. Specify 'ignoreDeprecations: "5.0"' to silence this error.
2+
3+
4+
!!! error TS5096: Flag 'ES3' is deprecated and will stop functioning in TypeScript 5.5. Specify 'ignoreDeprecations: "5.0"' to silence this error.
5+
==== tests/cases/compiler/2dArrays.ts (0 errors) ====
6+
class Cell {
7+
}
8+
9+
class Ship {
10+
isSunk: boolean;
11+
}
12+
13+
class Board {
14+
ships: Ship[];
15+
cells: Cell[];
16+
17+
private allShipsSunk() {
18+
return this.ships.every(function (val) { return val.isSunk; });
19+
}
20+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
error TS5096: Flag 'ES3' is deprecated and will stop functioning in TypeScript 5.5. Specify 'ignoreDeprecations: "5.0"' to silence this error.
2+
3+
4+
!!! error TS5096: Flag 'ES3' is deprecated and will stop functioning in TypeScript 5.5. Specify 'ignoreDeprecations: "5.0"' to silence this error.
5+
==== tests/cases/compiler/APISample_Watch.ts (0 errors) ====
6+
/*
7+
* Note: This test is a public API sample. The sample sources can be found
8+
* at: https://github.com/Microsoft/TypeScript-wiki/blob/master/Using-the-Compiler-API.md#writing-an-incremental-program-watcher
9+
* Please log a "breaking change" issue for any API breaking change affecting this issue
10+
*/
11+
12+
declare var process: any;
13+
declare var console: any;
14+
declare var os: any;
15+
16+
import ts = require("typescript");
17+
18+
const formatHost: ts.FormatDiagnosticsHost = {
19+
getCanonicalFileName: path => path,
20+
getCurrentDirectory: ts.sys.getCurrentDirectory,
21+
getNewLine: () => ts.sys.newLine,
22+
}
23+
24+
function watchMain() {
25+
const configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json");
26+
if (!configPath) {
27+
throw new Error("Could not find a valid 'tsconfig.json'.");
28+
}
29+
30+
// TypeScript can use several different program creation "strategies":
31+
// * ts.createEmitAndSemanticDiagnosticsBuilderProgram,
32+
// * ts.createSemanticDiagnosticsBuilderProgram
33+
// * ts.createAbstractBuilder
34+
// The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose
35+
// contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit.
36+
// The last uses an ordinary program which does a full type check after every change.
37+
// Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit.
38+
// For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable.
39+
40+
// Note that there is another overload for `createWatchCompilerHost` that takes a set of root files.
41+
const host = ts.createWatchCompilerHost(configPath, {}, ts.sys,
42+
ts.createSemanticDiagnosticsBuilderProgram,
43+
reportDiagnostic,
44+
reportWatchStatusChanged,
45+
);
46+
47+
// You can technically override any given hook on the host, though you probably don't need to.
48+
// Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all.
49+
const origCreateProgram = host.createProgram;
50+
host.createProgram = (rootNames: ReadonlyArray<string>, options, host, oldProgram) => {
51+
console.log("** We're about to create the program! **");
52+
return origCreateProgram(rootNames, options, host, oldProgram);
53+
}
54+
const origPostProgramCreate = host.afterProgramCreate;
55+
56+
host.afterProgramCreate = program => {
57+
console.log("** We finished making the program! **");
58+
origPostProgramCreate!(program);
59+
};
60+
61+
// `createWatchProgram` creates an initial program, watches files, and updates the program over time.
62+
ts.createWatchProgram(host);
63+
}
64+
65+
function reportDiagnostic(diagnostic: ts.Diagnostic) {
66+
console.error("Error", diagnostic.code, ":",
67+
ts.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine())
68+
);
69+
}
70+
71+
/**
72+
* Prints a diagnostic every time the watch status changes.
73+
* This is mainly for messages like "Starting compilation" or "Compilation completed".
74+
*/
75+
function reportWatchStatusChanged(diagnostic: ts.Diagnostic) {
76+
console.info(ts.formatDiagnostic(diagnostic, formatHost));
77+
}
78+
79+
watchMain();
80+
81+
==== tests/cases/compiler/node_modules/typescript/package.json (0 errors) ====
82+
{
83+
"name": "typescript",
84+
"types": "/.ts/typescript.d.ts"
85+
}
86+

0 commit comments

Comments
 (0)