Don't parse nodes, only to not include them in the tree. This will break incremental parsing scenarios.
Properly store the data for an external module reference in the AST.
This commit is contained in:
parent
4db6d3136c
commit
ada6cebef3
|
@ -467,9 +467,9 @@ module ts {
|
|||
if (!links.target) {
|
||||
links.target = resolvingSymbol;
|
||||
var node = <ImportDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ImportDeclaration);
|
||||
var target = node.externalModuleName ?
|
||||
resolveExternalModuleName(node, node.externalModuleName) :
|
||||
getSymbolOfPartOfRightHandSideOfImport(node.entityName, node);
|
||||
var target = node.externalModuleName
|
||||
? resolveExternalModuleName(node, node.externalModuleName.expression)
|
||||
: getSymbolOfPartOfRightHandSideOfImport(node.entityName, node);
|
||||
if (links.target === resolvingSymbol) {
|
||||
links.target = target || unknownSymbol;
|
||||
}
|
||||
|
@ -546,7 +546,12 @@ module ts {
|
|||
return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
|
||||
}
|
||||
|
||||
function resolveExternalModuleName(location: Node, moduleLiteral: LiteralExpression): Symbol {
|
||||
function resolveExternalModuleName(location: Node, moduleExpression: Expression): Symbol {
|
||||
if (moduleExpression.kind !== SyntaxKind.StringLiteral) {
|
||||
return;
|
||||
}
|
||||
|
||||
var moduleLiteral = <LiteralExpression>moduleExpression;
|
||||
var searchPath = getDirectoryPath(getSourceFile(location).filename);
|
||||
var moduleName = moduleLiteral.text;
|
||||
if (!moduleName) return;
|
||||
|
@ -8368,12 +8373,17 @@ module ts {
|
|||
// 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 (isExternalModuleNameRelative(node.externalModuleName.text)) {
|
||||
error(node, Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
|
||||
target = unknownSymbol;
|
||||
if (node.externalModuleName.expression.kind === SyntaxKind.StringLiteral) {
|
||||
if (isExternalModuleNameRelative((<LiteralExpression>node.externalModuleName.expression).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 = resolveImport(symbol);
|
||||
target = unknownSymbol;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -8948,8 +8958,8 @@ module ts {
|
|||
|
||||
case SyntaxKind.StringLiteral:
|
||||
// External module name in an import declaration
|
||||
if (node.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent).externalModuleName === node) {
|
||||
var importSymbol = getSymbolOfNode(node.parent);
|
||||
if (node.parent.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent.parent).externalModuleName.expression === node) {
|
||||
var importSymbol = getSymbolOfNode(node.parent.parent);
|
||||
var moduleType = getTypeOfSymbol(importSymbol);
|
||||
return moduleType ? moduleType.symbol : undefined;
|
||||
}
|
||||
|
|
|
@ -671,7 +671,7 @@ module ts {
|
|||
}
|
||||
else {
|
||||
write("require(");
|
||||
writeTextOfNode(currentSourceFile, node.externalModuleName);
|
||||
writeTextOfNode(currentSourceFile, node.externalModuleName.expression);
|
||||
write(");");
|
||||
}
|
||||
writer.writeLine();
|
||||
|
@ -3312,11 +3312,12 @@ module ts {
|
|||
emit(node.entityName);
|
||||
}
|
||||
else {
|
||||
var literal = <LiteralExpression>node.externalModuleName.expression;
|
||||
write("require(");
|
||||
emitStart(node.externalModuleName);
|
||||
emitLiteral(node.externalModuleName);
|
||||
emitEnd(node.externalModuleName);
|
||||
emitToken(SyntaxKind.CloseParenToken, node.externalModuleName.end);
|
||||
emitStart(literal);
|
||||
emitLiteral(literal);
|
||||
emitEnd(literal);
|
||||
emitToken(SyntaxKind.CloseParenToken, literal.end);
|
||||
}
|
||||
write(";");
|
||||
emitEnd(node);
|
||||
|
@ -3356,7 +3357,7 @@ module ts {
|
|||
write("[\"require\", \"exports\"");
|
||||
forEach(imports, imp => {
|
||||
write(", ");
|
||||
emitLiteral(imp.externalModuleName);
|
||||
emitLiteral(<LiteralExpression>imp.externalModuleName.expression);
|
||||
});
|
||||
forEach(node.amdDependencies, amdDependency => {
|
||||
var text = "\"" + amdDependency + "\"";
|
||||
|
|
|
@ -394,6 +394,8 @@ module ts {
|
|||
return child((<ComputedPropertyName>node).expression);
|
||||
case SyntaxKind.HeritageClause:
|
||||
return children((<HeritageClause>node).types);
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return child((<ExternalModuleReference>node).expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1726,14 +1728,6 @@ module ts {
|
|||
return node;
|
||||
}
|
||||
|
||||
function parseStringLiteral(): LiteralExpression {
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
return parseLiteralNode(/*internName:*/ true);
|
||||
}
|
||||
error(Diagnostics.String_literal_expected);
|
||||
return <LiteralExpression>createMissingNode();
|
||||
}
|
||||
|
||||
// TYPES
|
||||
|
||||
function parseTypeReference(): TypeReferenceNode {
|
||||
|
@ -1786,9 +1780,7 @@ module ts {
|
|||
|
||||
function parseParameterType(): TypeNode {
|
||||
return parseOptional(SyntaxKind.ColonToken)
|
||||
? token === SyntaxKind.StringLiteral
|
||||
? parseStringLiteral()
|
||||
: parseType()
|
||||
? token === SyntaxKind.StringLiteral ? parseLiteralNode(/*internName:*/ true) : parseType()
|
||||
: undefined;
|
||||
}
|
||||
|
||||
|
@ -3940,7 +3932,7 @@ module ts {
|
|||
function parseAmbientExternalModuleDeclaration(fullStart: number, flags: NodeFlags): ModuleDeclaration {
|
||||
var node = <ModuleDeclaration>createNode(SyntaxKind.ModuleDeclaration, fullStart);
|
||||
node.flags = flags;
|
||||
node.name = parseStringLiteral();
|
||||
node.name = parseLiteralNode(/*internName:*/ true);
|
||||
node.body = parseModuleBlock();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
@ -3952,24 +3944,45 @@ module ts {
|
|||
: parseInternalModuleTail(fullStart, flags);
|
||||
}
|
||||
|
||||
function isExternalModuleReference() {
|
||||
if (token === SyntaxKind.RequireKeyword) {
|
||||
return lookAhead(() => {
|
||||
nextToken();
|
||||
return token === SyntaxKind.OpenParenToken;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseImportDeclaration(fullStart: number, modifiers: ModifiersArray): ImportDeclaration {
|
||||
var node = <ImportDeclaration>createNode(SyntaxKind.ImportDeclaration, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ImportKeyword);
|
||||
node.name = parseIdentifier();
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
var entityName = parseEntityName(/*allowReservedWords*/ false);
|
||||
if (entityName.kind === SyntaxKind.Identifier && (<Identifier>entityName).text === "require" && parseOptional(SyntaxKind.OpenParenToken)) {
|
||||
node.externalModuleName = parseStringLiteral();
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
if (isExternalModuleReference()) {
|
||||
node.externalModuleName = parseExternalModuleReference();
|
||||
}
|
||||
else {
|
||||
node.entityName = entityName;
|
||||
node.entityName = parseEntityName(/*allowReservedWords*/ false);
|
||||
}
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseExternalModuleReference() {
|
||||
var node = <ExternalModuleReference>createNode(SyntaxKind.ExternalModuleReference);
|
||||
parseExpected(SyntaxKind.RequireKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = parseExpression();
|
||||
if (node.expression.kind === SyntaxKind.StringLiteral) {
|
||||
internIdentifier((<LiteralExpression>node.expression).text);
|
||||
}
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseExportAssignmentTail(fullStart: number, modifiers: ModifiersArray): ExportAssignment {
|
||||
var node = <ExportAssignment>createNode(SyntaxKind.ExportAssignment, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
|
@ -4307,6 +4320,7 @@ module ts {
|
|||
case SyntaxKind.DeleteExpression: return checkDeleteExpression(<DeleteExpression> node);
|
||||
case SyntaxKind.ElementAccessExpression: return checkElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.ExportAssignment: return checkExportAssignment(<ExportAssignment>node);
|
||||
case SyntaxKind.ExternalModuleReference: return checkExternalModuleReference(<ExternalModuleReference>node);
|
||||
case SyntaxKind.ForInStatement: return checkForInStatement(<ForInStatement>node);
|
||||
case SyntaxKind.ForStatement: return checkForStatement(<ForStatement>node);
|
||||
case SyntaxKind.FunctionDeclaration: return checkFunctionDeclaration(<FunctionLikeDeclaration>node);
|
||||
|
@ -4704,6 +4718,12 @@ module ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkExternalModuleReference(node: ExternalModuleReference) {
|
||||
if (node.expression.kind !== SyntaxKind.StringLiteral) {
|
||||
return grammarErrorOnNode(node.expression, Diagnostics.String_literal_expected);
|
||||
}
|
||||
}
|
||||
|
||||
function checkForInStatement(node: ForInStatement) {
|
||||
return checkVariableDeclarations(node.declarations) ||
|
||||
checkForMoreThanOneDeclaration(node.declarations);
|
||||
|
@ -4905,7 +4925,7 @@ module ts {
|
|||
return grammarErrorOnNode(statement, Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module);
|
||||
}
|
||||
else if (statement.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>statement).externalModuleName) {
|
||||
return grammarErrorOnNode((<ImportDeclaration>statement).externalModuleName, Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
return grammarErrorOnNode((<ImportDeclaration>statement).externalModuleName.expression, Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5627,8 +5647,11 @@ module ts {
|
|||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
forEach(file.statements, node => {
|
||||
if (node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).externalModuleName) {
|
||||
var nameLiteral = (<ImportDeclaration>node).externalModuleName;
|
||||
if (node.kind === SyntaxKind.ImportDeclaration &&
|
||||
(<ImportDeclaration>node).externalModuleName &&
|
||||
(<ImportDeclaration>node).externalModuleName.expression.kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>(<ImportDeclaration>node).externalModuleName.expression;
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
var searchPath = basePath;
|
||||
|
@ -5653,8 +5676,11 @@ module ts {
|
|||
// The StringLiteral must specify a top - level external module name.
|
||||
// Relative external module names are not permitted
|
||||
forEachChild((<ModuleDeclaration>node).body, node => {
|
||||
if (node.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node).externalModuleName) {
|
||||
var nameLiteral = (<ImportDeclaration>node).externalModuleName;
|
||||
if (node.kind === SyntaxKind.ImportDeclaration &&
|
||||
(<ImportDeclaration>node).externalModuleName &&
|
||||
(<ImportDeclaration>node).externalModuleName.expression.kind === SyntaxKind.StringLiteral) {
|
||||
|
||||
var nameLiteral = <LiteralExpression>(<ImportDeclaration>node).externalModuleName.expression;
|
||||
var moduleName = nameLiteral.text;
|
||||
if (moduleName) {
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
|
|
|
@ -221,6 +221,8 @@ module ts {
|
|||
ModuleBlock,
|
||||
ImportDeclaration,
|
||||
ExportAssignment,
|
||||
// Module references
|
||||
ExternalModuleReference,
|
||||
// Clauses
|
||||
CaseClause,
|
||||
DefaultClause,
|
||||
|
@ -730,7 +732,11 @@ module ts {
|
|||
export interface ImportDeclaration extends Declaration, ModuleElement {
|
||||
name: Identifier;
|
||||
entityName?: EntityName;
|
||||
externalModuleName?: LiteralExpression;
|
||||
externalModuleName?: ExternalModuleReference;
|
||||
}
|
||||
|
||||
export interface ExternalModuleReference extends Node {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface ExportAssignment extends Statement, ModuleElement {
|
||||
|
|
|
@ -1982,7 +1982,7 @@ module ts {
|
|||
function isNameOfExternalModuleImportOrDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.StringLiteral &&
|
||||
(isNameOfModuleDeclaration(node) ||
|
||||
(node.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent).externalModuleName === node));
|
||||
(node.parent.parent.kind === SyntaxKind.ImportDeclaration && (<ImportDeclaration>node.parent.parent).externalModuleName.expression === node));
|
||||
}
|
||||
|
||||
/** Returns true if the position is within a comment */
|
||||
|
@ -3086,7 +3086,7 @@ module ts {
|
|||
displayParts.push(spacePart());
|
||||
displayParts.push(keywordPart(SyntaxKind.RequireKeyword));
|
||||
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
displayParts.push(displayPart(getTextOfNode(importDeclaration.externalModuleName), SymbolDisplayPartKind.stringLiteral));
|
||||
displayParts.push(displayPart(getTextOfNode(importDeclaration.externalModuleName.expression), SymbolDisplayPartKind.stringLiteral));
|
||||
displayParts.push(punctuationPart(SyntaxKind.CloseParenToken));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
tests/cases/conformance/externalModules/importNonStringLiteral.ts(2,22): error TS1141: String literal expected.
|
||||
tests/cases/conformance/externalModules/importNonStringLiteral.ts(2,23): error TS1005: ';' expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/externalModules/importNonStringLiteral.ts (2 errors) ====
|
||||
==== tests/cases/conformance/externalModules/importNonStringLiteral.ts (1 errors) ====
|
||||
var x = "filename";
|
||||
import foo = require(x); // invalid
|
||||
~
|
||||
!!! error TS1141: String literal expected.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
|
Loading…
Reference in a new issue