diff --git a/src/main/factory.ts b/src/main/factory.ts index b78a764..f987009 100644 --- a/src/main/factory.ts +++ b/src/main/factory.ts @@ -22,6 +22,7 @@ import { KeywordType, ListType, MapType, + NamespaceScope, ParseError, PropertyAssignment, ScanError, @@ -84,6 +85,13 @@ export function createIdentifier( return { type: SyntaxType.Identifier, value, loc, annotations } } +export function createNamespaceScope( + value: string, + loc: TextLocation, +): NamespaceScope { + return { type: SyntaxType.NamespaceScope, value, loc } +} + export function creataePropertyAssignment( name: ConstValue, initializer: ConstValue, diff --git a/src/main/parser.ts b/src/main/parser.ts index 2410f55..87a3d2a 100644 --- a/src/main/parser.ts +++ b/src/main/parser.ts @@ -22,6 +22,7 @@ import { ListType, MapType, NamespaceDefinition, + NamespaceScope, ParametersDefinition, PropertyAssignment, ServiceDefinition, @@ -53,6 +54,7 @@ import { createIntegerLiteral, createKeywordFieldType, createMapFieldType, + createNamespaceScope, createParseError, createStringLiteral, createTextLocation, @@ -394,6 +396,23 @@ export function createParser( return null } + // NamespaceScope → '*' | Identifier + function parseNamespaceScope(): NamespaceScope { + if (currentToken().type === SyntaxType.StarToken) { + const loc = currentToken().loc + advance() + return createNamespaceScope('*', loc) + } + + const _scopeToken: Token | null = consume(SyntaxType.Identifier) + const scopeToken: Token = requireValue( + _scopeToken, + `Unable to find scope identifier for namespace`, + ) + + return createNamespaceScope(scopeToken.text, scopeToken.loc) + } + // Namespace → 'namespace' ( NamespaceScope Identifier ) function parseNamespace(): NamespaceDefinition { const _keywordToken: Token | null = consume(SyntaxType.NamespaceKeyword) @@ -401,11 +420,8 @@ export function createParser( _keywordToken, `'namespace' keyword expected`, ) - const _scopeToken: Token | null = consume(SyntaxType.Identifier) - const scopeToken: Token = requireValue( - _scopeToken, - `Unable to find scope identifier for namespace`, - ) + + const scope: NamespaceScope = parseNamespaceScope() const _nameToken: Token | null = consume(SyntaxType.Identifier) const nameToken: Token = requireValue( @@ -415,7 +431,7 @@ export function createParser( return { type: SyntaxType.NamespaceDefinition, - scope: createIdentifier(scopeToken.text, scopeToken.loc), + scope, name: createIdentifier(nameToken.text, nameToken.loc), comments: getComments(), loc: createTextLocation(keywordToken.loc.start, nameToken.loc.end), diff --git a/src/main/scanner.ts b/src/main/scanner.ts index 1cafc69..429b3ab 100644 --- a/src/main/scanner.ts +++ b/src/main/scanner.ts @@ -112,8 +112,12 @@ export function createScanner( nextLine() break + case '*': + addToken(SyntaxType.StarToken) + break + case '&': - // Thirft supports (undocumented by the grammar) a syntax for c-style pointers + // Thrift supports (undocumented by the grammar) a syntax for c-style pointers // Pointers are indicated by the '&' token. As these are not relevant to JavaScript we // drop them here. This may not be the best thing to do, perhaps should leave them in // the parse tree and allow consumers to deal. diff --git a/src/main/types.ts b/src/main/types.ts index f326a96..c0a05ec 100644 --- a/src/main/types.ts +++ b/src/main/types.ts @@ -149,7 +149,7 @@ export type ConstValue = export interface NamespaceDefinition extends PrimarySyntax { type: SyntaxType.NamespaceDefinition - scope: Identifier + scope: NamespaceScope name: Identifier } @@ -318,6 +318,11 @@ export interface Identifier extends SyntaxNode { annotations?: Annotations } +export interface NamespaceScope extends SyntaxNode { + type: SyntaxType.NamespaceScope + value: string +} + export enum ErrorType { ParseError = 'ParseError', ScanError = 'ScanError', @@ -328,6 +333,7 @@ export enum SyntaxType { ThriftErrors = 'ThriftErrors', Identifier = 'Identifier', + NamespaceScope = 'NamespaceScope', FieldID = 'FieldID', // Statements diff --git a/src/tests/parser/fixtures/namespace.thrift b/src/tests/parser/fixtures/namespace.thrift index 79082d4..2b5b05f 100644 --- a/src/tests/parser/fixtures/namespace.thrift +++ b/src/tests/parser/fixtures/namespace.thrift @@ -1,2 +1,3 @@ namespace js test namespace js.ts test +namespace * test diff --git a/src/tests/parser/solutions/namespace.solution.json b/src/tests/parser/solutions/namespace.solution.json index 91d2f54..178149d 100644 --- a/src/tests/parser/solutions/namespace.solution.json +++ b/src/tests/parser/solutions/namespace.solution.json @@ -4,7 +4,7 @@ { "type": "NamespaceDefinition", "scope": { - "type": "Identifier", + "type": "NamespaceScope", "value": "js", "loc": { "start": { @@ -52,7 +52,7 @@ { "type": "NamespaceDefinition", "scope": { - "type": "Identifier", + "type": "NamespaceScope", "value": "js.ts", "loc": { "start": { @@ -96,6 +96,54 @@ "index": 38 } } + }, + { + "type": "NamespaceDefinition", + "scope": { + "type": "NamespaceScope", + "value": "*", + "loc": { + "start": { + "line": 3, + "column": 11, + "index": 49 + }, + "end": { + "line": 3, + "column": 12, + "index": 50 + } + } + }, + "name": { + "type": "Identifier", + "value": "test", + "loc": { + "start": { + "line": 3, + "column": 13, + "index": 51 + }, + "end": { + "line": 3, + "column": 17, + "index": 55 + } + } + }, + "comments": [], + "loc": { + "start": { + "line": 3, + "column": 1, + "index": 39 + }, + "end": { + "line": 3, + "column": 17, + "index": 55 + } + } } ] -} +} \ No newline at end of file