@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 {};
@@ -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
- strParts.push(upToOpen.slice(0, upToOpen.length - 2));
56
+ yield upToOpen.slice(0, upToOpen.length - 2);
58
57
  }
59
58
  if (part.query()) {
60
- strParts.push(part.query());
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
- strParts.push(lastChars);
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('test internal string parsing', () => {
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('all strings are parsed in all places', () => {
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.56-dev230707230009",
3
+ "version": "0.0.56-dev230710162623",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",