@malloydata/malloy 0.0.55 → 0.0.56-dev230707230009
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/dist/lang/lib/Malloy/MalloyParser.d.ts +43 -32
- package/dist/lang/lib/Malloy/MalloyParser.js +1363 -1276
- package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +11 -0
- package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +7 -0
- package/dist/lang/malloy-to-ast.d.ts +4 -5
- package/dist/lang/malloy-to-ast.js +78 -114
- package/dist/lang/parse-tree-walkers/find-external-references.js +26 -11
- package/dist/lang/parse-utils.d.ts +50 -0
- package/dist/lang/{string-parser.js → parse-utils.js} +85 -2
- package/dist/lang/test/strings.spec.js +79 -12
- package/package.json +1 -1
- package/dist/lang/string-parser.d.ts +0 -11
|
@@ -165,6 +165,7 @@ import { SampleSpecContext } from "./MalloyParser";
|
|
|
165
165
|
import { AggregateContext } from "./MalloyParser";
|
|
166
166
|
import { MalloyTypeContext } from "./MalloyParser";
|
|
167
167
|
import { CompareOpContext } from "./MalloyParser";
|
|
168
|
+
import { StringContext } from "./MalloyParser";
|
|
168
169
|
import { ShortStringContext } from "./MalloyParser";
|
|
169
170
|
import { NumericLiteralContext } from "./MalloyParser";
|
|
170
171
|
import { LiteralContext } from "./MalloyParser";
|
|
@@ -2006,6 +2007,16 @@ export interface MalloyParserListener extends ParseTreeListener {
|
|
|
2006
2007
|
* @param ctx the parse tree
|
|
2007
2008
|
*/
|
|
2008
2009
|
exitCompareOp?: (ctx: CompareOpContext) => void;
|
|
2010
|
+
/**
|
|
2011
|
+
* Enter a parse tree produced by `MalloyParser.string`.
|
|
2012
|
+
* @param ctx the parse tree
|
|
2013
|
+
*/
|
|
2014
|
+
enterString?: (ctx: StringContext) => void;
|
|
2015
|
+
/**
|
|
2016
|
+
* Exit a parse tree produced by `MalloyParser.string`.
|
|
2017
|
+
* @param ctx the parse tree
|
|
2018
|
+
*/
|
|
2019
|
+
exitString?: (ctx: StringContext) => void;
|
|
2009
2020
|
/**
|
|
2010
2021
|
* Enter a parse tree produced by `MalloyParser.shortString`.
|
|
2011
2022
|
* @param ctx the parse tree
|
|
@@ -165,6 +165,7 @@ import { SampleSpecContext } from "./MalloyParser";
|
|
|
165
165
|
import { AggregateContext } from "./MalloyParser";
|
|
166
166
|
import { MalloyTypeContext } from "./MalloyParser";
|
|
167
167
|
import { CompareOpContext } from "./MalloyParser";
|
|
168
|
+
import { StringContext } from "./MalloyParser";
|
|
168
169
|
import { ShortStringContext } from "./MalloyParser";
|
|
169
170
|
import { NumericLiteralContext } from "./MalloyParser";
|
|
170
171
|
import { LiteralContext } from "./MalloyParser";
|
|
@@ -1270,6 +1271,12 @@ export interface MalloyParserVisitor<Result> extends ParseTreeVisitor<Result> {
|
|
|
1270
1271
|
* @return the visitor result
|
|
1271
1272
|
*/
|
|
1272
1273
|
visitCompareOp?: (ctx: CompareOpContext) => Result;
|
|
1274
|
+
/**
|
|
1275
|
+
* Visit a parse tree produced by `MalloyParser.string`.
|
|
1276
|
+
* @param ctx the parse tree
|
|
1277
|
+
* @return the visitor result
|
|
1278
|
+
*/
|
|
1279
|
+
visitString?: (ctx: StringContext) => Result;
|
|
1273
1280
|
/**
|
|
1274
1281
|
* Visit a parse tree produced by `MalloyParser.shortString`.
|
|
1275
1282
|
* @param ctx the parse tree
|
|
@@ -7,14 +7,12 @@ import * as ast from './ast';
|
|
|
7
7
|
import { LogSeverity, MessageLogger } from './parse-log';
|
|
8
8
|
import { MalloyParseRoot } from './parse-malloy';
|
|
9
9
|
import { FieldDeclarationConstructor } from './ast';
|
|
10
|
+
import { HasString, HasID } from './parse-utils';
|
|
10
11
|
declare class IgnoredElement extends ast.MalloyElement {
|
|
11
12
|
elementType: string;
|
|
12
13
|
malloySrc: string;
|
|
13
14
|
constructor(src: string);
|
|
14
15
|
}
|
|
15
|
-
declare type ContainsID = ParserRuleContext & {
|
|
16
|
-
id: () => parse.IdContext;
|
|
17
|
-
};
|
|
18
16
|
/**
|
|
19
17
|
* ANTLR visitor pattern parse tree traversal. Generates a Malloy
|
|
20
18
|
* AST from an ANTLR parse tree.
|
|
@@ -42,8 +40,8 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
42
40
|
protected contextError(cx: ParserRuleContext, msg: string, sev?: LogSeverity): void;
|
|
43
41
|
protected only<T extends ast.MalloyElement>(els: ast.MalloyElement[], isGood: (el: ast.MalloyElement) => T | false, desc: string): T[];
|
|
44
42
|
protected getNumber(term: ParseTree): number;
|
|
45
|
-
protected getFieldName(cx:
|
|
46
|
-
protected getModelEntryName(cx:
|
|
43
|
+
protected getFieldName(cx: HasID): ast.FieldName;
|
|
44
|
+
protected getModelEntryName(cx: HasID): ast.ModelEntryReference;
|
|
47
45
|
defaultResult(): ast.MalloyElement;
|
|
48
46
|
protected astAt<MT extends ast.MalloyElement>(el: MT, cx: ParserRuleContext): MT;
|
|
49
47
|
protected getSourceCode(cx: ParserRuleContext): string;
|
|
@@ -53,6 +51,7 @@ export declare class MalloyToAST extends AbstractParseTreeVisitor<ast.MalloyElem
|
|
|
53
51
|
protected getSegments(segments: parse.PipeElementContext[]): ast.QOPDesc[];
|
|
54
52
|
protected getFilterShortcut(cx: parse.FilterShortcutContext): ast.Filter;
|
|
55
53
|
protected getExploreSource(pcx: parse.ExploreSourceContext): ast.Source;
|
|
54
|
+
protected getPlainString(cx: HasString): string;
|
|
56
55
|
protected makeSqlString(pcx: parse.SqlStringContext, sqlStr: ast.SQLString): void;
|
|
57
56
|
/**
|
|
58
57
|
* Parse a time string into an AST TimeLiteral, if the string fails
|
|
@@ -46,11 +46,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
46
46
|
};
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
48
|
exports.MalloyToAST = void 0;
|
|
49
|
+
const antlr4ts_1 = require("antlr4ts");
|
|
49
50
|
const AbstractParseTreeVisitor_1 = require("antlr4ts/tree/AbstractParseTreeVisitor");
|
|
50
51
|
const ast = __importStar(require("./ast"));
|
|
51
52
|
const Interval_1 = require("antlr4ts/misc/Interval");
|
|
52
53
|
const ast_1 = require("./ast");
|
|
53
|
-
const
|
|
54
|
+
const parse_utils_1 = require("./parse-utils");
|
|
54
55
|
const ENABLE_M4_WARNINGS = false;
|
|
55
56
|
class IgnoredElement extends ast.MalloyElement {
|
|
56
57
|
constructor(src) {
|
|
@@ -59,64 +60,6 @@ class IgnoredElement extends ast.MalloyElement {
|
|
|
59
60
|
this.malloySrc = src;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Get all the possibly missing annotations from this parse rule
|
|
64
|
-
* @param cx Any parse context which has an ANNOTATION* rules
|
|
65
|
-
* @returns Array of texts for the annotations
|
|
66
|
-
*/
|
|
67
|
-
function getNotes(cx) {
|
|
68
|
-
return cx.ANNOTATION().map(a => a.text);
|
|
69
|
-
}
|
|
70
|
-
function getIsNotes(cx) {
|
|
71
|
-
const before = getNotes(cx._beforeIs);
|
|
72
|
-
return before.concat(getNotes(cx._afterIs));
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Take the text of a matched string, including the matching quote
|
|
76
|
-
* characters, and return the actual contents of the string after
|
|
77
|
-
* \ processing.
|
|
78
|
-
* @param cx Any parse context which contains a string
|
|
79
|
-
* @returns Decocded string
|
|
80
|
-
*/
|
|
81
|
-
function getShortString(cx) {
|
|
82
|
-
var _a, _b;
|
|
83
|
-
const scx = cx.shortString();
|
|
84
|
-
const str = ((_a = scx.DQ_STRING()) === null || _a === void 0 ? void 0 : _a.text) || ((_b = scx.SQ_STRING()) === null || _b === void 0 ? void 0 : _b.text);
|
|
85
|
-
if (str) {
|
|
86
|
-
return (0, string_parser_1.parseString)(str, str[0]);
|
|
87
|
-
}
|
|
88
|
-
// shortString: DQ_STRING | SQ_STRING; So this will never happen
|
|
89
|
-
return '';
|
|
90
|
-
}
|
|
91
|
-
function getOptionalString(cx) {
|
|
92
|
-
function containsString(cx) {
|
|
93
|
-
return 'shortString' in cx;
|
|
94
|
-
}
|
|
95
|
-
if (containsString(cx) && cx.shortString()) {
|
|
96
|
-
return getShortString(cx);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* An identifier is either a sequence of id characters or a `quoted`
|
|
101
|
-
* This parses either to simply the resulting text.
|
|
102
|
-
* @param cx A context which has an identifier
|
|
103
|
-
* @returns The indenftifier text
|
|
104
|
-
*/
|
|
105
|
-
function getId(cx) {
|
|
106
|
-
const quoted = cx.id().BQ_STRING();
|
|
107
|
-
if (quoted) {
|
|
108
|
-
return (0, string_parser_1.parseString)(quoted.text, '`');
|
|
109
|
-
}
|
|
110
|
-
return cx.id().text;
|
|
111
|
-
}
|
|
112
|
-
function getOptionalId(cx) {
|
|
113
|
-
function containsID(cx) {
|
|
114
|
-
return 'id' in cx;
|
|
115
|
-
}
|
|
116
|
-
if (containsID(cx) && cx.id()) {
|
|
117
|
-
return getId(cx);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
63
|
/**
|
|
121
64
|
* ANTLR visitor pattern parse tree traversal. Generates a Malloy
|
|
122
65
|
* AST from an ANTLR parse tree.
|
|
@@ -176,10 +119,10 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
176
119
|
return Number.parseInt(term.text);
|
|
177
120
|
}
|
|
178
121
|
getFieldName(cx) {
|
|
179
|
-
return this.astAt(new ast.FieldName(getId(cx)), cx);
|
|
122
|
+
return this.astAt(new ast.FieldName((0, parse_utils_1.getId)(cx)), cx);
|
|
180
123
|
}
|
|
181
124
|
getModelEntryName(cx) {
|
|
182
|
-
return this.astAt(new ast.ModelEntryReference(getId(cx)), cx);
|
|
125
|
+
return this.astAt(new ast.ModelEntryReference((0, parse_utils_1.getId)(cx)), cx);
|
|
183
126
|
}
|
|
184
127
|
defaultResult() {
|
|
185
128
|
return new ast.Unimplemented();
|
|
@@ -226,17 +169,36 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
226
169
|
}
|
|
227
170
|
throw this.internalError(pcx, `'${element.elementType}': illegal source`);
|
|
228
171
|
}
|
|
172
|
+
getPlainString(cx) {
|
|
173
|
+
const shortStr = (0, parse_utils_1.getStringIfShort)(cx);
|
|
174
|
+
if (shortStr) {
|
|
175
|
+
return shortStr;
|
|
176
|
+
}
|
|
177
|
+
const safeParts = [];
|
|
178
|
+
const multiLineStr = cx.string().sqlString();
|
|
179
|
+
if (multiLineStr) {
|
|
180
|
+
for (const part of (0, parse_utils_1.getStringParts)(multiLineStr)) {
|
|
181
|
+
if (part instanceof antlr4ts_1.ParserRuleContext) {
|
|
182
|
+
this.contextError(part, '%{ query }% illegal in this string');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
safeParts.push(part);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return safeParts.join('');
|
|
189
|
+
}
|
|
190
|
+
// string: shortString | sqlString; So this will never happen
|
|
191
|
+
return '';
|
|
192
|
+
}
|
|
229
193
|
makeSqlString(pcx, sqlStr) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
194
|
+
for (const part of (0, parse_utils_1.getStringParts)(pcx)) {
|
|
195
|
+
if (part instanceof antlr4ts_1.ParserRuleContext) {
|
|
196
|
+
sqlStr.push(this.visit(part));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
sqlStr.push(part);
|
|
235
200
|
}
|
|
236
|
-
sqlStr.push(this.visit(part.query()));
|
|
237
201
|
}
|
|
238
|
-
const lastChars = (_a = pcx.SQL_END()) === null || _a === void 0 ? void 0 : _a.text.slice(0, -3);
|
|
239
|
-
sqlStr.push(lastChars || '');
|
|
240
202
|
sqlStr.complete();
|
|
241
203
|
this.astAt(sqlStr, pcx);
|
|
242
204
|
}
|
|
@@ -260,14 +222,14 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
260
222
|
visitDefineSourceStatement(pcx) {
|
|
261
223
|
const defsCx = pcx.sourcePropertyList().sourceDefinition();
|
|
262
224
|
const defs = defsCx.map(dcx => this.visitSourceDefinition(dcx));
|
|
263
|
-
const blockNotes = getNotes(pcx.tags());
|
|
225
|
+
const blockNotes = (0, parse_utils_1.getNotes)(pcx.tags());
|
|
264
226
|
const defList = new ast.DefineSourceList(defs);
|
|
265
227
|
defList.extendNote({ blockNotes });
|
|
266
228
|
return defList;
|
|
267
229
|
}
|
|
268
230
|
visitSourceDefinition(pcx) {
|
|
269
|
-
const exploreDef = new ast.DefineSource(getId(pcx.sourceNameDef()), this.visitExplore(pcx.explore()), true, []);
|
|
270
|
-
const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
|
|
231
|
+
const exploreDef = new ast.DefineSource((0, parse_utils_1.getId)(pcx.sourceNameDef()), this.visitExplore(pcx.explore()), true, []);
|
|
232
|
+
const notes = (0, parse_utils_1.getNotes)(pcx.tags()).concat((0, parse_utils_1.getIsNotes)(pcx.isDefine()));
|
|
271
233
|
exploreDef.extendNote({ notes });
|
|
272
234
|
return this.astAt(exploreDef, pcx);
|
|
273
235
|
}
|
|
@@ -289,7 +251,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
289
251
|
return propList;
|
|
290
252
|
}
|
|
291
253
|
visitTableFunction(pcx) {
|
|
292
|
-
const tableURI =
|
|
254
|
+
const tableURI = this.getPlainString(pcx.tableURI());
|
|
293
255
|
const el = this.astAt(new ast.TableFunctionSource(tableURI), pcx);
|
|
294
256
|
if (ENABLE_M4_WARNINGS) {
|
|
295
257
|
this.astError(el, "`table('connection_name:table_path')` is deprecated; use `connection_name.table('table_path')`", 'warn');
|
|
@@ -299,7 +261,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
299
261
|
visitTableMethod(pcx) {
|
|
300
262
|
const connId = pcx.connectionId();
|
|
301
263
|
const connectionName = this.astAt(this.getModelEntryName(connId), connId);
|
|
302
|
-
const tablePath =
|
|
264
|
+
const tablePath = this.getPlainString(pcx.tablePath());
|
|
303
265
|
return this.astAt(new ast.TableMethodSource(connectionName, tablePath), pcx);
|
|
304
266
|
}
|
|
305
267
|
visitTableSource(pcx) {
|
|
@@ -321,9 +283,9 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
321
283
|
if (selCx) {
|
|
322
284
|
this.makeSqlString(selCx, sqlStr);
|
|
323
285
|
}
|
|
324
|
-
const
|
|
325
|
-
if (
|
|
326
|
-
sqlStr.push(
|
|
286
|
+
const shortCX = pcx.shortString();
|
|
287
|
+
if (shortCX) {
|
|
288
|
+
sqlStr.push((0, parse_utils_1.getShortString)(shortCX));
|
|
327
289
|
}
|
|
328
290
|
const expr = new ast.SQLSource(connectionName, sqlStr);
|
|
329
291
|
return this.astAt(expr, pcx);
|
|
@@ -353,7 +315,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
353
315
|
}
|
|
354
316
|
}
|
|
355
317
|
const joinMany = new ast.Joins(joins);
|
|
356
|
-
joinMany.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
318
|
+
joinMany.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
357
319
|
return joinMany;
|
|
358
320
|
}
|
|
359
321
|
visitDefJoinOne(pcx) {
|
|
@@ -368,7 +330,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
368
330
|
}
|
|
369
331
|
}
|
|
370
332
|
const joinOne = new ast.Joins(joins);
|
|
371
|
-
joinOne.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
333
|
+
joinOne.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
372
334
|
return joinOne;
|
|
373
335
|
}
|
|
374
336
|
visitDefJoinCross(pcx) {
|
|
@@ -386,7 +348,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
386
348
|
}
|
|
387
349
|
}
|
|
388
350
|
const joinCross = new ast.Joins(joins);
|
|
389
|
-
joinCross.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
351
|
+
joinCross.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
390
352
|
return joinCross;
|
|
391
353
|
}
|
|
392
354
|
getJoinList(pcx) {
|
|
@@ -395,7 +357,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
395
357
|
getJoinSource(name, ecx) {
|
|
396
358
|
if (ecx) {
|
|
397
359
|
const joinSrc = this.visitExplore(ecx.explore());
|
|
398
|
-
const notes = getNotes(ecx._before_is).concat(getNotes(ecx._after_is));
|
|
360
|
+
const notes = (0, parse_utils_1.getNotes)(ecx._before_is).concat((0, parse_utils_1.getNotes)(ecx._after_is));
|
|
399
361
|
return { joinFrom: joinSrc, notes };
|
|
400
362
|
}
|
|
401
363
|
return { joinFrom: new ast.NamedSource(name), notes: [] };
|
|
@@ -415,7 +377,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
415
377
|
if (onCx) {
|
|
416
378
|
join.joinOn = this.getFieldExpr(onCx);
|
|
417
379
|
}
|
|
418
|
-
join.extendNote({ notes: getNotes(pcx).concat(notes) });
|
|
380
|
+
join.extendNote({ notes: (0, parse_utils_1.getNotes)(pcx).concat(notes) });
|
|
419
381
|
return this.astAt(join, pcx);
|
|
420
382
|
}
|
|
421
383
|
visitJoinWith(pcx) {
|
|
@@ -423,28 +385,28 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
423
385
|
const { joinFrom, notes } = this.getJoinSource(joinAs, pcx.isExplore());
|
|
424
386
|
const joinOn = this.getFieldExpr(pcx.fieldExpr());
|
|
425
387
|
const join = new ast.KeyJoin(joinAs, joinFrom, joinOn);
|
|
426
|
-
join.extendNote({ notes: getNotes(pcx).concat(notes) });
|
|
388
|
+
join.extendNote({ notes: (0, parse_utils_1.getNotes)(pcx).concat(notes) });
|
|
427
389
|
return this.astAt(join, pcx);
|
|
428
390
|
}
|
|
429
391
|
getFieldDef(pcx, makeFieldDef) {
|
|
430
392
|
const defCx = pcx.fieldExpr();
|
|
431
|
-
const fieldName = getId(pcx.fieldNameDef());
|
|
393
|
+
const fieldName = (0, parse_utils_1.getId)(pcx.fieldNameDef());
|
|
432
394
|
const valExpr = this.getFieldExpr(defCx);
|
|
433
395
|
const def = new makeFieldDef(valExpr, fieldName, this.getSourceCode(defCx));
|
|
434
|
-
const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
|
|
396
|
+
const notes = (0, parse_utils_1.getNotes)(pcx.tags()).concat((0, parse_utils_1.getIsNotes)(pcx.isDefine()));
|
|
435
397
|
def.extendNote({ notes });
|
|
436
398
|
return this.astAt(def, pcx);
|
|
437
399
|
}
|
|
438
400
|
visitDefDimensions(pcx) {
|
|
439
401
|
const defs = this.getFieldDefs(pcx.defList().fieldDef(), ast.DimensionFieldDeclaration);
|
|
440
402
|
const stmt = new ast.Dimensions(defs);
|
|
441
|
-
stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
403
|
+
stmt.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
442
404
|
return this.astAt(stmt, pcx);
|
|
443
405
|
}
|
|
444
406
|
visitDefMeasures(pcx) {
|
|
445
407
|
const defs = this.getFieldDefs(pcx.defList().fieldDef(), ast.MeasureFieldDeclaration);
|
|
446
408
|
const stmt = new ast.Measures(defs);
|
|
447
|
-
stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
409
|
+
stmt.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
448
410
|
return this.astAt(stmt, pcx);
|
|
449
411
|
}
|
|
450
412
|
visitQueryExtend(pcx) {
|
|
@@ -476,7 +438,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
476
438
|
visitExploreRenameDef(pcx) {
|
|
477
439
|
const newName = pcx.fieldName(0);
|
|
478
440
|
const oldName = pcx.fieldName(1);
|
|
479
|
-
const rename = new ast.RenameField(getId(newName), this.getFieldName(oldName));
|
|
441
|
+
const rename = new ast.RenameField((0, parse_utils_1.getId)(newName), this.getFieldName(oldName));
|
|
480
442
|
return this.astAt(rename, pcx);
|
|
481
443
|
}
|
|
482
444
|
visitDefExploreRename(pcx) {
|
|
@@ -510,7 +472,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
510
472
|
}
|
|
511
473
|
visitDefExploreQuery(pcx) {
|
|
512
474
|
const queryDefs = this.visitSubQueryDefList(pcx.subQueryDefList());
|
|
513
|
-
const blockNotes = getNotes(pcx.tags());
|
|
475
|
+
const blockNotes = (0, parse_utils_1.getNotes)(pcx.tags());
|
|
514
476
|
queryDefs.extendNote({ blockNotes });
|
|
515
477
|
return queryDefs;
|
|
516
478
|
}
|
|
@@ -532,7 +494,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
532
494
|
return this.visitTimezoneStatement(cx.timezoneStatement());
|
|
533
495
|
}
|
|
534
496
|
visitTimezoneStatement(cx) {
|
|
535
|
-
const
|
|
497
|
+
const timezone = this.getPlainString(cx);
|
|
498
|
+
const timezoneStatement = this.astAt(new ast.TimezoneStatement(timezone), cx.string());
|
|
536
499
|
if (!timezoneStatement.isValid) {
|
|
537
500
|
this.astError(timezoneStatement, `Invalid timezone: ${timezoneStatement.tz}`);
|
|
538
501
|
}
|
|
@@ -574,22 +537,22 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
574
537
|
}
|
|
575
538
|
visitAggregateStatement(pcx) {
|
|
576
539
|
const agStmt = new ast.Aggregate(this.getQueryItems(pcx.queryFieldList(), ast.AggregateFieldDeclaration, ast.AggregateFieldReference));
|
|
577
|
-
agStmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
540
|
+
agStmt.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
578
541
|
return agStmt;
|
|
579
542
|
}
|
|
580
543
|
visitGroupByStatement(pcx) {
|
|
581
544
|
const groupBy = new ast.GroupBy(this.getQueryItems(pcx.queryFieldList(), ast.GroupByFieldDeclaration, ast.GroupByFieldReference));
|
|
582
|
-
groupBy.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
545
|
+
groupBy.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
583
546
|
return groupBy;
|
|
584
547
|
}
|
|
585
548
|
visitCalculateStatement(pcx) {
|
|
586
549
|
const stmt = new ast.Calculate(this.getQueryItems(pcx.queryFieldList(), ast.CalculateFieldDeclaration, ast.CalculateFieldReference));
|
|
587
|
-
stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
550
|
+
stmt.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
588
551
|
return stmt;
|
|
589
552
|
}
|
|
590
553
|
getTaggedRef(pcx, makeFieldRef) {
|
|
591
554
|
const ref = this.getFieldPath(pcx.fieldPath(), makeFieldRef);
|
|
592
|
-
ref.extendNote({ notes: getNotes(pcx.tags()) });
|
|
555
|
+
ref.extendNote({ notes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
593
556
|
return ref;
|
|
594
557
|
}
|
|
595
558
|
getFieldCollectionMember(pcx, makeFieldDef, makeFieldRef) {
|
|
@@ -616,7 +579,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
616
579
|
}
|
|
617
580
|
visitProjectStatement(pcx) {
|
|
618
581
|
const stmt = this.visitFieldCollection(pcx.fieldCollection());
|
|
619
|
-
stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
582
|
+
stmt.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
620
583
|
return stmt;
|
|
621
584
|
}
|
|
622
585
|
visitCollectionWildCard(pcx) {
|
|
@@ -691,7 +654,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
691
654
|
return this.astAt(top, pcx);
|
|
692
655
|
}
|
|
693
656
|
visitSourceID(pcx) {
|
|
694
|
-
return this.astAt(new ast.NamedSource(getId(pcx)), pcx);
|
|
657
|
+
return this.astAt(new ast.NamedSource((0, parse_utils_1.getId)(pcx)), pcx);
|
|
695
658
|
}
|
|
696
659
|
buildPipelineFromName(pipe, pipeCx) {
|
|
697
660
|
const firstCx = pipeCx.firstSegment();
|
|
@@ -732,16 +695,16 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
732
695
|
const stmts = pcx
|
|
733
696
|
.topLevelQueryDef()
|
|
734
697
|
.map(cx => this.visitTopLevelQueryDef(cx));
|
|
735
|
-
const blockNotes = getNotes(pcx.tags());
|
|
698
|
+
const blockNotes = (0, parse_utils_1.getNotes)(pcx.tags());
|
|
736
699
|
const queryDefs = new ast.DefineQueryList(stmts);
|
|
737
700
|
queryDefs.extendNote({ blockNotes });
|
|
738
701
|
return queryDefs;
|
|
739
702
|
}
|
|
740
703
|
visitTopLevelQueryDef(pcx) {
|
|
741
|
-
const queryName = getId(pcx.queryName());
|
|
704
|
+
const queryName = (0, parse_utils_1.getId)(pcx.queryName());
|
|
742
705
|
const queryExpr = this.visit(pcx.query());
|
|
743
706
|
if (ast.isQueryElement(queryExpr)) {
|
|
744
|
-
const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
|
|
707
|
+
const notes = (0, parse_utils_1.getNotes)(pcx.tags()).concat((0, parse_utils_1.getIsNotes)(pcx.isDefine()));
|
|
745
708
|
const queryDef = new ast.DefineQuery(queryName, queryExpr);
|
|
746
709
|
queryDef.extendNote({ notes });
|
|
747
710
|
return this.astAt(queryDef, pcx);
|
|
@@ -753,8 +716,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
753
716
|
const query = this.visit(defCx.query());
|
|
754
717
|
if (ast.isQueryElement(query)) {
|
|
755
718
|
const theQuery = new ast.AnonymousQuery(query);
|
|
756
|
-
const notes = getNotes(pcx.topLevelAnonQueryDef().tags());
|
|
757
|
-
const blockNotes = getNotes(pcx.tags());
|
|
719
|
+
const notes = (0, parse_utils_1.getNotes)(pcx.topLevelAnonQueryDef().tags());
|
|
720
|
+
const blockNotes = (0, parse_utils_1.getNotes)(pcx.tags());
|
|
758
721
|
theQuery.extendNote({ notes, blockNotes });
|
|
759
722
|
if (ENABLE_M4_WARNINGS) {
|
|
760
723
|
this.astError(theQuery, 'Anonymous `query:` statements are deprecated, use `run:` instead', 'warn');
|
|
@@ -767,8 +730,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
767
730
|
const query = this.visit(pcx.topLevelAnonQueryDef().query());
|
|
768
731
|
if (ast.isQueryElement(query)) {
|
|
769
732
|
const el = new ast.RunQueryDef(query);
|
|
770
|
-
el.extendNote({ blockNotes: getNotes(pcx._blockTags) });
|
|
771
|
-
el.extendNote({ notes: getNotes(pcx._noteTags) });
|
|
733
|
+
el.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx._blockTags) });
|
|
734
|
+
el.extendNote({ notes: (0, parse_utils_1.getNotes)(pcx._noteTags) });
|
|
772
735
|
return this.astAt(el, pcx);
|
|
773
736
|
}
|
|
774
737
|
throw this.internalError(pcx, `Run query matched, but ${query.elementType} found`);
|
|
@@ -780,7 +743,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
780
743
|
}
|
|
781
744
|
visitNestStatement(pcx) {
|
|
782
745
|
const nests = this.visitNestedQueryList(pcx.nestedQueryList());
|
|
783
|
-
nests.extendNote({ blockNotes: getNotes(pcx.tags()) });
|
|
746
|
+
nests.extendNote({ blockNotes: (0, parse_utils_1.getNotes)(pcx.tags()) });
|
|
784
747
|
return nests;
|
|
785
748
|
}
|
|
786
749
|
visitNestedQueryList(pcx) {
|
|
@@ -789,7 +752,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
789
752
|
visitNestExisting(pcx) {
|
|
790
753
|
const name = this.getFieldName(pcx.queryName());
|
|
791
754
|
const propsCx = pcx.queryProperties();
|
|
792
|
-
const notes = getNotes(pcx.tags());
|
|
755
|
+
const notes = (0, parse_utils_1.getNotes)(pcx.tags());
|
|
793
756
|
if (propsCx) {
|
|
794
757
|
const nestRefine = new ast.NestRefinement(name);
|
|
795
758
|
const queryDesc = this.visitQueryProperties(propsCx);
|
|
@@ -802,18 +765,18 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
802
765
|
return nestRef;
|
|
803
766
|
}
|
|
804
767
|
visitNestDef(pcx) {
|
|
805
|
-
const name = getId(pcx.queryName());
|
|
768
|
+
const name = (0, parse_utils_1.getId)(pcx.queryName());
|
|
806
769
|
const nestDef = new ast.NestDefinition(name);
|
|
807
770
|
this.buildPipelineFromName(nestDef, pcx.pipelineFromName());
|
|
808
771
|
nestDef.extendNote({
|
|
809
|
-
notes: getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine())),
|
|
772
|
+
notes: (0, parse_utils_1.getNotes)(pcx.tags()).concat((0, parse_utils_1.getIsNotes)(pcx.isDefine())),
|
|
810
773
|
});
|
|
811
774
|
return this.astAt(nestDef, pcx);
|
|
812
775
|
}
|
|
813
776
|
visitExploreQueryDef(pcx) {
|
|
814
|
-
const name = getId(pcx.exploreQueryNameDef());
|
|
777
|
+
const name = (0, parse_utils_1.getId)(pcx.exploreQueryNameDef());
|
|
815
778
|
const queryDef = new ast.TurtleDecl(name);
|
|
816
|
-
const notes = getNotes(pcx).concat(getIsNotes(pcx.isDefine()));
|
|
779
|
+
const notes = (0, parse_utils_1.getNotes)(pcx).concat((0, parse_utils_1.getIsNotes)(pcx.isDefine()));
|
|
817
780
|
queryDef.extendNote({ notes });
|
|
818
781
|
this.buildPipelineFromName(queryDef, pcx.pipelineFromName());
|
|
819
782
|
return this.astAt(queryDef, pcx);
|
|
@@ -865,7 +828,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
865
828
|
return fieldExpr;
|
|
866
829
|
}
|
|
867
830
|
visitExprString(pcx) {
|
|
868
|
-
|
|
831
|
+
const str = this.getPlainString(pcx);
|
|
832
|
+
return new ast.ExprString(str);
|
|
869
833
|
}
|
|
870
834
|
visitExprRegex(pcx) {
|
|
871
835
|
const malloyRegex = pcx.HACKY_REGEX().text;
|
|
@@ -1002,7 +966,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1002
966
|
visitExprAggFunc(pcx) {
|
|
1003
967
|
const argsCx = pcx.argumentList();
|
|
1004
968
|
const args = argsCx ? this.allFieldExpressions(argsCx.fieldExpr()) : [];
|
|
1005
|
-
const fn = getId(pcx);
|
|
969
|
+
const fn = (0, parse_utils_1.getId)(pcx);
|
|
1006
970
|
const pathCx = pcx.fieldPath();
|
|
1007
971
|
const path = pathCx
|
|
1008
972
|
? this.getFieldPath(pathCx, ast.ExpressionFieldReference)
|
|
@@ -1029,7 +993,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1029
993
|
rawType = undefined;
|
|
1030
994
|
}
|
|
1031
995
|
}
|
|
1032
|
-
let fn = getOptionalId(pcx) || ((_b = pcx.timeframe()) === null || _b === void 0 ? void 0 : _b.text);
|
|
996
|
+
let fn = (0, parse_utils_1.getOptionalId)(pcx) || ((_b = pcx.timeframe()) === null || _b === void 0 ? void 0 : _b.text);
|
|
1033
997
|
if (fn === undefined) {
|
|
1034
998
|
this.contextError(pcx, 'Function name error');
|
|
1035
999
|
fn = 'FUNCTION_NAME_ERROR';
|
|
@@ -1096,7 +1060,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1096
1060
|
return this.parseTime(pcx, ast.LiteralYear.parse);
|
|
1097
1061
|
}
|
|
1098
1062
|
visitImportStatement(pcx) {
|
|
1099
|
-
const url =
|
|
1063
|
+
const url = this.getPlainString(pcx.importURL());
|
|
1100
1064
|
return this.astAt(new ast.ImportStatement(url, this.parse.subTranslator.sourceURL), pcx);
|
|
1101
1065
|
}
|
|
1102
1066
|
visitJustExpr(pcx) {
|
|
@@ -1115,7 +1079,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
1115
1079
|
this.contextError(nmCx, 'Cannot redefine connection');
|
|
1116
1080
|
}
|
|
1117
1081
|
else {
|
|
1118
|
-
connectionName =
|
|
1082
|
+
connectionName = this.getPlainString(nmCx);
|
|
1119
1083
|
}
|
|
1120
1084
|
}
|
|
1121
1085
|
const selCx = blockEnt.sqlString();
|
|
@@ -24,6 +24,27 @@
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.findReferences = exports.deprecatedParseTableURI = exports.constructTableKey = void 0;
|
|
26
26
|
const ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker");
|
|
27
|
+
const parse_utils_1 = require("../parse-utils");
|
|
28
|
+
// Copy of the version in the parser which also errors on each non-string in a
|
|
29
|
+
// multi-line string collection. No need to error here, which is well, because
|
|
30
|
+
// we don't have access to the error log.
|
|
31
|
+
function getPlainString(cx) {
|
|
32
|
+
const shortStr = (0, parse_utils_1.getStringIfShort)(cx);
|
|
33
|
+
if (shortStr) {
|
|
34
|
+
return shortStr;
|
|
35
|
+
}
|
|
36
|
+
const safeParts = [];
|
|
37
|
+
const multiLineStr = cx.string().sqlString();
|
|
38
|
+
if (multiLineStr) {
|
|
39
|
+
for (const part of (0, parse_utils_1.getStringParts)(multiLineStr)) {
|
|
40
|
+
if (typeof part === 'string') {
|
|
41
|
+
safeParts.push(part);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return safeParts.join('');
|
|
45
|
+
}
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
27
48
|
class FindExternalReferences {
|
|
28
49
|
constructor(trans, tokens) {
|
|
29
50
|
this.trans = trans;
|
|
@@ -42,13 +63,13 @@ class FindExternalReferences {
|
|
|
42
63
|
}
|
|
43
64
|
}
|
|
44
65
|
enterTableMethod(pcx) {
|
|
45
|
-
const
|
|
46
|
-
const tablePath =
|
|
66
|
+
const connId = (0, parse_utils_1.getId)(pcx.connectionId());
|
|
67
|
+
const tablePath = getPlainString(pcx.tablePath());
|
|
47
68
|
const reference = this.trans.rangeFromContext(pcx);
|
|
48
|
-
this.registerTableReference(
|
|
69
|
+
this.registerTableReference(connId, tablePath, reference);
|
|
49
70
|
}
|
|
50
71
|
enterTableFunction(pcx) {
|
|
51
|
-
const tableURI =
|
|
72
|
+
const tableURI = getPlainString(pcx.tableURI());
|
|
52
73
|
// This use of `deprecatedParseTableURI` is ok because it is for handling the
|
|
53
74
|
// old, soon-to-be-deprecated table syntax.
|
|
54
75
|
const { connectionName, tablePath } = deprecatedParseTableURI(tableURI);
|
|
@@ -56,17 +77,11 @@ class FindExternalReferences {
|
|
|
56
77
|
this.registerTableReference(connectionName, tablePath, reference);
|
|
57
78
|
}
|
|
58
79
|
enterImportURL(pcx) {
|
|
59
|
-
const url =
|
|
80
|
+
const url = getPlainString(pcx);
|
|
60
81
|
if (!this.needImports[url]) {
|
|
61
82
|
this.needImports[url] = this.trans.rangeFromContext(pcx);
|
|
62
83
|
}
|
|
63
84
|
}
|
|
64
|
-
stripIdQuotes(id) {
|
|
65
|
-
if (id[0] === '`' && id[id.length - 1] === '`') {
|
|
66
|
-
return id.slice(1, -1);
|
|
67
|
-
}
|
|
68
|
-
return id;
|
|
69
|
-
}
|
|
70
85
|
}
|
|
71
86
|
function constructTableKey(connectionName, tablePath) {
|
|
72
87
|
return connectionName === undefined
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ParserRuleContext } from 'antlr4ts';
|
|
2
|
+
import { StringContext, ShortStringContext, SqlStringContext, IsDefineContext, IdContext } from './lib/Malloy/MalloyParser';
|
|
3
|
+
import { TerminalNode } from 'antlr4ts/tree/TerminalNode';
|
|
4
|
+
/**
|
|
5
|
+
* Take the text of a matched string, including the matching quote
|
|
6
|
+
* characters, and return the actual contents of the string after
|
|
7
|
+
* \ processing.
|
|
8
|
+
* @param cx Any parse context which contains a string
|
|
9
|
+
* @returns Decocded string
|
|
10
|
+
*/
|
|
11
|
+
export declare function getShortString(scx: ShortStringContext): string;
|
|
12
|
+
export declare function getStringIfShort(cx: HasString): string | undefined;
|
|
13
|
+
export declare type HasString = ParserRuleContext & {
|
|
14
|
+
string: () => StringContext;
|
|
15
|
+
};
|
|
16
|
+
declare type StringPart = ParserRuleContext | string;
|
|
17
|
+
export declare function getStringParts(cx: SqlStringContext): StringPart[];
|
|
18
|
+
/**
|
|
19
|
+
* Parses the interior of a string, doing all \ substitutions. In most cases
|
|
20
|
+
* a lexical analyzer has already recognized this as a string. As a convenience,
|
|
21
|
+
* strip off the quoting outer chartacters if asked, then parse the interior of
|
|
22
|
+
* the string. The intention is to be compatible with JSON strings, in terms
|
|
23
|
+
* of which \X substitutions are processed.
|
|
24
|
+
* @param str is the string to parse
|
|
25
|
+
* @param surround is the quoting character, default means quotes already stripped
|
|
26
|
+
* @returns a string with the \ processing completed
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseString(str: string, surround?: string): string;
|
|
29
|
+
declare type HasAnnotations = ParserRuleContext & {
|
|
30
|
+
ANNOTATION: () => TerminalNode[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Get all the possibly missing annotations from this parse rule
|
|
34
|
+
* @param cx Any parse context which has an ANNOTATION* rules
|
|
35
|
+
* @returns Array of texts for the annotations
|
|
36
|
+
*/
|
|
37
|
+
export declare function getNotes(cx: HasAnnotations): string[];
|
|
38
|
+
export declare function getIsNotes(cx: IsDefineContext): string[];
|
|
39
|
+
export declare type HasID = ParserRuleContext & {
|
|
40
|
+
id: () => IdContext;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* An identifier is either a sequence of id characters or a `quoted`
|
|
44
|
+
* This parses either to simply the resulting text.
|
|
45
|
+
* @param cx A context which has an identifier
|
|
46
|
+
* @returns The indenftifier text
|
|
47
|
+
*/
|
|
48
|
+
export declare function getId(cx: HasID): string;
|
|
49
|
+
export declare function getOptionalId(cx: ParserRuleContext): string | undefined;
|
|
50
|
+
export {};
|