Skip to content

Commit

Permalink
fix: Allow semicolon as object entry separator.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonseyock committed Jul 19, 2021
1 parent 5c89f97 commit d5a3df4
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ export class UnexpectedTypeError extends Error {
}
}

export class InvalidSyntax extends Error {
constructor (message: string) {
super(`Invalid syntax: ${message}`)

Object.setPrototypeOf(this, InvalidSyntax.prototype)
}
}

// export class UnexpectedTokenError extends Error {
// private expected: Token
// private found: Token
Expand Down
1 change: 1 addition & 0 deletions src/lexer/Lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const rules = [
makePunctuationRule('<'),
makePunctuationRule('>'),
makePunctuationRule(','),
makePunctuationRule(';'),
makePunctuationRule('*'),
makePunctuationRule('?'),
makePunctuationRule('!'),
Expand Down
1 change: 1 addition & 0 deletions src/lexer/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type TokenType =
| '&'
| '<'
| '>'
| ';'
| ','
| '*'
| '?'
Expand Down
27 changes: 24 additions & 3 deletions src/parslets/ObjectParslet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PrefixParslet } from './Parslet'
import { TokenType } from '../lexer/Token'
import { Parser } from '../Parser'
import { Precedence } from '../Precedence'
import { UnexpectedTypeError } from '../errors'
import { InvalidSyntax, UnexpectedTypeError } from '../errors'
import { ObjectResult, TerminalResult } from '../result/TerminalResult'

interface ObjectParsletOptions {
Expand All @@ -28,11 +28,16 @@ export class ObjectParslet implements PrefixParslet {
parser.consume('{')
const result: ObjectResult = {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: []
}

if (!parser.consume('}')) {
do {
let separator: 'comma' | 'semicolon' | undefined

while (true) {
let field = parser.parseIntermediateType(Precedence.OBJECT)

let optional = false
Expand Down Expand Up @@ -61,7 +66,23 @@ export class ObjectParslet implements PrefixParslet {
} else {
throw new UnexpectedTypeError(field)
}
} while (parser.consume(','))
if (parser.consume(',')) {
if (separator === 'semicolon') {
throw new InvalidSyntax('Object should use either comma or semicolon, not both.')
}
separator = 'comma'
} else if (parser.consume(';')) {
if (separator === 'comma') {
throw new InvalidSyntax('Object should use either comma or semicolon, not both.')
}
separator = 'semicolon'
} else {
break
}
}

result.meta.separator = separator ?? 'comma'

if (!parser.consume('}')) {
throw new Error('Unterminated record type. Missing \'}\'')
}
Expand Down
3 changes: 3 additions & 0 deletions src/result/TerminalResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ export interface FunctionResult {
export interface ObjectResult {
type: 'JsdocTypeObject'
elements: Array<KeyValueResult | JsdocObjectKeyValueResult>
meta: {
separator: 'comma' | 'semicolon'
}
}

export type SpecialNamePathType = 'module' | 'event' | 'external'
Expand Down
3 changes: 3 additions & 0 deletions src/transforms/identityTransformRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export function identityTransformRules (): TransformRules<NonTerminalResult> {

JsdocTypeObject: (result, transform) => ({
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: result.elements.map(transform) as Array<KeyValueResult | JsdocObjectKeyValueResult>
}),

Expand Down
2 changes: 1 addition & 1 deletion src/transforms/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export function stringifyRules (): TransformRules<string> {

JsdocTypeNumber: result => result.value.toString(),

JsdocTypeObject: (result, transform) => `{${result.elements.map(transform).join(', ')}}`,
JsdocTypeObject: (result, transform) => `{${result.elements.map(transform).join((result.meta.separator === 'comma' ? ',' : ';') + ' ')}}`,

JsdocTypeOptional: (result, transform) => applyPosition(result.meta.position, transform(result.element), '='),

Expand Down
15 changes: 15 additions & 0 deletions test/fixtures/catharsis/jsdoc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@ describe('catharsis jsdoc tests', () => {
input: '{Array.<string>: number}',
expected: {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: [
{
type: 'JsdocTypeKeyValue',
Expand Down Expand Up @@ -823,6 +826,9 @@ describe('catharsis jsdoc tests', () => {
stringified: '{(number | boolean | string): number}',
expected: {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: [
{
type: 'JsdocTypeKeyValue',
Expand Down Expand Up @@ -875,6 +881,9 @@ describe('catharsis jsdoc tests', () => {
stringified: '{undefinedHTML: (string | undefined)}',
expected: {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: [
{
type: 'JsdocTypeKeyValue',
Expand Down Expand Up @@ -925,6 +934,9 @@ describe('catharsis jsdoc tests', () => {
stringified: '{foo: function()}',
expected: {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: [
{
type: 'JsdocTypeKeyValue',
Expand Down Expand Up @@ -965,6 +977,9 @@ describe('catharsis jsdoc tests', () => {
stringified: '{foo: function(): void}',
expected: {
type: 'JsdocTypeObject',
meta: {
separator: 'comma'
},
elements: [
{
type: 'JsdocTypeKeyValue',
Expand Down
Loading

0 comments on commit d5a3df4

Please sign in to comment.