@xano/xanoscript-language-server 11.5.0 → 11.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +12 -0
- package/lexer/literal.js +1 -1
- package/onDidChangeContent/onDidChangeContent.js +4 -4
- package/onHover/onHoverDocument.js +3 -3
- package/onSemanticCheck/highlight.js +3 -3
- package/onSemanticCheck/onSemanticCheck.js +1 -1
- package/package.json +1 -1
- package/parser/agent_parser.js +7 -9
- package/parser/api_group_parser.js +10 -23
- package/parser/clauses/cacheClause.js +9 -10
- package/parser/functions/util/utilGetRawInputFn.js +1 -1
- package/parser/functions/util/utilGetRawInputFn.spec.js +7 -0
- package/parser/functions/varFn.js +39 -2
- package/parser/functions/varFn.spec.js +21 -0
- package/parser/generic/assignableVariableProperty.js +40 -3
- package/parser/generic/completeEnvVariable.js +1 -1
- package/parser/generic/completeEnvVariable.spec.js +5 -0
- package/parser/generic/expressionFn.spec.js +9 -4
- package/parser/generic/register.js +10 -22
- package/parser/mcp_server_parser.js +7 -9
- package/parser/mcp_server_trigger_parser.js +2 -6
- package/parser/realtime_trigger_parser.js +3 -7
- package/parser/table_trigger_parser.js +9 -11
- package/parser/test_parser.js +0 -4
- package/parser/workspace_trigger_parser.js +4 -8
- package/server.js +2 -2
- package/parser/generic/arrayOfObjectAttrReq.js +0 -47
- package/parser/generic/arrayOfObjectAttrReq.spec.js +0 -254
- package/parser/generic/arrayOfStringLiterals.js +0 -45
- package/parser/generic/arrayOfStringLiterals.spec.js +0 -56
- package/parser/generic/objectAttrReq.js +0 -243
- package/parser/generic/objectAttrReq.spec.js +0 -412
|
@@ -44,18 +44,14 @@ export function tableTriggerDeclaration($) {
|
|
|
44
44
|
const subParent = $.CONSUME(ActionsToken); // "actions"
|
|
45
45
|
$.CONSUME(EqualToken); // "="
|
|
46
46
|
|
|
47
|
-
$.SUBRULE($.
|
|
47
|
+
$.SUBRULE($.schemaParseObjectFn, {
|
|
48
48
|
ARGS: [
|
|
49
49
|
subParent,
|
|
50
|
-
[], // required
|
|
51
|
-
["delete", "insert", "truncate", "update"], // optional
|
|
52
50
|
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
update: "boolean",
|
|
58
|
-
},
|
|
51
|
+
"delete?": "[boolean]",
|
|
52
|
+
"insert?": "[boolean]",
|
|
53
|
+
"truncate?": "[boolean]",
|
|
54
|
+
"update?": "[boolean]",
|
|
59
55
|
},
|
|
60
56
|
],
|
|
61
57
|
});
|
|
@@ -74,9 +70,11 @@ export function tableTriggerDeclaration($) {
|
|
|
74
70
|
GATE: () => !hasDatasources,
|
|
75
71
|
ALT: () => {
|
|
76
72
|
hasDatasources = true;
|
|
77
|
-
$.CONSUME(DatasourcesToken);
|
|
73
|
+
const parent = $.CONSUME(DatasourcesToken);
|
|
78
74
|
$.CONSUME3(EqualToken);
|
|
79
|
-
$.SUBRULE($.
|
|
75
|
+
$.SUBRULE($.schemaFn, {
|
|
76
|
+
ARGS: [parent, ["[string]"]],
|
|
77
|
+
});
|
|
80
78
|
},
|
|
81
79
|
},
|
|
82
80
|
{
|
package/parser/test_parser.js
CHANGED
|
@@ -7,9 +7,7 @@ import { parserExtension as schemaParseConstantFnExtension } from "./functions/s
|
|
|
7
7
|
import { parserExtension as schemaParseEnumFnExtension } from "./functions/schema/schemaParseEnum.spec.js";
|
|
8
8
|
import { parserExtension as schemaParseImmutableFnExtension } from "./functions/schema/schemaParseImmutableFn.spec.js";
|
|
9
9
|
import { parserExtension as schemaParseObjectFnExtension } from "./functions/schema/schemaParseObjectFn.spec.js";
|
|
10
|
-
import { parserExtension as arrayOfObjectAttrReqExtension } from "./generic/arrayOfObjectAttrReq.spec.js";
|
|
11
10
|
import { parserExtension as functionAttrReqExtension } from "./generic/functionAttrReq.spec.js";
|
|
12
|
-
import { parserExtension as objectAttrReqExtension } from "./generic/objectAttrReq.spec.js";
|
|
13
11
|
import { parserExtension as objectWithAttributesExtension } from "./generic/objectWithAttributes.spec.js";
|
|
14
12
|
|
|
15
13
|
/**
|
|
@@ -26,9 +24,7 @@ class TestParser extends XanoBaseParser {
|
|
|
26
24
|
schemaParseObjectFnExtension.bind(this)();
|
|
27
25
|
schemaParseEnumFnExtension.bind(this)();
|
|
28
26
|
schemaParseImmutableFnExtension.bind(this)();
|
|
29
|
-
arrayOfObjectAttrReqExtension.bind(this)();
|
|
30
27
|
functionAttrReqExtension.bind(this)();
|
|
31
|
-
objectAttrReqExtension.bind(this)();
|
|
32
28
|
objectWithAttributesExtension.bind(this)();
|
|
33
29
|
schemaParseAttributeFnExtension.bind(this)();
|
|
34
30
|
|
|
@@ -39,17 +39,13 @@ export function workspaceTriggerDeclaration($) {
|
|
|
39
39
|
const subParent = $.CONSUME(ActionsToken); // "actions"
|
|
40
40
|
$.CONSUME(EqualToken); // "="
|
|
41
41
|
|
|
42
|
-
$.SUBRULE($.
|
|
42
|
+
$.SUBRULE($.schemaParseObjectFn, {
|
|
43
43
|
ARGS: [
|
|
44
44
|
subParent,
|
|
45
|
-
[], // required
|
|
46
|
-
["branch_live", "branch_merge", "branch_new"], // optional
|
|
47
45
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
branch_new: "boolean",
|
|
52
|
-
},
|
|
46
|
+
"branch_live?": "[boolean]",
|
|
47
|
+
"branch_merge?": "[boolean]",
|
|
48
|
+
"branch_new?": "[boolean]",
|
|
53
49
|
},
|
|
54
50
|
],
|
|
55
51
|
});
|
package/server.js
CHANGED
|
@@ -44,10 +44,10 @@ connection.onInitialize(() => {
|
|
|
44
44
|
connection.onHover((params) => onHover(params, documents));
|
|
45
45
|
connection.onCompletion((params) => onCompletion(params, documents));
|
|
46
46
|
connection.onRequest("textDocument/semanticTokens/full", (params) =>
|
|
47
|
-
onSemanticCheck(params, documents, SemanticTokensBuilder)
|
|
47
|
+
onSemanticCheck(params, documents, SemanticTokensBuilder),
|
|
48
48
|
);
|
|
49
49
|
documents.onDidChangeContent((params) =>
|
|
50
|
-
onDidChangeContent(params, connection)
|
|
50
|
+
onDidChangeContent(params, connection),
|
|
51
51
|
);
|
|
52
52
|
connection.onDidOpenTextDocument((params) => {
|
|
53
53
|
console.log("Document opened:", params.textDocument.uri);
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { CommaToken, LSquare, RSquare } from "../../lexer/control.js";
|
|
2
|
-
import { NewlineToken } from "../../lexer/tokens.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* see objectAttrReq signature for arrayOfObjectAttrReq arguments details
|
|
6
|
-
* @param {import('../base_parser.js').XanoBaseParser} $
|
|
7
|
-
*/
|
|
8
|
-
export function arrayOfObjectAttrReq($) {
|
|
9
|
-
/**
|
|
10
|
-
* @param {import('chevrotain').Rule} rule
|
|
11
|
-
**/
|
|
12
|
-
return (parent, required, optional, options = {}) => {
|
|
13
|
-
$.CONSUME(LSquare); // "["
|
|
14
|
-
$.OPTION(() => {
|
|
15
|
-
$.OR([
|
|
16
|
-
// multi line, each value on a new line
|
|
17
|
-
{
|
|
18
|
-
ALT: () => {
|
|
19
|
-
$.CONSUME(NewlineToken);
|
|
20
|
-
$.AT_LEAST_ONE(() => {
|
|
21
|
-
$.SUBRULE($.objectAttrReq, {
|
|
22
|
-
ARGS: [parent, required, optional, options],
|
|
23
|
-
});
|
|
24
|
-
$.OPTION1(() => $.CONSUME(CommaToken)); // optional comma
|
|
25
|
-
$.AT_LEAST_ONE1(() => $.CONSUME3(NewlineToken));
|
|
26
|
-
});
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
// one line, comma separated [ ..., ... ]
|
|
30
|
-
{
|
|
31
|
-
ALT: () => {
|
|
32
|
-
$.AT_LEAST_ONE_SEP({
|
|
33
|
-
SEP: CommaToken,
|
|
34
|
-
DEF: () => {
|
|
35
|
-
$.SUBRULE1($.objectAttrReq, {
|
|
36
|
-
ARGS: [parent, required, optional, options],
|
|
37
|
-
});
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
$.MANY(() => $.CONSUME2(NewlineToken));
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
]);
|
|
44
|
-
});
|
|
45
|
-
$.CONSUME(RSquare); // "]"
|
|
46
|
-
};
|
|
47
|
-
}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import { describe, it } from "mocha";
|
|
3
|
-
import { EqualToken } from "../../lexer/control.js";
|
|
4
|
-
import { lexDocument } from "../../lexer/lexer.js";
|
|
5
|
-
import { Identifier } from "../../lexer/tokens.js";
|
|
6
|
-
import { parser } from "../test_parser.js";
|
|
7
|
-
|
|
8
|
-
export function parserExtension() {
|
|
9
|
-
// this rule requires a foo field to be defined
|
|
10
|
-
this.arrayOfObjectAttrReq_test_required = this.RULE(
|
|
11
|
-
"arrayOfObjectAttrReq_test_required",
|
|
12
|
-
() => {
|
|
13
|
-
const name = this.CONSUME(Identifier);
|
|
14
|
-
this.CONSUME(EqualToken); // "="
|
|
15
|
-
this.SUBRULE(this.arrayOfObjectAttrReq, { ARGS: [name, ["foo"]] });
|
|
16
|
-
}
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
this.arrayOfObjectAttrReq_test_optionals = this.RULE(
|
|
20
|
-
"arrayOfObjectAttrReq_test_optionals",
|
|
21
|
-
() => {
|
|
22
|
-
const name = this.CONSUME(Identifier);
|
|
23
|
-
this.CONSUME(EqualToken); // "="
|
|
24
|
-
this.SUBRULE(this.arrayOfObjectAttrReq, {
|
|
25
|
-
ARGS: [name, [], ["foo", "bar"]],
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
this.arrayOfObjectAttrReq_test_index = this.RULE(
|
|
31
|
-
"arrayOfObjectAttrReq_test_index",
|
|
32
|
-
() => {
|
|
33
|
-
const parent = this.CONSUME(Identifier);
|
|
34
|
-
this.CONSUME(EqualToken); // "="
|
|
35
|
-
this.SUBRULE(this.arrayOfObjectAttrReq, {
|
|
36
|
-
ARGS: [
|
|
37
|
-
parent,
|
|
38
|
-
["type", "field"],
|
|
39
|
-
[],
|
|
40
|
-
{
|
|
41
|
-
types: {
|
|
42
|
-
type: "string",
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
this.arrayOfObjectAttrReq_test_recursive_value = this.RULE(
|
|
51
|
-
"test_recursive_value",
|
|
52
|
-
() => {
|
|
53
|
-
const name = this.CONSUME(Identifier);
|
|
54
|
-
this.CONSUME(EqualToken); // "="
|
|
55
|
-
this.SUBRULE(this.arrayOfObjectAttrReq, {
|
|
56
|
-
ARGS: [
|
|
57
|
-
name,
|
|
58
|
-
["name", "as", "input"],
|
|
59
|
-
["addon"],
|
|
60
|
-
{ recursive: ["addon"] },
|
|
61
|
-
],
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
);
|
|
65
|
-
this.arrayOfObjectAttrReq_test_recursive_array_addon = this.RULE(
|
|
66
|
-
"test_recursive_array_addon",
|
|
67
|
-
() => {
|
|
68
|
-
const name = this.CONSUME(Identifier);
|
|
69
|
-
this.CONSUME(EqualToken); // "="
|
|
70
|
-
this.SUBRULE(this.arrayOfObjectAttrReq, {
|
|
71
|
-
ARGS: [
|
|
72
|
-
name,
|
|
73
|
-
["name", "as", "input"],
|
|
74
|
-
["addon"],
|
|
75
|
-
{ recursiveArray: ["addon"] },
|
|
76
|
-
],
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function parse(inputText) {
|
|
83
|
-
parser.reset();
|
|
84
|
-
const lexResult = lexDocument(inputText);
|
|
85
|
-
parser.input = lexResult.tokens;
|
|
86
|
-
return parser;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
describe("arrayOfObjectAttrReq", () => {
|
|
90
|
-
it("arrayOfObjectAttrReq accepts required attribute", () => {
|
|
91
|
-
parse(`something = [ {foo: "true"}]`).arrayOfObjectAttrReq_test_required();
|
|
92
|
-
expect(parser.errors).to.be.empty;
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("arrayOfObjectAttrReq accepts multilines attributes", () => {
|
|
96
|
-
parse(`something = [
|
|
97
|
-
{
|
|
98
|
-
foo: true
|
|
99
|
-
bar: 12
|
|
100
|
-
}
|
|
101
|
-
]`).arrayOfObjectAttrReq_test_optionals();
|
|
102
|
-
expect(parser.errors).to.be.empty;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it("arrayOfObjectAttrReq accepts list of single lines", () => {
|
|
106
|
-
parse(`something = [
|
|
107
|
-
{foo: true, bar: 12}
|
|
108
|
-
]`).arrayOfObjectAttrReq_test_optionals();
|
|
109
|
-
expect(parser.errors).to.be.empty;
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it("arrayOfObjectAttrReq accepts multiple values", () => {
|
|
113
|
-
parse(`something = [
|
|
114
|
-
{
|
|
115
|
-
foo: true
|
|
116
|
-
}
|
|
117
|
-
{
|
|
118
|
-
bar: 12
|
|
119
|
-
}
|
|
120
|
-
]`).arrayOfObjectAttrReq_test_optionals();
|
|
121
|
-
expect(parser.errors).to.be.empty;
|
|
122
|
-
|
|
123
|
-
parse(
|
|
124
|
-
`something = [{ foo: true }, {bar: 12}]`
|
|
125
|
-
).arrayOfObjectAttrReq_test_optionals();
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("arrayOfObjectAttrReq detects missing required attribute", () => {
|
|
129
|
-
parse(`something = [ {}]`).arrayOfObjectAttrReq_test_required();
|
|
130
|
-
expect(parser.errors).to.not.be.empty;
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it("arrayOfObjectAttrReq allow for recursive definition", () => {
|
|
134
|
-
parse(`addon = [
|
|
135
|
-
{
|
|
136
|
-
name : "client"
|
|
137
|
-
as : "_client"
|
|
138
|
-
input: {client_id: ""}
|
|
139
|
-
addon: {
|
|
140
|
-
name : "client"
|
|
141
|
-
as : "_client"
|
|
142
|
-
input: {client_id: ""}
|
|
143
|
-
addon: {
|
|
144
|
-
name : "client"
|
|
145
|
-
as : "_client"
|
|
146
|
-
input: {client_id: ""}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
]`).arrayOfObjectAttrReq_test_recursive_value();
|
|
151
|
-
expect(parser.errors).to.be.empty;
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("arrayOfObjectAttrReq detects missing definition on recursive attributes", () => {
|
|
155
|
-
parse(`addon = [
|
|
156
|
-
{
|
|
157
|
-
name : "client"
|
|
158
|
-
as : "_client"
|
|
159
|
-
input: {client_id: ""}
|
|
160
|
-
addon: {
|
|
161
|
-
name : "client"
|
|
162
|
-
input: {client_id: ""}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
]`).arrayOfObjectAttrReq_test_recursive_value();
|
|
166
|
-
expect(parser.errors).to.not.be.empty;
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("arrayOfObjectAttrReq allow for recursive array", () => {
|
|
170
|
-
parse(`addon = [
|
|
171
|
-
{
|
|
172
|
-
name : "client"
|
|
173
|
-
as : "_client"
|
|
174
|
-
input: {client_id: ""}
|
|
175
|
-
addon: [
|
|
176
|
-
{
|
|
177
|
-
name : "client"
|
|
178
|
-
as : "_client"
|
|
179
|
-
input: {client_id: ""}
|
|
180
|
-
addon: [
|
|
181
|
-
{
|
|
182
|
-
name : "client"
|
|
183
|
-
as : "_client"
|
|
184
|
-
input: {client_id: ""}
|
|
185
|
-
addon: []
|
|
186
|
-
}
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
]`).arrayOfObjectAttrReq_test_recursive_array_addon();
|
|
192
|
-
expect(parser.errors).to.be.empty;
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it("arrayOfObjectAttrReq detects missing definition on recursive array", () => {
|
|
196
|
-
parse(`addon = [
|
|
197
|
-
{
|
|
198
|
-
name : "client"
|
|
199
|
-
as : "_client"
|
|
200
|
-
input: {client_id: ""}
|
|
201
|
-
addon: [
|
|
202
|
-
{
|
|
203
|
-
name : "client"
|
|
204
|
-
input: {client_id: ""}
|
|
205
|
-
}
|
|
206
|
-
]
|
|
207
|
-
}
|
|
208
|
-
]`).arrayOfObjectAttrReq_test_recursive_array_addon();
|
|
209
|
-
expect(parser.errors).to.not.be.empty;
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it("arrayOfObjectAttrReq accepts optional attributes", () => {
|
|
213
|
-
parse(`something = [{}]`).arrayOfObjectAttrReq_test_optionals();
|
|
214
|
-
expect(parser.errors).to.be.empty;
|
|
215
|
-
|
|
216
|
-
parse(`something = [{foo: true}]`).arrayOfObjectAttrReq_test_optionals();
|
|
217
|
-
expect(parser.errors).to.be.empty;
|
|
218
|
-
|
|
219
|
-
parse(`something = [{bar: "ok"}]`).arrayOfObjectAttrReq_test_optionals();
|
|
220
|
-
expect(parser.errors).to.be.empty;
|
|
221
|
-
|
|
222
|
-
parse(
|
|
223
|
-
`something = [{bar: "ok", "foo": 12.1}]`
|
|
224
|
-
).arrayOfObjectAttrReq_test_optionals();
|
|
225
|
-
expect(parser.errors).to.be.empty;
|
|
226
|
-
|
|
227
|
-
parse(`something = [
|
|
228
|
-
{bar: "ok", "foo": 12.1},
|
|
229
|
-
{bar: "ok", "foo": 12.1}
|
|
230
|
-
]`).arrayOfObjectAttrReq_test_optionals();
|
|
231
|
-
expect(parser.errors).to.be.empty;
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it("arrayOfObjectAttrReq can be used for single line index clause", () => {
|
|
235
|
-
parse(
|
|
236
|
-
`index = [{type: "primary", field: [{name: "id"}]}]`
|
|
237
|
-
).arrayOfObjectAttrReq_test_index();
|
|
238
|
-
expect(parser.errors).to.be.empty;
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it("arrayOfObjectAttrReq can be used for index clause", () => {
|
|
242
|
-
parse(`index = [
|
|
243
|
-
{type: "primary", field: [{name: "id"}]}
|
|
244
|
-
{type: "gin", field: [{name: "xdo", op: "jsonb_path_op"}]}
|
|
245
|
-
{type: "btree", field: [{name: "created_at", op: "desc"}]}
|
|
246
|
-
]`).arrayOfObjectAttrReq_test_index();
|
|
247
|
-
expect(parser.errors).to.be.empty;
|
|
248
|
-
|
|
249
|
-
parse(`index = [
|
|
250
|
-
{type: "primary", field: [{name: "id"}]}
|
|
251
|
-
]`).arrayOfObjectAttrReq_test_index();
|
|
252
|
-
expect(parser.errors).to.be.empty;
|
|
253
|
-
});
|
|
254
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { CommaToken, LSquare, RSquare } from "../../lexer/control.js";
|
|
2
|
-
import { StringLiteral } from "../../lexer/literal.js";
|
|
3
|
-
import { NewlineToken } from "../../lexer/tokens.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Dynamicly raises error for missing and required attributes
|
|
7
|
-
* @param {import('../base_parser.js').XanoBaseParser} $
|
|
8
|
-
*/
|
|
9
|
-
export function arrayOfStringLiterals($) {
|
|
10
|
-
return () => {
|
|
11
|
-
$.CONSUME(LSquare); // "["
|
|
12
|
-
$.OPTION(() => {
|
|
13
|
-
$.OR([
|
|
14
|
-
// multi line, each value on a new line
|
|
15
|
-
// [
|
|
16
|
-
// value
|
|
17
|
-
// value2
|
|
18
|
-
// ]
|
|
19
|
-
{
|
|
20
|
-
ALT: () => {
|
|
21
|
-
$.CONSUME(NewlineToken);
|
|
22
|
-
$.AT_LEAST_ONE(() => {
|
|
23
|
-
$.CONSUME(StringLiteral);
|
|
24
|
-
$.OPTION1(() => $.CONSUME(CommaToken)); // optional comma
|
|
25
|
-
$.AT_LEAST_ONE1(() => $.CONSUME3(NewlineToken));
|
|
26
|
-
});
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
// one line, comma separated [ value, value2 ]
|
|
30
|
-
{
|
|
31
|
-
ALT: () => {
|
|
32
|
-
$.AT_LEAST_ONE_SEP({
|
|
33
|
-
SEP: CommaToken,
|
|
34
|
-
DEF: () => {
|
|
35
|
-
$.CONSUME1(StringLiteral);
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
$.MANY(() => $.CONSUME2(NewlineToken));
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
]);
|
|
42
|
-
});
|
|
43
|
-
$.CONSUME(RSquare); // "]"
|
|
44
|
-
};
|
|
45
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import { describe, it } from "mocha";
|
|
3
|
-
import { lexDocument } from "../../lexer/lexer.js";
|
|
4
|
-
import { parser } from "../test_parser.js";
|
|
5
|
-
|
|
6
|
-
function parse(inputText) {
|
|
7
|
-
parser.reset();
|
|
8
|
-
const lexResult = lexDocument(inputText);
|
|
9
|
-
parser.input = lexResult.tokens;
|
|
10
|
-
parser.arrayOfStringLiterals();
|
|
11
|
-
return parser;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe("arrayOfStringLiterals", () => {
|
|
15
|
-
it("arrayOfStringLiterals accepts a single string ", () => {
|
|
16
|
-
const parser = parse(`[ "true" ]`);
|
|
17
|
-
expect(parser.errors).to.be.empty;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("arrayOfStringLiterals can be empty ", () => {
|
|
21
|
-
const parser = parse(`[]`);
|
|
22
|
-
expect(parser.errors).to.be.empty;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("arrayOfStringLiterals can be multilines without trailing commas", () => {
|
|
26
|
-
const parser = parse(`[
|
|
27
|
-
"foo"
|
|
28
|
-
"bar"
|
|
29
|
-
]`);
|
|
30
|
-
expect(parser.errors).to.be.empty;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("arrayOfStringLiterals can be multilines with trailing commas ", () => {
|
|
34
|
-
const parser = parse(`[
|
|
35
|
-
"foo",
|
|
36
|
-
"bar"
|
|
37
|
-
]`);
|
|
38
|
-
expect(parser.errors).to.be.empty;
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("arrayOfStringLiterals can be compact ", () => {
|
|
42
|
-
const parser = parse(`["foo","bar"]`);
|
|
43
|
-
expect(parser.errors).to.be.empty;
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("arrayOfStringLiterals cannot contain a non string ", () => {
|
|
47
|
-
let parser = parse(`[4]`);
|
|
48
|
-
expect(parser.errors).to.not.be.empty;
|
|
49
|
-
|
|
50
|
-
parser = parse(`[true]`);
|
|
51
|
-
expect(parser.errors).to.not.be.empty;
|
|
52
|
-
|
|
53
|
-
parser = parse(`["test", 4]`);
|
|
54
|
-
expect(parser.errors).to.not.be.empty;
|
|
55
|
-
});
|
|
56
|
-
});
|