@malloydata/malloy 0.0.56-dev230707230009 → 0.0.56-dev230710162623
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.
|
@@ -185,6 +185,7 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
185
185
|
safeParts.push(part);
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
+
(0, parse_utils_1.unIndent)(safeParts);
|
|
188
189
|
return safeParts.join('');
|
|
189
190
|
}
|
|
190
191
|
// string: shortString | sqlString; So this will never happen
|
|
@@ -199,6 +200,9 @@ class MalloyToAST extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor {
|
|
|
199
200
|
sqlStr.push(part);
|
|
200
201
|
}
|
|
201
202
|
}
|
|
203
|
+
// Until SQL writer properly indents turducken, it actually looks better
|
|
204
|
+
// in the output to NOT de-indent the SQL sources
|
|
205
|
+
// unIndent(sqlStr.elements);
|
|
202
206
|
sqlStr.complete();
|
|
203
207
|
this.astAt(sqlStr, pcx);
|
|
204
208
|
}
|
|
@@ -14,7 +14,7 @@ export declare type HasString = ParserRuleContext & {
|
|
|
14
14
|
string: () => StringContext;
|
|
15
15
|
};
|
|
16
16
|
declare type StringPart = ParserRuleContext | string;
|
|
17
|
-
export declare function getStringParts(cx: SqlStringContext): StringPart
|
|
17
|
+
export declare function getStringParts(cx: SqlStringContext): Generator<StringPart>;
|
|
18
18
|
/**
|
|
19
19
|
* Parses the interior of a string, doing all \ substitutions. In most cases
|
|
20
20
|
* a lexical analyzer has already recognized this as a string. As a convenience,
|
|
@@ -47,4 +47,5 @@ export declare type HasID = ParserRuleContext & {
|
|
|
47
47
|
*/
|
|
48
48
|
export declare function getId(cx: HasID): string;
|
|
49
49
|
export declare function getOptionalId(cx: ParserRuleContext): string | undefined;
|
|
50
|
+
export declare function unIndent(parts: (string | unknown)[]): void;
|
|
50
51
|
export {};
|
package/dist/lang/parse-utils.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.getOptionalId = exports.getId = exports.getIsNotes = exports.getNotes = exports.parseString = exports.getStringParts = exports.getStringIfShort = exports.getShortString = void 0;
|
|
25
|
+
exports.unIndent = exports.getOptionalId = exports.getId = exports.getIsNotes = exports.getNotes = exports.parseString = exports.getStringParts = exports.getStringIfShort = exports.getShortString = void 0;
|
|
26
26
|
/**
|
|
27
27
|
* Take the text of a matched string, including the matching quote
|
|
28
28
|
* characters, and return the actual contents of the string after
|
|
@@ -47,26 +47,23 @@ function getStringIfShort(cx) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
exports.getStringIfShort = getStringIfShort;
|
|
50
|
-
function getStringParts(cx) {
|
|
50
|
+
function* getStringParts(cx) {
|
|
51
51
|
var _a;
|
|
52
52
|
if (cx) {
|
|
53
|
-
const strParts = [];
|
|
54
53
|
for (const part of cx.sqlInterpolation()) {
|
|
55
54
|
const upToOpen = part.OPEN_CODE().text;
|
|
56
55
|
if (upToOpen.length > 2) {
|
|
57
|
-
|
|
56
|
+
yield upToOpen.slice(0, upToOpen.length - 2);
|
|
58
57
|
}
|
|
59
58
|
if (part.query()) {
|
|
60
|
-
|
|
59
|
+
yield part.query();
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
const lastChars = (_a = cx.SQL_END()) === null || _a === void 0 ? void 0 : _a.text.slice(0, -3);
|
|
64
63
|
if (lastChars && lastChars.length > 0) {
|
|
65
|
-
|
|
64
|
+
yield lastChars;
|
|
66
65
|
}
|
|
67
|
-
return strParts;
|
|
68
66
|
}
|
|
69
|
-
return [];
|
|
70
67
|
}
|
|
71
68
|
exports.getStringParts = getStringParts;
|
|
72
69
|
var ParseState;
|
|
@@ -185,4 +182,57 @@ function getOptionalId(cx) {
|
|
|
185
182
|
}
|
|
186
183
|
}
|
|
187
184
|
exports.getOptionalId = getOptionalId;
|
|
185
|
+
function* linesOf(allText) {
|
|
186
|
+
while (allText.length > 0) {
|
|
187
|
+
const lineMatch = allText.match(/^.*?\r?\n/);
|
|
188
|
+
let nextLine = allText;
|
|
189
|
+
if (lineMatch) {
|
|
190
|
+
nextLine = lineMatch[0];
|
|
191
|
+
}
|
|
192
|
+
yield nextLine;
|
|
193
|
+
allText = allText.slice(nextLine.length);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function minIndent(allText) {
|
|
197
|
+
let leftMost;
|
|
198
|
+
for (const line of linesOf(allText)) {
|
|
199
|
+
// look for lines starting with spaces, that have a non blank character somewhere
|
|
200
|
+
const leadingMatch = line.match(/^( *).*[^\s]/);
|
|
201
|
+
if (leadingMatch) {
|
|
202
|
+
const indentBy = leadingMatch[1].length;
|
|
203
|
+
if (leftMost === undefined || indentBy < leftMost) {
|
|
204
|
+
leftMost = indentBy;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return leftMost;
|
|
209
|
+
}
|
|
210
|
+
function unIndent(parts) {
|
|
211
|
+
let removeSpaces;
|
|
212
|
+
for (const part of parts) {
|
|
213
|
+
if (typeof part === 'string') {
|
|
214
|
+
const newLeft = minIndent(part);
|
|
215
|
+
if (newLeft !== undefined &&
|
|
216
|
+
(removeSpaces === undefined || newLeft < removeSpaces)) {
|
|
217
|
+
removeSpaces = newLeft;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (removeSpaces) {
|
|
222
|
+
for (let i = 0; i <= parts.length; i += 1) {
|
|
223
|
+
const ent = parts[i];
|
|
224
|
+
if (typeof ent === 'string') {
|
|
225
|
+
let newEnt = '';
|
|
226
|
+
for (let line of linesOf(ent)) {
|
|
227
|
+
if (line[0] === ' ') {
|
|
228
|
+
line = line.slice(removeSpaces);
|
|
229
|
+
}
|
|
230
|
+
newEnt += line;
|
|
231
|
+
}
|
|
232
|
+
parts[i] = newEnt;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.unIndent = unIndent;
|
|
188
238
|
//# sourceMappingURL=parse-utils.js.map
|
|
@@ -25,7 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
require("./parse-expects");
|
|
26
26
|
const parse_utils_1 = require("../parse-utils");
|
|
27
27
|
const test_translator_1 = require("./test-translator");
|
|
28
|
-
describe('
|
|
28
|
+
describe('quote comprehension inside strings', () => {
|
|
29
29
|
test('\\b', () => {
|
|
30
30
|
expect((0, parse_utils_1.parseString)('\\b')).toEqual('\b');
|
|
31
31
|
});
|
|
@@ -58,8 +58,36 @@ describe('test internal string parsing', () => {
|
|
|
58
58
|
expect((0, parse_utils_1.parseString)('|42|', '|')).toEqual('42');
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
|
-
describe('
|
|
61
|
+
describe('string parsing in language', () => {
|
|
62
62
|
const tz = 'America/Mexico_City';
|
|
63
|
+
test('multi-line indent increasing', () => {
|
|
64
|
+
const checking = new test_translator_1.BetaExpression(`"""
|
|
65
|
+
left
|
|
66
|
+
mid
|
|
67
|
+
right
|
|
68
|
+
"""`);
|
|
69
|
+
expect(checking).toTranslate();
|
|
70
|
+
const v = checking.generated().value[0];
|
|
71
|
+
expect(v).toMatchObject({ literal: '\nleft\n mid\n right\n' });
|
|
72
|
+
});
|
|
73
|
+
test('multi-line indent decreasing', () => {
|
|
74
|
+
const checking = new test_translator_1.BetaExpression(`"""
|
|
75
|
+
right
|
|
76
|
+
mid
|
|
77
|
+
left
|
|
78
|
+
"""`);
|
|
79
|
+
expect(checking).toTranslate();
|
|
80
|
+
const v = checking.generated().value[0];
|
|
81
|
+
expect(v).toMatchObject({ literal: '\n right\n mid\nleft\n' });
|
|
82
|
+
});
|
|
83
|
+
test('multi-line indent keep', () => {
|
|
84
|
+
const checking = new test_translator_1.BetaExpression(`"""right
|
|
85
|
+
mid
|
|
86
|
+
left"""`);
|
|
87
|
+
expect(checking).toTranslate();
|
|
88
|
+
const v = checking.generated().value[0];
|
|
89
|
+
expect(v).toMatchObject({ literal: 'right\n mid\n left' });
|
|
90
|
+
});
|
|
63
91
|
test('timezone single quote', () => {
|
|
64
92
|
const m = new test_translator_1.TestTranslator(`run: a-> {timezone: '${tz}'; project: *}`);
|
|
65
93
|
expect(m).toParse();
|