Skip to content

Commit 48189c8

Browse files
committed
Merge branch 'master' into ownJsonParsing
2 parents c4ad151 + 52e867c commit 48189c8

File tree

181 files changed

+5617
-122
lines changed

Some content is hidden

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

181 files changed

+5617
-122
lines changed

src/compiler/binder.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ namespace ts {
23332333
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
23342334
// is still pointing to 'module.exports'.
23352335
// We do not want to consider this as 'export=' since a module can have only one of these.
2336-
// Similarlly we do not want to treat 'module.exports = exports' as an 'export='.
2336+
// Similarly we do not want to treat 'module.exports = exports' as an 'export='.
23372337
const assignedExpression = getRightMostAssignedExpression(node.right);
23382338
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
23392339
// Mark it as a module in case there are no other exports in the file
@@ -2741,6 +2741,10 @@ namespace ts {
27412741
transformFlags |= TransformFlags.AssertES2015;
27422742
}
27432743

2744+
if (expression.kind === SyntaxKind.ImportKeyword) {
2745+
transformFlags |= TransformFlags.ContainsDynamicImport;
2746+
}
2747+
27442748
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
27452749
return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes;
27462750
}

src/compiler/checker.ts

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8372,6 +8372,12 @@ namespace ts {
83728372
/**
83738373
* This is *not* a bi-directional relationship.
83748374
* If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
8375+
*
8376+
* A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
8377+
* It is used to check following cases:
8378+
* - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
8379+
* - the types of `case` clause expressions and their respective `switch` expressions.
8380+
* - the type of an expression in a type assertion with the type being asserted.
83758381
*/
83768382
function isTypeComparableTo(source: Type, target: Type): boolean {
83778383
return isTypeRelatedTo(source, target, comparableRelation);
@@ -8599,6 +8605,7 @@ namespace ts {
85998605

86008606
function isEmptyObjectType(type: Type): boolean {
86018607
return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type)) :
8608+
type.flags & TypeFlags.NonPrimitive ? true :
86028609
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isEmptyObjectType) :
86038610
type.flags & TypeFlags.Intersection ? !forEach((<UnionType>type).types, t => !isEmptyObjectType(t)) :
86048611
false;
@@ -16179,6 +16186,35 @@ namespace ts {
1617916186
return getReturnTypeOfSignature(signature);
1618016187
}
1618116188

16189+
function checkImportCallExpression(node: ImportCall): Type {
16190+
// Check grammar of dynamic import
16191+
checkGrammarArguments(node, node.arguments) || checkGrammarImportCallExpression(node);
16192+
16193+
if (node.arguments.length === 0) {
16194+
return createPromiseReturnType(node, anyType);
16195+
}
16196+
const specifier = node.arguments[0];
16197+
const specifierType = checkExpressionCached(specifier);
16198+
// Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion
16199+
for (let i = 1; i < node.arguments.length; ++i) {
16200+
checkExpressionCached(node.arguments[i]);
16201+
}
16202+
16203+
if (specifierType.flags & TypeFlags.Undefined || specifierType.flags & TypeFlags.Null || !isTypeAssignableTo(specifierType, stringType)) {
16204+
error(specifier, Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
16205+
}
16206+
16207+
// resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
16208+
const moduleSymbol = resolveExternalModuleName(node, specifier);
16209+
if (moduleSymbol) {
16210+
const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
16211+
if (esModuleSymbol) {
16212+
return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol));
16213+
}
16214+
}
16215+
return createPromiseReturnType(node, anyType);
16216+
}
16217+
1618216218
function isCommonJsRequire(node: Node) {
1618316219
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
1618416220
return false;
@@ -16385,14 +16421,18 @@ namespace ts {
1638516421
return emptyObjectType;
1638616422
}
1638716423

16388-
function createPromiseReturnType(func: FunctionLikeDeclaration, promisedType: Type) {
16424+
function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) {
1638916425
const promiseType = createPromiseType(promisedType);
1639016426
if (promiseType === emptyObjectType) {
16391-
error(func, Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
16427+
error(func, isImportCall(func) ?
16428+
Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
16429+
Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
1639216430
return unknownType;
1639316431
}
1639416432
else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
16395-
error(func, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
16433+
error(func, isImportCall(func) ?
16434+
Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
16435+
Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
1639616436
}
1639716437

1639816438
return promiseType;
@@ -17751,6 +17791,10 @@ namespace ts {
1775117791
case SyntaxKind.ElementAccessExpression:
1775217792
return checkIndexedAccess(<ElementAccessExpression>node);
1775317793
case SyntaxKind.CallExpression:
17794+
if ((<CallExpression>node).expression.kind === SyntaxKind.ImportKeyword) {
17795+
return checkImportCallExpression(<ImportCall>node);
17796+
}
17797+
/* falls through */
1775417798
case SyntaxKind.NewExpression:
1775517799
return checkCallExpression(<CallExpression>node);
1775617800
case SyntaxKind.TaggedTemplateExpression:
@@ -24676,6 +24720,27 @@ namespace ts {
2467624720
});
2467724721
return result;
2467824722
}
24723+
24724+
function checkGrammarImportCallExpression(node: ImportCall): boolean {
24725+
if (modulekind === ModuleKind.ES2015) {
24726+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
24727+
}
24728+
24729+
if (node.typeArguments) {
24730+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_have_type_arguments);
24731+
}
24732+
24733+
const arguments = node.arguments;
24734+
if (arguments.length !== 1) {
24735+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
24736+
}
24737+
24738+
// see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
24739+
// parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
24740+
if (isSpreadElement(arguments[0])) {
24741+
return grammarErrorOnNode(arguments[0], Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
24742+
}
24743+
}
2467924744
}
2468024745

2468124746
/** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */

src/compiler/commandLineParser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,12 @@ namespace ts {
100100
"umd": ModuleKind.UMD,
101101
"es6": ModuleKind.ES2015,
102102
"es2015": ModuleKind.ES2015,
103+
"esnext": ModuleKind.ESNext
103104
}),
104105
paramType: Diagnostics.KIND,
105106
showInSimplifiedHelpView: true,
106107
category: Diagnostics.Basic_Options,
107-
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
108+
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_es2015_or_ESNext,
108109
},
109110
{
110111
name: "lib",

src/compiler/diagnosticMessages.json

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -883,14 +883,31 @@
883883
"category": "Error",
884884
"code": 1322
885885
},
886-
"String literal with double quotes expected.": {
886+
"Dynamic import cannot be used when targeting ECMAScript 2015 modules.": {
887887
"category": "Error",
888888
"code": 1323
889889
},
890-
"Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": {
890+
"Dynamic import must have one specifier as an argument.": {
891891
"category": "Error",
892892
"code": 1324
893893
},
894+
"Specifier of dynamic import cannot be spread element.": {
895+
"category": "Error",
896+
"code": 1325
897+
},
898+
"Dynamic import cannot have type arguments": {
899+
"category": "Error",
900+
"code": 1326
901+
},
902+
"String literal with double quotes expected.": {
903+
"category": "Error",
904+
"code": 1327
905+
},
906+
"Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": {
907+
"category": "Error",
908+
"code": 1328
909+
},
910+
894911
"Duplicate identifier '{0}'.": {
895912
"category": "Error",
896913
"code": 2300
@@ -1935,10 +1952,6 @@
19351952
"category": "Error",
19361953
"code": 2649
19371954
},
1938-
"Cannot emit namespaced JSX elements in React.": {
1939-
"category": "Error",
1940-
"code": 2650
1941-
},
19421955
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": {
19431956
"category": "Error",
19441957
"code": 2651
@@ -2171,6 +2184,14 @@
21712184
"category": "Error",
21722185
"code": 2710
21732186
},
2187+
"A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.": {
2188+
"category": "Error",
2189+
"code": 2711
2190+
},
2191+
"A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.": {
2192+
"category": "Error",
2193+
"code": 2712
2194+
},
21742195

21752196
"Import declaration '{0}' is using private name '{1}'.": {
21762197
"category": "Error",
@@ -2637,7 +2658,7 @@
26372658
"category": "Message",
26382659
"code": 6015
26392660
},
2640-
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.": {
2661+
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
26412662
"category": "Message",
26422663
"code": 6016
26432664
},
@@ -3373,6 +3394,11 @@
33733394
"category": "Error",
33743395
"code": 7035
33753396
},
3397+
"Dynamic import's specifier must be of type 'string', but here has type '{0}'.": {
3398+
"category": "Error",
3399+
"code": 7036
3400+
},
3401+
33763402
"You cannot rename this element.": {
33773403
"category": "Error",
33783404
"code": 8000
@@ -3603,7 +3629,7 @@
36033629
"category": "Message",
36043630
"code": 90024
36053631
},
3606-
3632+
36073633
"Convert function to an ES2015 class": {
36083634
"category": "Message",
36093635
"code": 95001

src/compiler/emitter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ namespace ts {
740740
case SyntaxKind.SuperKeyword:
741741
case SyntaxKind.TrueKeyword:
742742
case SyntaxKind.ThisKeyword:
743+
case SyntaxKind.ImportKeyword:
743744
writeTokenNode(node);
744745
return;
745746

src/compiler/factory.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,8 +2495,9 @@ namespace ts {
24952495
helpers
24962496
} = sourceEmitNode;
24972497
if (!destEmitNode) destEmitNode = {};
2498-
if (leadingComments) destEmitNode.leadingComments = concatenate(leadingComments, destEmitNode.leadingComments);
2499-
if (trailingComments) destEmitNode.trailingComments = concatenate(trailingComments, destEmitNode.trailingComments);
2498+
// We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
2499+
if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments);
2500+
if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments);
25002501
if (flags) destEmitNode.flags = flags;
25012502
if (commentRange) destEmitNode.commentRange = commentRange;
25022503
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;

0 commit comments

Comments
 (0)