Skip to content

Commit

Permalink
chore: apply review suggestions
Browse files Browse the repository at this point in the history
* pref: optimize `common` rules and matchers
* chore: rename diagrams services to short form
* chore: sort imports
  • Loading branch information
Yokozuna59 committed Sep 6, 2023
1 parent 795baed commit 24d4384
Show file tree
Hide file tree
Showing 22 changed files with 165 additions and 188 deletions.
13 changes: 9 additions & 4 deletions packages/parser/src/language/common/common.langium
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
interface Common {
accDescr?: string;
accTitle?: string;
title?: string;
}

fragment TitleAndAccessibilities:
((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) NEWLINE+)+
;

terminal NEWLINE: /\r?\n/;
terminal ACC_DESCR: /accDescr(?:[\t ]*:[\t ]*[^\n\r]*?(?=%%)|\s*{[^}]*})|accDescr(?:[\t ]*:[\t ]*[^\n\r]*|\s*{[^}]*})/;
terminal ACC_TITLE: /accTitle[\t ]*:[\t ]*[^\n\r]*?(?=%%)|accTitle[\t ]*:[\t ]*[^\n\r]*/;
terminal TITLE: /title(?:[\t ]+[^\n\r]*?|)(?=%%)|title(?:[\t ]+[^\n\r]*|)/;
terminal ACC_DESCR: /accDescr([\t ]*:[^\n\r]*(?=%%)|\s*{[^}]*})|accDescr([\t ]*:[^\n\r]*|\s*{[^}]*})/;
terminal ACC_TITLE: /accTitle[\t ]*:[^\n\r]*(?=%%)|accTitle[\t ]*:[^\n\r]*/;
terminal TITLE: /title([\t ][^\n\r]*|)(?=%%)|title([\t ][^\n\r]*|)/;

hidden terminal WHITESPACE: /[\t ]+/;
// TODO: add YAML_COMMENT hidden rule without interfere actual grammar
hidden terminal YAML: /---[\t ]*\r?\n[\S\s]*?---[\t ]*(?!.)/;
hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%\s*/;
hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/;
14 changes: 0 additions & 14 deletions packages/parser/src/language/common/commonMatcher.ts

This file was deleted.

74 changes: 0 additions & 74 deletions packages/parser/src/language/common/commonValueConverters.ts

This file was deleted.

5 changes: 3 additions & 2 deletions packages/parser/src/language/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './commonLexer.js';
export * from './commonValueConverters.js';
export * from './lexer.js';
export * from './tokenBuilder.js';
export { MermaidValueConverter } from './valueConverter.js';
14 changes: 14 additions & 0 deletions packages/parser/src/language/common/matcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Matches single and multi line accessible description
*/
export const accessibilityDescrRegex = /accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/;

/**
* Matches single line accessible title
*/
export const accessibilityTitleRegex = /accTitle[\t ]*:([^\n\r]*)/;

/**
* Matches a single line title
*/
export const titleRegex = /title([\t ][^\n\r]*|)/;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ import { DefaultTokenBuilder } from 'langium';

import type { TokenType } from '../chevrotainWrapper.js';

export class InfoTokenBuilder extends DefaultTokenBuilder {
export class CommonTokenBuilder extends DefaultTokenBuilder {
private keywords: Set<string>;

public constructor(keywords: string[]) {
super();
this.keywords = new Set<string>(keywords);
}

protected override buildKeywordTokens(
rules: Stream<GrammarAST.AbstractRule>,
terminalTokens: TokenType[],
Expand All @@ -12,10 +19,7 @@ export class InfoTokenBuilder extends DefaultTokenBuilder {
const tokenTypes: TokenType[] = super.buildKeywordTokens(rules, terminalTokens, options);
// to restrict users, they mustn't have any non-whitespace characters after the keyword.
tokenTypes.forEach((tokenType: TokenType): void => {
if (
(tokenType.name === 'info' || tokenType.name === 'showInfo') &&
tokenType.PATTERN !== undefined
) {
if (this.keywords.has(tokenType.name) && tokenType.PATTERN !== undefined) {
tokenType.PATTERN = new RegExp(tokenType.PATTERN.toString() + '(?!\\S)');
}
});
Expand Down
82 changes: 82 additions & 0 deletions packages/parser/src/language/common/valueConverter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { CstNode, GrammarAST, ValueType } from 'langium';
import { DefaultValueConverter } from 'langium';

import { accessibilityDescrRegex, accessibilityTitleRegex, titleRegex } from './matcher.js';

const rulesRegexes: Record<string, RegExp> = {
ACC_DESCR: accessibilityDescrRegex,
ACC_TITLE: accessibilityTitleRegex,
TITLE: titleRegex,
};

export abstract class MermaidValueConverter extends DefaultValueConverter {
/**
* A method contains convert logic to be used by class.
*
* @param rule - Parsed rule.
* @param input - Matched string.
* @param cstNode - Node in the Concrete Syntax Tree (CST).
* @returns converted the value if it's available or `undefined` if it's not.
*/
protected abstract runCustomConverter(
rule: GrammarAST.AbstractRule,
input: string,
cstNode: CstNode
): ValueType | undefined;

protected override runConverter(
rule: GrammarAST.AbstractRule,
input: string,
cstNode: CstNode
): ValueType {
let value: ValueType | undefined = this.runCommonConverter(rule, input, cstNode);

if (value === undefined) {
value = this.runCustomConverter(rule, input, cstNode);
}
if (value === undefined) {
return super.runConverter(rule, input, cstNode);
}

return value;
}

private runCommonConverter(
rule: GrammarAST.AbstractRule,
input: string,
_cstNode: CstNode
): ValueType | undefined {
const regex: RegExp | undefined = rulesRegexes[rule.name];
if (regex === undefined) {
return undefined;
}
const match = regex.exec(input);
if (match === null) {
return undefined;
}
// single line title, accTitle, accDescr
if (match[1] !== undefined) {
return match[1].trim().replace(/[\t ]{2,}/gm, ' ');
}
// multi line accDescr
if (match[2] !== undefined) {
return match[2]
.replace(/^\s*/gm, '')
.replace(/\s+$/gm, '')
.replace(/[\t ]{2,}/gm, ' ')
.replace(/[\n\r]{2,}/gm, '\n');
}
return undefined;
}
}

export class CommonValueConverter extends MermaidValueConverter {
protected runCustomConverter(
_rule: GrammarAST.AbstractRule,
_input: string,
_cstNode: CstNode
): ValueType | undefined {
return undefined;
}
}
2 changes: 1 addition & 1 deletion packages/parser/src/language/info/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './infoModule.js';
export * from './module.js';
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import type {
} from 'langium';
import { EmptyFileSystem, createDefaultModule, createDefaultSharedModule, inject } from 'langium';

import { MermaidGeneratedSharedModule, InfoGeneratedModule } from '../generated/module.js';
import { CommonLexer } from '../common/commonLexer.js';
import { CommonValueConverter } from '../common/commonValueConverters.js';
import { InfoTokenBuilder } from './infoTokenBuilder.js';
import { CommonLexer } from '../common/lexer.js';
import { CommonValueConverter } from '../common/valueConverter.js';
import { InfoGeneratedModule, MermaidGeneratedSharedModule } from '../generated/module.js';
import { InfoTokenBuilder } from './tokenBuilder.js';

/**
* Declaration of `Info` services.
Expand All @@ -34,7 +34,7 @@ export type InfoServices = LangiumServices & InfoAddedServices;
*/
export const InfoModule: Module<InfoServices, PartialLangiumServices & InfoAddedServices> = {
parser: {
Lexer: (services) => new CommonLexer(services),
Lexer: (services: InfoServices) => new CommonLexer(services),
TokenBuilder: () => new InfoTokenBuilder(),
ValueConverter: () => new CommonValueConverter(),
},
Expand Down
7 changes: 7 additions & 0 deletions packages/parser/src/language/info/tokenBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { CommonTokenBuilder } from '../common/index.js';

export class InfoTokenBuilder extends CommonTokenBuilder {
public constructor() {
super(['info', 'showInfo']);
}
}
2 changes: 1 addition & 1 deletion packages/parser/src/language/pie/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './pieModule.js';
export * from './module.js';
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import type {
} from 'langium';
import { EmptyFileSystem, createDefaultModule, createDefaultSharedModule, inject } from 'langium';

import { CommonLexer } from '../common/lexer.js';
import { MermaidGeneratedSharedModule, PieGeneratedModule } from '../generated/module.js';
import { CommonLexer } from '../common/commonLexer.js';
import { PieTokenBuilder } from './pieTokenBuilder.js';
import { PieValueConverter } from './pieValueConverter.js';
import { PieTokenBuilder } from './tokenBuilder.js';
import { PieValueConverter } from './valueConverter.js';

/**
* Declaration of `Pie` services.
Expand All @@ -32,9 +32,9 @@ export type PieServices = LangiumServices & PieAddedServices;
* Dependency injection module that overrides Langium default services and
* contributes the declared `Pie` services.
*/
const PieModule: Module<PieServices, PartialLangiumServices & PieAddedServices> = {
export const PieModule: Module<PieServices, PartialLangiumServices & PieAddedServices> = {
parser: {
Lexer: (services) => new CommonLexer(services),
Lexer: (services: PieServices) => new CommonLexer(services),
TokenBuilder: () => new PieTokenBuilder(),
ValueConverter: () => new PieValueConverter(),
},
Expand Down
3 changes: 1 addition & 2 deletions packages/parser/src/language/pie/pie.langium
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ entry Pie:
;

PieSection:
label=PIE_SECTION_LABEL ":" value=PIE_SECTION_VALUE
NEWLINE+
label=PIE_SECTION_LABEL ":" value=PIE_SECTION_VALUE NEWLINE+
;

terminal PIE_SECTION_LABEL: /"[^"]+"/;
Expand Down
23 changes: 0 additions & 23 deletions packages/parser/src/language/pie/pieTokenBuilder.ts

This file was deleted.

49 changes: 0 additions & 49 deletions packages/parser/src/language/pie/pieValueConverter.ts

This file was deleted.

Loading

0 comments on commit 24d4384

Please sign in to comment.