Skip to content

Commit 2f6c6e6

Browse files
committed
Merge branch 'master' into fix16086
2 parents b5f81f9 + 70c1c57 commit 2f6c6e6

File tree

195 files changed

+6031
-194
lines changed

Some content is hidden

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

195 files changed

+6031
-194
lines changed

Jakefile.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,8 @@ function runConsoleTests(defaultReporter, runInParallel) {
802802

803803
var debug = process.env.debug || process.env.d;
804804
var inspect = process.env.inspect;
805-
tests = process.env.test || process.env.tests || process.env.t;
805+
var testTimeout = process.env.timeout || defaultTestTimeout;
806+
var tests = process.env.test || process.env.tests || process.env.t;
806807
var light = process.env.light || false;
807808
var stackTraceLimit = process.env.stackTraceLimit;
808809
var testConfigFile = 'test.config';
@@ -820,7 +821,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
820821
} while (fs.existsSync(taskConfigsFolder));
821822
fs.mkdirSync(taskConfigsFolder);
822823

823-
workerCount = process.env.workerCount || os.cpus().length;
824+
workerCount = process.env.workerCount || process.env.p || os.cpus().length;
824825
}
825826

826827
if (tests || light || taskConfigsFolder) {
@@ -925,7 +926,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
925926
}
926927
}
927928

928-
var testTimeout = 22000;
929+
var defaultTestTimeout = 22000;
929930
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
930931
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () {
931932
runConsoleTests('min', /*runInParallel*/ true);

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: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7649,11 +7649,9 @@ namespace ts {
76497649
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
76507650
return anyType;
76517651
}
7652-
left = filterType(left, t => !(t.flags & TypeFlags.Nullable));
76537652
if (left.flags & TypeFlags.Never) {
76547653
return right;
76557654
}
7656-
right = filterType(right, t => !(t.flags & TypeFlags.Nullable));
76577655
if (right.flags & TypeFlags.Never) {
76587656
return left;
76597657
}
@@ -8373,6 +8371,12 @@ namespace ts {
83738371
/**
83748372
* This is *not* a bi-directional relationship.
83758373
* If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
8374+
*
8375+
* 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.
8376+
* It is used to check following cases:
8377+
* - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
8378+
* - the types of `case` clause expressions and their respective `switch` expressions.
8379+
* - the type of an expression in a type assertion with the type being asserted.
83768380
*/
83778381
function isTypeComparableTo(source: Type, target: Type): boolean {
83788382
return isTypeRelatedTo(source, target, comparableRelation);
@@ -8600,6 +8604,7 @@ namespace ts {
86008604

86018605
function isEmptyObjectType(type: Type): boolean {
86028606
return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(<ObjectType>type)) :
8607+
type.flags & TypeFlags.NonPrimitive ? true :
86038608
type.flags & TypeFlags.Union ? forEach((<UnionType>type).types, isEmptyObjectType) :
86048609
type.flags & TypeFlags.Intersection ? !forEach((<UnionType>type).types, t => !isEmptyObjectType(t)) :
86058610
false;
@@ -15894,7 +15899,7 @@ namespace ts {
1589415899
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
1589515900
if (callSignatures.length) {
1589615901
const signature = resolveCall(node, callSignatures, candidatesOutArray);
15897-
if (getReturnTypeOfSignature(signature) !== voidType) {
15902+
if (!isJavaScriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
1589815903
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
1589915904
}
1590015905
if (getThisTypeOfSignature(signature) === voidType) {
@@ -16121,10 +16126,30 @@ namespace ts {
1612116126
return getNodeLinks(node).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(node);
1612216127
}
1612316128

16129+
/**
16130+
* Indicates whether a declaration can be treated as a constructor in a JavaScript
16131+
* file.
16132+
*/
16133+
function isJavaScriptConstructor(node: Declaration): boolean {
16134+
if (isInJavaScriptFile(node)) {
16135+
// If the node has a @class tag, treat it like a constructor.
16136+
if (getJSDocClassTag(node)) return true;
16137+
16138+
// If the symbol of the node has members, treat it like a constructor.
16139+
const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) :
16140+
isVariableDeclaration(node) && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
16141+
undefined;
16142+
16143+
return symbol && symbol.members !== undefined;
16144+
}
16145+
16146+
return false;
16147+
}
16148+
1612416149
function getInferredClassType(symbol: Symbol) {
1612516150
const links = getSymbolLinks(symbol);
1612616151
if (!links.inferredClassType) {
16127-
links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
16152+
links.inferredClassType = createAnonymousType(symbol, symbol.members || emptySymbols, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined);
1612816153
}
1612916154
return links.inferredClassType;
1613016155
}
@@ -16164,7 +16189,7 @@ namespace ts {
1616416189
if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
1616516190
funcSymbol = getSymbolOfNode((<VariableDeclaration>funcSymbol.valueDeclaration).initializer);
1616616191
}
16167-
if (funcSymbol && funcSymbol.members && funcSymbol.flags & SymbolFlags.Function) {
16192+
if (funcSymbol && funcSymbol.flags & SymbolFlags.Function && (funcSymbol.members || getJSDocClassTag(funcSymbol.valueDeclaration))) {
1616816193
return getInferredClassType(funcSymbol);
1616916194
}
1617016195
else if (noImplicitAny) {
@@ -16182,6 +16207,35 @@ namespace ts {
1618216207
return getReturnTypeOfSignature(signature);
1618316208
}
1618416209

16210+
function checkImportCallExpression(node: ImportCall): Type {
16211+
// Check grammar of dynamic import
16212+
checkGrammarArguments(node, node.arguments) || checkGrammarImportCallExpression(node);
16213+
16214+
if (node.arguments.length === 0) {
16215+
return createPromiseReturnType(node, anyType);
16216+
}
16217+
const specifier = node.arguments[0];
16218+
const specifierType = checkExpressionCached(specifier);
16219+
// Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion
16220+
for (let i = 1; i < node.arguments.length; ++i) {
16221+
checkExpressionCached(node.arguments[i]);
16222+
}
16223+
16224+
if (specifierType.flags & TypeFlags.Undefined || specifierType.flags & TypeFlags.Null || !isTypeAssignableTo(specifierType, stringType)) {
16225+
error(specifier, Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
16226+
}
16227+
16228+
// resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
16229+
const moduleSymbol = resolveExternalModuleName(node, specifier);
16230+
if (moduleSymbol) {
16231+
const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true);
16232+
if (esModuleSymbol) {
16233+
return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol));
16234+
}
16235+
}
16236+
return createPromiseReturnType(node, anyType);
16237+
}
16238+
1618516239
function isCommonJsRequire(node: Node) {
1618616240
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
1618716241
return false;
@@ -16388,14 +16442,18 @@ namespace ts {
1638816442
return emptyObjectType;
1638916443
}
1639016444

16391-
function createPromiseReturnType(func: FunctionLikeDeclaration, promisedType: Type) {
16445+
function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) {
1639216446
const promiseType = createPromiseType(promisedType);
1639316447
if (promiseType === emptyObjectType) {
16394-
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);
16448+
error(func, isImportCall(func) ?
16449+
Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
16450+
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);
1639516451
return unknownType;
1639616452
}
1639716453
else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
16398-
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);
16454+
error(func, isImportCall(func) ?
16455+
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 :
16456+
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);
1639916457
}
1640016458

1640116459
return promiseType;
@@ -17754,6 +17812,10 @@ namespace ts {
1775417812
case SyntaxKind.ElementAccessExpression:
1775517813
return checkIndexedAccess(<ElementAccessExpression>node);
1775617814
case SyntaxKind.CallExpression:
17815+
if ((<CallExpression>node).expression.kind === SyntaxKind.ImportKeyword) {
17816+
return checkImportCallExpression(<ImportCall>node);
17817+
}
17818+
/* falls through */
1775717819
case SyntaxKind.NewExpression:
1775817820
return checkCallExpression(<CallExpression>node);
1775917821
case SyntaxKind.TaggedTemplateExpression:
@@ -24681,6 +24743,27 @@ namespace ts {
2468124743
});
2468224744
return result;
2468324745
}
24746+
24747+
function checkGrammarImportCallExpression(node: ImportCall): boolean {
24748+
if (modulekind === ModuleKind.ES2015) {
24749+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
24750+
}
24751+
24752+
if (node.typeArguments) {
24753+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_have_type_arguments);
24754+
}
24755+
24756+
const arguments = node.arguments;
24757+
if (arguments.length !== 1) {
24758+
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
24759+
}
24760+
24761+
// see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
24762+
// parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
24763+
if (isSpreadElement(arguments[0])) {
24764+
return grammarErrorOnNode(arguments[0], Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
24765+
}
24766+
}
2468424767
}
2468524768

2468624769
/** 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: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,23 @@
883883
"category": "Error",
884884
"code": 1322
885885
},
886+
"Dynamic import cannot be used when targeting ECMAScript 2015 modules.": {
887+
"category": "Error",
888+
"code": 1323
889+
},
890+
"Dynamic import must have one specifier as an argument.": {
891+
"category": "Error",
892+
"code": 1324
893+
},
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+
886903
"Duplicate identifier '{0}'.": {
887904
"category": "Error",
888905
"code": 2300
@@ -1927,10 +1944,6 @@
19271944
"category": "Error",
19281945
"code": 2649
19291946
},
1930-
"Cannot emit namespaced JSX elements in React.": {
1931-
"category": "Error",
1932-
"code": 2650
1933-
},
19341947
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": {
19351948
"category": "Error",
19361949
"code": 2651
@@ -2163,6 +2176,14 @@
21632176
"category": "Error",
21642177
"code": 2710
21652178
},
2179+
"A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.": {
2180+
"category": "Error",
2181+
"code": 2711
2182+
},
2183+
"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.": {
2184+
"category": "Error",
2185+
"code": 2712
2186+
},
21662187

21672188
"Import declaration '{0}' is using private name '{1}'.": {
21682189
"category": "Error",
@@ -2629,7 +2650,7 @@
26292650
"category": "Message",
26302651
"code": 6015
26312652
},
2632-
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.": {
2653+
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
26332654
"category": "Message",
26342655
"code": 6016
26352656
},
@@ -3365,6 +3386,11 @@
33653386
"category": "Error",
33663387
"code": 7035
33673388
},
3389+
"Dynamic import's specifier must be of type 'string', but here has type '{0}'.": {
3390+
"category": "Error",
3391+
"code": 7036
3392+
},
3393+
33683394
"You cannot rename this element.": {
33693395
"category": "Error",
33703396
"code": 8000

src/compiler/emitter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ namespace ts {
676676
case SyntaxKind.SuperKeyword:
677677
case SyntaxKind.TrueKeyword:
678678
case SyntaxKind.ThisKeyword:
679+
case SyntaxKind.ImportKeyword:
679680
writeTokenNode(node);
680681
return;
681682

src/compiler/factory.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,8 +2503,9 @@ namespace ts {
25032503
helpers
25042504
} = sourceEmitNode;
25052505
if (!destEmitNode) destEmitNode = {};
2506-
if (leadingComments) destEmitNode.leadingComments = concatenate(leadingComments, destEmitNode.leadingComments);
2507-
if (trailingComments) destEmitNode.trailingComments = concatenate(trailingComments, destEmitNode.trailingComments);
2506+
// We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
2507+
if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments);
2508+
if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments);
25082509
if (flags) destEmitNode.flags = flags;
25092510
if (commentRange) destEmitNode.commentRange = commentRange;
25102511
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;

0 commit comments

Comments
 (0)