Skip to content

Commit 5eb0094

Browse files
committed
Parsing for NamedImports
NamedImports : { } { ImportsList } { ImportsList , } ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding IdentifierName as ImportedBinding Conflicts: src/compiler/parser.ts
1 parent fdd7032 commit 5eb0094

9 files changed

+204
-7
lines changed

Diff for: src/compiler/parser.ts

+47-7
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ module ts {
287287
TypeArguments, // Type arguments in type argument list
288288
TupleElementTypes, // Element types in tuple element type list
289289
HeritageClauses, // Heritage clauses for a class or interface declaration.
290+
ImportSpecifiers, // Named import clause's import specifier list
290291
Count // Number of parsing contexts
291292
}
292293

@@ -306,7 +307,7 @@ module ts {
306307
case ParsingContext.TypeMembers: return Diagnostics.Property_or_signature_expected;
307308
case ParsingContext.ClassMembers: return Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
308309
case ParsingContext.EnumMembers: return Diagnostics.Enum_member_expected;
309-
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
310+
case ParsingContext.TypeReferences: return Diagnostics.Type_reference_expected;
310311
case ParsingContext.VariableDeclarations: return Diagnostics.Variable_declaration_expected;
311312
case ParsingContext.ObjectBindingElements: return Diagnostics.Property_destructuring_pattern_expected;
312313
case ParsingContext.ArrayBindingElements: return Diagnostics.Array_element_destructuring_pattern_expected;
@@ -318,6 +319,7 @@ module ts {
318319
case ParsingContext.TypeArguments: return Diagnostics.Type_argument_expected;
319320
case ParsingContext.TupleElementTypes: return Diagnostics.Type_expected;
320321
case ParsingContext.HeritageClauses: return Diagnostics.Unexpected_token_expected;
322+
case ParsingContext.ImportSpecifiers: return Diagnostics.Identifier_expected;
321323
}
322324
};
323325

@@ -1450,6 +1452,8 @@ module ts {
14501452
return token === SyntaxKind.CommaToken || isStartOfType();
14511453
case ParsingContext.HeritageClauses:
14521454
return isHeritageClause();
1455+
case ParsingContext.ImportSpecifiers:
1456+
return isIdentifierOrKeyword();
14531457
}
14541458

14551459
Debug.fail("Non-exhaustive case in 'isListElement'.");
@@ -1486,6 +1490,7 @@ module ts {
14861490
case ParsingContext.EnumMembers:
14871491
case ParsingContext.ObjectLiteralMembers:
14881492
case ParsingContext.ObjectBindingElements:
1493+
case ParsingContext.ImportSpecifiers:
14891494
return token === SyntaxKind.CloseBraceToken;
14901495
case ParsingContext.SwitchClauseStatements:
14911496
return token === SyntaxKind.CloseBraceToken || token === SyntaxKind.CaseKeyword || token === SyntaxKind.DefaultKeyword;
@@ -4521,7 +4526,8 @@ module ts {
45214526
function parseImportDeclarationOrStatement(fullStart: number, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportStatement {
45224527
parseExpected(SyntaxKind.ImportKeyword);
45234528
if (token === SyntaxKind.StringLiteral ||
4524-
token === SyntaxKind.AsteriskToken) {
4529+
token === SyntaxKind.AsteriskToken ||
4530+
token === SyntaxKind.OpenBraceToken) {
45254531
return parseImportStatement(fullStart, modifiers);
45264532
}
45274533

@@ -4598,7 +4604,7 @@ module ts {
45984604
// ImportedDefaultBinding, NamedImports from
45994605

46004606
var importClause = <ImportClause>createNode(SyntaxKind.ImportClause);
4601-
importClause.bindings = parseNamespaceImport();
4607+
importClause.bindings = token === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImports();
46024608
parseExpected(SyntaxKind.FromKeyword);
46034609
return finishNode(importClause);
46044610
}
@@ -4613,6 +4619,36 @@ module ts {
46134619
return finishNode(namespaceImport);
46144620
}
46154621

4622+
function parseNamedImports(): NamedImports {
4623+
var namedImports = <NamedImports>createNode(SyntaxKind.NamedImports);
4624+
4625+
// NamedImports:
4626+
// { }
4627+
// { ImportsList }
4628+
// { ImportsList, }
4629+
4630+
// ImportsList:
4631+
// ImportSpecifier
4632+
// ImportsList, ImportSpecifier
4633+
parseExpected(SyntaxKind.OpenBraceToken);
4634+
namedImports.elements = parseDelimitedList(ParsingContext.ImportSpecifiers, parseImportSpecifier);
4635+
parseExpected(SyntaxKind.CloseBraceToken);
4636+
return finishNode(namedImports);
4637+
}
4638+
4639+
function parseImportSpecifier(): ImportSpecifier {
4640+
var node = <ImportSpecifier>createNode(SyntaxKind.ImportSpecifier);
4641+
// ImportSpecifier:
4642+
// ImportedBinding
4643+
// IdentifierName as ImportedBinding
4644+
if (lookAhead(nextTokenIsAsKeyword)) {
4645+
node.propertyName = parseIdentifierName();
4646+
parseExpected(SyntaxKind.AsKeyword);
4647+
}
4648+
node.name = parseIdentifier();
4649+
return finishNode(node);
4650+
}
4651+
46164652
function parseExportAssignmentTail(fullStart: number, modifiers: ModifiersArray): ExportAssignment {
46174653
var node = <ExportAssignment>createNode(SyntaxKind.ExportAssignment, fullStart);
46184654
setModifiers(node, modifiers);
@@ -4642,8 +4678,8 @@ module ts {
46424678
// Not true keywords so ensure an identifier follows
46434679
return lookAhead(nextTokenIsIdentifierOrKeyword);
46444680
case SyntaxKind.ImportKeyword:
4645-
// Not true keywords so ensure an identifier follows or is string literal or asterisk
4646-
return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsterisk) ;
4681+
// Not true keywords so ensure an identifier follows or is string literal or asterisk or open brace
4682+
return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsteriskOrOpenBrace) ;
46474683
case SyntaxKind.ModuleKeyword:
46484684
// Not a true keyword so ensure an identifier or string literal follows
46494685
return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral);
@@ -4674,10 +4710,10 @@ module ts {
46744710
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral;
46754711
}
46764712

4677-
function nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsterisk() {
4713+
function nextTokenIsIdentifierOrKeywordOrStringLiteralOrAsteriskOrOpenBrace() {
46784714
nextToken();
46794715
return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral ||
4680-
token === SyntaxKind.AsteriskToken;
4716+
token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBraceToken;
46814717
}
46824718

46834719
function nextTokenIsEqualsTokenOrDeclarationStart() {
@@ -4690,6 +4726,10 @@ module ts {
46904726
return isDeclarationStart();
46914727
}
46924728

4729+
function nextTokenIsAsKeyword() {
4730+
return nextToken() === SyntaxKind.AsKeyword;
4731+
}
4732+
46934733
function parseDeclaration(): ModuleElement {
46944734
var fullStart = getNodePos();
46954735
var modifiers = parseModifiers();

Diff for: tests/baselines/reference/es6ImportNamedImport.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [tests/cases/compiler/es6ImportNamedImport.ts] ////
2+
3+
//// [es6ImportNamedImport_0.ts]
4+
5+
export var a = 10;
6+
export var x = a;
7+
export var m = a;
8+
9+
//// [es6ImportNamedImport_1.ts]
10+
import { } from "es6ImportNamedImport_0";
11+
import { a } from "es6ImportNamedImport_0";
12+
import { a as b } from "es6ImportNamedImport_0";
13+
import { x, a as y } from "es6ImportNamedImport_0";
14+
import { x as z, } from "es6ImportNamedImport_0";
15+
import { m, } from "es6ImportNamedImport_0";
16+
17+
//// [es6ImportNamedImport_0.js]
18+
exports.a = 10;
19+
exports.x = exports.a;
20+
exports.m = exports.a;
21+
//// [es6ImportNamedImport_1.js]

Diff for: tests/baselines/reference/es6ImportNamedImport.types

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/es6ImportNamedImport_0.ts ===
2+
3+
export var a = 10;
4+
>a : number
5+
6+
export var x = a;
7+
>x : number
8+
>a : number
9+
10+
export var m = a;
11+
>m : number
12+
>a : number
13+
14+
=== tests/cases/compiler/es6ImportNamedImport_1.ts ===
15+
import { } from "es6ImportNamedImport_0";
16+
No type information for this code.import { a } from "es6ImportNamedImport_0";
17+
No type information for this code.import { a as b } from "es6ImportNamedImport_0";
18+
No type information for this code.import { x, a as y } from "es6ImportNamedImport_0";
19+
No type information for this code.import { x as z, } from "es6ImportNamedImport_0";
20+
No type information for this code.import { m, } from "es6ImportNamedImport_0";
21+
No type information for this code.
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [tests/cases/compiler/es6ImportNamedImportInEs5.ts] ////
2+
3+
//// [es6ImportNamedImportInEs5_0.ts]
4+
5+
export var a = 10;
6+
export var x = a;
7+
export var m = a;
8+
9+
//// [es6ImportNamedImportInEs5_1.ts]
10+
import { } from "es6ImportNamedImportInEs5_0";
11+
import { a } from "es6ImportNamedImportInEs5_0";
12+
import { a as b } from "es6ImportNamedImportInEs5_0";
13+
import { x, a as y } from "es6ImportNamedImportInEs5_0";
14+
import { x as z, } from "es6ImportNamedImportInEs5_0";
15+
import { m, } from "es6ImportNamedImportInEs5_0";
16+
17+
//// [es6ImportNamedImportInEs5_0.js]
18+
exports.a = 10;
19+
exports.x = exports.a;
20+
exports.m = exports.a;
21+
//// [es6ImportNamedImportInEs5_1.js]
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/es6ImportNamedImportInEs5_0.ts ===
2+
3+
export var a = 10;
4+
>a : number
5+
6+
export var x = a;
7+
>x : number
8+
>a : number
9+
10+
export var m = a;
11+
>m : number
12+
>a : number
13+
14+
=== tests/cases/compiler/es6ImportNamedImportInEs5_1.ts ===
15+
import { } from "es6ImportNamedImportInEs5_0";
16+
No type information for this code.import { a } from "es6ImportNamedImportInEs5_0";
17+
No type information for this code.import { a as b } from "es6ImportNamedImportInEs5_0";
18+
No type information for this code.import { x, a as y } from "es6ImportNamedImportInEs5_0";
19+
No type information for this code.import { x as z, } from "es6ImportNamedImportInEs5_0";
20+
No type information for this code.import { m, } from "es6ImportNamedImportInEs5_0";
21+
No type information for this code.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,10): error TS1003: Identifier expected.
2+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,12): error TS1109: Expression expected.
3+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,14): error TS2304: Cannot find name 'from'.
4+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(1,19): error TS1005: ';' expected.
5+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,22): error TS1005: '=' expected.
6+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,24): error TS2304: Cannot find name 'from'.
7+
tests/cases/compiler/es6ImportNamedImportParsingError_1.ts(2,29): error TS1005: ';' expected.
8+
9+
10+
==== tests/cases/compiler/es6ImportNamedImportParsingError_0.ts (0 errors) ====
11+
12+
export var a = 10;
13+
export var x = a;
14+
export var m = a;
15+
16+
==== tests/cases/compiler/es6ImportNamedImportParsingError_1.ts (7 errors) ====
17+
import { * } from "es6ImportNamedImportParsingError_0";
18+
~
19+
!!! error TS1003: Identifier expected.
20+
~
21+
!!! error TS1109: Expression expected.
22+
~~~~
23+
!!! error TS2304: Cannot find name 'from'.
24+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25+
!!! error TS1005: ';' expected.
26+
import defaultBinding, from "es6ImportNamedImportParsingError_0";
27+
~
28+
!!! error TS1005: '=' expected.
29+
~~~~
30+
!!! error TS2304: Cannot find name 'from'.
31+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32+
!!! error TS1005: ';' expected.

Diff for: tests/cases/compiler/es6ImportNamedImport.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @target: es6
2+
// @module: commonjs
3+
4+
// @filename: es6ImportNamedImport_0.ts
5+
export var a = 10;
6+
export var x = a;
7+
export var m = a;
8+
9+
// @filename: es6ImportNamedImport_1.ts
10+
import { } from "es6ImportNamedImport_0";
11+
import { a } from "es6ImportNamedImport_0";
12+
import { a as b } from "es6ImportNamedImport_0";
13+
import { x, a as y } from "es6ImportNamedImport_0";
14+
import { x as z, } from "es6ImportNamedImport_0";
15+
import { m, } from "es6ImportNamedImport_0";

Diff for: tests/cases/compiler/es6ImportNamedImportInEs5.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @target: es5
2+
// @module: commonjs
3+
4+
// @filename: es6ImportNamedImportInEs5_0.ts
5+
export var a = 10;
6+
export var x = a;
7+
export var m = a;
8+
9+
// @filename: es6ImportNamedImportInEs5_1.ts
10+
import { } from "es6ImportNamedImportInEs5_0";
11+
import { a } from "es6ImportNamedImportInEs5_0";
12+
import { a as b } from "es6ImportNamedImportInEs5_0";
13+
import { x, a as y } from "es6ImportNamedImportInEs5_0";
14+
import { x as z, } from "es6ImportNamedImportInEs5_0";
15+
import { m, } from "es6ImportNamedImportInEs5_0";
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @target: es6
2+
// @module: commonjs
3+
4+
// @filename: es6ImportNamedImportParsingError_0.ts
5+
export var a = 10;
6+
export var x = a;
7+
export var m = a;
8+
9+
// @filename: es6ImportNamedImportParsingError_1.ts
10+
import { * } from "es6ImportNamedImportParsingError_0";
11+
import defaultBinding, from "es6ImportNamedImportParsingError_0";

0 commit comments

Comments
 (0)