@malloydata/malloy 0.0.43 → 0.0.44-dev230623185845

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.
Files changed (102) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.js +3 -1
  3. package/dist/lang/ast/elements/define-query.d.ts +7 -1
  4. package/dist/lang/ast/elements/define-query.js +10 -1
  5. package/dist/lang/ast/elements/define-source.d.ts +7 -1
  6. package/dist/lang/ast/elements/define-source.js +16 -9
  7. package/dist/lang/ast/elements/pipeline-desc.d.ts +2 -1
  8. package/dist/lang/ast/elements/pipeline-desc.js +6 -2
  9. package/dist/lang/ast/elements/refined-source.d.ts +5 -4
  10. package/dist/lang/ast/elements/refined-source.js +5 -0
  11. package/dist/lang/ast/expressions/expr-id-reference.js +4 -4
  12. package/dist/lang/ast/field-space/column-space-field.d.ts +1 -1
  13. package/dist/lang/ast/field-space/column-space-field.js +3 -3
  14. package/dist/lang/ast/field-space/field-definition-value.d.ts +1 -1
  15. package/dist/lang/ast/field-space/field-definition-value.js +16 -10
  16. package/dist/lang/ast/field-space/query-field-struct.js +1 -0
  17. package/dist/lang/ast/field-space/query-spaces.js +4 -1
  18. package/dist/lang/ast/field-space/reference-field.d.ts +8 -2
  19. package/dist/lang/ast/field-space/reference-field.js +51 -9
  20. package/dist/lang/ast/index.d.ts +2 -2
  21. package/dist/lang/ast/index.js +2 -2
  22. package/dist/lang/ast/query-elements/anonymous-query.d.ts +6 -1
  23. package/dist/lang/ast/query-elements/anonymous-query.js +8 -0
  24. package/dist/lang/ast/query-elements/existing-query.js +3 -0
  25. package/dist/lang/ast/query-elements/full-query.js +7 -4
  26. package/dist/lang/ast/query-elements/run-query.d.ts +6 -1
  27. package/dist/lang/ast/query-elements/run-query.js +11 -1
  28. package/dist/lang/ast/query-items/field-declaration.d.ts +6 -2
  29. package/dist/lang/ast/query-items/field-declaration.js +6 -0
  30. package/dist/lang/ast/query-items/field-references.d.ts +13 -5
  31. package/dist/lang/ast/query-items/field-references.js +10 -4
  32. package/dist/lang/ast/query-properties/aggregate.d.ts +3 -3
  33. package/dist/lang/ast/query-properties/aggregate.js +5 -4
  34. package/dist/lang/ast/query-properties/calculate.d.ts +3 -3
  35. package/dist/lang/ast/query-properties/calculate.js +5 -4
  36. package/dist/lang/ast/query-properties/declare-fields.d.ts +4 -3
  37. package/dist/lang/ast/query-properties/declare-fields.js +5 -4
  38. package/dist/lang/ast/query-properties/dimensions.d.ts +4 -0
  39. package/dist/lang/ast/query-properties/{dimmensions.js → dimensions.js} +4 -3
  40. package/dist/lang/ast/query-properties/extend.d.ts +1 -1
  41. package/dist/lang/ast/query-properties/extend.js +3 -2
  42. package/dist/lang/ast/query-properties/filters.d.ts +0 -1
  43. package/dist/lang/ast/query-properties/filters.js +2 -2
  44. package/dist/lang/ast/query-properties/group-by.d.ts +3 -3
  45. package/dist/lang/ast/query-properties/group-by.js +5 -4
  46. package/dist/lang/ast/query-properties/joins.d.ts +10 -4
  47. package/dist/lang/ast/query-properties/joins.js +16 -2
  48. package/dist/lang/ast/query-properties/measures.d.ts +1 -2
  49. package/dist/lang/ast/query-properties/measures.js +3 -2
  50. package/dist/lang/ast/query-properties/nest.d.ts +5 -1
  51. package/dist/lang/ast/query-properties/nest.js +11 -1
  52. package/dist/lang/ast/query-properties/nests.d.ts +3 -2
  53. package/dist/lang/ast/query-properties/nests.js +4 -3
  54. package/dist/lang/ast/query-properties/ordering.d.ts +1 -0
  55. package/dist/lang/ast/query-properties/ordering.js +2 -1
  56. package/dist/lang/ast/query-properties/project-statement.d.ts +3 -3
  57. package/dist/lang/ast/query-properties/project-statement.js +5 -4
  58. package/dist/lang/ast/query-properties/qop-desc.d.ts +1 -1
  59. package/dist/lang/ast/query-properties/qop-desc.js +3 -2
  60. package/dist/lang/ast/source-properties/renames.d.ts +1 -1
  61. package/dist/lang/ast/source-properties/renames.js +3 -2
  62. package/dist/lang/ast/source-properties/turtles.d.ts +3 -3
  63. package/dist/lang/ast/source-properties/turtles.js +5 -4
  64. package/dist/lang/ast/types/definition-list.d.ts +10 -0
  65. package/dist/lang/ast/types/definition-list.js +52 -0
  66. package/dist/lang/ast/types/malloy-element.d.ts +21 -6
  67. package/dist/lang/ast/types/malloy-element.js +45 -13
  68. package/dist/lang/ast/types/noteable.d.ts +12 -0
  69. package/dist/lang/ast/types/noteable.js +42 -0
  70. package/dist/lang/ast/types/query-extend-property.d.ts +1 -1
  71. package/dist/lang/ast/types/query-extend-property.js +2 -2
  72. package/dist/lang/ast/types/query-property.d.ts +3 -2
  73. package/dist/lang/ast/types/query-property.js +2 -0
  74. package/dist/lang/ast/types/source-desc.d.ts +5 -0
  75. package/dist/lang/ast/types/{explore-desc.js → source-desc.js} +7 -6
  76. package/dist/lang/ast/types/source-property.d.ts +2 -2
  77. package/dist/lang/ast/types/source-property.js +2 -0
  78. package/dist/lang/ast/types/space-field.d.ts +1 -0
  79. package/dist/lang/lib/Malloy/MalloyLexer.d.ts +56 -54
  80. package/dist/lang/lib/Malloy/MalloyLexer.js +1051 -1042
  81. package/dist/lang/lib/Malloy/MalloyParser.d.ts +326 -182
  82. package/dist/lang/lib/Malloy/MalloyParser.js +2894 -1718
  83. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +133 -19
  84. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +83 -11
  85. package/dist/lang/malloy-to-ast.d.ts +23 -10
  86. package/dist/lang/malloy-to-ast.js +144 -122
  87. package/dist/lang/parse-tree-walkers/document-symbol-walker.js +2 -1
  88. package/dist/lang/test/annotation.spec.d.ts +1 -0
  89. package/dist/lang/test/annotation.spec.js +565 -0
  90. package/dist/lang/test/parse.spec.js +20 -19
  91. package/dist/lang/test/test-translator.d.ts +2 -2
  92. package/dist/lang/test/test-translator.js +27 -15
  93. package/dist/malloy.d.ts +11 -5
  94. package/dist/malloy.js +16 -0
  95. package/dist/model/malloy_query.js +10 -0
  96. package/dist/model/malloy_types.d.ts +19 -2
  97. package/dist/model/malloy_types.js +1 -1
  98. package/dist/tags.d.ts +21 -0
  99. package/dist/tags.js +155 -0
  100. package/package.json +1 -1
  101. package/dist/lang/ast/query-properties/dimmensions.d.ts +0 -5
  102. package/dist/lang/ast/types/explore-desc.d.ts +0 -5
@@ -50,6 +50,25 @@ const AbstractParseTreeVisitor_1 = require("antlr4ts/tree/AbstractParseTreeVisit
50
50
  const ast = __importStar(require("./ast"));
51
51
  const Interval_1 = require("antlr4ts/misc/Interval");
52
52
  const ENABLE_M4_WARNINGS = false;
53
+ class IgnoredElement extends ast.MalloyElement {
54
+ constructor(src) {
55
+ super();
56
+ this.elementType = 'ignoredByParser';
57
+ this.malloySrc = src;
58
+ }
59
+ }
60
+ /**
61
+ * Get all the possibly missing annotations from this parse rule
62
+ * @param cx Any parse context which has an ANNOTATION* rules
63
+ * @returns Array of texts for the annotations
64
+ */
65
+ function getNotes(cx) {
66
+ return cx.ANNOTATION().map(a => a.text);
67
+ }
68
+ function getIsNotes(cx) {
69
+ const before = getNotes(cx._beforeIs);
70
+ return before.concat(getNotes(cx._afterIs));
71
+ }
53
72
  /**
54
73
  * ANTLR visitor pattern parse tree traversal. Generates a Malloy
55
74
  * AST from an ANTLR parse tree.
@@ -92,69 +111,18 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
92
111
  severity: sev,
93
112
  });
94
113
  }
95
- onlyExploreProperties(els) {
96
- const eps = [];
114
+ only(els, isGood, desc) {
115
+ const acceptable = [];
97
116
  for (const el of els) {
98
- if (ast.isSourceProperty(el)) {
99
- eps.push(el);
117
+ const checked = isGood(el);
118
+ if (checked) {
119
+ acceptable.push(checked);
100
120
  }
101
- else {
102
- this.astError(el, `Expected source property, not '${el.elementType}'`);
121
+ else if (!(el instanceof IgnoredElement)) {
122
+ this.astError(el, `Expected ${desc}, not '${el.elementType}'`);
103
123
  }
104
124
  }
105
- return eps;
106
- }
107
- onlyJoins(els) {
108
- const eps = [];
109
- for (const el of els) {
110
- if (el instanceof ast.Join) {
111
- eps.push(el);
112
- }
113
- else {
114
- this.astError(el, `Expected source property, not '${el.elementType}'`);
115
- }
116
- }
117
- return eps;
118
- }
119
- onlyDocStatements(els) {
120
- const eps = [];
121
- for (const el of els) {
122
- if (ast.isDocStatement(el)) {
123
- eps.push(el);
124
- }
125
- else {
126
- this.astError(el, `Expected statement, not '${el.elementType}'`);
127
- }
128
- }
129
- return eps;
130
- }
131
- onlyNestedQueries(els) {
132
- const eps = [];
133
- for (const el of els) {
134
- if (ast.isNestedQuery(el)) {
135
- eps.push(el);
136
- }
137
- else {
138
- this.astError(el, `Expected query, not '${el.elementType}'`);
139
- }
140
- }
141
- return eps;
142
- }
143
- onlyQueryRefs(els) {
144
- const eps = [];
145
- for (const el of els) {
146
- if (el instanceof ast.FieldReference ||
147
- el instanceof ast.FieldDeclaration) {
148
- eps.push(el);
149
- }
150
- else {
151
- const reported = el instanceof ast.Unimplemented && el.reported;
152
- if (!reported) {
153
- this.astError(el, `Expected query field, not '${el.elementType}'`);
154
- }
155
- }
156
- }
157
- return eps;
125
+ return acceptable;
158
126
  }
159
127
  getNumber(term) {
160
128
  return Number.parseInt(term.text);
@@ -260,19 +228,21 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
260
228
  return this.astAt(def, pcx);
261
229
  }
262
230
  visitMalloyDocument(pcx) {
263
- const stmts = this.onlyDocStatements(pcx.malloyStatement().map(scx => this.visit(scx)));
231
+ const stmts = this.only(pcx.malloyStatement().map(scx => this.visit(scx)), x => ast.isDocStatement(x) && x, 'statement');
264
232
  return new ast.Document(stmts);
265
233
  }
266
234
  visitDefineSourceStatement(pcx) {
267
235
  const defsCx = pcx.sourcePropertyList().sourceDefinition();
268
- const defs = defsCx.map(dcx => this.visitsourceDefinition(dcx));
269
- if (defs.length === 1) {
270
- return defs[0];
271
- }
272
- return new ast.DefineSourceList(defs);
236
+ const defs = defsCx.map(dcx => this.visitSourceDefinition(dcx));
237
+ const blockNotes = getNotes(pcx.tags());
238
+ const defList = new ast.DefineSourceList(defs);
239
+ defList.extendNote({ blockNotes });
240
+ return defList;
273
241
  }
274
- visitsourceDefinition(pcx) {
242
+ visitSourceDefinition(pcx) {
275
243
  const exploreDef = new ast.DefineSource(this.getIdText(pcx.sourceNameDef()), this.visitExplore(pcx.explore()), true, []);
244
+ const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
245
+ exploreDef.extendNote({ notes });
276
246
  return this.astAt(exploreDef, pcx);
277
247
  }
278
248
  visitExplore(pcx) {
@@ -285,8 +255,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
285
255
  }
286
256
  visitExploreProperties(pcx) {
287
257
  const filterCx = pcx.filterShortcut();
288
- const visited = pcx.exploreStatement().map(ecx => this.visit(ecx));
289
- const propList = new ast.ExploreDesc(this.onlyExploreProperties(visited));
258
+ const visited = this.only(pcx.exploreStatement().map(ecx => this.visit(ecx)), x => ast.isSourceProperty(x) && x, 'source property');
259
+ const propList = new ast.SourceDesc(visited);
290
260
  if (filterCx) {
291
261
  propList.push(this.getFilterShortcut(filterCx));
292
262
  }
@@ -327,7 +297,9 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
327
297
  }
328
298
  }
329
299
  }
330
- return new ast.Joins(joins);
300
+ const joinMany = new ast.Joins(joins);
301
+ joinMany.extendNote({ blockNotes: getNotes(pcx.tags()) });
302
+ return joinMany;
331
303
  }
332
304
  visitDefJoinOne(pcx) {
333
305
  const joinList = this.getJoinList(pcx.joinList());
@@ -340,7 +312,9 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
340
312
  }
341
313
  }
342
314
  }
343
- return new ast.Joins(joins);
315
+ const joinOne = new ast.Joins(joins);
316
+ joinOne.extendNote({ blockNotes: getNotes(pcx.tags()) });
317
+ return joinOne;
344
318
  }
345
319
  visitDefJoinCross(pcx) {
346
320
  const joinList = this.getJoinList(pcx.joinList());
@@ -356,16 +330,20 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
356
330
  }
357
331
  }
358
332
  }
359
- return new ast.Joins(joins);
333
+ const joinCross = new ast.Joins(joins);
334
+ joinCross.extendNote({ blockNotes: getNotes(pcx.tags()) });
335
+ return joinCross;
360
336
  }
361
337
  getJoinList(pcx) {
362
338
  return pcx.joinDef().map(jcx => this.visit(jcx));
363
339
  }
364
340
  getJoinSource(name, ecx) {
365
341
  if (ecx) {
366
- return this.visitExplore(ecx);
342
+ const joinSrc = this.visitExplore(ecx.explore());
343
+ const notes = getNotes(ecx._before_is).concat(getNotes(ecx._after_is));
344
+ return { joinFrom: joinSrc, notes };
367
345
  }
368
- return new ast.NamedSource(name);
346
+ return { joinFrom: new ast.NamedSource(name), notes: [] };
369
347
  }
370
348
  visitQueryJoinStatement(pcx) {
371
349
  const result = this.astAt(this.visit(pcx.joinStatement()), pcx);
@@ -376,19 +354,21 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
376
354
  }
377
355
  visitJoinOn(pcx) {
378
356
  const joinAs = this.getModelEntryName(pcx.joinNameDef());
379
- const joinFrom = this.getJoinSource(joinAs, pcx.explore());
357
+ const { joinFrom, notes } = this.getJoinSource(joinAs, pcx.isExplore());
380
358
  const join = new ast.ExpressionJoin(joinAs, joinFrom);
381
359
  const onCx = pcx.joinExpression();
382
360
  if (onCx) {
383
361
  join.joinOn = this.getFieldExpr(onCx);
384
362
  }
363
+ join.extendNote({ notes: getNotes(pcx).concat(notes) });
385
364
  return this.astAt(join, pcx);
386
365
  }
387
366
  visitJoinWith(pcx) {
388
367
  const joinAs = this.getModelEntryName(pcx.joinNameDef());
389
- const joinFrom = this.getJoinSource(joinAs, pcx.explore());
368
+ const { joinFrom, notes } = this.getJoinSource(joinAs, pcx.isExplore());
390
369
  const joinOn = this.getFieldExpr(pcx.fieldExpr());
391
370
  const join = new ast.KeyJoin(joinAs, joinFrom, joinOn);
371
+ join.extendNote({ notes: getNotes(pcx).concat(notes) });
392
372
  return this.astAt(join, pcx);
393
373
  }
394
374
  getFieldDef(pcx, makeFieldDef) {
@@ -396,16 +376,20 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
396
376
  const fieldName = this.getIdText(pcx.fieldNameDef());
397
377
  const valExpr = this.getFieldExpr(defCx);
398
378
  const def = new makeFieldDef(valExpr, fieldName, this.getSourceCode(defCx));
379
+ const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
380
+ def.extendNote({ notes });
399
381
  return this.astAt(def, pcx);
400
382
  }
401
383
  visitDefDimensions(pcx) {
402
384
  const defs = this.getFieldDefs(pcx.defList().fieldDef(), ast.DimensionFieldDeclaration);
403
385
  const stmt = new ast.Dimensions(defs);
386
+ stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
404
387
  return this.astAt(stmt, pcx);
405
388
  }
406
389
  visitDefMeasures(pcx) {
407
390
  const defs = this.getFieldDefs(pcx.defList().fieldDef(), ast.MeasureFieldDeclaration);
408
391
  const stmt = new ast.Measures(defs);
392
+ stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
409
393
  return this.astAt(stmt, pcx);
410
394
  }
411
395
  visitQueryExtend(pcx) {
@@ -469,6 +453,12 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
469
453
  .map(cx => this.visitExploreQueryDef(cx));
470
454
  return new ast.Turtles(babyTurtles);
471
455
  }
456
+ visitDefExploreQuery(pcx) {
457
+ const queryDefs = this.visitSubQueryDefList(pcx.subQueryDefList());
458
+ const blockNotes = getNotes(pcx.tags());
459
+ queryDefs.extendNote({ blockNotes });
460
+ return queryDefs;
461
+ }
472
462
  visitDefExplorePrimaryKey(pcx) {
473
463
  const node = new ast.PrimaryKey(this.getFieldName(pcx.fieldName()));
474
464
  return this.astAt(node, pcx);
@@ -495,16 +485,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
495
485
  return this.astAt(timezoneStatement, cx);
496
486
  }
497
487
  visitQueryProperties(pcx) {
498
- const qProps = pcx
499
- .queryStatement()
500
- .map(qcx => this.astAt(this.visit(qcx), qcx))
501
- .filter((p) => {
502
- if (ast.isQueryProperty(p)) {
503
- return true;
504
- }
505
- p.log(`Unexpected statement type '${p.elementType}' in query`);
506
- return false;
507
- });
488
+ const qProps = this.only(pcx.queryStatement().map(qcx => this.astAt(this.visit(qcx), qcx)), x => ast.isQueryProperty(x) && x, 'query statement');
508
489
  const fcx = pcx.filterShortcut();
509
490
  if (fcx) {
510
491
  qProps.push(this.getFilterShortcut(fcx));
@@ -519,18 +500,10 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
519
500
  const dim = this.getFieldDef(pcx, makeFieldDef);
520
501
  return this.astAt(dim, pcx);
521
502
  }
522
- // visitQueryFieldNameless(
523
- // pcx: parse.QueryFieldNamelessContext
524
- // ): ast.MalloyElement {
525
- // this.contextError(pcx, `Expressions in queries must have names`);
526
- // const noItem = new ast.Unimplemented();
527
- // noItem.reported = true;
528
- // return noItem;
529
- // }
530
503
  getQueryFieldEntry(ctx, makeFieldDef, makeFieldRef) {
531
- const fieldPath = ctx.fieldPath();
532
- if (fieldPath) {
533
- return this.getFieldPath(fieldPath, makeFieldRef);
504
+ const refCx = ctx.taggedRef();
505
+ if (refCx) {
506
+ return this.getTaggedRef(refCx, makeFieldRef);
534
507
  }
535
508
  const def = ctx.fieldDef();
536
509
  if (def) {
@@ -539,28 +512,40 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
539
512
  throw new Error('Expected query field entry to be a field reference or definition');
540
513
  }
541
514
  getQueryItems(pcx, makeFieldDef, makeFieldRef) {
542
- const itemList = pcx
515
+ return this.only(pcx
543
516
  .queryFieldEntry()
544
- .map(e => this.getQueryFieldEntry(e, makeFieldDef, makeFieldRef));
545
- return this.onlyQueryRefs(itemList);
517
+ .map(e => this.getQueryFieldEntry(e, makeFieldDef, makeFieldRef)), x => x instanceof ast.FieldReference || x instanceof ast.FieldDeclaration
518
+ ? x
519
+ : false, 'query field');
546
520
  }
547
521
  visitAggregateStatement(pcx) {
548
- return new ast.Aggregate(this.getQueryItems(pcx.queryFieldList(), ast.AggregateFieldDeclaration, ast.AggregateFieldReference));
522
+ const agStmt = new ast.Aggregate(this.getQueryItems(pcx.queryFieldList(), ast.AggregateFieldDeclaration, ast.AggregateFieldReference));
523
+ agStmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
524
+ return agStmt;
549
525
  }
550
526
  visitGroupByStatement(pcx) {
551
- return new ast.GroupBy(this.getQueryItems(pcx.queryFieldList(), ast.GroupByFieldDeclaration, ast.GroupByFieldReference));
527
+ const groupBy = new ast.GroupBy(this.getQueryItems(pcx.queryFieldList(), ast.GroupByFieldDeclaration, ast.GroupByFieldReference));
528
+ groupBy.extendNote({ blockNotes: getNotes(pcx.tags()) });
529
+ return groupBy;
552
530
  }
553
531
  visitCalculateStatement(pcx) {
554
- return new ast.Calculate(this.getQueryItems(pcx.queryFieldList(), ast.CalculateFieldDeclaration, ast.CalculateFieldReference));
532
+ const stmt = new ast.Calculate(this.getQueryItems(pcx.queryFieldList(), ast.CalculateFieldDeclaration, ast.CalculateFieldReference));
533
+ stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
534
+ return stmt;
535
+ }
536
+ getTaggedRef(pcx, makeFieldRef) {
537
+ const ref = this.getFieldPath(pcx.fieldPath(), makeFieldRef);
538
+ ref.extendNote({ notes: getNotes(pcx.tags()) });
539
+ return ref;
555
540
  }
556
541
  getFieldCollectionMember(pcx, makeFieldDef, makeFieldRef) {
557
542
  const fieldDef = pcx.fieldDef();
558
543
  if (fieldDef) {
559
544
  return this.getFieldDef(fieldDef, makeFieldDef);
560
545
  }
561
- const fieldPath = pcx.fieldPath();
562
- if (fieldPath) {
563
- return this.getFieldPath(fieldPath, makeFieldRef);
546
+ const refCx = pcx.taggedRef();
547
+ if (refCx) {
548
+ return this.getTaggedRef(refCx, makeFieldRef);
564
549
  }
565
550
  const collectionWildcard = pcx.collectionWildCard();
566
551
  if (collectionWildcard) {
@@ -575,6 +560,11 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
575
560
  .map(c => this.getFieldCollectionMember(c, ast.ProjectFieldDeclaration, ast.ProjectFieldReference));
576
561
  return this.astAt(new ast.ProjectStatement(fields), pcx);
577
562
  }
563
+ visitProjectStatement(pcx) {
564
+ const stmt = this.visitFieldCollection(pcx.fieldCollection());
565
+ stmt.extendNote({ blockNotes: getNotes(pcx.tags()) });
566
+ return stmt;
567
+ }
578
568
  visitCollectionWildCard(pcx) {
579
569
  const nameCx = pcx.fieldPath();
580
570
  const stars = pcx.STAR() ? '*' : '**';
@@ -689,28 +679,34 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
689
679
  const stmts = pcx
690
680
  .topLevelQueryDef()
691
681
  .map(cx => this.visitTopLevelQueryDef(cx));
692
- if (stmts.length === 1) {
693
- return stmts[0];
694
- }
695
- return new ast.DefineQueryList(stmts);
682
+ const blockNotes = getNotes(pcx.tags());
683
+ const queryDefs = new ast.DefineQueryList(stmts);
684
+ queryDefs.extendNote({ blockNotes });
685
+ return queryDefs;
696
686
  }
697
687
  visitTopLevelQueryDef(pcx) {
698
688
  const queryName = this.getIdText(pcx.queryName());
699
- const queryDef = this.visit(pcx.query());
700
- if (ast.isQueryElement(queryDef)) {
701
- return this.astAt(new ast.DefineQuery(queryName, queryDef), pcx);
689
+ const queryExpr = this.visit(pcx.query());
690
+ if (ast.isQueryElement(queryExpr)) {
691
+ const notes = getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine()));
692
+ const queryDef = new ast.DefineQuery(queryName, queryExpr);
693
+ queryDef.extendNote({ notes });
694
+ return this.astAt(queryDef, pcx);
702
695
  }
703
- throw this.internalError(pcx, `Expect query definition, got a '${queryDef.elementType}'`);
696
+ throw this.internalError(pcx, `Expected query definition, got a '${queryExpr.elementType}'`);
704
697
  }
705
698
  visitAnonymousQuery(pcx) {
706
699
  const defCx = pcx.topLevelAnonQueryDef();
707
700
  const query = this.visit(defCx.query());
708
701
  if (ast.isQueryElement(query)) {
709
- const el = this.astAt(new ast.AnonymousQuery(query), defCx);
702
+ const theQuery = new ast.AnonymousQuery(query);
703
+ const notes = getNotes(pcx.topLevelAnonQueryDef().tags());
704
+ const blockNotes = getNotes(pcx.tags());
705
+ theQuery.extendNote({ notes, blockNotes });
710
706
  if (ENABLE_M4_WARNINGS) {
711
- this.astError(el, 'Anonymous `query:` statements are deprecated, use `run:` instead', 'warn');
707
+ this.astError(theQuery, 'Anonymous `query:` statements are deprecated, use `run:` instead', 'warn');
712
708
  }
713
- return el;
709
+ return this.astAt(theQuery, pcx);
714
710
  }
715
711
  throw this.internalError(pcx, `Anonymous query matched, but ${query.elementType} found`);
716
712
  }
@@ -718,6 +714,8 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
718
714
  const query = this.visit(pcx.topLevelAnonQueryDef().query());
719
715
  if (ast.isQueryElement(query)) {
720
716
  const el = new ast.RunQueryDef(query);
717
+ el.extendNote({ blockNotes: getNotes(pcx._blockTags) });
718
+ el.extendNote({ notes: getNotes(pcx._noteTags) });
721
719
  return this.astAt(el, pcx);
722
720
  }
723
721
  throw this.internalError(pcx, `Run query matched, but ${query.elementType} found`);
@@ -727,33 +725,43 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
727
725
  const el = this.astAt(new ast.RunQueryRef(name), pcx.queryName());
728
726
  return this.astAt(el, pcx);
729
727
  }
728
+ visitNestStatement(pcx) {
729
+ const nests = this.visitNestedQueryList(pcx.nestedQueryList());
730
+ nests.extendNote({ blockNotes: getNotes(pcx.tags()) });
731
+ return nests;
732
+ }
730
733
  visitNestedQueryList(pcx) {
731
- const nestedList = pcx.nestEntry().map(cx => this.visit(cx));
732
- if (nestedList.length === 1) {
733
- return nestedList[0];
734
- }
735
- return new ast.Nests(this.onlyNestedQueries(nestedList));
734
+ return new ast.Nests(this.only(pcx.nestEntry().map(cx => this.visit(cx)), x => ast.isNestedQuery(x) && x, 'query'));
736
735
  }
737
736
  visitNestExisting(pcx) {
738
737
  const name = this.getFieldName(pcx.queryName());
739
738
  const propsCx = pcx.queryProperties();
739
+ const notes = getNotes(pcx.tags());
740
740
  if (propsCx) {
741
741
  const nestRefine = new ast.NestRefinement(name);
742
742
  const queryDesc = this.visitQueryProperties(propsCx);
743
743
  nestRefine.refineHead(queryDesc);
744
+ nestRefine.extendNote({ notes });
744
745
  return this.astAt(nestRefine, pcx);
745
746
  }
746
- return this.astAt(new ast.NestReference(name), pcx);
747
+ const nestRef = this.astAt(new ast.NestReference(name), pcx);
748
+ nestRef.extendNote({ notes });
749
+ return nestRef;
747
750
  }
748
751
  visitNestDef(pcx) {
749
752
  const name = this.getIdText(pcx.queryName());
750
753
  const nestDef = new ast.NestDefinition(name);
751
754
  this.buildPipelineFromName(nestDef, pcx.pipelineFromName());
755
+ nestDef.extendNote({
756
+ notes: getNotes(pcx.tags()).concat(getIsNotes(pcx.isDefine())),
757
+ });
752
758
  return this.astAt(nestDef, pcx);
753
759
  }
754
760
  visitExploreQueryDef(pcx) {
755
761
  const name = this.getIdText(pcx.exploreQueryNameDef());
756
762
  const queryDef = new ast.TurtleDecl(name);
763
+ const notes = getNotes(pcx).concat(getIsNotes(pcx.isDefine()));
764
+ queryDef.extendNote({ notes });
757
765
  this.buildPipelineFromName(queryDef, pcx.pipelineFromName());
758
766
  return this.astAt(queryDef, pcx);
759
767
  }
@@ -1102,6 +1110,20 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
1102
1110
  const enabled = pcx.sampleSpec().TRUE() !== undefined;
1103
1111
  return new ast.SampleProperty({ enable: enabled });
1104
1112
  }
1113
+ visitDocAnnotations(pcx) {
1114
+ const allNotes = pcx.DOC_ANNOTATION().map(note => note.text);
1115
+ return new ast.ModelAnnotation(allNotes);
1116
+ }
1117
+ visitIgnoredObjectAnnotations(pcx) {
1118
+ return new IgnoredElement(pcx.text);
1119
+ }
1120
+ visitIgnoredModelAnnotations(pcx) {
1121
+ return new IgnoredElement(pcx.text);
1122
+ }
1123
+ visitDefExploreAnnotation(pcx) {
1124
+ const allNotes = pcx.ANNOTATION().map(note => note.text);
1125
+ return new ast.ObjectAnnotation(allNotes);
1126
+ }
1105
1127
  }
1106
1128
  exports.MalloyToAST = MalloyToAST;
1107
1129
  //# sourceMappingURL=malloy-to-ast.js.map
@@ -135,7 +135,8 @@ class DocumentSymbolWalker {
135
135
  }
136
136
  }
137
137
  enterQueryFieldEntry(pcx) {
138
- const fieldRef = pcx.fieldPath();
138
+ var _a;
139
+ const fieldRef = (_a = pcx.taggedRef()) === null || _a === void 0 ? void 0 : _a.fieldPath();
139
140
  if (fieldRef === undefined)
140
141
  return;
141
142
  const symbol = {
@@ -0,0 +1 @@
1
+ import './parse-expects';