aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-31 02:06:07 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-10-31 19:26:15 +0100
commitd933f00be208a586143b35d06e689f94a6a6f7e6 (patch)
treed9d1eddd6058a48f5c5189a2d8bb1b77f2ab5579 /language-web/src
parentfix(web): fix server-side content assist filtering (diff)
downloadrefinery-d933f00be208a586143b35d06e689f94a6a6f7e6.tar.gz
refinery-d933f00be208a586143b35d06e689f94a6a6f7e6.tar.zst
refinery-d933f00be208a586143b35d06e689f94a6a6f7e6.zip
feat(web): client support for transformation rules
Diffstat (limited to 'language-web/src')
-rw-r--r--language-web/src/main/js/editor/EditorParent.ts2
-rw-r--r--language-web/src/main/js/index.tsx7
-rw-r--r--language-web/src/main/js/language/folding.ts30
-rw-r--r--language-web/src/main/js/language/indentation.ts5
-rw-r--r--language-web/src/main/js/language/problem.grammar26
-rw-r--r--language-web/src/main/js/language/problemLanguageSupport.ts18
6 files changed, 69 insertions, 19 deletions
diff --git a/language-web/src/main/js/editor/EditorParent.ts b/language-web/src/main/js/editor/EditorParent.ts
index b890ac3c..ee1323f6 100644
--- a/language-web/src/main/js/editor/EditorParent.ts
+++ b/language-web/src/main/js/editor/EditorParent.ts
@@ -127,7 +127,7 @@ export const EditorParent = styled('div')(({ theme }) => {
127 '.cmt-keyword': { 127 '.cmt-keyword': {
128 color: theme.palette.primary.main, 128 color: theme.palette.primary.main,
129 }, 129 },
130 '.cmt-typeName, .cmt-atom': { 130 '.cmt-typeName, .cmt-macroName, .cmt-atom': {
131 color: theme.palette.text.primary, 131 color: theme.palette.text.primary,
132 }, 132 },
133 '.cmt-variableName': { 133 '.cmt-variableName': {
diff --git a/language-web/src/main/js/index.tsx b/language-web/src/main/js/index.tsx
index 595498fc..dfecde37 100644
--- a/language-web/src/main/js/index.tsx
+++ b/language-web/src/main/js/index.tsx
@@ -31,6 +31,13 @@ pred invalidTaxStatus(Person p) <->
31 parent(p, q), 31 parent(p, q),
32 !taxStatus(q, retired). 32 !taxStatus(q, retired).
33 33
34direct rule createChild(p):
35 children(p, newPerson) = unknown,
36 equals(newPerson, newPerson) = unknown
37 ~> new q,
38 children(p, q) = true,
39 taxStatus(q, child) = true.
40
34unique family. 41unique family.
35Family(family). 42Family(family).
36members(family, anne). 43members(family, anne).
diff --git a/language-web/src/main/js/language/folding.ts b/language-web/src/main/js/language/folding.ts
index 54c7294d..5d51f796 100644
--- a/language-web/src/main/js/language/folding.ts
+++ b/language-web/src/main/js/language/folding.ts
@@ -75,18 +75,22 @@ export function foldDeclaration(node: SyntaxNode, state: EditorState): FoldRange
75 * @param node the node to fold 75 * @param node the node to fold
76 * @returns the folding range or `null` is there is nothing to fold 76 * @returns the folding range or `null` is there is nothing to fold
77 */ 77 */
78export function foldConjunction(node: SyntaxNode): FoldRange | null { 78function foldWithSibling(node: SyntaxNode): FoldRange | null {
79 const { parent } = node; 79 const { parent } = node;
80 if (parent === null) { 80 if (parent === null) {
81 return null; 81 return null;
82 } 82 }
83 const { cursor } = parent; 83 const { firstChild } = parent;
84 let nConjunctions = 0; 84 if (firstChild === null) {
85 while (cursor.next()) { 85 return null;
86 }
87 const { cursor } = firstChild;
88 let nSiblings = 0;
89 while (cursor.nextSibling()) {
86 if (cursor.type === node.type) { 90 if (cursor.type === node.type) {
87 nConjunctions += 1; 91 nSiblings += 1;
88 } 92 }
89 if (nConjunctions >= 2) { 93 if (nSiblings >= 2) {
90 return { 94 return {
91 from: node.from, 95 from: node.from,
92 to: node.to, 96 to: node.to,
@@ -95,3 +99,17 @@ export function foldConjunction(node: SyntaxNode): FoldRange | null {
95 } 99 }
96 return null; 100 return null;
97} 101}
102
103export function foldWholeNode(node: SyntaxNode): FoldRange {
104 return {
105 from: node.from,
106 to: node.to,
107 };
108}
109
110export function foldConjunction(node: SyntaxNode): FoldRange | null {
111 if (node.parent?.type?.name === 'PredicateBody') {
112 return foldWithSibling(node);
113 }
114 return foldWholeNode(node);
115}
diff --git a/language-web/src/main/js/language/indentation.ts b/language-web/src/main/js/language/indentation.ts
index 973b4a80..78f0a750 100644
--- a/language-web/src/main/js/language/indentation.ts
+++ b/language-web/src/main/js/language/indentation.ts
@@ -75,10 +75,13 @@ export function indentDeclaration(context: TreeIndentContext): number {
75 return indentDeclarationStrategy(context, 1); 75 return indentDeclarationStrategy(context, 1);
76} 76}
77 77
78export function indentPredicate(context: TreeIndentContext): number { 78export function indentPredicateOrRule(context: TreeIndentContext): number {
79 const clauseIndent = indentDeclarationStrategy(context, 1); 79 const clauseIndent = indentDeclarationStrategy(context, 1);
80 if (/^\s+(;|\.)/.exec(context.textAfter) !== null) { 80 if (/^\s+(;|\.)/.exec(context.textAfter) !== null) {
81 return clauseIndent - 2; 81 return clauseIndent - 2;
82 } 82 }
83 if (/^\s+(~>)/.exec(context.textAfter) !== null) {
84 return clauseIndent - 3;
85 }
83 return clauseIndent; 86 return clauseIndent;
84} 87}
diff --git a/language-web/src/main/js/language/problem.grammar b/language-web/src/main/js/language/problem.grammar
index cf940698..c242a4ba 100644
--- a/language-web/src/main/js/language/problem.grammar
+++ b/language-web/src/main/js/language/problem.grammar
@@ -14,9 +14,15 @@ statement {
14 (EnumBody { "{" sep<",", UniqueNodeName> "}" } | ".") 14 (EnumBody { "{" sep<",", UniqueNodeName> "}" } | ".")
15 } | 15 } |
16 PredicateDefinition { 16 PredicateDefinition {
17 (ckw<"error"> ckw<"pred">? | ckw<"pred">) RelationName ParameterList<Parameter>? 17 (ckw<"error"> ckw<"pred">? | ckw<"direct">? ckw<"pred">)
18 RelationName ParameterList<Parameter>?
18 PredicateBody { ("<->" sep<OrOp, Conjunction>)? "." } 19 PredicateBody { ("<->" sep<OrOp, Conjunction>)? "." }
19 } | 20 } |
21 RuleDefinition {
22 ckw<"direct">? ckw<"rule">
23 RuleName ParameterList<Parameter>?
24 RuleBody { ":" sep<OrOp, Conjunction> "~>" sep<OrOp, Action> "." }
25 } |
20 Assertion { 26 Assertion {
21 ckw<"default">? (NotOp | UnknownOp)? RelationName 27 ckw<"default">? (NotOp | UnknownOp)? RelationName
22 ParameterList<AssertionArgument> (":" LogicValue)? "." 28 ParameterList<AssertionArgument> (":" LogicValue)? "."
@@ -47,9 +53,17 @@ Conjunction { ("," | Literal)+ }
47 53
48OrOp { ";" } 54OrOp { ";" }
49 55
50Literal { NotOp? Atom } 56Literal { NotOp? Atom (("=" | ":") sep1<"|", LogicValue>)? }
57
58Atom { RelationName "+"? ParameterList<Argument> }
51 59
52Atom { RelationName ParameterList<Argument>? } 60Action { ("," | ActionLiteral)+ }
61
62ActionLiteral {
63 ckw<"new"> VariableName |
64 ckw<"delete"> VariableName |
65 Literal
66}
53 67
54Argument { VariableName | Constant } 68Argument { VariableName | Constant }
55 69
@@ -67,6 +81,8 @@ Multiplicity { (IntMult "..")? (IntMult | StarMult)}
67 81
68RelationName { QualifiedName } 82RelationName { QualifiedName }
69 83
84RuleName { QualifiedName }
85
70UniqueNodeName { QualifiedName } 86UniqueNodeName { QualifiedName }
71 87
72VariableName { QualifiedName } 88VariableName { QualifiedName }
@@ -83,7 +99,7 @@ ParameterList<content> { "(" sep<",", content> ")" }
83 99
84sep<separator, content> { sep1<separator, content>? } 100sep<separator, content> { sep1<separator, content>? }
85 101
86sep1<separator, content> { content (separator content?)* } 102sep1<separator, content> { content (separator content)* }
87 103
88@skip { LineComment | BlockComment | whitespace } 104@skip { LineComment | BlockComment | whitespace }
89 105
@@ -123,7 +139,7 @@ sep1<separator, content> { content (separator content?)* }
123 139
124 StarArgument { "*" } 140 StarArgument { "*" }
125 141
126 "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" 142 "{" "}" "(" ")" "[" "]" "." ".." "," ":" "<->" "~>"
127} 143}
128 144
129@detectDelim 145@detectDelim
diff --git a/language-web/src/main/js/language/problemLanguageSupport.ts b/language-web/src/main/js/language/problemLanguageSupport.ts
index 80d25d71..ab1c55f9 100644
--- a/language-web/src/main/js/language/problemLanguageSupport.ts
+++ b/language-web/src/main/js/language/problemLanguageSupport.ts
@@ -14,11 +14,12 @@ import {
14 foldBlockComment, 14 foldBlockComment,
15 foldConjunction, 15 foldConjunction,
16 foldDeclaration, 16 foldDeclaration,
17 foldWholeNode,
17} from './folding'; 18} from './folding';
18import { 19import {
19 indentBlockComment, 20 indentBlockComment,
20 indentDeclaration, 21 indentDeclaration,
21 indentPredicate, 22 indentPredicateOrRule,
22} from './indentation'; 23} from './indentation';
23 24
24const parserWithMetadata = (parser as LRParser).configure({ 25const parserWithMetadata = (parser as LRParser).configure({
@@ -26,9 +27,10 @@ const parserWithMetadata = (parser as LRParser).configure({
26 styleTags({ 27 styleTags({
27 LineComment: t.lineComment, 28 LineComment: t.lineComment,
28 BlockComment: t.blockComment, 29 BlockComment: t.blockComment,
29 'problem class enum pred unique scope': t.definitionKeyword, 30 'problem class enum pred rule unique scope': t.definitionKeyword,
30 'abstract extends refers contains opposite error default': t.modifier, 31 'abstract extends refers contains opposite error direct default': t.modifier,
31 'true false unknown error': t.keyword, 32 'true false unknown error': t.keyword,
33 'new delete': t.operatorKeyword,
32 NotOp: t.keyword, 34 NotOp: t.keyword,
33 UnknownOp: t.keyword, 35 UnknownOp: t.keyword,
34 OrOp: t.keyword, 36 OrOp: t.keyword,
@@ -37,19 +39,21 @@ const parserWithMetadata = (parser as LRParser).configure({
37 StarMult: t.number, 39 StarMult: t.number,
38 String: t.string, 40 String: t.string,
39 'RelationName/QualifiedName': t.typeName, 41 'RelationName/QualifiedName': t.typeName,
42 'RuleName/QualifiedName': t.macroName,
40 'UniqueNodeName/QualifiedName': t.atom, 43 'UniqueNodeName/QualifiedName': t.atom,
41 'VariableName/QualifiedName': t.variableName, 44 'VariableName/QualifiedName': t.variableName,
42 '{ }': t.brace, 45 '{ }': t.brace,
43 '( )': t.paren, 46 '( )': t.paren,
44 '[ ]': t.squareBracket, 47 '[ ]': t.squareBracket,
45 '. .. , :': t.separator, 48 '. .. , :': t.separator,
46 '<->': t.definitionOperator, 49 '<-> ~>': t.definitionOperator,
47 }), 50 }),
48 indentNodeProp.add({ 51 indentNodeProp.add({
49 ProblemDeclaration: indentDeclaration, 52 ProblemDeclaration: indentDeclaration,
50 UniqueDeclaration: indentDeclaration, 53 UniqueDeclaration: indentDeclaration,
51 ScopeDeclaration: indentDeclaration, 54 ScopeDeclaration: indentDeclaration,
52 PredicateBody: indentPredicate, 55 PredicateBody: indentPredicateOrRule,
56 RuleBody: indentPredicateOrRule,
53 BlockComment: indentBlockComment, 57 BlockComment: indentBlockComment,
54 }), 58 }),
55 foldNodeProp.add({ 59 foldNodeProp.add({
@@ -57,7 +61,9 @@ const parserWithMetadata = (parser as LRParser).configure({
57 EnumBody: foldInside, 61 EnumBody: foldInside,
58 ParameterList: foldInside, 62 ParameterList: foldInside,
59 PredicateBody: foldInside, 63 PredicateBody: foldInside,
64 RuleBody: foldInside,
60 Conjunction: foldConjunction, 65 Conjunction: foldConjunction,
66 Action: foldWholeNode,
61 UniqueDeclaration: foldDeclaration, 67 UniqueDeclaration: foldDeclaration,
62 ScopeDeclaration: foldDeclaration, 68 ScopeDeclaration: foldDeclaration,
63 BlockComment: foldBlockComment, 69 BlockComment: foldBlockComment,
@@ -75,7 +81,7 @@ const problemLanguage = LRLanguage.define({
75 }, 81 },
76 line: '%', 82 line: '%',
77 }, 83 },
78 indentOnInput: /^\s*(?:\{|\}|\(|\)|;|\.)$/, 84 indentOnInput: /^\s*(?:\{|\}|\(|\)|;|\.|~>)$/,
79 }, 85 },
80}); 86});
81 87