dql-language-support 1.0.1 → 1.4.3
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/.turbo/turbo-build.log +9 -0
- package/dist/lsp-server.js +181 -16
- package/dist/lsp-server.js.map +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
> dql-language-support@1.4.2 build /Users/Kranthi_1/DuckCode-DQL/DQL/dql/apps/vscode-extension
|
|
3
|
+
> pnpm run typecheck && node ./scripts/build.mjs
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> dql-language-support@1.4.2 typecheck /Users/Kranthi_1/DuckCode-DQL/DQL/dql/apps/vscode-extension
|
|
7
|
+
> tsc -p . --noEmit
|
|
8
|
+
|
|
9
|
+
[dql-vscode-extension] build complete
|
package/dist/lsp-server.js
CHANGED
|
@@ -9135,7 +9135,9 @@ var KEYWORDS = {
|
|
|
9135
9135
|
default: "DefaultKeyword" /* DefaultKeyword */,
|
|
9136
9136
|
IN: "InKeyword" /* InKeyword */,
|
|
9137
9137
|
metric: "MetricKeyword" /* MetricKeyword */,
|
|
9138
|
-
metrics: "MetricsKeyword" /* MetricsKeyword
|
|
9138
|
+
metrics: "MetricsKeyword" /* MetricsKeyword */,
|
|
9139
|
+
digest: "DigestKeyword" /* DigestKeyword */,
|
|
9140
|
+
narrative: "NarrativeKeyword" /* NarrativeKeyword */
|
|
9139
9141
|
};
|
|
9140
9142
|
function lookupKeyword(identifier) {
|
|
9141
9143
|
return KEYWORDS[identifier] ?? "Identifier" /* Identifier */;
|
|
@@ -9637,6 +9639,9 @@ var Parser = class {
|
|
|
9637
9639
|
if (this.check("DashboardKeyword" /* DashboardKeyword */)) {
|
|
9638
9640
|
return this.parseDashboard(decorators);
|
|
9639
9641
|
}
|
|
9642
|
+
if (this.check("DigestKeyword" /* DigestKeyword */)) {
|
|
9643
|
+
return this.parseDigest(decorators);
|
|
9644
|
+
}
|
|
9640
9645
|
if (this.check("ChartKeyword" /* ChartKeyword */)) {
|
|
9641
9646
|
return this.parseChartCall(decorators);
|
|
9642
9647
|
}
|
|
@@ -9652,7 +9657,7 @@ var Parser = class {
|
|
|
9652
9657
|
if (this.check("EOF" /* EOF */)) {
|
|
9653
9658
|
return null;
|
|
9654
9659
|
}
|
|
9655
|
-
this.error(`Unexpected token '${this.current().value}'. Expected 'dashboard', 'workbook', 'chart', 'block', or 'import'.`);
|
|
9660
|
+
this.error(`Unexpected token '${this.current().value}'. Expected 'dashboard', 'digest', 'workbook', 'chart', 'block', or 'import'.`);
|
|
9656
9661
|
return null;
|
|
9657
9662
|
}
|
|
9658
9663
|
parseFilterCall() {
|
|
@@ -9744,6 +9749,84 @@ var Parser = class {
|
|
|
9744
9749
|
span: this.makeSpan(start, this.previousSpan())
|
|
9745
9750
|
};
|
|
9746
9751
|
}
|
|
9752
|
+
parseDigest(decorators) {
|
|
9753
|
+
const start = decorators.length > 0 ? decorators[0].span : this.currentSpan();
|
|
9754
|
+
this.expect("DigestKeyword" /* DigestKeyword */);
|
|
9755
|
+
const titleToken = this.expect("StringLiteral" /* StringLiteral */);
|
|
9756
|
+
this.expect("LeftBrace" /* LeftBrace */);
|
|
9757
|
+
const body = [];
|
|
9758
|
+
let narrative;
|
|
9759
|
+
while (!this.check("RightBrace" /* RightBrace */) && !this.isAtEnd()) {
|
|
9760
|
+
const itemDecorators = this.parseDecoratorList();
|
|
9761
|
+
if (this.check("NarrativeKeyword" /* NarrativeKeyword */)) {
|
|
9762
|
+
if (itemDecorators.length > 0) {
|
|
9763
|
+
this.error("Decorators cannot be applied to narrative blocks.");
|
|
9764
|
+
}
|
|
9765
|
+
if (narrative) {
|
|
9766
|
+
this.error("A digest can only contain one narrative block.");
|
|
9767
|
+
}
|
|
9768
|
+
narrative = this.parseNarrative();
|
|
9769
|
+
} else if (this.check("LetKeyword" /* LetKeyword */)) {
|
|
9770
|
+
if (itemDecorators.length > 0) {
|
|
9771
|
+
this.error("Decorators cannot be applied to variable declarations.");
|
|
9772
|
+
}
|
|
9773
|
+
body.push(this.parseVariableDecl());
|
|
9774
|
+
} else if (this.check("ParamKeyword" /* ParamKeyword */)) {
|
|
9775
|
+
if (itemDecorators.length > 0) {
|
|
9776
|
+
this.error("Decorators cannot be applied to param declarations.");
|
|
9777
|
+
}
|
|
9778
|
+
body.push(this.parseParamDecl());
|
|
9779
|
+
} else if (this.check("ChartKeyword" /* ChartKeyword */)) {
|
|
9780
|
+
body.push(this.parseChartCall(itemDecorators));
|
|
9781
|
+
} else if (this.check("FilterKeyword" /* FilterKeyword */)) {
|
|
9782
|
+
if (itemDecorators.length > 0) {
|
|
9783
|
+
this.error("Decorators cannot be applied to filter declarations.");
|
|
9784
|
+
}
|
|
9785
|
+
body.push(this.parseFilterCall());
|
|
9786
|
+
} else if (this.check("UseKeyword" /* UseKeyword */)) {
|
|
9787
|
+
if (itemDecorators.length > 0) {
|
|
9788
|
+
this.error("Decorators cannot be applied to use declarations.");
|
|
9789
|
+
}
|
|
9790
|
+
body.push(this.parseUseDecl());
|
|
9791
|
+
} else if (this.check("LayoutKeyword" /* LayoutKeyword */)) {
|
|
9792
|
+
if (itemDecorators.length > 0) {
|
|
9793
|
+
this.error("Decorators cannot be applied to layout blocks.");
|
|
9794
|
+
}
|
|
9795
|
+
body.push(this.parseLayoutBlock());
|
|
9796
|
+
} else if (this.check("RightBrace" /* RightBrace */)) {
|
|
9797
|
+
break;
|
|
9798
|
+
} else {
|
|
9799
|
+
this.error(
|
|
9800
|
+
`Unexpected token '${this.current().value}' inside digest. Expected 'narrative', 'let', 'param', 'chart', 'filter', 'use', 'layout', or '}'.`
|
|
9801
|
+
);
|
|
9802
|
+
this.advance();
|
|
9803
|
+
}
|
|
9804
|
+
}
|
|
9805
|
+
this.expect("RightBrace" /* RightBrace */);
|
|
9806
|
+
return {
|
|
9807
|
+
kind: "Digest" /* Digest */,
|
|
9808
|
+
title: titleToken.value,
|
|
9809
|
+
decorators,
|
|
9810
|
+
narrative,
|
|
9811
|
+
body,
|
|
9812
|
+
span: this.makeSpan(start, this.previousSpan())
|
|
9813
|
+
};
|
|
9814
|
+
}
|
|
9815
|
+
parseNarrative() {
|
|
9816
|
+
const start = this.currentSpan();
|
|
9817
|
+
this.expect("NarrativeKeyword" /* NarrativeKeyword */);
|
|
9818
|
+
this.expect("LeftBrace" /* LeftBrace */);
|
|
9819
|
+
const properties = [];
|
|
9820
|
+
while (!this.check("RightBrace" /* RightBrace */) && !this.isAtEnd()) {
|
|
9821
|
+
properties.push(this.parseNamedArg());
|
|
9822
|
+
}
|
|
9823
|
+
this.expect("RightBrace" /* RightBrace */);
|
|
9824
|
+
return {
|
|
9825
|
+
kind: "Narrative" /* Narrative */,
|
|
9826
|
+
properties,
|
|
9827
|
+
span: this.makeSpan(start, this.previousSpan())
|
|
9828
|
+
};
|
|
9829
|
+
}
|
|
9747
9830
|
parseChartCall(decorators) {
|
|
9748
9831
|
const start = decorators.length > 0 ? decorators[0].span : this.currentSpan();
|
|
9749
9832
|
this.expect("ChartKeyword" /* ChartKeyword */);
|
|
@@ -10063,6 +10146,10 @@ var Parser = class {
|
|
|
10063
10146
|
let query;
|
|
10064
10147
|
let visualization;
|
|
10065
10148
|
let tests;
|
|
10149
|
+
let llmContext;
|
|
10150
|
+
let invariants;
|
|
10151
|
+
let examples;
|
|
10152
|
+
let status;
|
|
10066
10153
|
while (!this.check("RightBrace" /* RightBrace */) && !this.isAtEnd()) {
|
|
10067
10154
|
if (this.check("DomainKeyword" /* DomainKeyword */)) {
|
|
10068
10155
|
this.advance();
|
|
@@ -10134,9 +10221,53 @@ var Parser = class {
|
|
|
10134
10221
|
tests = this.parseBlockTests();
|
|
10135
10222
|
} else if (this.check("RightBrace" /* RightBrace */)) {
|
|
10136
10223
|
break;
|
|
10224
|
+
} else if (this.check("Identifier" /* Identifier */) && this.current().value === "status") {
|
|
10225
|
+
this.advance();
|
|
10226
|
+
this.expect("Equals" /* Equals */);
|
|
10227
|
+
const val = this.expect("StringLiteral" /* StringLiteral */);
|
|
10228
|
+
status = val.value;
|
|
10229
|
+
} else if (this.check("Identifier" /* Identifier */) && (this.current().value === "llmContext" || this.current().value === "invariants" || this.current().value === "examples")) {
|
|
10230
|
+
const keyToken = this.advance();
|
|
10231
|
+
this.expect("Equals" /* Equals */);
|
|
10232
|
+
if (keyToken.value === "llmContext") {
|
|
10233
|
+
const val = this.expect("StringLiteral" /* StringLiteral */);
|
|
10234
|
+
llmContext = val.value;
|
|
10235
|
+
} else if (keyToken.value === "invariants") {
|
|
10236
|
+
const arrExpr = this.parseArrayLiteral();
|
|
10237
|
+
if (arrExpr.kind === "ArrayLiteral" /* ArrayLiteral */) {
|
|
10238
|
+
invariants = arrExpr.elements.filter((e) => e.kind === "StringLiteral" /* StringLiteral */).map((e) => e.value);
|
|
10239
|
+
}
|
|
10240
|
+
} else {
|
|
10241
|
+
this.expect("LeftBracket" /* LeftBracket */);
|
|
10242
|
+
const items = [];
|
|
10243
|
+
while (!this.check("RightBracket" /* RightBracket */) && !this.isAtEnd()) {
|
|
10244
|
+
this.expect("LeftBrace" /* LeftBrace */);
|
|
10245
|
+
let question;
|
|
10246
|
+
let sql;
|
|
10247
|
+
while (!this.check("RightBrace" /* RightBrace */) && !this.isAtEnd()) {
|
|
10248
|
+
const propToken = this.current();
|
|
10249
|
+
if (propToken.type !== "Identifier" /* Identifier */) {
|
|
10250
|
+
this.error(`Expected 'question' or 'sql' in example entry, got '${propToken.value}'.`);
|
|
10251
|
+
this.advance();
|
|
10252
|
+
continue;
|
|
10253
|
+
}
|
|
10254
|
+
this.advance();
|
|
10255
|
+
this.expect("Equals" /* Equals */);
|
|
10256
|
+
const val = this.expect("StringLiteral" /* StringLiteral */);
|
|
10257
|
+
if (propToken.value === "question") question = val.value;
|
|
10258
|
+
else if (propToken.value === "sql") sql = val.value;
|
|
10259
|
+
if (this.check("Comma" /* Comma */)) this.advance();
|
|
10260
|
+
}
|
|
10261
|
+
this.expect("RightBrace" /* RightBrace */);
|
|
10262
|
+
if (question) items.push(sql ? { question, sql } : { question });
|
|
10263
|
+
if (this.check("Comma" /* Comma */)) this.advance();
|
|
10264
|
+
}
|
|
10265
|
+
this.expect("RightBracket" /* RightBracket */);
|
|
10266
|
+
if (items.length > 0) examples = items;
|
|
10267
|
+
}
|
|
10137
10268
|
} else {
|
|
10138
10269
|
this.error(
|
|
10139
|
-
`Unexpected token '${this.current().value}' inside block. Expected 'domain', 'type', 'metric', 'metrics', 'description', 'tags', 'owner', 'params', 'query', 'visualization', 'tests', or '}'.`
|
|
10270
|
+
`Unexpected token '${this.current().value}' inside block. Expected 'domain', 'type', 'status', 'metric', 'metrics', 'description', 'tags', 'owner', 'params', 'query', 'visualization', 'tests', 'llmContext', 'invariants', 'examples', or '}'.`
|
|
10140
10271
|
);
|
|
10141
10272
|
this.advance();
|
|
10142
10273
|
}
|
|
@@ -10163,6 +10294,10 @@ var Parser = class {
|
|
|
10163
10294
|
visualization,
|
|
10164
10295
|
tests,
|
|
10165
10296
|
decorators,
|
|
10297
|
+
llmContext,
|
|
10298
|
+
invariants,
|
|
10299
|
+
examples,
|
|
10300
|
+
status,
|
|
10166
10301
|
span: this.makeSpan(start, this.previousSpan())
|
|
10167
10302
|
};
|
|
10168
10303
|
}
|
|
@@ -10808,6 +10943,9 @@ var SemanticAnalyzer = class {
|
|
|
10808
10943
|
case "BlockDecl" /* BlockDecl */:
|
|
10809
10944
|
this.analyzeBlockDecl(stmt);
|
|
10810
10945
|
break;
|
|
10946
|
+
case "Digest" /* Digest */:
|
|
10947
|
+
this.analyzeDashboard(stmt);
|
|
10948
|
+
break;
|
|
10811
10949
|
}
|
|
10812
10950
|
}
|
|
10813
10951
|
return this.reporter.getAll();
|
|
@@ -10823,7 +10961,7 @@ var SemanticAnalyzer = class {
|
|
|
10823
10961
|
}
|
|
10824
10962
|
}
|
|
10825
10963
|
analyzeWorkbook(node) {
|
|
10826
|
-
this.validateDecorators(node.decorators, "
|
|
10964
|
+
this.validateDecorators(node.decorators, "block");
|
|
10827
10965
|
if (node.pages.length === 0) {
|
|
10828
10966
|
this.reporter.warning("Workbook has no pages.", node.span);
|
|
10829
10967
|
}
|
|
@@ -11090,9 +11228,9 @@ var SemanticAnalyzer = class {
|
|
|
11090
11228
|
}
|
|
11091
11229
|
break;
|
|
11092
11230
|
case "rls":
|
|
11093
|
-
if (context !== "chart") {
|
|
11231
|
+
if (context !== "chart" && context !== "block") {
|
|
11094
11232
|
this.reporter.error(
|
|
11095
|
-
"@rls can only be applied to chart declarations.",
|
|
11233
|
+
"@rls can only be applied to chart or block declarations.",
|
|
11096
11234
|
dec.span
|
|
11097
11235
|
);
|
|
11098
11236
|
}
|
|
@@ -14194,15 +14332,19 @@ function formatCall(callName, decorators, query, args, level, state) {
|
|
|
14194
14332
|
const lines = [];
|
|
14195
14333
|
lines.push(...formatDecorators(decorators, level, state));
|
|
14196
14334
|
lines.push(`${indent(level, state)}${callName}(`);
|
|
14197
|
-
const
|
|
14335
|
+
const parts = [];
|
|
14198
14336
|
if (query) {
|
|
14199
|
-
|
|
14337
|
+
parts.push(formatSQLQuery(query, level + 1, state));
|
|
14200
14338
|
}
|
|
14201
|
-
|
|
14202
|
-
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
|
|
14339
|
+
for (const arg of args) {
|
|
14340
|
+
parts.push([`${indent(level + 1, state)}${formatNamedArg(arg)}`]);
|
|
14341
|
+
}
|
|
14342
|
+
for (let i = 0; i < parts.length; i++) {
|
|
14343
|
+
const isLast = i === parts.length - 1;
|
|
14344
|
+
const chunk = parts[i];
|
|
14345
|
+
for (let j = 0; j < chunk.length; j++) {
|
|
14346
|
+
const lastInChunk = j === chunk.length - 1;
|
|
14347
|
+
lines.push(lastInChunk && !isLast ? `${chunk[j]},` : chunk[j]);
|
|
14206
14348
|
}
|
|
14207
14349
|
}
|
|
14208
14350
|
lines.push(`${indent(level, state)})`);
|
|
@@ -14239,11 +14381,19 @@ function formatBlock(node, level, state) {
|
|
|
14239
14381
|
lines.push(`${indent(level, state)}block ${quote(node.name)} {`);
|
|
14240
14382
|
if (node.domain) lines.push(`${indent(level + 1, state)}domain = ${quote(node.domain)}`);
|
|
14241
14383
|
if (node.blockType) lines.push(`${indent(level + 1, state)}type = ${quote(node.blockType)}`);
|
|
14384
|
+
if (node.status) lines.push(`${indent(level + 1, state)}status = ${quote(node.status)}`);
|
|
14242
14385
|
if (node.description) lines.push(`${indent(level + 1, state)}description = ${quote(node.description)}`);
|
|
14243
14386
|
if (node.tags && node.tags.length > 0) {
|
|
14244
14387
|
lines.push(`${indent(level + 1, state)}tags = [${node.tags.map(quote).join(", ")}]`);
|
|
14245
14388
|
}
|
|
14246
14389
|
if (node.owner) lines.push(`${indent(level + 1, state)}owner = ${quote(node.owner)}`);
|
|
14390
|
+
if (node.llmContext) lines.push(`${indent(level + 1, state)}llmContext = ${quote(node.llmContext)}`);
|
|
14391
|
+
if (node.examples && node.examples.length > 0) {
|
|
14392
|
+
lines.push(`${indent(level + 1, state)}examples = [${formatBlockExamples(node.examples)}]`);
|
|
14393
|
+
}
|
|
14394
|
+
if (node.invariants && node.invariants.length > 0) {
|
|
14395
|
+
lines.push(`${indent(level + 1, state)}invariants = [${node.invariants.map(quote).join(", ")}]`);
|
|
14396
|
+
}
|
|
14247
14397
|
if (node.params) {
|
|
14248
14398
|
lines.push(`${indent(level + 1, state)}params {`);
|
|
14249
14399
|
for (const entry of node.params.params) {
|
|
@@ -14276,13 +14426,28 @@ function formatBlock(node, level, state) {
|
|
|
14276
14426
|
return lines.join("\n");
|
|
14277
14427
|
}
|
|
14278
14428
|
function formatSQLQuery(query, level, state) {
|
|
14279
|
-
const sql = query.rawSQL.
|
|
14280
|
-
if (!sql) return [`${indent(level, state)}SELECT 1`];
|
|
14281
|
-
|
|
14429
|
+
const sql = query.rawSQL.replace(/^\n+|\s+$/g, "");
|
|
14430
|
+
if (!sql.trim()) return [`${indent(level, state)}SELECT 1`];
|
|
14431
|
+
const rawLines = sql.split("\n").map((line) => line.trimEnd());
|
|
14432
|
+
const tail = rawLines.slice(1).filter((l) => l.length > 0);
|
|
14433
|
+
const sample = tail.length ? tail : rawLines.filter((l) => l.length > 0);
|
|
14434
|
+
const minLeading = sample.length ? Math.min(...sample.map((l) => l.match(/^[ \t]*/)[0].length)) : 0;
|
|
14435
|
+
return rawLines.map((line) => {
|
|
14436
|
+
if (line.length === 0) return "";
|
|
14437
|
+
const stripped = line.startsWith(" ".repeat(minLeading)) || line.startsWith(" ".repeat(minLeading)) ? line.slice(minLeading) : line.trimStart();
|
|
14438
|
+
return `${indent(level, state)}${stripped}`;
|
|
14439
|
+
});
|
|
14282
14440
|
}
|
|
14283
14441
|
function formatNamedArg(arg) {
|
|
14284
14442
|
return `${arg.name} = ${formatExpression(arg.value)}`;
|
|
14285
14443
|
}
|
|
14444
|
+
function formatBlockExamples(examples) {
|
|
14445
|
+
return examples.map((example) => {
|
|
14446
|
+
const props = [`question = ${quote(example.question)}`];
|
|
14447
|
+
if (example.sql) props.push(`sql = ${quote(example.sql)}`);
|
|
14448
|
+
return `{ ${props.join(", ")} }`;
|
|
14449
|
+
}).join(", ");
|
|
14450
|
+
}
|
|
14286
14451
|
function formatExpression(node) {
|
|
14287
14452
|
switch (node.kind) {
|
|
14288
14453
|
case "StringLiteral" /* StringLiteral */:
|