Skip to content

Commit

Permalink
langium generate: fixed a hidden bug in 'node-processor.ts' of Langiu…
Browse files Browse the repository at this point in the history
…m's 'generate' facility

* added some test cases
* extended 'Vitest: Run Selected File' launch config
* brought config of the Vitest VSCode extension closer to the Vitest setup in 'vite.config.mts'
  • Loading branch information
sailingKieler committed Feb 19, 2025
1 parent 87cbe24 commit 1df3bcf
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@
"args": ["run", "${relativeFile}"],
"smartStep": true,
"console": "integratedTerminal",
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/packages/vscode-uri/lib/**/*.js",
"${workspaceFolder}/packages/langium/lib/**/*.js"
]
}
]
}
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"javascript",
"typescript"
],
"vitest.enable": true,
"vitest.configSearchPatternExclude": "{**/node_modules/**,**/dist/**,**/generated/**,**/templates/**,**/examples/hello*/**,**/.*/**,**/*.d.ts}",
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
Expand Down
23 changes: 11 additions & 12 deletions packages/langium/src/generate/node-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ class Context {
this.length -= this.lines[this.currentLineNumber].join('').length;
this.lines[this.currentLineNumber] = [];
this.pendingIndent = true;
this.recentNonImmediateIndents.length = 0;
}

addNewLine() {
this.pendingIndent = true;
this.lines.push([]);
this.pendingIndent = true;
this.recentNonImmediateIndents.length = 0;
}

Expand Down Expand Up @@ -228,20 +229,20 @@ function hasContent(node: GeneratorNode | string, ctx: Context): boolean {

function processStringNode(node: string, context: Context) {
if (node) {
if (context.pendingIndent) {
handlePendingIndent(context, false);
}
handlePendingIndent(context, false);
context.append(node);
}
}

function handlePendingIndent(ctx: Context, endOfLine: boolean) {
let indent = '';
for (const indentNode of ctx.relevantIndents.filter(e => e.indentEmptyLines || !endOfLine)) {
indent += indentNode.indentation ?? ctx.defaultIndentation;
if (ctx.pendingIndent) {
let indent = '';
for (const indentNode of ctx.relevantIndents.filter(e => e.indentEmptyLines || !endOfLine)) {
indent += indentNode.indentation ?? ctx.defaultIndentation;
}
ctx.append(indent, true);
ctx.pendingIndent = false;
}
ctx.append(indent, true);
ctx.pendingIndent = false;
}

function processCompositeNode(node: CompositeGeneratorNode, context: Context) {
Expand Down Expand Up @@ -288,9 +289,7 @@ function processNewLineNode(node: NewLineNode, context: Context) {
if (node.ifNotEmpty && !hasNonWhitespace(context.currentLineContent)) {
context.resetCurrentLine();
} else {
if (context.pendingIndent) {
handlePendingIndent(context, true);
}
handlePendingIndent(context, true);
context.append(node.lineDelimiter);
context.addNewLine();
}
Expand Down
16 changes: 16 additions & 0 deletions packages/langium/test/generate/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,22 @@ describe('indentation', () => {
expect(process(comp, '\t')).toBe(`No indent${EOL}\tIndent {${EOL}\t}${EOL}`);
});

test('should indent nested template starting with a new line with \'ifNotEmpty\', with \'indentImmediately: false\'', () => {
const comp = new CompositeGeneratorNode();
comp.append('No indent', NL);
comp.indent({
indentImmediately: false,
indentedChildren: [
'\t',
NLEmpty,
'Indented',
NL,
'Indented',
NL
]
});
expect(process(comp, '\t')).toBe(`No indent${EOL}\tIndented${EOL}\tIndented${EOL}`);
});
});

describe('composite', () => {
Expand Down
52 changes: 51 additions & 1 deletion packages/langium/test/generate/template-node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -832,9 +832,47 @@ describe('Multiple nested substitution templates', () => {
generated text!
`);
});

test('Nested substitution of with indented nested template starting with an _undefined_ line', () => {
expect(
toString(n`
begin:
${n`
${undefined}
${nestedNode}
`}
`)
).toBe(
s`
begin:
More
generated text!
`
);
});

test('Nested substitution of with indented nested template starting with an _empty string_ line', () => {
expect(
toString(n`
begin:
${n`
${''}
${nestedNode}
`}
`)
).toBe(
s`
begin:
${/* 's' automatically trims the empty lines completely, so insert */'<DUMMY>'}
More
generated text!
`.replace('<DUMMY>', '')
);
});

});

describe('Embedded forEach loops', () => {
describe('Joining lists', () => {
test('ForEach loop with empty iterable', () => {
const node = n`
Data:
Expand Down Expand Up @@ -1083,6 +1121,18 @@ describe('Embedded forEach loops', () => {
b
`);
});

test('Nested ForEach loop with empty iterable followed by an indented line', () => {
const node = n`
${joinToNode([], { appendNewLineIfNotEmpty: true})}
a
`;
const text = toString(node);
expect(text).toBe(s`
a
`);
});

});

describe('Appending templates to existing nodes', () => {
Expand Down

0 comments on commit 1df3bcf

Please sign in to comment.