Skip to content

Commit 69198cc

Browse files
committed
chore: apply review suggestions
* pref: optimize `common` rules and matchers * chore: rename diagrams services to short form * chore: sort imports
1 parent 795baed commit 69198cc

22 files changed

+165
-188
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
interface Common {
2+
accDescr?: string;
3+
accTitle?: string;
4+
title?: string;
5+
}
6+
17
fragment TitleAndAccessibilities:
28
((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) NEWLINE+)+
39
;
410

511
terminal NEWLINE: /\r?\n/;
6-
terminal ACC_DESCR: /accDescr(?:[\t ]*:[\t ]*[^\n\r]*?(?=%%)|\s*{[^}]*})|accDescr(?:[\t ]*:[\t ]*[^\n\r]*|\s*{[^}]*})/;
7-
terminal ACC_TITLE: /accTitle[\t ]*:[\t ]*[^\n\r]*?(?=%%)|accTitle[\t ]*:[\t ]*[^\n\r]*/;
8-
terminal TITLE: /title(?:[\t ]+[^\n\r]*?|)(?=%%)|title(?:[\t ]+[^\n\r]*|)/;
12+
terminal ACC_DESCR: /accDescr([\t ]*:[^\n\r]*(?=%%)|\s*{[^}]*})|accDescr([\t ]*:[^\n\r]*|\s*{[^}]*})/;
13+
terminal ACC_TITLE: /accTitle[\t ]*:[^\n\r]*(?=%%)|accTitle[\t ]*:[^\n\r]*/;
14+
terminal TITLE: /title([\t ][^\n\r]*|)(?=%%)|title([\t ][^\n\r]*|)/;
915

1016
hidden terminal WHITESPACE: /[\t ]+/;
11-
// TODO: add YAML_COMMENT hidden rule without interfere actual grammar
1217
hidden terminal YAML: /---[\t ]*\r?\n[\S\s]*?---[\t ]*(?!.)/;
1318
hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%\s*/;
1419
hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/;

packages/parser/src/language/common/commonMatcher.ts

-14
This file was deleted.

packages/parser/src/language/common/commonValueConverters.ts

-74
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
export * from './commonLexer.js';
2-
export * from './commonValueConverters.js';
1+
export * from './lexer.js';
2+
export * from './tokenBuilder.js';
3+
export { MermaidValueConverter } from './valueConverter.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Matches single and multi line accessible description
3+
*/
4+
export const accessibilityDescrRegex = /accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/;
5+
6+
/**
7+
* Matches single line accessible title
8+
*/
9+
export const accessibilityTitleRegex = /accTitle[\t ]*:([^\n\r]*)/;
10+
11+
/**
12+
* Matches a single line title
13+
*/
14+
export const titleRegex = /title(?:[\t ]([^\n\r]*)|)/;

packages/parser/src/language/info/infoTokenBuilder.ts renamed to packages/parser/src/language/common/tokenBuilder.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import { DefaultTokenBuilder } from 'langium';
33

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

6-
export class InfoTokenBuilder extends DefaultTokenBuilder {
6+
export class CommonTokenBuilder extends DefaultTokenBuilder {
7+
private keywords: Set<string>;
8+
9+
public constructor(keywords: string[]) {
10+
super();
11+
this.keywords = new Set<string>(keywords);
12+
}
13+
714
protected override buildKeywordTokens(
815
rules: Stream<GrammarAST.AbstractRule>,
916
terminalTokens: TokenType[],
@@ -12,10 +19,7 @@ export class InfoTokenBuilder extends DefaultTokenBuilder {
1219
const tokenTypes: TokenType[] = super.buildKeywordTokens(rules, terminalTokens, options);
1320
// to restrict users, they mustn't have any non-whitespace characters after the keyword.
1421
tokenTypes.forEach((tokenType: TokenType): void => {
15-
if (
16-
(tokenType.name === 'info' || tokenType.name === 'showInfo') &&
17-
tokenType.PATTERN !== undefined
18-
) {
22+
if (this.keywords.has(tokenType.name) && tokenType.PATTERN !== undefined) {
1923
tokenType.PATTERN = new RegExp(tokenType.PATTERN.toString() + '(?!\\S)');
2024
}
2125
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
2+
import type { CstNode, GrammarAST, ValueType } from 'langium';
3+
import { DefaultValueConverter } from 'langium';
4+
5+
import { accessibilityDescrRegex, accessibilityTitleRegex, titleRegex } from './matcher.js';
6+
7+
const rulesRegexes: Record<string, RegExp> = {
8+
ACC_DESCR: accessibilityDescrRegex,
9+
ACC_TITLE: accessibilityTitleRegex,
10+
TITLE: titleRegex,
11+
};
12+
13+
export abstract class MermaidValueConverter extends DefaultValueConverter {
14+
/**
15+
* A method contains convert logic to be used by class.
16+
*
17+
* @param rule - Parsed rule.
18+
* @param input - Matched string.
19+
* @param cstNode - Node in the Concrete Syntax Tree (CST).
20+
* @returns converted the value if it's available or `undefined` if it's not.
21+
*/
22+
protected abstract runCustomConverter(
23+
rule: GrammarAST.AbstractRule,
24+
input: string,
25+
cstNode: CstNode
26+
): ValueType | undefined;
27+
28+
protected override runConverter(
29+
rule: GrammarAST.AbstractRule,
30+
input: string,
31+
cstNode: CstNode
32+
): ValueType {
33+
let value: ValueType | undefined = this.runCommonConverter(rule, input, cstNode);
34+
35+
if (value === undefined) {
36+
value = this.runCustomConverter(rule, input, cstNode);
37+
}
38+
if (value === undefined) {
39+
return super.runConverter(rule, input, cstNode);
40+
}
41+
42+
return value;
43+
}
44+
45+
private runCommonConverter(
46+
rule: GrammarAST.AbstractRule,
47+
input: string,
48+
_cstNode: CstNode
49+
): ValueType | undefined {
50+
const regex: RegExp | undefined = rulesRegexes[rule.name];
51+
if (regex === undefined) {
52+
return undefined;
53+
}
54+
const match = regex.exec(input);
55+
if (match === null) {
56+
return undefined;
57+
}
58+
// single line title, accTitle, accDescr
59+
if (match[1] !== undefined) {
60+
return match[1].trim().replace(/[\t ]{2,}/gm, ' ');
61+
}
62+
// multi line accDescr
63+
if (match[2] !== undefined) {
64+
return match[2]
65+
.replace(/^\s*/gm, '')
66+
.replace(/\s+$/gm, '')
67+
.replace(/[\t ]{2,}/gm, ' ')
68+
.replace(/[\n\r]{2,}/gm, '\n');
69+
}
70+
return undefined;
71+
}
72+
}
73+
74+
export class CommonValueConverter extends MermaidValueConverter {
75+
protected runCustomConverter(
76+
_rule: GrammarAST.AbstractRule,
77+
_input: string,
78+
_cstNode: CstNode
79+
): ValueType | undefined {
80+
return undefined;
81+
}
82+
}
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './infoModule.js';
1+
export * from './module.js';

packages/parser/src/language/info/infoModule.ts renamed to packages/parser/src/language/info/module.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import type {
77
} from 'langium';
88
import { EmptyFileSystem, createDefaultModule, createDefaultSharedModule, inject } from 'langium';
99

10-
import { MermaidGeneratedSharedModule, InfoGeneratedModule } from '../generated/module.js';
11-
import { CommonLexer } from '../common/commonLexer.js';
12-
import { CommonValueConverter } from '../common/commonValueConverters.js';
13-
import { InfoTokenBuilder } from './infoTokenBuilder.js';
10+
import { CommonLexer } from '../common/lexer.js';
11+
import { CommonValueConverter } from '../common/valueConverter.js';
12+
import { InfoGeneratedModule, MermaidGeneratedSharedModule } from '../generated/module.js';
13+
import { InfoTokenBuilder } from './tokenBuilder.js';
1414

1515
/**
1616
* Declaration of `Info` services.
@@ -34,7 +34,7 @@ export type InfoServices = LangiumServices & InfoAddedServices;
3434
*/
3535
export const InfoModule: Module<InfoServices, PartialLangiumServices & InfoAddedServices> = {
3636
parser: {
37-
Lexer: (services) => new CommonLexer(services),
37+
Lexer: (services: InfoServices) => new CommonLexer(services),
3838
TokenBuilder: () => new InfoTokenBuilder(),
3939
ValueConverter: () => new CommonValueConverter(),
4040
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { CommonTokenBuilder } from '../common/index.js';
2+
3+
export class InfoTokenBuilder extends CommonTokenBuilder {
4+
public constructor() {
5+
super(['info', 'showInfo']);
6+
}
7+
}
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './pieModule.js';
1+
export * from './module.js';

packages/parser/src/language/pie/pieModule.ts renamed to packages/parser/src/language/pie/module.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import type {
77
} from 'langium';
88
import { EmptyFileSystem, createDefaultModule, createDefaultSharedModule, inject } from 'langium';
99

10+
import { CommonLexer } from '../common/lexer.js';
1011
import { MermaidGeneratedSharedModule, PieGeneratedModule } from '../generated/module.js';
11-
import { CommonLexer } from '../common/commonLexer.js';
12-
import { PieTokenBuilder } from './pieTokenBuilder.js';
13-
import { PieValueConverter } from './pieValueConverter.js';
12+
import { PieTokenBuilder } from './tokenBuilder.js';
13+
import { PieValueConverter } from './valueConverter.js';
1414

1515
/**
1616
* Declaration of `Pie` services.
@@ -32,9 +32,9 @@ export type PieServices = LangiumServices & PieAddedServices;
3232
* Dependency injection module that overrides Langium default services and
3333
* contributes the declared `Pie` services.
3434
*/
35-
const PieModule: Module<PieServices, PartialLangiumServices & PieAddedServices> = {
35+
export const PieModule: Module<PieServices, PartialLangiumServices & PieAddedServices> = {
3636
parser: {
37-
Lexer: (services) => new CommonLexer(services),
37+
Lexer: (services: PieServices) => new CommonLexer(services),
3838
TokenBuilder: () => new PieTokenBuilder(),
3939
ValueConverter: () => new PieValueConverter(),
4040
},

packages/parser/src/language/pie/pie.langium

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ entry Pie:
1212
;
1313

1414
PieSection:
15-
label=PIE_SECTION_LABEL ":" value=PIE_SECTION_VALUE
16-
NEWLINE+
15+
label=PIE_SECTION_LABEL ":" value=PIE_SECTION_VALUE NEWLINE+
1716
;
1817

1918
terminal PIE_SECTION_LABEL: /"[^"]+"/;

packages/parser/src/language/pie/pieTokenBuilder.ts

-23
This file was deleted.

packages/parser/src/language/pie/pieValueConverter.ts

-49
This file was deleted.

0 commit comments

Comments
 (0)