Skip to content

Commit 859abb6

Browse files
committed
Merge branch 'mjscjs-support' into imports-exports-selfs
2 parents 093002c + 5bf44ac commit 859abb6

File tree

294 files changed

+9386
-7386
lines changed

Some content is hidden

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

294 files changed

+9386
-7386
lines changed

Gulpfile.js

-4
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

+1
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

+48-247
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

-1
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

+1-1
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

+425-149
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+18-1
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"],
@@ -572,7 +573,7 @@ namespace ts {
572573
type: new Map(getEntries({
573574
remove: ImportsNotUsedAsValues.Remove,
574575
preserve: ImportsNotUsedAsValues.Preserve,
575-
error: ImportsNotUsedAsValues.Error
576+
error: ImportsNotUsedAsValues.Error,
576577
})),
577578
affectsEmit: true,
578579
affectsSemanticDiagnostics: true,
@@ -1170,6 +1171,14 @@ namespace ts {
11701171
description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields,
11711172
defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext
11721173
},
1174+
{
1175+
name: "preserveValueImports",
1176+
type: "boolean",
1177+
affectsEmit: true,
1178+
category: Diagnostics.Emit,
1179+
description: Diagnostics.Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed,
1180+
},
1181+
11731182
{
11741183
name: "keyofStringsOnly",
11751184
type: "boolean",
@@ -2854,6 +2863,7 @@ namespace ts {
28542863
let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined;
28552864
let watchOptions: WatchOptions | undefined;
28562865
let extendedConfigPath: string | undefined;
2866+
let rootCompilerOptions: PropertyName[] | undefined;
28572867

28582868
const optionsIterator: JsonConversionNotifier = {
28592869
onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) {
@@ -2896,6 +2906,9 @@ namespace ts {
28962906
if (key === "excludes") {
28972907
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, keyNode, Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
28982908
}
2909+
if (find(commandOptionsWithoutBuild, (opt) => opt.name === key)) {
2910+
rootCompilerOptions = append(rootCompilerOptions, keyNode);
2911+
}
28992912
}
29002913
};
29012914
const json = convertConfigFileToObject(sourceFile, errors, /*reportOptionsErrors*/ true, optionsIterator);
@@ -2915,6 +2928,10 @@ namespace ts {
29152928
}
29162929
}
29172930

2931+
if (rootCompilerOptions && json && json.compilerOptions === undefined) {
2932+
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));
2933+
}
2934+
29182935
return { raw: json, options, watchOptions, typeAcquisition, extendedConfigPath };
29192936
}
29202937

src/compiler/diagnosticMessages.json

+31-10
Original file line numberDiff line numberDiff line change
@@ -1372,13 +1372,30 @@
13721372
"category": "Error",
13731373
"code": 1443
13741374
},
1375-
"The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": {
1375+
"'{0}' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.": {
13761376
"category": "Error",
13771377
"code": 1444
13781378
},
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+
},
1391+
1392+
"The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": {
1393+
"category": "Error",
1394+
"code": 1470
1395+
},
13791396
"Module '{0}' cannot be imported using this construct. The specifier only resolves to an es module, which cannot be imported synchronously. Use dynamic import instead.": {
13801397
"category": "Error",
1381-
"code": 1445
1398+
"code": 1471
13821399
},
13831400

13841401
"The types of '{0}' are incompatible between these types.": {
@@ -3292,6 +3309,10 @@
32923309
"category": "Error",
32933310
"code": 2819
32943311
},
3312+
"Type '{0}' is not assignable to type '{1}'. Did you mean '{2}'?": {
3313+
"category": "Error",
3314+
"code": 2820
3315+
},
32953316

32963317
"Import declaration '{0}' is using private name '{1}'.": {
32973318
"category": "Error",
@@ -3918,6 +3939,10 @@
39183939
"category": "Error",
39193940
"code": 5094
39203941
},
3942+
"Option 'preserveValueImports' can only be used when 'module' is set to 'es2015' or later.": {
3943+
"category": "Error",
3944+
"code": 5095
3945+
},
39213946

39223947
"Generates a sourcemap for each corresponding '.d.ts' file.": {
39233948
"category": "Message",
@@ -3931,10 +3956,6 @@
39313956
"category": "Message",
39323957
"code": 6002
39333958
},
3934-
"Specify the location where debugger should locate map files instead of generated locations.": {
3935-
"category": "Message",
3936-
"code": 6003
3937-
},
39383959
"Specify the location where debugger should locate TypeScript files instead of source locations.": {
39393960
"category": "Message",
39403961
"code": 6004
@@ -4501,10 +4522,6 @@
45014522
"category": "Message",
45024523
"code": 6163
45034524
},
4504-
"Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": {
4505-
"category": "Message",
4506-
"code": 6164
4507-
},
45084525
"Do not truncate error messages.": {
45094526
"category": "Message",
45104527
"code": 6165
@@ -4842,6 +4859,10 @@
48424859
"category": "Message",
48434860
"code": 6257
48444861
},
4862+
"'{0}' should be set inside the 'compilerOptions' object of the config json file": {
4863+
"category": "Error",
4864+
"code": 6258
4865+
},
48454866

48464867
"Directory '{0}' has no containing package.json scope. Imports will not resolve.": {
48474868
"category": "Message",

src/compiler/factory/nodeFactory.ts

+9-7
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

+14-1
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

+7-3
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,10 @@ namespace ts {
34143414
}
34153415
}
34163416

3417+
if (options.preserveValueImports && getEmitModuleKind(options) < ModuleKind.ES2015) {
3418+
createOptionValueDiagnostic("importsNotUsedAsValues", Diagnostics.Option_preserveValueImports_can_only_be_used_when_module_is_set_to_es2015_or_later);
3419+
}
3420+
34173421
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
34183422
if (!options.noEmit && !options.suppressOutputPathCheck) {
34193423
const emitHost = getEmitHost();
@@ -3684,7 +3688,7 @@ namespace ts {
36843688
createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3);
36853689
}
36863690

3687-
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) {
3691+
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string) {
36883692
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
36893693
}
36903694

@@ -3699,7 +3703,7 @@ namespace ts {
36993703
}
37003704
}
37013705

3702-
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) {
3706+
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) {
37033707
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
37043708
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
37053709
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
@@ -3725,7 +3729,7 @@ namespace ts {
37253729
return _compilerOptionsObjectLiteralSyntax || undefined;
37263730
}
37273731

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

src/compiler/transformers/ts.ts

+17-15
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)