Skip to content

Commit 6d0db0f

Browse files
committed
Resolve ES6 imports in type checker
1 parent c6a6619 commit 6d0db0f

File tree

1 file changed

+89
-36
lines changed

1 file changed

+89
-36
lines changed

src/compiler/checker.ts

+89-36
Original file line numberDiff line numberDiff line change
@@ -439,22 +439,65 @@ module ts {
439439
return result;
440440
}
441441

442+
function getDeclarationOfImportSymbol(symbol: Symbol): Declaration {
443+
return forEach(symbol.declarations, d =>
444+
d.kind === SyntaxKind.ImportEqualsDeclaration ||
445+
d.kind === SyntaxKind.ImportClause ||
446+
d.kind === SyntaxKind.NamespaceImport ||
447+
d.kind === SyntaxKind.ImportSpecifier ? d : undefined);
448+
}
449+
450+
function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration): Symbol {
451+
return node.moduleReference.kind === SyntaxKind.ExternalModuleReference ?
452+
resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node)) :
453+
getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, node);
454+
}
455+
456+
function getTargetOfImportClause(node: ImportClause): Symbol {
457+
// TODO: Verify that returned symbol originates in "export default" statement
458+
return resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
459+
}
460+
461+
function getTargetOfNamespaceImport(node: NamespaceImport): Symbol {
462+
// TODO: Verify that returned symbol does not originate in "export default" statement
463+
return resolveExternalModuleName(node, (<ImportDeclaration>node.parent.parent).moduleSpecifier);
464+
}
465+
466+
function getTargetOfImportSpecifier(node: ImportSpecifier): Symbol {
467+
var moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent.parent.parent).moduleSpecifier);
468+
if (moduleSymbol) {
469+
var name = node.propertyName || node.name;
470+
if (name.text) {
471+
var symbol = getSymbol(moduleSymbol.exports, name.text, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
472+
if (!symbol) {
473+
error(name, Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), declarationNameToString(name));
474+
return;
475+
}
476+
return symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace) ? symbol : resolveImport(symbol);
477+
}
478+
}
479+
}
480+
481+
function getTargetOfImportDeclaration(node: Declaration): Symbol {
482+
switch (node.kind) {
483+
case SyntaxKind.ImportEqualsDeclaration:
484+
return getTargetOfImportEqualsDeclaration(<ImportEqualsDeclaration>node);
485+
case SyntaxKind.ImportClause:
486+
return getTargetOfImportClause(<ImportClause>node);
487+
case SyntaxKind.NamespaceImport:
488+
return getTargetOfNamespaceImport(<NamespaceImport>node);
489+
case SyntaxKind.ImportSpecifier:
490+
return getTargetOfImportSpecifier(<ImportSpecifier>node);
491+
}
492+
}
493+
442494
function resolveImport(symbol: Symbol): Symbol {
443495
Debug.assert((symbol.flags & SymbolFlags.Import) !== 0, "Should only get Imports here.");
444496
var links = getSymbolLinks(symbol);
445497
if (!links.target) {
446498
links.target = resolvingSymbol;
447-
var node = <ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration);
448-
// Grammar checking
449-
if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) {
450-
if ((<ExternalModuleReference>node.moduleReference).expression.kind !== SyntaxKind.StringLiteral) {
451-
grammarErrorOnNode((<ExternalModuleReference>node.moduleReference).expression, Diagnostics.String_literal_expected);
452-
}
453-
}
454-
455-
var target = node.moduleReference.kind === SyntaxKind.ExternalModuleReference
456-
? resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node))
457-
: getSymbolOfPartOfRightHandSideOfImportEquals(<EntityName>node.moduleReference, node);
499+
var node = getDeclarationOfImportSymbol(symbol);
500+
var target = getTargetOfImportDeclaration(node);
458501
if (links.target === resolvingSymbol) {
459502
links.target = target || unknownSymbol;
460503
}
@@ -4837,31 +4880,36 @@ module ts {
48374880
var symbol = getResolvedSymbol(node);
48384881

48394882
if (symbol.flags & SymbolFlags.Import) {
4883+
48404884
var symbolLinks = getSymbolLinks(symbol);
4841-
if (!symbolLinks.referenced) {
4842-
var importOrExportAssignment = getLeftSideOfImportEqualsOrExportAssignment(node);
4843-
4844-
// decision about whether import is referenced can be made now if
4845-
// - import that are used anywhere except right side of import declarations
4846-
// - imports that are used on the right side of exported import declarations
4847-
// for other cases defer decision until the check of left side
4848-
if (!importOrExportAssignment ||
4849-
(importOrExportAssignment.flags & NodeFlags.Export) ||
4850-
(importOrExportAssignment.kind === SyntaxKind.ExportAssignment)) {
4851-
// Mark the import as referenced so that we emit it in the final .js file.
4852-
// exception: identifiers that appear in type queries, const enums, modules that contain only const enums
4853-
symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4854-
}
4855-
else {
4856-
var nodeLinks = getNodeLinks(importOrExportAssignment);
4857-
Debug.assert(!nodeLinks.importOnRightSide);
4858-
nodeLinks.importOnRightSide = symbol;
4859-
}
4860-
}
4885+
symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4886+
4887+
// TODO(andersh): Figure out what this does
4888+
//var symbolLinks = getSymbolLinks(symbol);
4889+
//if (!symbolLinks.referenced) {
4890+
// var importOrExportAssignment = getLeftSideOfImportEqualsOrExportAssignment(node);
4891+
4892+
// // decision about whether import is referenced can be made now if
4893+
// // - import that are used anywhere except right side of import declarations
4894+
// // - imports that are used on the right side of exported import declarations
4895+
// // for other cases defer decision until the check of left side
4896+
// if (!importOrExportAssignment ||
4897+
// (importOrExportAssignment.flags & NodeFlags.Export) ||
4898+
// (importOrExportAssignment.kind === SyntaxKind.ExportAssignment)) {
4899+
// // Mark the import as referenced so that we emit it in the final .js file.
4900+
// // exception: identifiers that appear in type queries, const enums, modules that contain only const enums
4901+
// symbolLinks.referenced = !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol));
4902+
// }
4903+
// else {
4904+
// var nodeLinks = getNodeLinks(importOrExportAssignment);
4905+
// Debug.assert(!nodeLinks.importOnRightSide);
4906+
// nodeLinks.importOnRightSide = symbol;
4907+
// }
4908+
//}
48614909

4862-
if (symbolLinks.referenced) {
4863-
markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration));
4864-
}
4910+
//if (symbolLinks.referenced) {
4911+
// markLinkedImportsAsReferenced(<ImportEqualsDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportEqualsDeclaration));
4912+
//}
48654913
}
48664914

48674915
checkCollisionWithCapturedSuperVariable(node, node);
@@ -9228,6 +9276,10 @@ module ts {
92289276
}
92299277
}
92309278
else {
9279+
var moduleNameExpr = getExternalModuleImportEqualsDeclarationExpression(node);
9280+
if (moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
9281+
grammarErrorOnNode(moduleNameExpr, Diagnostics.String_literal_expected);
9282+
}
92319283
// Import declaration for an external module
92329284
if (node.parent.kind === SyntaxKind.SourceFile) {
92339285
target = resolveImport(symbol);
@@ -9237,8 +9289,8 @@ module ts {
92379289
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
92389290
// other external modules only through top - level external module names.
92399291
// Relative external module names are not permitted.
9240-
if (getExternalModuleImportEqualsDeclarationExpression(node).kind === SyntaxKind.StringLiteral) {
9241-
if (isExternalModuleNameRelative((<LiteralExpression>getExternalModuleImportEqualsDeclarationExpression(node)).text)) {
9292+
if (moduleNameExpr.kind === SyntaxKind.StringLiteral) {
9293+
if (isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
92429294
error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
92439295
target = unknownSymbol;
92449296
}
@@ -11037,6 +11089,7 @@ module ts {
1103711089
// export_opt AmbientDeclaration
1103811090
//
1103911091
if (node.kind === SyntaxKind.InterfaceDeclaration ||
11092+
node.kind === SyntaxKind.ImportDeclaration ||
1104011093
node.kind === SyntaxKind.ImportEqualsDeclaration ||
1104111094
node.kind === SyntaxKind.ExportAssignment ||
1104211095
(node.flags & NodeFlags.Ambient)) {

0 commit comments

Comments
 (0)