From 015d2bcb74969de16b8c91bf7523719bc812f00c Mon Sep 17 00:00:00 2001 From: Lucas Terra Date: Tue, 28 Jan 2020 11:17:48 +0100 Subject: [PATCH] feat: allow trailing semicolon after typedef --- src/main/parser.ts | 2 + .../fixtures/trailing-semi-colon.thrift | 2 + src/tests/parser/parser.spec.ts | 13 + .../trailing-semi-colon.solution.json | 115 +++++++ .../scanner/fixtures/trailing-semi-colon.txt | 4 + src/tests/scanner/scanner.spec.ts | 10 + .../trailing-semi-colon.solution.json | 306 ++++++++++++++++++ 7 files changed, 452 insertions(+) create mode 100644 src/tests/parser/fixtures/trailing-semi-colon.thrift create mode 100644 src/tests/parser/solutions/trailing-semi-colon.solution.json create mode 100644 src/tests/scanner/fixtures/trailing-semi-colon.txt create mode 100644 src/tests/scanner/solutions/trailing-semi-colon.solution.json diff --git a/src/main/parser.ts b/src/main/parser.ts index 2410f55..c1412e0 100644 --- a/src/main/parser.ts +++ b/src/main/parser.ts @@ -536,6 +536,8 @@ export function createParser( const annotations: Annotations | undefined = parseAnnotations() + readListSeparator() + return { type: SyntaxType.TypedefDefinition, name: createIdentifier(nameToken.text, nameToken.loc), diff --git a/src/tests/parser/fixtures/trailing-semi-colon.thrift b/src/tests/parser/fixtures/trailing-semi-colon.thrift new file mode 100644 index 0000000..3d25fe0 --- /dev/null +++ b/src/tests/parser/fixtures/trailing-semi-colon.thrift @@ -0,0 +1,2 @@ +const string test = 'asdf'; +typedef i32 MyInteger; diff --git a/src/tests/parser/parser.spec.ts b/src/tests/parser/parser.spec.ts index 956d8fa..d4de612 100644 --- a/src/tests/parser/parser.spec.ts +++ b/src/tests/parser/parser.spec.ts @@ -154,6 +154,19 @@ describe('Parser', () => { assert.deepEqual(objectify(thrift), expected) }) + it('should correctly parse the consts and typedefs with trailing-comma', () => { + const content: string = loadSource('trailing-semi-colon') + const scanner: Scanner = createScanner(content) + const tokens: Array = scanner.scan() + + const parser: Parser = createParser(tokens) + const thrift: ThriftDocument = parser.parse() + + const expected: any = loadSolution('trailing-semi-colon') + + assert.deepEqual(objectify(thrift), expected) + }) + it('should correctly parse the syntax of an exception', () => { const content: string = loadSource('exception') const scanner: Scanner = createScanner(content) diff --git a/src/tests/parser/solutions/trailing-semi-colon.solution.json b/src/tests/parser/solutions/trailing-semi-colon.solution.json new file mode 100644 index 0000000..c2c3481 --- /dev/null +++ b/src/tests/parser/solutions/trailing-semi-colon.solution.json @@ -0,0 +1,115 @@ +{ + "type": "ThriftDocument", + "body": [ + { + "type": "ConstDefinition", + "name": { + "type": "Identifier", + "value": "test", + "loc": { + "start": { + "line": 1, + "column": 14, + "index": 13 + }, + "end": { + "line": 1, + "column": 18, + "index": 17 + } + } + }, + "fieldType": { + "type": "StringKeyword", + "loc": { + "start": { + "line": 1, + "column": 7, + "index": 6 + }, + "end": { + "line": 1, + "column": 13, + "index": 12 + } + } + }, + "initializer": { + "type": "StringLiteral", + "value": "asdf", + "loc": { + "start": { + "line": 1, + "column": 21, + "index": 20 + }, + "end": { + "line": 1, + "column": 27, + "index": 26 + } + } + }, + "comments": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "index": 0 + }, + "end": { + "line": 1, + "column": 27, + "index": 26 + } + } + }, + { + "type": "TypedefDefinition", + "name": { + "type": "Identifier", + "value": "MyInteger", + "loc": { + "start": { + "line": 2, + "column": 13, + "index": 40 + }, + "end": { + "line": 2, + "column": 22, + "index": 49 + } + } + }, + "definitionType": { + "type": "I32Keyword", + "loc": { + "start": { + "line": 2, + "column": 9, + "index": 36 + }, + "end": { + "line": 2, + "column": 12, + "index": 39 + } + } + }, + "comments": [], + "loc": { + "start": { + "line": 2, + "column": 1, + "index": 28 + }, + "end": { + "line": 2, + "column": 22, + "index": 49 + } + } + } + ] +} \ No newline at end of file diff --git a/src/tests/scanner/fixtures/trailing-semi-colon.txt b/src/tests/scanner/fixtures/trailing-semi-colon.txt new file mode 100644 index 0000000..278b2c6 --- /dev/null +++ b/src/tests/scanner/fixtures/trailing-semi-colon.txt @@ -0,0 +1,4 @@ +const string test = 'asdf'; +typedef i32 MyInteger; +const string test = 'asdf' +typedef i32 MyInteger diff --git a/src/tests/scanner/scanner.spec.ts b/src/tests/scanner/scanner.spec.ts index 02e395c..ee5c38e 100644 --- a/src/tests/scanner/scanner.spec.ts +++ b/src/tests/scanner/scanner.spec.ts @@ -151,6 +151,16 @@ describe('Scanner', () => { assert.deepEqual(tokens, expected) }) + it('should allow trailing semicolon in const and typedef', () => { + const content = loadSource('trailing-semi-colon') + const scanner: Scanner = createScanner(content) + const tokens: Array = scanner.scan() + + const expected: any = loadSolution('trailing-semi-colon') + + assert.deepEqual(tokens, expected) + }) + it('should correctly handle assignment to a negative number', () => { const content = loadSource('const-number') const scanner: Scanner = createScanner(content) diff --git a/src/tests/scanner/solutions/trailing-semi-colon.solution.json b/src/tests/scanner/solutions/trailing-semi-colon.solution.json new file mode 100644 index 0000000..3f51cd5 --- /dev/null +++ b/src/tests/scanner/solutions/trailing-semi-colon.solution.json @@ -0,0 +1,306 @@ +[ + { + "type": "ConstKeyword", + "text": "const", + "loc": { + "start": { + "line": 1, + "column": 1, + "index": 0 + }, + "end": { + "line": 1, + "column": 6, + "index": 5 + } + } + }, + { + "type": "StringKeyword", + "text": "string", + "loc": { + "start": { + "line": 1, + "column": 7, + "index": 6 + }, + "end": { + "line": 1, + "column": 13, + "index": 12 + } + } + }, + { + "type": "Identifier", + "text": "test", + "loc": { + "start": { + "line": 1, + "column": 14, + "index": 13 + }, + "end": { + "line": 1, + "column": 18, + "index": 17 + } + } + }, + { + "type": "EqualToken", + "text": "", + "loc": { + "start": { + "line": 1, + "column": 19, + "index": 18 + }, + "end": { + "line": 1, + "column": 20, + "index": 19 + } + } + }, + { + "type": "StringLiteral", + "text": "asdf", + "loc": { + "start": { + "line": 1, + "column": 21, + "index": 20 + }, + "end": { + "line": 1, + "column": 27, + "index": 26 + } + } + }, + { + "type": "SemicolonToken", + "text": "", + "loc": { + "start": { + "line": 1, + "column": 27, + "index": 26 + }, + "end": { + "line": 1, + "column": 28, + "index": 27 + } + } + }, + { + "type": "TypedefKeyword", + "text": "typedef", + "loc": { + "start": { + "line": 2, + "column": 1, + "index": 28 + }, + "end": { + "line": 2, + "column": 8, + "index": 35 + } + } + }, + { + "type": "I32Keyword", + "text": "i32", + "loc": { + "start": { + "line": 2, + "column": 9, + "index": 36 + }, + "end": { + "line": 2, + "column": 12, + "index": 39 + } + } + }, + { + "type": "Identifier", + "text": "MyInteger", + "loc": { + "start": { + "line": 2, + "column": 13, + "index": 40 + }, + "end": { + "line": 2, + "column": 22, + "index": 49 + } + } + }, + { + "type": "SemicolonToken", + "text": "", + "loc": { + "start": { + "line": 2, + "column": 22, + "index": 49 + }, + "end": { + "line": 2, + "column": 23, + "index": 50 + } + } + }, + { + "type": "ConstKeyword", + "text": "const", + "loc": { + "start": { + "line": 3, + "column": 1, + "index": 51 + }, + "end": { + "line": 3, + "column": 6, + "index": 56 + } + } + }, + { + "type": "StringKeyword", + "text": "string", + "loc": { + "start": { + "line": 3, + "column": 7, + "index": 57 + }, + "end": { + "line": 3, + "column": 13, + "index": 63 + } + } + }, + { + "type": "Identifier", + "text": "test", + "loc": { + "start": { + "line": 3, + "column": 14, + "index": 64 + }, + "end": { + "line": 3, + "column": 18, + "index": 68 + } + } + }, + { + "type": "EqualToken", + "text": "", + "loc": { + "start": { + "line": 3, + "column": 19, + "index": 69 + }, + "end": { + "line": 3, + "column": 20, + "index": 70 + } + } + }, + { + "type": "StringLiteral", + "text": "asdf", + "loc": { + "start": { + "line": 3, + "column": 21, + "index": 71 + }, + "end": { + "line": 3, + "column": 27, + "index": 77 + } + } + }, + { + "type": "TypedefKeyword", + "text": "typedef", + "loc": { + "start": { + "line": 4, + "column": 1, + "index": 78 + }, + "end": { + "line": 4, + "column": 8, + "index": 85 + } + } + }, + { + "type": "I32Keyword", + "text": "i32", + "loc": { + "start": { + "line": 4, + "column": 9, + "index": 86 + }, + "end": { + "line": 4, + "column": 12, + "index": 89 + } + } + }, + { + "type": "Identifier", + "text": "MyInteger", + "loc": { + "start": { + "line": 4, + "column": 13, + "index": 90 + }, + "end": { + "line": 4, + "column": 22, + "index": 99 + } + } + }, + { + "type": "EOF", + "text": "", + "loc": { + "start": { + "line": 4, + "column": 22, + "index": 100 + }, + "end": { + "line": 5, + "column": 1, + "index": 100 + } + } + } +] \ No newline at end of file