Skip to content

Commit

Permalink
Add codeaction about adding 'entry' keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
pluralia committed Nov 17, 2021
1 parent 5da1cd5 commit f399b6c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
4 changes: 1 addition & 3 deletions packages/langium/src/grammar/grammar-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,7 @@ export function getRuleType(rule: ast.AbstractRule | undefined): string {
}

export function getEntryRule(grammar: ast.Grammar): ast.ParserRule | undefined {
const entryRules = grammar.rules.filter(e => ast.isParserRule(e) && e.entry) as ast.ParserRule[];
// returns undefined if more than 1 entry rules are found
return entryRules.length !== 1 ? undefined : entryRules[0];
return grammar.rules.find(e => ast.isParserRule(e) && e.entry) as ast.ParserRule;
}

export function loadGrammar(json: string): ast.Grammar {
Expand Down
19 changes: 19 additions & 0 deletions packages/langium/src/grammar/langium-grammar-code-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export class LangiumGrammarCodeActionProvider implements CodeActionProvider {
return this.fixHiddenTerminals(diagnostic, document);
case IssueCodes.UseRegexTokens:
return this.fixRegexTokens(diagnostic, document);
case IssueCodes.MakeRuleEntry:
return this.addEntryKeyword(diagnostic, document);
default:
return undefined;
}
Expand Down Expand Up @@ -67,6 +69,23 @@ export class LangiumGrammarCodeActionProvider implements CodeActionProvider {
};
}

private addEntryKeyword(diagnostic: Diagnostic, document: LangiumDocument): CodeAction | undefined {
return {
title: 'Add entry keyword',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {start: diagnostic.range.start, end: diagnostic.range.start},
newText: 'entry '
}]
}
}
};
}

private fixRegexTokens(diagnostic: Diagnostic, document: LangiumDocument): CodeAction | undefined {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
Expand Down
8 changes: 7 additions & 1 deletion packages/langium/src/grammar/langium-grammar-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export namespace IssueCodes {
export const RuleNameUppercase = 'rule-name-uppercase';
export const HiddenGrammarTokens = 'hidden-grammar-tokens';
export const UseRegexTokens = 'use-regex-tokens';
export const MakeRuleEntry = 'make-rule-entry';
}

export class LangiumGrammarValidator {
Expand All @@ -74,7 +75,12 @@ export class LangiumGrammarValidator {
checkEntryGrammarRule(grammar: ast.Grammar, accept: ValidationAcceptor): void {
const entryRules = grammar.rules.filter(e => ast.isParserRule(e) && e.entry) as ast.ParserRule[];
if (entryRules.length === 0) {
accept('error', 'This grammar is missing an entry parser rule.', { node: grammar, property: 'name' });
const possibleEntryRule = grammar.rules.find(e => ast.isParserRule(e) && !isDataTypeRule(e));
if (possibleEntryRule) {
accept('error', 'The grammar is missing an entry parser rule. This rule can be an entry one.', { node: possibleEntryRule, property: 'name', code: IssueCodes.MakeRuleEntry });
} else {
accept('error', 'This grammar is missing an entry parser rule.', { node: grammar, property: 'name' });
}
} else if (entryRules.length > 1) {
entryRules.forEach(rule => accept('error', 'The entry rule has to be unique.', { node: rule, property: 'name' }));
} else if (isDataTypeRule(entryRules[0])) {
Expand Down

0 comments on commit f399b6c

Please sign in to comment.