Checking of ES6 import declarations
This commit is contained in:
parent
69d47ef854
commit
e47f64c510
|
@ -9336,18 +9336,78 @@ module ts {
|
||||||
return <Identifier>node;
|
return <Identifier>node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
function checkExternalImportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration): boolean {
|
||||||
// Grammar checking
|
var moduleName = getImportedModuleName(node);
|
||||||
checkGrammarModifiers(node);
|
if (getFullWidth(moduleName) !== 0 && moduleName.kind !== SyntaxKind.StringLiteral) {
|
||||||
|
error(moduleName, Diagnostics.String_literal_expected);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral;
|
||||||
|
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) {
|
||||||
|
error(moduleName, Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (inAmbientExternalModule && isExternalModuleNameRelative((<LiteralExpression>moduleName).text)) {
|
||||||
|
// TypeScript 1.0 spec (April 2013): 12.1.6
|
||||||
|
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
|
||||||
|
// other external modules only through top - level external module names.
|
||||||
|
// Relative external module names are not permitted.
|
||||||
|
error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkImportSymbol(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) {
|
||||||
|
var symbol = getSymbolOfNode(node);
|
||||||
|
var target = resolveImport(symbol);
|
||||||
|
if (target !== unknownSymbol) {
|
||||||
|
var excludedMeanings =
|
||||||
|
(symbol.flags & SymbolFlags.Value ? SymbolFlags.Value : 0) |
|
||||||
|
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
|
||||||
|
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
|
||||||
|
if (target.flags & excludedMeanings) {
|
||||||
|
error(node, Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0, symbolToString(symbol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkImportBinding(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) {
|
||||||
checkCollisionWithCapturedThisVariable(node, node.name);
|
checkCollisionWithCapturedThisVariable(node, node.name);
|
||||||
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
|
||||||
var symbol = getSymbolOfNode(node);
|
checkImportSymbol(node);
|
||||||
var target: Symbol;
|
}
|
||||||
|
|
||||||
|
function checkImportDeclaration(node: ImportDeclaration) {
|
||||||
|
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
|
||||||
|
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
|
||||||
|
}
|
||||||
|
if (checkExternalImportDeclaration(node)) {
|
||||||
|
var importClause = node.importClause;
|
||||||
|
if (importClause) {
|
||||||
|
if (importClause.name) {
|
||||||
|
// TODO: Check that import references an export default instance
|
||||||
|
checkImportBinding(importClause);
|
||||||
|
}
|
||||||
|
if (importClause.namedBindings) {
|
||||||
|
// TODO: Check that import references an export namespace
|
||||||
|
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
|
||||||
|
checkImportBinding(<NamespaceImport>importClause.namedBindings);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
forEach((<NamedImports>importClause.namedBindings).elements, checkImportBinding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||||
|
checkGrammarModifiers(node);
|
||||||
if (isInternalModuleImportEqualsDeclaration(node)) {
|
if (isInternalModuleImportEqualsDeclaration(node)) {
|
||||||
target = resolveImport(symbol);
|
checkImportBinding(node);
|
||||||
// Import declaration for an internal module
|
var symbol = getSymbolOfNode(node);
|
||||||
|
var target = resolveImport(symbol);
|
||||||
if (target !== unknownSymbol) {
|
if (target !== unknownSymbol) {
|
||||||
if (target.flags & SymbolFlags.Value) {
|
if (target.flags & SymbolFlags.Value) {
|
||||||
// Target is a value symbol, check that it is not hidden by a local declaration with the same name and
|
// Target is a value symbol, check that it is not hidden by a local declaration with the same name and
|
||||||
|
@ -9366,44 +9426,8 @@ module ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var moduleNameExpr = getExternalModuleImportEqualsDeclarationExpression(node);
|
if (checkExternalImportDeclaration(node)) {
|
||||||
if (moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
|
checkImportBinding(node);
|
||||||
grammarErrorOnNode(moduleNameExpr, Diagnostics.String_literal_expected);
|
|
||||||
}
|
|
||||||
// Import declaration for an external module
|
|
||||||
if (node.parent.kind === SyntaxKind.SourceFile) {
|
|
||||||
target = resolveImport(symbol);
|
|
||||||
}
|
|
||||||
else if (node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral) {
|
|
||||||
// TypeScript 1.0 spec (April 2013): 12.1.6
|
|
||||||
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
|
|
||||||
// other external modules only through top - level external module names.
|
|
||||||
// Relative external module names are not permitted.
|
|
||||||
if (moduleNameExpr.kind === SyntaxKind.StringLiteral) {
|
|
||||||
if (isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
|
|
||||||
error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
|
|
||||||
target = unknownSymbol;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
target = resolveImport(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
target = unknownSymbol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Parent is an internal module (syntax error is already reported)
|
|
||||||
target = unknownSymbol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target !== unknownSymbol) {
|
|
||||||
var excludedMeanings =
|
|
||||||
(symbol.flags & SymbolFlags.Value ? SymbolFlags.Value : 0) |
|
|
||||||
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
|
|
||||||
(symbol.flags & SymbolFlags.Namespace ? SymbolFlags.Namespace : 0);
|
|
||||||
if (target.flags & excludedMeanings) {
|
|
||||||
error(node, Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0, symbolToString(symbol));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9509,6 +9533,8 @@ module ts {
|
||||||
return checkEnumDeclaration(<EnumDeclaration>node);
|
return checkEnumDeclaration(<EnumDeclaration>node);
|
||||||
case SyntaxKind.ModuleDeclaration:
|
case SyntaxKind.ModuleDeclaration:
|
||||||
return checkModuleDeclaration(<ModuleDeclaration>node);
|
return checkModuleDeclaration(<ModuleDeclaration>node);
|
||||||
|
case SyntaxKind.ImportDeclaration:
|
||||||
|
return checkImportDeclaration(<ImportDeclaration>node);
|
||||||
case SyntaxKind.ImportEqualsDeclaration:
|
case SyntaxKind.ImportEqualsDeclaration:
|
||||||
return checkImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
return checkImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||||
case SyntaxKind.ExportAssignment:
|
case SyntaxKind.ExportAssignment:
|
||||||
|
@ -10347,6 +10373,7 @@ module ts {
|
||||||
case SyntaxKind.VariableStatement:
|
case SyntaxKind.VariableStatement:
|
||||||
case SyntaxKind.FunctionDeclaration:
|
case SyntaxKind.FunctionDeclaration:
|
||||||
case SyntaxKind.TypeAliasDeclaration:
|
case SyntaxKind.TypeAliasDeclaration:
|
||||||
|
case SyntaxKind.ImportDeclaration:
|
||||||
case SyntaxKind.ImportEqualsDeclaration:
|
case SyntaxKind.ImportEqualsDeclaration:
|
||||||
case SyntaxKind.Parameter:
|
case SyntaxKind.Parameter:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -147,6 +147,7 @@ module ts {
|
||||||
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
|
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
|
||||||
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
|
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
|
||||||
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
|
A_parameter_property_may_not_be_a_binding_pattern: { code: 1187, category: DiagnosticCategory.Error, key: "A parameter property may not be a binding pattern." },
|
||||||
|
An_import_declaration_cannot_have_modifiers: { code: 1188, category: DiagnosticCategory.Error, key: "An import declaration cannot have modifiers." },
|
||||||
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||||
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
||||||
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
||||||
|
|
|
@ -579,6 +579,10 @@
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 1187
|
"code": 1187
|
||||||
},
|
},
|
||||||
|
"An import declaration cannot have modifiers.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1188
|
||||||
|
},
|
||||||
|
|
||||||
"Duplicate identifier '{0}'.": {
|
"Duplicate identifier '{0}'.": {
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
|
|
|
@ -3898,7 +3898,7 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitRequire(moduleName: Expression) {
|
function emitRequire(moduleName: Expression) {
|
||||||
if (moduleName) {
|
if (moduleName.kind === SyntaxKind.StringLiteral) {
|
||||||
write("require(");
|
write("require(");
|
||||||
emitStart(moduleName);
|
emitStart(moduleName);
|
||||||
emitLiteral(<LiteralExpression>moduleName);
|
emitLiteral(<LiteralExpression>moduleName);
|
||||||
|
@ -4080,8 +4080,8 @@ module ts {
|
||||||
forEach(externalImports, info => {
|
forEach(externalImports, info => {
|
||||||
write(", ");
|
write(", ");
|
||||||
var moduleName = getImportedModuleName(info.importNode);
|
var moduleName = getImportedModuleName(info.importNode);
|
||||||
if (moduleName) {
|
if (moduleName.kind === SyntaxKind.StringLiteral) {
|
||||||
emitLiteral(moduleName);
|
emitLiteral(<LiteralExpression>moduleName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
write("\"\"");
|
write("\"\"");
|
||||||
|
|
|
@ -352,21 +352,22 @@ module ts {
|
||||||
function processImportedModules(file: SourceFile, basePath: string) {
|
function processImportedModules(file: SourceFile, basePath: string) {
|
||||||
forEach(file.statements, node => {
|
forEach(file.statements, node => {
|
||||||
if (node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
if (node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||||
var nameLiteral = getImportedModuleName(node);
|
var moduleNameExpr = getImportedModuleName(node);
|
||||||
var moduleName = nameLiteral && nameLiteral.text;
|
if (moduleNameExpr && moduleNameExpr.kind === SyntaxKind.StringLiteral) {
|
||||||
if (moduleName) {
|
var moduleNameText = (<LiteralExpression>moduleNameExpr).text;
|
||||||
var searchPath = basePath;
|
if (moduleNameText) {
|
||||||
while (true) {
|
var searchPath = basePath;
|
||||||
var searchName = normalizePath(combinePaths(searchPath, moduleName));
|
while (true) {
|
||||||
if (findModuleSourceFile(searchName + ".ts", nameLiteral) || findModuleSourceFile(searchName + ".d.ts", nameLiteral)) {
|
var searchName = normalizePath(combinePaths(searchPath, moduleNameText));
|
||||||
break;
|
if (findModuleSourceFile(searchName + ".ts", moduleNameExpr) || findModuleSourceFile(searchName + ".d.ts", moduleNameExpr)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var parentPath = getDirectoryPath(searchPath);
|
||||||
|
if (parentPath === searchPath) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
searchPath = parentPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentPath = getDirectoryPath(searchPath);
|
|
||||||
if (parentPath === searchPath) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
searchPath = parentPath;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,7 +398,7 @@ module ts {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function findModuleSourceFile(fileName: string, nameLiteral: LiteralExpression) {
|
function findModuleSourceFile(fileName: string, nameLiteral: Expression) {
|
||||||
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
|
return findSourceFile(fileName, /* isDefaultLib */ false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,18 +597,14 @@ module ts {
|
||||||
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
|
return node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind !== SyntaxKind.ExternalModuleReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractStringLiteral(node: Expression): StringLiteralExpression {
|
export function getImportedModuleName(node: Node): Expression {
|
||||||
return node && node.kind === SyntaxKind.StringLiteral ? <StringLiteralExpression>node : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getImportedModuleName(node: Node): StringLiteralExpression {
|
|
||||||
if (node.kind === SyntaxKind.ImportDeclaration) {
|
if (node.kind === SyntaxKind.ImportDeclaration) {
|
||||||
return extractStringLiteral((<ImportDeclaration>node).moduleSpecifier);
|
return (<ImportDeclaration>node).moduleSpecifier;
|
||||||
}
|
}
|
||||||
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||||
var reference = (<ImportEqualsDeclaration>node).moduleReference;
|
var reference = (<ImportEqualsDeclaration>node).moduleReference;
|
||||||
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
if (reference.kind === SyntaxKind.ExternalModuleReference) {
|
||||||
return extractStringLiteral((<ExternalModuleReference>reference).expression);
|
return (<ExternalModuleReference>reference).expression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue