@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.
- package/dist/lang/parse-tree-walkers/document-symbol-walker.d.ts +1 -0
- package/dist/lang/parse-tree-walkers/document-symbol-walker.js +44 -7
- package/dist/lang/test/document-symbol-walker.spec.js +59 -0
- package/dist/lang/test/test-translator.js +3 -1
- package/dist/malloy.d.ts +22 -1
- package/dist/malloy.js +22 -1
- package/dist/tags.js +6 -4
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
189
|
-
type:
|
|
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
|
|
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 =
|
|
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
|
-
|
|
75
|
-
|
|
74
|
+
const docMatch = src.match(/^##?" /);
|
|
75
|
+
if (docMatch) {
|
|
76
|
+
return { docString: src.slice(docMatch[0].length) };
|
|
76
77
|
}
|
|
77
|
-
|
|
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(
|
|
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) {
|