Skip to content

Commit 976e8af

Browse files
authored
Generate errors cause langium-cli to fail with exit code 2 (#1437)
1 parent f3321b6 commit 976e8af

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

packages/langium-cli/src/generate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ export async function generate(options: GenerateOptions): Promise<boolean> {
4545
printSuccess(result);
4646
console.log(getTime() + 'Langium generator will continue running in watch mode.');
4747
await runWatcher(config, options, await allGeneratorFiles(result));
48-
} else {
49-
console.log(`Langium generator finished ${chalk.green.bold('successfully')} in ${elapsedTime()}ms`);
5048
}
49+
// Outside of watch mode, report elapsed time for successful generation.
50+
printSuccess(result);
5151
return result.success;
5252
}
5353

packages/langium-cli/src/langium.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,18 @@ program
1919
.option('-w, --watch', 'enables watch mode', false)
2020
.addOption(new Option('-m, --mode <mode>', 'used mode for optimized builds for your current environment').choices(['development', 'production']))
2121
.action((options: GenerateOptions) => {
22-
generate(options).catch(err => {
23-
console.error(err);
24-
process.exit(1);
25-
});
22+
generate(options)
23+
.then(success => {
24+
if(!success) {
25+
process.exit(2);
26+
}
27+
else {
28+
process.exit(0);
29+
}
30+
}).catch(err => {
31+
console.error(err);
32+
process.exit(1);
33+
});
2634
});
2735

2836
program.command('extract-types')

packages/langium/src/grammar/validation/validator.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import * as ast from '../../languages/generated/ast.js';
2323
import { getTypeNameWithoutError, hasDataTypeReturn, isPrimitiveGrammarType, isStringGrammarType, resolveImport, resolveTransitiveImports } from '../internal-grammar-util.js';
2424
import { typeDefinitionToPropertyType } from '../type-system/type-collector/declared-types.js';
2525
import { flattenPlainType, isPlainReferenceType } from '../type-system/type-collector/plain-types.js';
26+
import { AstUtils } from '../../index.js';
2627

2728
export function registerValidationChecks(services: LangiumGrammarServices): void {
2829
const registry = services.validation.ValidationRegistry;
@@ -687,11 +688,17 @@ export class LangiumGrammarValidator {
687688
}
688689
return result;
689690
};
690-
const isNotAFragment = call.rule.ref !== undefined && !call.rule.ref.fragment;
691-
const appearsMultipleTimes = findContainerWithCardinality(call) !== undefined;
692-
const hasAssignment = call.$container && call.$container.$type === ast.Assignment;
691+
// Locate called rule, ensure it is not a fragment.
692+
const refersToFragment = call.rule.ref !== undefined && call.rule.ref.fragment;
693+
// Data type rules do not cause problems, too.
694+
const callInDataTypeRule = (AstUtils.getContainerOfType(call, ast.isParserRule))?.dataType !== undefined;
695+
if (refersToFragment || callInDataTypeRule) {
696+
return;
697+
}
693698

694-
if (appearsMultipleTimes && !hasAssignment && isNotAFragment) {
699+
const appearsMultipleTimes = findContainerWithCardinality(call) !== undefined;
700+
const hasAssignment = AstUtils.getContainerOfType(call, ast.isAssignment) !== undefined;
701+
if (appearsMultipleTimes && !hasAssignment) {
695702
accept('error', `Rule call ${call.rule.$refText} requires assignment when used with multiplicity.`, {
696703
node: call,
697704
property: 'cardinality'

packages/langium/test/grammar/grammar-validator.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,19 @@ describe('Langium grammar validation', () => {
151151
grammar RuleCallMult
152152
153153
entry List1:
154-
'(' Mult (',' Mult)* ')' '/' List2 '/' List3;
154+
'(' Mult (',' Mult)* ')' '/' List2 '/' List3 '/' List4;
155155
List2:
156156
Plus+;
157157
List3:
158158
Exp+;
159+
// addresses https://github.com/eclipse-langium/langium/pull/1437#pullrequestreview-1994232830
160+
List4:
161+
elems += (Minus | Div);
159162
160163
Mult: content=ID;
161164
Plus: content=ID;
165+
Minus: '-' variable=ID;
166+
Div: 'div' variable=ID;
162167
fragment Exp: content+=ID;
163168
164169
terminal ID: /[_a-zA-Z][\\w_]*/;

0 commit comments

Comments
 (0)