Skip to content

Commit d680720

Browse files
committed
Merge branch 'master' into ownJsonParsing
2 parents 8f4f6c5 + 9d16d34 commit d680720

File tree

381 files changed

+8516
-2843
lines changed

Some content is hidden

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

381 files changed

+8516
-2843
lines changed

Jakefile.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename);
268268
* @param {boolean} opts.preserveConstEnums: true if compiler should keep const enums in code
269269
* @param {boolean} opts.noResolve: true if compiler should not include non-rooted files in compilation
270270
* @param {boolean} opts.stripInternal: true if compiler should remove declarations marked as @internal
271-
* @param {boolean} opts.noMapRoot: true if compiler omit mapRoot option
272271
* @param {boolean} opts.inlineSourceMap: true if compiler should inline sourceMap
273272
* @param {Array} opts.types: array of types to include in compilation
274273
* @param callback: a function to execute after the compilation process ends
@@ -321,9 +320,6 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
321320
}
322321
else {
323322
options += " -sourcemap";
324-
if (!opts.noMapRoot) {
325-
options += " -mapRoot file:///" + path.resolve(path.dirname(outFile));
326-
}
327323
}
328324
}
329325
else {
@@ -527,7 +523,7 @@ task("importDefinitelyTypedTests", [importDefinitelyTypedTestsJs], function () {
527523

528524
// Local target to build the compiler and services
529525
var tscFile = path.join(builtLocalDirectory, compilerFilename);
530-
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false, { noMapRoot: true });
526+
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);
531527

532528
var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js");
533529
var servicesFileInBrowserTest = path.join(builtLocalDirectory, "typescriptServicesInBrowserTest.js");
@@ -582,7 +578,6 @@ compileFile(
582578
keepComments: true,
583579
noResolve: false,
584580
stripInternal: true,
585-
noMapRoot: true,
586581
inlineSourceMap: true
587582
});
588583

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: 136 additions & 37 deletions
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

Lines changed: 3 additions & 2 deletions
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",
@@ -1339,7 +1340,7 @@ namespace ts {
13391340
for (let i = 0; i < nameColumn.length; i++) {
13401341
const optionName = nameColumn[i];
13411342
const description = descriptionColumn[i];
1342-
result.push(tab + tab + optionName + makePadding(marginLength - optionName.length + 2) + description);
1343+
result.push(optionName && `${tab}${tab}${optionName}${ description && (makePadding(marginLength - optionName.length + 2) + description)}`);
13431344
}
13441345
if (configurations.files && configurations.files.length) {
13451346
result.push(`${tab}},`);

src/compiler/diagnosticMessages.json

Lines changed: 37 additions & 7 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
@@ -1887,6 +1904,10 @@
18871904
"category": "Error",
18881905
"code": 2558
18891906
},
1907+
"Type '{0}' has no properties in common with type '{1}'.": {
1908+
"category": "Error",
1909+
"code": 2559
1910+
},
18901911
"JSX element attributes type '{0}' may not be a union type.": {
18911912
"category": "Error",
18921913
"code": 2600
@@ -1931,10 +1952,6 @@
19311952
"category": "Error",
19321953
"code": 2649
19331954
},
1934-
"Cannot emit namespaced JSX elements in React.": {
1935-
"category": "Error",
1936-
"code": 2650
1937-
},
19381955
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": {
19391956
"category": "Error",
19401957
"code": 2651
@@ -2167,6 +2184,14 @@
21672184
"category": "Error",
21682185
"code": 2710
21692186
},
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+
},
21702195

21712196
"Import declaration '{0}' is using private name '{1}'.": {
21722197
"category": "Error",
@@ -2633,7 +2658,7 @@
26332658
"category": "Message",
26342659
"code": 6015
26352660
},
2636-
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.": {
2661+
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
26372662
"category": "Message",
26382663
"code": 6016
26392664
},
@@ -3369,6 +3394,11 @@
33693394
"category": "Error",
33703395
"code": 7035
33713396
},
3397+
"Dynamic import's specifier must be of type 'string', but here has type '{0}'.": {
3398+
"category": "Error",
3399+
"code": 7036
3400+
},
3401+
33723402
"You cannot rename this element.": {
33733403
"category": "Error",
33743404
"code": 8000

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/parser.ts

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@ namespace ts {
4545
}
4646
}
4747

48-
// Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
49-
// stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
50-
// embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
51-
// a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
48+
/**
49+
* Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
50+
* stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
51+
* embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
52+
* a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
53+
*
54+
* @param node a given node to visit its children
55+
* @param cbNode a callback to be invoked for all child nodes
56+
* @param cbNodeArray a callback to be invoked for embedded array
57+
*/
5258
export function forEachChild<T>(node: Node, cbNode: (node: Node) => T | undefined, cbNodeArray?: (nodes: NodeArray<Node>) => T | undefined): T | undefined {
5359
if (!node) {
5460
return;
@@ -2442,7 +2448,7 @@ namespace ts {
24422448
if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
24432449
return parseSignatureMember(SyntaxKind.CallSignature);
24442450
}
2445-
if (token() === SyntaxKind.NewKeyword && lookAhead(isStartOfConstructSignature)) {
2451+
if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) {
24462452
return parseSignatureMember(SyntaxKind.ConstructSignature);
24472453
}
24482454
const fullStart = getNodePos();
@@ -2453,7 +2459,7 @@ namespace ts {
24532459
return parsePropertyOrMethodSignature(fullStart, modifiers);
24542460
}
24552461

2456-
function isStartOfConstructSignature() {
2462+
function nextTokenIsOpenParenOrLessThan() {
24572463
nextToken();
24582464
return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken;
24592465
}
@@ -2809,6 +2815,7 @@ namespace ts {
28092815
case SyntaxKind.SlashToken:
28102816
case SyntaxKind.SlashEqualsToken:
28112817
case SyntaxKind.Identifier:
2818+
case SyntaxKind.ImportKeyword:
28122819
return true;
28132820
default:
28142821
return isIdentifier();
@@ -3542,10 +3549,10 @@ namespace ts {
35423549
* 5) --UnaryExpression[?Yield]
35433550
*/
35443551
if (isUpdateExpression()) {
3545-
const incrementExpression = parseIncrementExpression();
3552+
const updateExpression = parseUpdateExpression();
35463553
return token() === SyntaxKind.AsteriskAsteriskToken ?
3547-
<BinaryExpression>parseBinaryExpressionRest(getBinaryOperatorPrecedence(), incrementExpression) :
3548-
incrementExpression;
3554+
<BinaryExpression>parseBinaryExpressionRest(getBinaryOperatorPrecedence(), updateExpression) :
3555+
updateExpression;
35493556
}
35503557

35513558
/**
@@ -3611,7 +3618,7 @@ namespace ts {
36113618
}
36123619
// falls through
36133620
default:
3614-
return parseIncrementExpression();
3621+
return parseUpdateExpression();
36153622
}
36163623
}
36173624

@@ -3627,7 +3634,7 @@ namespace ts {
36273634
*/
36283635
function isUpdateExpression(): boolean {
36293636
// This function is called inside parseUnaryExpression to decide
3630-
// whether to call parseSimpleUnaryExpression or call parseIncrementExpression directly
3637+
// whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
36313638
switch (token()) {
36323639
case SyntaxKind.PlusToken:
36333640
case SyntaxKind.MinusToken:
@@ -3651,17 +3658,17 @@ namespace ts {
36513658
}
36523659

36533660
/**
3654-
* Parse ES7 IncrementExpression. IncrementExpression is used instead of ES6's PostFixExpression.
3661+
* Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
36553662
*
3656-
* ES7 IncrementExpression[yield]:
3663+
* ES7 UpdateExpression[yield]:
36573664
* 1) LeftHandSideExpression[?yield]
36583665
* 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
36593666
* 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
36603667
* 4) ++LeftHandSideExpression[?yield]
36613668
* 5) --LeftHandSideExpression[?yield]
36623669
* In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
36633670
*/
3664-
function parseIncrementExpression(): IncrementExpression {
3671+
function parseUpdateExpression(): UpdateExpression {
36653672
if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) {
36663673
const node = <PrefixUnaryExpression>createNode(SyntaxKind.PrefixUnaryExpression);
36673674
node.operator = <PrefixUnaryOperator>token();
@@ -3711,25 +3718,35 @@ namespace ts {
37113718
// CallExpression Arguments
37123719
// CallExpression[Expression]
37133720
// CallExpression.IdentifierName
3714-
// super ( ArgumentListopt )
3721+
// import (AssignmentExpression)
3722+
// super Arguments
37153723
// super.IdentifierName
37163724
//
3717-
// Because of the recursion in these calls, we need to bottom out first. There are two
3718-
// bottom out states we can run into. Either we see 'super' which must start either of
3719-
// the last two CallExpression productions. Or we have a MemberExpression which either
3720-
// completes the LeftHandSideExpression, or starts the beginning of the first four
3721-
// CallExpression productions.
3722-
const expression = token() === SyntaxKind.SuperKeyword
3723-
? parseSuperExpression()
3724-
: parseMemberExpressionOrHigher();
3725+
// Because of the recursion in these calls, we need to bottom out first. There are three
3726+
// bottom out states we can run into: 1) We see 'super' which must start either of
3727+
// the last two CallExpression productions. 2) We see 'import' which must start import call.
3728+
// 3)we have a MemberExpression which either completes the LeftHandSideExpression,
3729+
// or starts the beginning of the first four CallExpression productions.
3730+
let expression: MemberExpression;
3731+
if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) {
3732+
// We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
3733+
// For example:
3734+
// var foo3 = require("subfolder
3735+
// import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression
3736+
sourceFile.flags |= NodeFlags.PossiblyContainDynamicImport;
3737+
expression = parseTokenNode<PrimaryExpression>();
3738+
}
3739+
else {
3740+
expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher();
3741+
}
37253742

37263743
// Now, we *may* be complete. However, we might have consumed the start of a
37273744
// CallExpression. As such, we need to consume the rest of it here to be complete.
37283745
return parseCallExpressionRest(expression);
37293746
}
37303747

37313748
function parseMemberExpressionOrHigher(): MemberExpression {
3732-
// Note: to make our lives simpler, we decompose the the NewExpression productions and
3749+
// Note: to make our lives simpler, we decompose the NewExpression productions and
37333750
// place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
37343751
// like so:
37353752
//
@@ -4823,11 +4840,11 @@ namespace ts {
48234840
// however, we say they are here so that we may gracefully parse them and error later.
48244841
case SyntaxKind.CatchKeyword:
48254842
case SyntaxKind.FinallyKeyword:
4843+
case SyntaxKind.ImportKeyword:
48264844
return true;
48274845

48284846
case SyntaxKind.ConstKeyword:
48294847
case SyntaxKind.ExportKeyword:
4830-
case SyntaxKind.ImportKeyword:
48314848
return isStartOfDeclaration();
48324849

48334850
case SyntaxKind.AsyncKeyword:

src/compiler/program.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,10 +1070,10 @@ namespace ts {
10701070
const typeChecker = getDiagnosticsProducingTypeChecker();
10711071

10721072
Debug.assert(!!sourceFile.bindDiagnostics);
1073-
const bindDiagnostics = sourceFile.bindDiagnostics;
10741073
// For JavaScript files, we don't want to report semantic errors unless explicitly requested.
1075-
const includeCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options);
1076-
const checkDiagnostics = includeCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : [];
1074+
const includeBindAndCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options);
1075+
const bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
1076+
const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
10771077
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
10781078
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
10791079

@@ -1370,6 +1370,7 @@ namespace ts {
13701370
const isJavaScriptFile = isSourceFileJavaScript(file);
13711371
const isExternalModuleFile = isExternalModule(file);
13721372

1373+
// file.imports may not be undefined if there exists dynamic import
13731374
let imports: LiteralExpression[];
13741375
let moduleAugmentations: LiteralExpression[];
13751376
let ambientModules: string[];
@@ -1389,8 +1390,8 @@ namespace ts {
13891390

13901391
for (const node of file.statements) {
13911392
collectModuleReferences(node, /*inAmbientModule*/ false);
1392-
if (isJavaScriptFile) {
1393-
collectRequireCalls(node);
1393+
if ((file.flags & NodeFlags.PossiblyContainDynamicImport) || isJavaScriptFile) {
1394+
collectDynamicImportOrRequireCalls(node);
13941395
}
13951396
}
13961397

@@ -1453,12 +1454,16 @@ namespace ts {
14531454
}
14541455
}
14551456

1456-
function collectRequireCalls(node: Node): void {
1457+
function collectDynamicImportOrRequireCalls(node: Node): void {
14571458
if (isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) {
14581459
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
14591460
}
1461+
// we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
1462+
else if (isImportCall(node) && node.arguments.length === 1 && node.arguments[0].kind === SyntaxKind.StringLiteral) {
1463+
(imports || (imports = [])).push(<StringLiteral>(<CallExpression>node).arguments[0]);
1464+
}
14601465
else {
1461-
forEachChild(node, collectRequireCalls);
1466+
forEachChild(node, collectDynamicImportOrRequireCalls);
14621467
}
14631468
}
14641469
}

0 commit comments

Comments
 (0)