aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-28 00:20:44 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-12-09 00:07:39 +0100
commit0173a4e5deb5dbe71c91a68c02ef88e3de778068 (patch)
tree8498ac382150f59ba626b85827c11dca3c33f880
parentfeat(frontend): scroll beyond last line in editor (diff)
downloadrefinery-0173a4e5deb5dbe71c91a68c02ef88e3de778068.tar.gz
refinery-0173a4e5deb5dbe71c91a68c02ef88e3de778068.tar.zst
refinery-0173a4e5deb5dbe71c91a68c02ef88e3de778068.zip
fix(frontend): content assist error recovery
-rw-r--r--subprojects/frontend/src/language/problem.grammar10
-rw-r--r--subprojects/frontend/src/xtext/ContentAssistService.ts32
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext4
3 files changed, 33 insertions, 13 deletions
diff --git a/subprojects/frontend/src/language/problem.grammar b/subprojects/frontend/src/language/problem.grammar
index f4cf1712..704badab 100644
--- a/subprojects/frontend/src/language/problem.grammar
+++ b/subprojects/frontend/src/language/problem.grammar
@@ -16,6 +16,11 @@
16@top Problem { statement* } 16@top Problem { statement* }
17 17
18statement { 18statement {
19 Assertion {
20 kw<"default">? (NotOp | UnknownOp)? RelationName
21 ParameterList<AssertionArgument>
22 (":" Expr)? "."
23 } |
19 ProblemDeclaration { 24 ProblemDeclaration {
20 kw<"problem"> QualifiedName "." 25 kw<"problem"> QualifiedName "."
21 } | 26 } |
@@ -45,11 +50,6 @@ statement {
45 // RuleName ParameterList<Parameter>? 50 // RuleName ParameterList<Parameter>?
46 // RuleBody { ":" sep<OrOp, Conjunction> "==>" sep<OrOp, Consequent> "." } 51 // RuleBody { ":" sep<OrOp, Conjunction> "==>" sep<OrOp, Consequent> "." }
47 //} | 52 //} |
48 Assertion {
49 kw<"default">? (NotOp | UnknownOp)? RelationName
50 ParameterList<AssertionArgument>
51 (":" Expr)? "."
52 } |
53 IndividualDeclaration { 53 IndividualDeclaration {
54 kw<"indiv"> sep<",", IndividualNodeName> "." 54 kw<"indiv"> sep<",", IndividualNodeName> "."
55 } | 55 } |
diff --git a/subprojects/frontend/src/xtext/ContentAssistService.ts b/subprojects/frontend/src/xtext/ContentAssistService.ts
index fa894e4d..78f61c06 100644
--- a/subprojects/frontend/src/xtext/ContentAssistService.ts
+++ b/subprojects/frontend/src/xtext/ContentAssistService.ts
@@ -33,16 +33,36 @@ interface IFoundToken {
33 33
34function findToken({ pos, state }: CompletionContext): IFoundToken | undefined { 34function findToken({ pos, state }: CompletionContext): IFoundToken | undefined {
35 const token = syntaxTree(state).resolveInner(pos, -1); 35 const token = syntaxTree(state).resolveInner(pos, -1);
36 if (token.firstChild !== null) { 36 const { from } = token;
37 // We only autocomplete terminal nodes. If the current node is nonterminal, 37 if (from > pos) {
38 // returning `undefined` makes us autocomplete with the empty prefix instead. 38 // We haven't found the token we want to complete.
39 // Complete with an empty prefix from `pos` instead.
40 // The other `return undefined;` lines also handle this condition.
41 return undefined;
42 }
43 // We look at the text at the beginning of the token.
44 // For QualifiedName tokens right before a comment, this may be a comment token.
45 const endIndex = token.firstChild?.from ?? token.to;
46 if (pos > endIndex) {
47 return undefined;
48 }
49 const text = state.sliceDoc(from, endIndex).trimEnd();
50 // Due to parser error recovery, we may get spurious whitespace
51 // at the end of the token.
52 const to = from + text.length;
53 if (to > endIndex) {
54 return undefined;
55 }
56 if (from > pos || endIndex < pos) {
57 // We haven't found the token we want to complete.
58 // Complete with an empty prefix from `pos` instead.
39 return undefined; 59 return undefined;
40 } 60 }
41 return { 61 return {
42 from: token.from, 62 from,
43 to: token.to, 63 to,
44 implicitCompletion: token.type.prop(implicitCompletion) || false, 64 implicitCompletion: token.type.prop(implicitCompletion) || false,
45 text: state.sliceDoc(token.from, token.to), 65 text,
46 }; 66 };
47} 67}
48 68
diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
index 95a64737..187ebf1f 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -8,9 +8,9 @@ Problem:
8 statements+=Statement*; 8 statements+=Statement*;
9 9
10Statement: 10Statement:
11 ClassDeclaration | EnumDeclaration | 11 Assertion | ClassDeclaration | EnumDeclaration |
12 PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ 12 PredicateDefinition | FunctionDefinition | /* RuleDefinition | */
13 Assertion | ScopeDeclaration | IndividualDeclaration; 13 ScopeDeclaration | IndividualDeclaration;
14 14
15ClassDeclaration: 15ClassDeclaration:
16 abstract?="abstract"? "class" 16 abstract?="abstract"? "class"