Skip to content

Commit

Permalink
Generate errors cause langium-cli to fail with exit code 2 (#1437)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjthehun authored Apr 15, 2024
1 parent f3321b6 commit 976e8af
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 11 deletions.
4 changes: 2 additions & 2 deletions packages/langium-cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ export async function generate(options: GenerateOptions): Promise<boolean> {
printSuccess(result);
console.log(getTime() + 'Langium generator will continue running in watch mode.');
await runWatcher(config, options, await allGeneratorFiles(result));
} else {
console.log(`Langium generator finished ${chalk.green.bold('successfully')} in ${elapsedTime()}ms`);
}
// Outside of watch mode, report elapsed time for successful generation.
printSuccess(result);
return result.success;
}

Expand Down
16 changes: 12 additions & 4 deletions packages/langium-cli/src/langium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ program
.option('-w, --watch', 'enables watch mode', false)
.addOption(new Option('-m, --mode <mode>', 'used mode for optimized builds for your current environment').choices(['development', 'production']))
.action((options: GenerateOptions) => {
generate(options).catch(err => {
console.error(err);
process.exit(1);
});
generate(options)
.then(success => {
if(!success) {
process.exit(2);
}
else {
process.exit(0);
}
}).catch(err => {
console.error(err);
process.exit(1);
});
});

program.command('extract-types')
Expand Down
15 changes: 11 additions & 4 deletions packages/langium/src/grammar/validation/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as ast from '../../languages/generated/ast.js';
import { getTypeNameWithoutError, hasDataTypeReturn, isPrimitiveGrammarType, isStringGrammarType, resolveImport, resolveTransitiveImports } from '../internal-grammar-util.js';
import { typeDefinitionToPropertyType } from '../type-system/type-collector/declared-types.js';
import { flattenPlainType, isPlainReferenceType } from '../type-system/type-collector/plain-types.js';
import { AstUtils } from '../../index.js';

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

if (appearsMultipleTimes && !hasAssignment && isNotAFragment) {
const appearsMultipleTimes = findContainerWithCardinality(call) !== undefined;
const hasAssignment = AstUtils.getContainerOfType(call, ast.isAssignment) !== undefined;
if (appearsMultipleTimes && !hasAssignment) {
accept('error', `Rule call ${call.rule.$refText} requires assignment when used with multiplicity.`, {
node: call,
property: 'cardinality'
Expand Down
7 changes: 6 additions & 1 deletion packages/langium/test/grammar/grammar-validator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,19 @@ describe('Langium grammar validation', () => {
grammar RuleCallMult
entry List1:
'(' Mult (',' Mult)* ')' '/' List2 '/' List3;
'(' Mult (',' Mult)* ')' '/' List2 '/' List3 '/' List4;
List2:
Plus+;
List3:
Exp+;
// addresses https://github.com/eclipse-langium/langium/pull/1437#pullrequestreview-1994232830
List4:
elems += (Minus | Div);
Mult: content=ID;
Plus: content=ID;
Minus: '-' variable=ID;
Div: 'div' variable=ID;
fragment Exp: content+=ID;
terminal ID: /[_a-zA-Z][\\w_]*/;
Expand Down

0 comments on commit 976e8af

Please sign in to comment.