Skip to content

Commit 82c02a7

Browse files
committed
Merge branch 'main' into fix44572
2 parents 813b04b + 630012a commit 82c02a7

File tree

246 files changed

+71721
-25330
lines changed

Some content is hidden

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

246 files changed

+71721
-25330
lines changed

Gulpfile.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,10 +437,6 @@ task("watch-local").flags = {
437437
" --built": "Compile using the built version of the compiler."
438438
};
439439

440-
const generateCodeCoverage = () => exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", "" + cmdLineOptions.testTimeout, "built/local/run.js"]);
441-
task("generate-code-coverage", series(preBuild, buildTests, generateCodeCoverage));
442-
task("generate-code-coverage").description = "Generates code coverage data via istanbul";
443-
444440
const preTest = parallel(buildTsc, buildTests, buildServices, buildLssl);
445441
preTest.displayName = "preTest";
446442

lib/lib.es2021.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ and limitations under the License.
2222
/// <reference lib="es2021.promise" />
2323
/// <reference lib="es2021.string" />
2424
/// <reference lib="es2021.weakref" />
25+
/// <reference lib="es2021.intl" />

package-lock.json

Lines changed: 67 additions & 266 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
"gulp-newer": "latest",
8080
"gulp-rename": "latest",
8181
"gulp-sourcemaps": "latest",
82-
"istanbul": "latest",
8382
"merge2": "latest",
8483
"minimist": "latest",
8584
"mkdirp": "latest",

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3388,7 +3388,7 @@ namespace ts {
33883388

33893389
function bindTypeParameter(node: TypeParameterDeclaration) {
33903390
if (isJSDocTemplateTag(node.parent)) {
3391-
const container = find((node.parent.parent as JSDoc).tags!, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
3391+
const container = getEffectiveContainerForJSDocTemplateTag(node.parent);
33923392
if (container) {
33933393
if (!container.locals) {
33943394
container.locals = createSymbolTable();

src/compiler/checker.ts

Lines changed: 200 additions & 44 deletions
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ namespace ts {
7171
["es2021.promise", "lib.es2021.promise.d.ts"],
7272
["es2021.string", "lib.es2021.string.d.ts"],
7373
["es2021.weakref", "lib.es2021.weakref.d.ts"],
74+
["es2021.intl", "lib.es2021.intl.d.ts"],
7475
["esnext.array", "lib.es2019.array.d.ts"],
7576
["esnext.symbol", "lib.es2019.symbol.d.ts"],
7677
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
@@ -570,7 +571,7 @@ namespace ts {
570571
type: new Map(getEntries({
571572
remove: ImportsNotUsedAsValues.Remove,
572573
preserve: ImportsNotUsedAsValues.Preserve,
573-
error: ImportsNotUsedAsValues.Error
574+
error: ImportsNotUsedAsValues.Error,
574575
})),
575576
affectsEmit: true,
576577
affectsSemanticDiagnostics: true,
@@ -1166,8 +1167,16 @@ namespace ts {
11661167
affectsEmit: true,
11671168
category: Diagnostics.Language_and_Environment,
11681169
description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields,
1169-
defaultValueDescription: "false"
1170+
defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext
1171+
},
1172+
{
1173+
name: "preserveValueImports",
1174+
type: "boolean",
1175+
affectsEmit: true,
1176+
category: Diagnostics.Emit,
1177+
description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed,
11701178
},
1179+
11711180
{
11721181
name: "keyofStringsOnly",
11731182
type: "boolean",
@@ -2852,6 +2861,7 @@ namespace ts {
28522861
let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined;
28532862
let watchOptions: WatchOptions | undefined;
28542863
let extendedConfigPath: string | undefined;
2864+
let rootCompilerOptions: PropertyName[] | undefined;
28552865

28562866
const optionsIterator: JsonConversionNotifier = {
28572867
onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) {
@@ -2894,6 +2904,9 @@ namespace ts {
28942904
if (key === "excludes") {
28952905
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
28962906
}
2907+
if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) {
2908+
rootCompilerOptions = append(rootCompilerOptions, keyNode);
2909+
}
28972910
}
28982911
};
28992912
const json = convertConfigFileToObject(sourceFile, errors, /*reportOptionsErrors*/ true, optionsIterator);
@@ -2913,6 +2926,10 @@ namespace ts {
29132926
}
29142927
}
29152928

2929+
if (rootCompilerOptions && json && json.compilerOptions === undefined) {
2930+
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, rootCompilerOptions[0], Diagnostics._0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file, getTextOfPropertyName(rootCompilerOptions[0]) as string));
2931+
}
2932+
29162933
return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath };
29172934
}
29182935

src/compiler/diagnosticMessages.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,22 @@
13721372
"category": "Error",
13731373
"code": 1443
13741374
},
1375+
"'{0}' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": {
1376+
"category": "Error",
1377+
"code": 1444
1378+
},
1379+
"'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": {
1380+
"category": "Error",
1381+
"code": 1446
1382+
},
1383+
"'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when 'isolatedModules' is enabled.": {
1384+
"category": "Error",
1385+
"code": 1448
1386+
},
1387+
"Preserve unused imported values in the JavaScript output that would otherwise be removed.": {
1388+
"category": "Message",
1389+
"code": 1449
1390+
},
13751391

13761392
"The types of '{0}' are incompatible between these types.": {
13771393
"category": "Error",
@@ -3910,6 +3926,10 @@
39103926
"category": "Error",
39113927
"code": 5094
39123928
},
3929+
"Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.": {
3930+
"category": "Error",
3931+
"code": 5095
3932+
},
39133933

39143934
"Generates a sourcemap for each corresponding '.d.ts' file.": {
39153935
"category": "Message",
@@ -4834,6 +4854,10 @@
48344854
"category": "Message",
48354855
"code": 6257
48364856
},
4857+
"'{0}' should be set inside the 'compilerOptions' object of the config json file": {
4858+
"category": "Error",
4859+
"code": 6258
4860+
},
48374861

48384862
"Enable project compilation": {
48394863
"category": "Message",
@@ -5668,6 +5692,11 @@
56685692
"category": "Message",
56695693
"code": 6929
56705694
},
5695+
"`true` for ES2022 and above, including ESNext.": {
5696+
"category": "Message",
5697+
"code": 6930
5698+
},
5699+
56715700

56725701
"Variable '{0}' implicitly has an '{1}' type.": {
56735702
"category": "Error",

src/compiler/factory/nodeFactory.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4939,14 +4939,16 @@ namespace ts {
49394939
}
49404940

49414941
// @api
4942-
function createCatchClause(variableDeclaration: string | VariableDeclaration | undefined, block: Block) {
4942+
function createCatchClause(variableDeclaration: string | BindingName | VariableDeclaration | undefined, block: Block) {
49434943
const node = createBaseNode<CatchClause>(SyntaxKind.CatchClause);
4944-
variableDeclaration = !isString(variableDeclaration) ? variableDeclaration : createVariableDeclaration(
4945-
variableDeclaration,
4946-
/*exclamationToken*/ undefined,
4947-
/*type*/ undefined,
4948-
/*initializer*/ undefined
4949-
);
4944+
if (typeof variableDeclaration === "string" || variableDeclaration && !isVariableDeclaration(variableDeclaration)) {
4945+
variableDeclaration = createVariableDeclaration(
4946+
variableDeclaration,
4947+
/*exclamationToken*/ undefined,
4948+
/*type*/ undefined,
4949+
/*initializer*/ undefined
4950+
);
4951+
}
49504952
node.variableDeclaration = variableDeclaration;
49514953
node.block = block;
49524954
node.transformFlags |=

src/compiler/parser.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8441,11 +8441,24 @@ namespace ts {
84418441

84428442
function parseTemplateTagTypeParameter() {
84438443
const typeParameterPos = getNodePos();
8444+
const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken);
8445+
if (isBracketed) {
8446+
skipWhitespace();
8447+
}
84448448
const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces);
8449+
8450+
let defaultType: TypeNode | undefined;
8451+
if (isBracketed) {
8452+
skipWhitespace();
8453+
parseExpected(SyntaxKind.EqualsToken);
8454+
defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
8455+
parseExpected(SyntaxKind.CloseBracketToken);
8456+
}
8457+
84458458
if (nodeIsMissing(name)) {
84468459
return undefined;
84478460
}
8448-
return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined), typeParameterPos);
8461+
return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, defaultType), typeParameterPos);
84498462
}
84508463

84518464
function parseTemplateTagTypeParameters() {

src/compiler/program.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3305,6 +3305,10 @@ namespace ts {
33053305
}
33063306
}
33073307

3308+
if (options.preserveValueImports && getEmitModuleKind(options) < ModuleKind.ES2015) {
3309+
createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later);
3310+
}
3311+
33083312
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
33093313
if (!options.noEmit && !options.suppressOutputPathCheck) {
33103314
const emitHost = getEmitHost();
@@ -3575,7 +3579,7 @@ namespace ts {
35753579
createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3);
35763580
}
35773581

3578-
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) {
3582+
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string) {
35793583
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
35803584
}
35813585

@@ -3590,7 +3594,7 @@ namespace ts {
35903594
}
35913595
}
35923596

3593-
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) {
3597+
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) {
35943598
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
35953599
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
35963600
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
@@ -3616,7 +3620,7 @@ namespace ts {
36163620
return _compilerOptionsObjectLiteralSyntax || undefined;
36173621
}
36183622

3619-
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean {
3623+
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): boolean {
36203624
const props = getPropertyAssignment(objectLiteral, key1, key2);
36213625
for (const prop of props) {
36223626
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));

src/compiler/transformers/ts.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,7 +2791,7 @@ namespace ts {
27912791
}
27922792

27932793
/**
2794-
* Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve'.
2794+
* Visits an import declaration, eliding it if it is type-only or if it has an import clause that may be elided.
27952795
*
27962796
* @param node The import declaration node.
27972797
*/
@@ -2821,29 +2821,27 @@ namespace ts {
28212821
}
28222822

28232823
/**
2824-
* Visits an import clause, eliding it if it is not referenced.
2824+
* Visits an import clause, eliding it if its `name` and `namedBindings` may both be elided.
28252825
*
28262826
* @param node The import clause node.
28272827
*/
28282828
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
2829-
if (node.isTypeOnly) {
2830-
return undefined;
2831-
}
2829+
Debug.assert(!node.isTypeOnly);
28322830
// Elide the import clause if we elide both its name and its named bindings.
2833-
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
2831+
const name = shouldEmitAliasDeclaration(node) ? node.name : undefined;
28342832
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
28352833
return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined;
28362834
}
28372835

28382836
/**
2839-
* Visits named import bindings, eliding it if it is not referenced.
2837+
* Visits named import bindings, eliding them if their targets, their references, and the compilation settings allow.
28402838
*
28412839
* @param node The named import bindings node.
28422840
*/
28432841
function visitNamedImportBindings(node: NamedImportBindings): VisitResult<NamedImportBindings> {
28442842
if (node.kind === SyntaxKind.NamespaceImport) {
28452843
// Elide a namespace import if it is not referenced.
2846-
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
2844+
return shouldEmitAliasDeclaration(node) ? node : undefined;
28472845
}
28482846
else {
28492847
// Elide named imports if all of its import specifiers are elided.
@@ -2853,13 +2851,12 @@ namespace ts {
28532851
}
28542852

28552853
/**
2856-
* Visits an import specifier, eliding it if it is not referenced.
2854+
* Visits an import specifier, eliding it if its target, its references, and the compilation settings allow.
28572855
*
28582856
* @param node The import specifier node.
28592857
*/
28602858
function visitImportSpecifier(node: ImportSpecifier): VisitResult<ImportSpecifier> {
2861-
// Elide an import specifier if it is not referenced.
2862-
return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
2859+
return shouldEmitAliasDeclaration(node) ? node : undefined;
28632860
}
28642861

28652862
/**
@@ -2876,8 +2873,7 @@ namespace ts {
28762873
}
28772874

28782875
/**
2879-
* Visits an export declaration, eliding it if it does not contain a clause that resolves
2880-
* to a value.
2876+
* Visits an export declaration, eliding it if it does not contain a clause that resolves to a value.
28812877
*
28822878
* @param node The export declaration node.
28832879
*/
@@ -2950,7 +2946,7 @@ namespace ts {
29502946
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
29512947
// - current file is not external module
29522948
// - import declaration is top level and target is value imported by entity name
2953-
return resolver.isReferencedAliasDeclaration(node)
2949+
return shouldEmitAliasDeclaration(node)
29542950
|| (!isExternalModule(currentSourceFile)
29552951
&& resolver.isTopLevelValueImportEqualsWithEntityName(node));
29562952
}
@@ -2967,7 +2963,7 @@ namespace ts {
29672963
}
29682964

29692965
if (isExternalModuleImportEqualsDeclaration(node)) {
2970-
const isReferenced = resolver.isReferencedAliasDeclaration(node);
2966+
const isReferenced = shouldEmitAliasDeclaration(node);
29712967
// If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'.
29722968
if (!isReferenced && compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Preserve) {
29732969
return setOriginalNode(
@@ -3358,5 +3354,11 @@ namespace ts {
33583354

33593355
return isPropertyAccessExpression(node) || isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
33603356
}
3357+
3358+
function shouldEmitAliasDeclaration(node: Node): boolean {
3359+
return compilerOptions.preserveValueImports
3360+
? resolver.isValueAliasDeclaration(node)
3361+
: resolver.isReferencedAliasDeclaration(node);
3362+
}
33613363
}
33623364
}

0 commit comments

Comments
 (0)