Wip-type check dynamic import

This commit is contained in:
Yui T
2017-03-10 22:07:08 -08:00
parent 827abb3576
commit 126fb640db
6 changed files with 39 additions and 13 deletions

View File

@@ -2317,7 +2317,7 @@ namespace ts {
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
// is still pointing to 'module.exports'.
// We do not want to consider this as 'export=' since a module can have only one of these.
// Similarlly we do not want to treat 'module.exports = exports' as an 'export='.
// Similarly we do not want to treat 'module.exports = exports' as an 'export='.
const assignedExpression = getRightMostAssignedExpression(node.right);
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
// Mark it as a module in case there are no other exports in the file

View File

@@ -14862,6 +14862,18 @@ namespace ts {
return getReturnTypeOfSignature(signature);
}
function checkImportCallExpression(node: ImportCallExpression): Type {
// resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
const moduleSymbol = resolveExternalModuleName(node, node.specifier);
if (moduleSymbol) {
const esModuleSymbol = resolveESModuleSymbol(moduleSymbol, node.specifier);
if (esModuleSymbol) {
return createPromiseReturnType(node, getTypeOfSymbol(esModuleSymbol));
}
}
return createPromiseReturnType(node, anyType);
}
function isCommonJsRequire(node: Node) {
if (!isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) {
return false;
@@ -15068,14 +15080,18 @@ namespace ts {
return emptyObjectType;
}
function createPromiseReturnType(func: FunctionLikeDeclaration, promisedType: Type) {
function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCallExpression, promisedType: Type) {
const promiseType = createPromiseType(promisedType);
if (promiseType === emptyObjectType) {
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);
error(func, isImportCallExpression(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 :
Diagnostics.A_dynamic_import_call_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
return unknownType;
}
else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
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);
error(func, isImportCallExpression(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 :
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);
}
return promiseType;
@@ -16398,6 +16414,8 @@ namespace ts {
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
return checkCallExpression(<CallExpression>node);
case SyntaxKind.ImportCallExpression:
return checkImportCallExpression(<ImportCallExpression>node);
case SyntaxKind.TaggedTemplateExpression:
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.ParenthesizedExpression:

View File

@@ -2091,6 +2091,14 @@
"category": "Error",
"code": 2707
},
"A dynamic import call must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.": {
"category": "Error",
"code": 2708
},
"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.": {
"category": "Error",
"code": 2709
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@@ -168,7 +168,7 @@ namespace ts {
visitNodes(cbNodes, (<CallExpression>node).typeArguments) ||
visitNodes(cbNodes, (<CallExpression>node).arguments);
case SyntaxKind.ImportCallExpression:
return visitNode(cbNode, (<ImportCall>node).expression);
return visitNode(cbNode, (<ImportCallExpression>node).specifier);
case SyntaxKind.TaggedTemplateExpression:
return visitNode(cbNode, (<TaggedTemplateExpression>node).tag) ||
visitNode(cbNode, (<TaggedTemplateExpression>node).template);
@@ -3695,8 +3695,8 @@ namespace ts {
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression
const importCall = parseImportCall();
if (importCall.expression.kind === SyntaxKind.StringLiteral) {
(sourceFile.imports || (sourceFile.imports = [])).push(importCall.expression as StringLiteral);
if (importCall.specifier.kind === SyntaxKind.StringLiteral) {
(sourceFile.imports || (sourceFile.imports = [])).push(importCall.specifier as StringLiteral);
}
return importCall;
}
@@ -3774,11 +3774,11 @@ namespace ts {
return finishNode(node);
}
function parseImportCall(): ImportCall {
const importCallExpr = <ImportCall>createNode(SyntaxKind.ImportCallExpression);
function parseImportCall(): ImportCallExpression {
const importCallExpr = <ImportCallExpression>createNode(SyntaxKind.ImportCallExpression);
parseExpected(SyntaxKind.ImportKeyword);
parseExpected(SyntaxKind.OpenParenToken);
importCallExpr.expression = parseAssignmentExpressionOrHigher();
importCallExpr.specifier = parseAssignmentExpressionOrHigher();
parseExpected(SyntaxKind.CloseParenToken);
return finishNode(importCallExpr);
}

View File

@@ -1447,9 +1447,9 @@ namespace ts {
expression: SuperExpression;
}
export interface ImportCall extends LeftHandSideExpression, Declaration {
export interface ImportCallExpression extends LeftHandSideExpression, Declaration {
kind: SyntaxKind.ImportCallExpression;
expression: Expression;
specifier: Expression;
}
export interface ExpressionWithTypeArguments extends TypeNode {

View File

@@ -662,7 +662,7 @@ namespace ts {
return n.kind === SyntaxKind.CallExpression && (<CallExpression>n).expression.kind === SyntaxKind.SuperKeyword;
}
export function isImportCall(n: Node): n is ImportCall {
export function isImportCallExpression(n: Node): n is ImportCallExpression {
return n.kind === SyntaxKind.ImportCallExpression;
}