@malloydata/malloy 0.0.48-dev230624040051 → 0.0.48-dev230626171048

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.
@@ -7,5 +7,6 @@ export interface DocumentSymbol {
7
7
  type: string;
8
8
  name: string;
9
9
  children: DocumentSymbol[];
10
+ lensRange?: DocumentRange;
10
11
  }
11
12
  export declare function walkForDocumentSymbols(forParse: MalloyTranslation, tokens: CommonTokenStream, parseTree: ParseTree): DocumentSymbol[];
@@ -37,20 +37,32 @@ class DocumentSymbolWalker {
37
37
  peekScope() {
38
38
  return this.scopes[this.scopes.length - 1];
39
39
  }
40
+ enterTopLevelQueryDefs(pcx) {
41
+ const blockRange = this.translator.rangeFromContext(pcx);
42
+ const defs = pcx.topLevelQueryDef();
43
+ if (defs.length === 1) {
44
+ this.blockRange = blockRange;
45
+ }
46
+ }
40
47
  enterTopLevelQueryDef(pcx) {
41
48
  this.symbols.push({
42
49
  range: this.translator.rangeFromContext(pcx),
43
50
  name: pcx.queryName().text,
44
51
  type: 'query',
45
52
  children: [],
53
+ lensRange: this.blockRange,
46
54
  });
47
55
  }
56
+ exitTopLevelQueryDefs(_pcx) {
57
+ this.blockRange = undefined;
58
+ }
48
59
  enterRunStatementDef(pcx) {
49
60
  this.symbols.push({
50
61
  range: this.translator.rangeFromContext(pcx.topLevelAnonQueryDef()),
51
62
  name: 'unnamed_query',
52
63
  type: 'unnamed_query',
53
64
  children: [],
65
+ lensRange: this.translator.rangeFromContext(pcx),
54
66
  });
55
67
  }
56
68
  enterRunStatementRef(pcx) {
@@ -59,22 +71,37 @@ class DocumentSymbolWalker {
59
71
  name: pcx.queryName().id().text,
60
72
  type: 'query',
61
73
  children: [],
74
+ lensRange: this.translator.rangeFromContext(pcx),
62
75
  });
63
76
  }
64
- enterTopLevelAnonQueryDef(pcx) {
77
+ enterAnonymousQuery(pcx) {
65
78
  this.symbols.push({
66
- range: this.translator.rangeFromContext(pcx),
79
+ range: this.translator.rangeFromContext(pcx.topLevelAnonQueryDef().query()),
67
80
  name: 'unnamed_query',
68
81
  type: 'unnamed_query',
69
82
  children: [],
83
+ lensRange: this.translator.rangeFromContext(pcx),
70
84
  });
71
85
  }
86
+ enterDefineSourceStatement(pcx) {
87
+ const blockRange = this.translator.rangeFromContext(pcx);
88
+ const sourcePl = pcx.sourcePropertyList();
89
+ const defs = sourcePl.sourceDefinition();
90
+ if (defs.length === 1) {
91
+ this.blockRange = blockRange;
92
+ }
93
+ }
94
+ exitDefineSourceStatement(_pcx) {
95
+ this.blockRange = undefined;
96
+ }
72
97
  enterSourceDefinition(pcx) {
98
+ const range = this.translator.rangeFromContext(pcx);
73
99
  this.scopes.push({
74
- range: this.translator.rangeFromContext(pcx),
100
+ range,
75
101
  name: pcx.sourceNameDef().id().text,
76
102
  type: 'explore',
77
103
  children: [],
104
+ lensRange: this.blockRange,
78
105
  });
79
106
  }
80
107
  exitSourceDefinition(_pcx) {
@@ -83,12 +110,20 @@ class DocumentSymbolWalker {
83
110
  this.symbols.push(scope);
84
111
  }
85
112
  }
113
+ enterDefExploreQuery(pcx) {
114
+ const blockRange = this.translator.rangeFromContext(pcx);
115
+ const defs = pcx.subQueryDefList().exploreQueryDef();
116
+ if (defs.length === 1) {
117
+ this.blockRange = blockRange;
118
+ }
119
+ }
86
120
  enterExploreQueryDef(pcx) {
87
121
  const symbol = {
88
122
  range: this.translator.rangeFromContext(pcx),
89
123
  name: pcx.exploreQueryNameDef().id().text,
90
124
  type: 'query',
91
125
  children: [],
126
+ lensRange: this.blockRange,
92
127
  };
93
128
  const parent = this.peekScope();
94
129
  if (parent) {
@@ -99,6 +134,9 @@ class DocumentSymbolWalker {
99
134
  exitExploreQueryDef(_pcx) {
100
135
  this.popScope();
101
136
  }
137
+ exitDefExploreQuery(_pcx) {
138
+ this.blockRange = undefined;
139
+ }
102
140
  handleNestEntry(pcx) {
103
141
  const symbol = {
104
142
  range: this.translator.rangeFromContext(pcx),
@@ -181,12 +219,11 @@ class DocumentSymbolWalker {
181
219
  }
182
220
  }
183
221
  enterDefineSQLStatement(pcx) {
184
- var _a;
185
- const name = (_a = pcx.nameSQLBlock()) === null || _a === void 0 ? void 0 : _a.text;
222
+ const name = pcx.nameSQLBlock().text;
186
223
  const symbol = {
187
224
  range: this.translator.rangeFromContext(pcx),
188
- name: name || 'unnamed_sql',
189
- type: name === undefined ? 'unnamed_sql' : 'sql',
225
+ name: name,
226
+ type: 'sql',
190
227
  children: [],
191
228
  };
192
229
  this.symbols.push(symbol);
@@ -45,6 +45,21 @@ function testSymbol(source, name, type, path) {
45
45
  type,
46
46
  });
47
47
  }
48
+ function testLens(source, path) {
49
+ const doc = new MalloyExplore(source.code);
50
+ let current = {
51
+ children: doc.symbols,
52
+ };
53
+ path.forEach(segment => {
54
+ current = current.children[segment];
55
+ });
56
+ expect(doc.logger.hasErrors()).toBeFalsy();
57
+ const expectedLensRange = source.locations[0].range;
58
+ const expected = 'lensRange' in current && current.lensRange !== undefined
59
+ ? { lensRange: expectedLensRange }
60
+ : { range: expectedLensRange };
61
+ expect(current).toMatchObject(expected);
62
+ }
48
63
  test('source symbols are included', () => {
49
64
  testSymbol((0, test_translator_1.markSource) `source: ${"flights is table('my.table.flights')"}`, 'flights', 'explore', [0]);
50
65
  });
@@ -114,4 +129,48 @@ test('join ons are included', () => {
114
129
  }
115
130
  `, 'a', 'join', [0, 0]);
116
131
  });
132
+ test('source lenses go before block annotations when one source', () => {
133
+ testLens((0, test_translator_1.markSource) `${`# tag
134
+ # tag2
135
+ source:
136
+ # tag3
137
+ flights is table('my.table.flights')`}`, [0]);
138
+ });
139
+ test('source lenses go before individual annotations when more than one source', () => {
140
+ testLens((0, test_translator_1.markSource) `# tag
141
+ source:
142
+ ${`# tag2
143
+ flights is table('my.table.flights')`}
144
+
145
+ flights2 is table('my.table.flights')`, [0]);
146
+ });
147
+ test('query lenses go before block annotations when one source', () => {
148
+ testLens((0, test_translator_1.markSource) `${`# tag
149
+ # tag2
150
+ query:
151
+ # tag3
152
+ q is flights -> by_carrier`}`, [0]);
153
+ });
154
+ test('query lenses go before individual annotations when more than one source', () => {
155
+ testLens((0, test_translator_1.markSource) `# tag
156
+ query:
157
+ ${`# tag2
158
+ q is flights -> by_carrier`}
159
+
160
+ q2 is flights -> by_carrier`, [0]);
161
+ });
162
+ test('anonymous query lenses go before block annotations', () => {
163
+ testLens((0, test_translator_1.markSource) `${`# tag
164
+ # tag2
165
+ query:
166
+ # tag3
167
+ flights -> by_carrier`}`, [0]);
168
+ });
169
+ test('run lenses go before block annotations', () => {
170
+ testLens((0, test_translator_1.markSource) `${`# tag
171
+ # tag2
172
+ run:
173
+ # tag3
174
+ flights -> by_carrier`}`, [0]);
175
+ });
117
176
  //# sourceMappingURL=document-symbol-walker.spec.js.map
@@ -464,7 +464,9 @@ function markSource(unmarked, ...marked) {
464
464
  start,
465
465
  end: {
466
466
  line: start.line + bitLines.length - 1,
467
- character: bitLines.length === 1 ? start.character + mark.length : mark.length,
467
+ character: bitLines.length === 1
468
+ ? start.character + mark.length
469
+ : bitLines[bitLines.length - 1].length,
468
470
  },
469
471
  },
470
472
  };
package/dist/malloy.d.ts CHANGED
@@ -144,13 +144,14 @@ export declare class MalloyError extends Error {
144
144
  /**
145
145
  * A compiled Malloy document.
146
146
  */
147
- export declare class Model {
147
+ export declare class Model implements Taggable {
148
148
  private modelDef;
149
149
  private queryList;
150
150
  private sqlBlocks;
151
151
  _referenceAt: (location: ModelDocumentPosition) => DocumentReference | undefined;
152
152
  readonly problems: LogMessage[];
153
153
  constructor(modelDef: ModelDef, queryList: InternalQuery[], sqlBlocks: SQLBlockStructDef[], problems: LogMessage[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined);
154
+ getTags(): Tags;
154
155
  /**
155
156
  * Retrieve a document reference for the token at the given position within
156
157
  * the document that produced this model.
@@ -315,6 +316,19 @@ export declare class DocumentRange {
315
316
  character: number;
316
317
  };
317
318
  };
319
+ /**
320
+ * Construct a DocumentRange from JSON.
321
+ */
322
+ static fromJSON(json: {
323
+ start: {
324
+ line: number;
325
+ character: number;
326
+ };
327
+ end: {
328
+ line: number;
329
+ character: number;
330
+ };
331
+ }): DocumentRange;
318
332
  }
319
333
  /**
320
334
  * A position within a Malloy document.
@@ -346,6 +360,7 @@ export declare class DocumentPosition {
346
360
  */
347
361
  export declare class DocumentSymbol {
348
362
  private _range;
363
+ private _lensRange;
349
364
  private _type;
350
365
  private _name;
351
366
  private _children;
@@ -354,6 +369,12 @@ export declare class DocumentSymbol {
354
369
  * @return The range of characters in the source Malloy document that define this symbol.
355
370
  */
356
371
  get range(): DocumentRange;
372
+ /**
373
+ * @return The range of characters in the source Malloy document that define this symbol,
374
+ * including tags. Note: "block tags" are included if there is exactly one
375
+ * definition in the block.
376
+ */
377
+ get lensRange(): DocumentRange;
357
378
  /**
358
379
  * @return The type of symbol.
359
380
  *
package/dist/malloy.js CHANGED
@@ -325,6 +325,9 @@ class Model {
325
325
  this._referenceAt = referenceAt;
326
326
  this.problems = problems;
327
327
  }
328
+ getTags() {
329
+ return new tags_1.Tags(this.modelDef.annotation);
330
+ }
328
331
  /**
329
332
  * Retrieve a document reference for the token at the given position within
330
333
  * the document that produced this model.
@@ -593,6 +596,12 @@ class DocumentRange {
593
596
  end: this.end.toJSON(),
594
597
  };
595
598
  }
599
+ /**
600
+ * Construct a DocumentRange from JSON.
601
+ */
602
+ static fromJSON(json) {
603
+ return new DocumentRange(new DocumentPosition(json.start.line, json.start.character), new DocumentPosition(json.end.line, json.end.character));
604
+ }
596
605
  }
597
606
  exports.DocumentRange = DocumentRange;
598
607
  /**
@@ -630,7 +639,10 @@ exports.DocumentPosition = DocumentPosition;
630
639
  */
631
640
  class DocumentSymbol {
632
641
  constructor(documentSymbol) {
633
- this._range = new DocumentRange(new DocumentPosition(documentSymbol.range.start.line, documentSymbol.range.start.character), new DocumentPosition(documentSymbol.range.end.line, documentSymbol.range.end.character));
642
+ this._range = DocumentRange.fromJSON(documentSymbol.range);
643
+ this._lensRange = documentSymbol.lensRange
644
+ ? DocumentRange.fromJSON(documentSymbol.lensRange)
645
+ : undefined;
634
646
  this._type = documentSymbol.type;
635
647
  this._name = documentSymbol.name;
636
648
  this._children = documentSymbol.children.map(child => new DocumentSymbol(child));
@@ -641,6 +653,15 @@ class DocumentSymbol {
641
653
  get range() {
642
654
  return this._range;
643
655
  }
656
+ /**
657
+ * @return The range of characters in the source Malloy document that define this symbol,
658
+ * including tags. Note: "block tags" are included if there is exactly one
659
+ * definition in the block.
660
+ */
661
+ get lensRange() {
662
+ var _a;
663
+ return (_a = this._lensRange) !== null && _a !== void 0 ? _a : this._range;
664
+ }
644
665
  /**
645
666
  * @return The type of symbol.
646
667
  *
package/dist/tags.js CHANGED
@@ -71,10 +71,12 @@ function tagList(tagNode) {
71
71
  * A string is " enclosing and ending in " with \" allowed inside
72
72
  */
73
73
  function parseTag(src, tagProp) {
74
- if (src.startsWith('#" ')) {
75
- return { docString: src.slice(3) };
74
+ const docMatch = src.match(/^##?" /);
75
+ if (docMatch) {
76
+ return { docString: src.slice(docMatch[0].length) };
76
77
  }
77
- if (!src.startsWith('# ')) {
78
+ const propMatch = src.match(/^##? /);
79
+ if (!propMatch) {
78
80
  return;
79
81
  }
80
82
  /*
@@ -84,7 +86,7 @@ function parseTag(src, tagProp) {
84
86
  *
85
87
  * Seems wrong to be writing a parser though.
86
88
  */
87
- const tokens = tokenize(src.slice(2));
89
+ const tokens = tokenize(src.slice(propMatch[0].length));
88
90
  let tn = 0;
89
91
  const lastToken = tokens.length - 1;
90
92
  while (tn <= lastToken) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.48-dev230624040051",
3
+ "version": "0.0.48-dev230626171048",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",