From b0f2265fe39b8d0d8dde9f9dfeb750f4f854204c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 29 Jan 2015 13:38:26 -0800 Subject: [PATCH] Code review feedback --- src/compiler/parser.ts | 116 +++++++++--------- src/compiler/types.ts | 10 ++ ...s6ImportNamedImportParsingError.errors.txt | 7 +- 3 files changed, 68 insertions(+), 65 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 01f286fb9c1..a25f99d59b3 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4531,20 +4531,61 @@ module ts { function parseImportDeclarationOrStatement(fullStart: number, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportStatement { parseExpected(SyntaxKind.ImportKeyword); - if (token === SyntaxKind.StringLiteral || - token === SyntaxKind.AsteriskToken || - token === SyntaxKind.OpenBraceToken || - (isIdentifier() && lookAhead(nextTokenIsCommaOrFromKeyword))) { - return parseImportStatement(fullStart, modifiers); + var identifier: Identifier; + if (isIdentifier()) { + identifier = parseIdentifier(); + if (token !== SyntaxKind.CommaToken && token !== SyntaxKind.FromKeyword) { + // ImportEquals declaration of type: + // import x = require("mod"); or + // import x = M.x; + var importEqualsDeclaration = createNode(SyntaxKind.ImportEqualsDeclaration, fullStart); + setModifiers(importEqualsDeclaration, modifiers); + importEqualsDeclaration.name = identifier; + parseExpected(SyntaxKind.EqualsToken); + importEqualsDeclaration.moduleReference = parseModuleReference(); + parseSemicolon(); + return finishNode(importEqualsDeclaration); + } } - var node = createNode(SyntaxKind.ImportEqualsDeclaration, fullStart); - setModifiers(node, modifiers); - node.name = parseIdentifier(); - parseExpected(SyntaxKind.EqualsToken); - node.moduleReference = parseModuleReference(); + // Import statement + var importStatement = createNode(SyntaxKind.ImportStatement, fullStart); + setModifiers(importStatement, modifiers); + + // ImportDeclaration: + // import ImportClause from ModuleSpecifier ; + // import ModuleSpecifier; + if (identifier || // import id + token === SyntaxKind.AsteriskToken || // import * + token === SyntaxKind.OpenBraceToken) { // import { + //ImportClause: + // ImportedDefaultBinding + // NameSpaceImport + // NamedImports + // ImportedDefaultBinding, NameSpaceImport + // ImportedDefaultBinding, NamedImports + + var importClause = createNode(SyntaxKind.ImportClause); + if (identifier) { + // ImportedDefaultBinding: + // ImportedBinding + importClause.defaultBinding = identifier; + } + + // If there was no default import or if there is comma token after default import + // parse namespace or named imports + if (!importClause.defaultBinding || + parseOptional(SyntaxKind.CommaToken)) { + importClause.namedBindings = token === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImports(); + } + + importStatement.importClause = finishNode(importClause); + parseExpected(SyntaxKind.FromKeyword); + } + + importStatement.moduleSpecifier = parseModuleSpecifier(); parseSemicolon(); - return finishNode(node); + return finishNode(importStatement); } function parseModuleReference() { @@ -4573,61 +4614,18 @@ module ts { return finishNode(node); } - function parseImportStatement(fullStart: number, modifiers: ModifiersArray): ImportStatement { - var node = createNode(SyntaxKind.ImportStatement, fullStart); - setModifiers(node, modifiers); - - // ImportDeclaration: - // import ImportClause ModuleSpecifier ; - // import ModuleSpecifier; - if (token !== SyntaxKind.StringLiteral) { - // ImportDeclaration: - node.importClause = parseImportClause(); - } - node.moduleSpecifier = parseModuleSpecifier(); - parseSemicolon(); - return finishNode(node); - } - function parseModuleSpecifier(): StringLiteralExpression { // ModuleSpecifier: // StringLiteral if (token === SyntaxKind.StringLiteral) { // Ensure the string being required is in our 'identifier' table. This will ensure // that features like 'find refs' will look inside this file when search for its name. - var moduleSpecifier = parseLiteralNode(/*internName*/ true); - return moduleSpecifier; + return parseLiteralNode(/*internName*/ true); } parseErrorAtCurrentToken(Diagnostics.String_literal_expected); } - function parseImportClause(): ImportClause { - //ImportClause: - // ImportedDefaultBinding from - // NameSpaceImport from - // NamedImports from - // ImportedDefaultBinding, NameSpaceImport from - // ImportedDefaultBinding, NamedImports from - - var importClause = createNode(SyntaxKind.ImportClause); - if (isIdentifier()) { - // ImportedDefaultBinding: - // ImportedBinding - importClause.defaultBinding = parseIdentifier(); - } - - // If there was no default import or if there is comma token after default import - // parse namespace or named imports - if (!importClause.defaultBinding || - parseOptional(SyntaxKind.CommaToken)) { - importClause.namedBindings = token === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImports(); - } - - parseExpected(SyntaxKind.FromKeyword); - return finishNode(importClause); - } - function parseNamespaceImport(): NamespaceImport { // NameSpaceImport: // * as ImportedBinding @@ -4649,9 +4647,7 @@ module ts { // ImportsList: // ImportSpecifier // ImportsList, ImportSpecifier - parseExpected(SyntaxKind.OpenBraceToken); - namedImports.elements = parseDelimitedList(ParsingContext.ImportSpecifiers, parseImportSpecifier); - parseExpected(SyntaxKind.CloseBraceToken); + namedImports.elements = parseBracketedList(ParsingContext.ImportSpecifiers, parseImportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken); return finishNode(namedImports); } @@ -4698,7 +4694,7 @@ module ts { return lookAhead(nextTokenIsIdentifierOrKeyword); case SyntaxKind.ImportKeyword: // Not true keywords so ensure an identifier follows or is string literal or asterisk or open brace - return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsteriskOrOpenBrace) ; + return lookAhead(nextTokenCanFollowImportKeyword); case SyntaxKind.ModuleKeyword: // Not a true keyword so ensure an identifier or string literal follows return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); @@ -4729,7 +4725,7 @@ module ts { return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral; } - function nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsteriskOrOpenBrace() { + function nextTokenCanFollowImportKeyword() { nextToken(); return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBraceToken; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 30a1453959a..3d5696beec3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -868,11 +868,21 @@ module ts { expression?: Expression; } + // In case of: + // import "mod" => importClause = undefined, moduleSpecifier = "mod" + // In rest of the cases, module specifier is string literal corresponding to module + // ImportClause information is shown at its declaration below. export interface ImportStatement extends Statement, ModuleElement { importClause?: ImportClause; moduleSpecifier: StringLiteralExpression; } + // In case of: + // import d from "mod" => defaultBinding = d, namedBinding = undefined + // import * as ns from "mod" => defaultBinding = undefined, namedBinding: NamespaceImport = { name: ns } + // import d, * as ns from "mod" => defaultBinding = d, namedBinding: NamespaceImport = { name: ns } + // import { a, b as x } from "mod" => defaultBinding = undefined, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} + // import d, { a, b as x } from "mod" => defaultBinding = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]} export interface ImportClause extends Node { defaultBinding?: Identifier; namedBindings?: NamespaceImport | NamedImports; diff --git a/tests/baselines/reference/es6ImportNamedImportParsingError.errors.txt b/tests/baselines/reference/es6ImportNamedImportParsingError.errors.txt index f33c218afcd..45f2732be25 100644 --- a/tests/baselines/reference/es6ImportNamedImportParsingError.errors.txt +++ b/tests/baselines/reference/es6ImportNamedImportParsingError.errors.txt @@ -3,7 +3,6 @@ tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,12): error TS1109: tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,14): error TS2304: Cannot find name 'from'. tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,19): error TS1005: ';' expected. tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,24): error TS1005: '{' expected. -tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,29): error TS1005: ',' expected. ==== tests/cases/compiler/es6ImportNamedImportParsingError_0.ts (0 errors) ==== @@ -12,7 +11,7 @@ tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,29): error TS1005: export var x = a; export var m = a; -==== tests/cases/compiler/es6ImportNamedImportParsingError_1.ts (6 errors) ==== +==== tests/cases/compiler/es6ImportNamedImportParsingError_1.ts (5 errors) ==== import { * } from "es6ImportNamedImportParsingError_0"; ~ !!! error TS1003: Identifier expected. @@ -24,6 +23,4 @@ tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,29): error TS1005: !!! error TS1005: ';' expected. import defaultBinding, from "es6ImportNamedImportParsingError_0"; ~~~~ -!!! error TS1005: '{' expected. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1005: ',' expected. \ No newline at end of file +!!! error TS1005: '{' expected. \ No newline at end of file