coffeehaml 0.7.5 → 0.7.7
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/expressions.js +195 -40
- package/dist/prettier/options.js +1 -1
- package/package.json +3 -3
- package/dist/coffeescript-formatter.js +0 -309
- package/dist/options.js +0 -232
- package/dist/printer.js +0 -583
package/dist/expressions.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
// expressions.coffee — CoffeeScript expression compilation bridge
|
|
3
|
-
var _coffeeScriptAvailable, _coffeeScriptUnavailableReason, _require, checkCoffeeScript, loadCoffeeScript, stripCoffeeWrapper, stripToConst
|
|
2
|
+
// expressions.coffee — CoffeeScript expression compilation bridge
|
|
3
|
+
var _coffeeScriptAvailable, _coffeeScriptUnavailableReason, _require, checkCoffeeScript, collapseWs, loadCoffeeScript, objectTarget, splitTopLevelStatements, stripCoffeeWrapper, stripToConst,
|
|
4
|
+
indexOf = [].indexOf;
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
createRequire
|
|
@@ -110,11 +111,11 @@ stripCoffeeWrapper = function(js, _original) {
|
|
|
110
111
|
result = js.trim();
|
|
111
112
|
result = result.replace(/;\s*$/, '');
|
|
112
113
|
lines = (function() {
|
|
113
|
-
var
|
|
114
|
+
var j, len, ref, results;
|
|
114
115
|
ref = result.split('\n');
|
|
115
116
|
results = [];
|
|
116
|
-
for (
|
|
117
|
-
l = ref[
|
|
117
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
|
118
|
+
l = ref[j];
|
|
118
119
|
if (l.trim() !== '') {
|
|
119
120
|
results.push(l);
|
|
120
121
|
}
|
|
@@ -123,10 +124,10 @@ stripCoffeeWrapper = function(js, _original) {
|
|
|
123
124
|
})();
|
|
124
125
|
if (lines.length > 0) {
|
|
125
126
|
varLines = (function() {
|
|
126
|
-
var
|
|
127
|
+
var j, len, results;
|
|
127
128
|
results = [];
|
|
128
|
-
for (
|
|
129
|
-
l = lines[
|
|
129
|
+
for (j = 0, len = lines.length; j < len; j++) {
|
|
130
|
+
l = lines[j];
|
|
130
131
|
if (/^\s*var\b/.test(l)) {
|
|
131
132
|
results.push(l);
|
|
132
133
|
}
|
|
@@ -134,10 +135,10 @@ stripCoffeeWrapper = function(js, _original) {
|
|
|
134
135
|
return results;
|
|
135
136
|
})();
|
|
136
137
|
meaningful = (function() {
|
|
137
|
-
var
|
|
138
|
+
var j, len, results;
|
|
138
139
|
results = [];
|
|
139
|
-
for (
|
|
140
|
-
l = lines[
|
|
140
|
+
for (j = 0, len = lines.length; j < len; j++) {
|
|
141
|
+
l = lines[j];
|
|
141
142
|
if (!/^\s*var\b/.test(l)) {
|
|
142
143
|
results.push(l);
|
|
143
144
|
}
|
|
@@ -179,45 +180,199 @@ export var compileStatement = function(source, location = null) {
|
|
|
179
180
|
};
|
|
180
181
|
|
|
181
182
|
// ─── Convert var → const/let ───────────────────────────────
|
|
183
|
+
|
|
184
|
+
// Extract the bound variable name from one entry of an object
|
|
185
|
+
// destructuring pattern — shorthand `x` stays `x`, aliased `key: target`
|
|
186
|
+
// yields `target`.
|
|
187
|
+
objectTarget = function(pair) {
|
|
188
|
+
pair = pair.trim();
|
|
189
|
+
if (pair.includes(':')) {
|
|
190
|
+
return pair.split(':')[1].trim();
|
|
191
|
+
} else {
|
|
192
|
+
return pair;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
182
196
|
stripToConst = function(js) {
|
|
183
|
-
var
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (l.trim() !== '') {
|
|
191
|
-
results.push(l);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return results;
|
|
195
|
-
})();
|
|
196
|
-
varLine = lines.find(function(l) {
|
|
197
|
-
return /^\s*var\b/.test(l);
|
|
197
|
+
var allConsumed, assignments, body, consumed, inner, j, len, m, n, name, names, s, stmts, varIdx, varNames;
|
|
198
|
+
stmts = splitTopLevelStatements(js);
|
|
199
|
+
if (stmts.length === 0) {
|
|
200
|
+
return js.replace(/;\s*$/, '');
|
|
201
|
+
}
|
|
202
|
+
varIdx = stmts.findIndex(function(s) {
|
|
203
|
+
return /^\s*var\b/.test(s);
|
|
198
204
|
});
|
|
199
|
-
if (
|
|
205
|
+
if (varIdx < 0) {
|
|
200
206
|
return js.replace(/;\s*$/, '');
|
|
201
207
|
}
|
|
202
|
-
varNames =
|
|
208
|
+
varNames = stmts[varIdx].replace(/^\s*var\s+/, '').replace(/;\s*$/, '').split(',').map(function(s) {
|
|
203
209
|
return s.trim();
|
|
204
210
|
}).filter(Boolean);
|
|
211
|
+
body = (function() {
|
|
212
|
+
var j, len, ref, results;
|
|
213
|
+
ref = stmts.filter(function(s, i) {
|
|
214
|
+
return i !== varIdx;
|
|
215
|
+
});
|
|
216
|
+
results = [];
|
|
217
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
|
218
|
+
s = ref[j];
|
|
219
|
+
results.push(collapseWs(s).replace(/;\s*$/, ''));
|
|
220
|
+
}
|
|
221
|
+
return results;
|
|
222
|
+
})();
|
|
205
223
|
assignments = [];
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
224
|
+
consumed = [];
|
|
225
|
+
for (j = 0, len = body.length; j < len; j++) {
|
|
226
|
+
s = body[j];
|
|
227
|
+
m = s.match(/^\[([^\]]*)\]\s*=/);
|
|
228
|
+
if (m != null) {
|
|
229
|
+
// Array destructuring: [a, b] = expr
|
|
230
|
+
names = (function() {
|
|
231
|
+
var k, len1, ref, results;
|
|
232
|
+
ref = m[1].split(',');
|
|
233
|
+
results = [];
|
|
234
|
+
for (k = 0, len1 = ref.length; k < len1; k++) {
|
|
235
|
+
n = ref[k];
|
|
236
|
+
if (n.trim()) {
|
|
237
|
+
results.push(n.trim());
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return results;
|
|
241
|
+
})();
|
|
242
|
+
consumed = consumed.concat(names);
|
|
243
|
+
assignments.push('const ' + s);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
m = s.match(/^\(\s*\{([^}]*)\}\s*=.*\)$/);
|
|
247
|
+
if (m != null) {
|
|
248
|
+
// Object destructuring: ({x, y} = expr) -> const {x, y} = expr
|
|
249
|
+
inner = s.replace(/^\s*\(\s*/, '').replace(/\s*\)\s*$/, '');
|
|
250
|
+
names = (function() {
|
|
251
|
+
var k, len1, ref, results;
|
|
252
|
+
ref = m[1].split(',');
|
|
253
|
+
results = [];
|
|
254
|
+
for (k = 0, len1 = ref.length; k < len1; k++) {
|
|
255
|
+
n = ref[k];
|
|
256
|
+
if (n.trim()) {
|
|
257
|
+
results.push(objectTarget(n));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return results;
|
|
261
|
+
})();
|
|
262
|
+
consumed = consumed.concat(names);
|
|
263
|
+
assignments.push('const ' + inner);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
name = varNames.find(function(n) {
|
|
267
|
+
return s.startsWith(`${n} =`) || s.startsWith(`${n}=`);
|
|
212
268
|
});
|
|
213
|
-
if (
|
|
214
|
-
|
|
269
|
+
if (name != null) {
|
|
270
|
+
consumed.push(name);
|
|
271
|
+
assignments.push('const ' + s);
|
|
215
272
|
}
|
|
216
273
|
}
|
|
217
|
-
|
|
274
|
+
allConsumed = varNames.every(function(n) {
|
|
275
|
+
return indexOf.call(consumed, n) >= 0;
|
|
276
|
+
});
|
|
277
|
+
if (assignments.length > 0 && allConsumed) {
|
|
218
278
|
return assignments.join('; ');
|
|
219
279
|
}
|
|
220
|
-
return
|
|
221
|
-
|
|
222
|
-
|
|
280
|
+
return ((function() {
|
|
281
|
+
var k, len1, results;
|
|
282
|
+
results = [];
|
|
283
|
+
for (k = 0, len1 = stmts.length; k < len1; k++) {
|
|
284
|
+
s = stmts[k];
|
|
285
|
+
// Fallback: keep the original var declaration so no variable goes
|
|
286
|
+
// undeclared (e.g. chained assignment `a = b = 1`).
|
|
287
|
+
results.push(collapseWs(s).replace(/;\s*$/, ''));
|
|
288
|
+
}
|
|
289
|
+
return results;
|
|
290
|
+
})()).join('; ');
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// Split compiled JS into top-level statements, respecting string literals
|
|
294
|
+
// and bracket nesting so multiline object/array/call literals stay intact.
|
|
295
|
+
splitTopLevelStatements = function(js) {
|
|
296
|
+
var ch, depth, i, inString, last, start, stmts;
|
|
297
|
+
stmts = [];
|
|
298
|
+
depth = 0;
|
|
299
|
+
inString = null;
|
|
300
|
+
start = 0;
|
|
301
|
+
i = 0;
|
|
302
|
+
while (i < js.length) {
|
|
303
|
+
ch = js[i];
|
|
304
|
+
if (inString) {
|
|
305
|
+
if (ch === '\\') {
|
|
306
|
+
i += 2;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (ch === inString) {
|
|
310
|
+
inString = null;
|
|
311
|
+
}
|
|
312
|
+
i++;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (ch === "'" || ch === '"' || ch === '`') {
|
|
316
|
+
inString = ch;
|
|
317
|
+
} else if (ch === '{' || ch === '[' || ch === '(') {
|
|
318
|
+
depth++;
|
|
319
|
+
} else if (ch === '}' || ch === ']' || ch === ')') {
|
|
320
|
+
depth--;
|
|
321
|
+
} else if (ch === ';' && depth === 0) {
|
|
322
|
+
stmts.push(js.slice(start, i).trim());
|
|
323
|
+
start = i + 1;
|
|
324
|
+
}
|
|
325
|
+
i++;
|
|
326
|
+
}
|
|
327
|
+
last = js.slice(start).trim();
|
|
328
|
+
if (last) {
|
|
329
|
+
stmts.push(last);
|
|
330
|
+
}
|
|
331
|
+
return stmts;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// Collapse runs of whitespace to single spaces, preserving string contents.
|
|
335
|
+
collapseWs = function(s) {
|
|
336
|
+
var ch, i, inString, out, pendingSpace;
|
|
337
|
+
out = '';
|
|
338
|
+
inString = null;
|
|
339
|
+
pendingSpace = false;
|
|
340
|
+
i = 0;
|
|
341
|
+
while (i < s.length) {
|
|
342
|
+
ch = s[i];
|
|
343
|
+
if (inString) {
|
|
344
|
+
out += ch;
|
|
345
|
+
if (ch === '\\' && i + 1 < s.length) {
|
|
346
|
+
out += s[i + 1];
|
|
347
|
+
i += 2;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (ch === inString) {
|
|
351
|
+
inString = null;
|
|
352
|
+
}
|
|
353
|
+
i++;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (ch === "'" || ch === '"' || ch === '`') {
|
|
357
|
+
if (pendingSpace && out.length) {
|
|
358
|
+
out += ' ';
|
|
359
|
+
}
|
|
360
|
+
pendingSpace = false;
|
|
361
|
+
inString = ch;
|
|
362
|
+
out += ch;
|
|
363
|
+
i++;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
if (/\s/.test(ch)) {
|
|
367
|
+
pendingSpace = true;
|
|
368
|
+
} else {
|
|
369
|
+
if (pendingSpace && out.length) {
|
|
370
|
+
out += ' ';
|
|
371
|
+
}
|
|
372
|
+
pendingSpace = false;
|
|
373
|
+
out += ch;
|
|
374
|
+
}
|
|
375
|
+
i++;
|
|
376
|
+
}
|
|
377
|
+
return out;
|
|
223
378
|
};
|
package/dist/prettier/options.js
CHANGED
|
@@ -216,7 +216,7 @@ export var defaultOptions = {
|
|
|
216
216
|
implicitDivExpansion: false,
|
|
217
217
|
maxChainLength: 4,
|
|
218
218
|
inlineThreshold: -1,
|
|
219
|
-
voidElementStyle: '
|
|
219
|
+
voidElementStyle: 'explicit',
|
|
220
220
|
attributeStyle: 'preserve',
|
|
221
221
|
attributeMultilineThreshold: 1,
|
|
222
222
|
attributeSort: 'none',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coffeehaml",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "Haml structure. CoffeeScript semantics. React runtime. Zero runtime. Vite-native.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "coffee -c -o dist/ src/*.coffee && coffee -c -o dist/prettier/ src/prettier/*.coffee",
|
|
64
64
|
"dev": "coffee -c -w -o dist/ src/*.coffee & coffee -c -w -o dist/prettier/ src/prettier/*.coffee",
|
|
65
|
-
"test": "node test/prettier/run-integration-tests.mjs && node test/prettier/run-coffeescript-tests.mjs && node test/prettier/run-statement-merge-tests.mjs",
|
|
65
|
+
"test": "node test/run-compiler-tests.mjs && node test/prettier/run-integration-tests.mjs && node test/prettier/run-coffeescript-tests.mjs && node test/prettier/run-statement-merge-tests.mjs",
|
|
66
66
|
"prepublishOnly": "npm run build",
|
|
67
67
|
"fmt": "prettier --write --plugin=. **/*.chaml"
|
|
68
68
|
},
|
|
@@ -91,4 +91,4 @@
|
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"source-map": "^0.7.4"
|
|
93
93
|
}
|
|
94
|
-
}
|
|
94
|
+
}
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
// coffeescript-formatter.coffee — CoffeeScript token-based expression formatter
|
|
3
|
-
var DEFAULT_OPTS, EXPR_STARTERS, FOR_KEYWORDS, KEYWORD_SPACE_AFTER, NO_SPACE_AFTER, NO_SPACE_BEFORE, SPACE_AFTER, SPACE_BOTH, _require, getTokenText, hasImplicitTokens, hasMethodChain, isUnaryOp, lineWrap, loadCoffeeScript, needsSpaceBetween, normalizeSpacing, wrapMethodChain;
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
createRequire
|
|
7
|
-
} from 'module';
|
|
8
|
-
|
|
9
|
-
_require = createRequire(import.meta.url);
|
|
10
|
-
|
|
11
|
-
loadCoffeeScript = function() {
|
|
12
|
-
try {
|
|
13
|
-
return _require('coffeescript');
|
|
14
|
-
} catch (error) {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// ─── Token types ──────────────────────────────────────────
|
|
20
|
-
// CSToken: { type, value, range, generated?, originalText? }
|
|
21
|
-
|
|
22
|
-
// ─── Spacing categories ───────────────────────────────────
|
|
23
|
-
NO_SPACE_BEFORE = new Set([',', ':', ';', '.', '?.', '::', ')', ']', '}', 'CALL_END', 'PARAM_END', 'INDEX_END', 'POST_IF', 'POST_FOR', 'POST_WHILE', 'TERMINATOR']);
|
|
24
|
-
|
|
25
|
-
NO_SPACE_AFTER = new Set(['.', '?.', '::', '...', '..', '(', '[', '{', 'CALL_START', 'PARAM_START', 'INDEX_START', 'STRING_START', 'INTERPOLATION_START', 'INDENT', '@']);
|
|
26
|
-
|
|
27
|
-
SPACE_AFTER = new Set([',', ':']);
|
|
28
|
-
|
|
29
|
-
SPACE_BOTH = new Set(['=', '?=', '+', '-', 'MATH', '**', 'SHIFT', '&', '|', '^', '&&', '||', '?', '=>', '->', 'COMPARE', 'COMPOUND_ASSIGN', 'RELATION', 'FOR', 'ELSE', 'IF', 'WHILE']);
|
|
30
|
-
|
|
31
|
-
KEYWORD_SPACE_AFTER = new Set(['RETURN', 'THROW', 'NEW', 'TYPEOF', 'INSTANCEOF', 'DELETE', 'CLASS', 'EXTENDS', 'DEFAULT', 'IMPORT', 'EXPORT', 'AWAIT', 'YIELD', 'BREAK', 'CONTINUE', 'SWITCH']);
|
|
32
|
-
|
|
33
|
-
FOR_KEYWORDS = new Set(['FORIN', 'FOROF', 'WHEN', 'BY']);
|
|
34
|
-
|
|
35
|
-
EXPR_STARTERS = new Set(['(', '[', '{', ',', ':', '=', '?=', '+', '-', 'MATH', '**', 'SHIFT', '&', '|', '^', '&&', '||', '?', '=>', '->', 'COMPARE', 'COMPOUND_ASSIGN', 'RETURN', 'INDENT', 'OUTDENT', 'TERMINATOR', 'FOR', 'FORIN', 'FOROF', 'WHILE', 'IF', 'ELSE', 'THROW', 'NEW', 'TYPEOF', 'INSTANCEOF', 'DELETE', 'EXTENDS', 'DEFAULT', 'CALL_START', 'PARAM_START', 'INDEX_START', 'UNARY']);
|
|
36
|
-
|
|
37
|
-
DEFAULT_OPTS = {
|
|
38
|
-
printWidth: 80,
|
|
39
|
-
methodChainAlign: true,
|
|
40
|
-
enabled: true
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// ─── Public API ───────────────────────────────────────────
|
|
44
|
-
export var formatCoffeeScript = function(source, options = {}) {
|
|
45
|
-
var cs, normalized, opts, rawTokens, tokens;
|
|
46
|
-
opts = {...DEFAULT_OPTS, ...options};
|
|
47
|
-
if (!opts.enabled) {
|
|
48
|
-
return source;
|
|
49
|
-
}
|
|
50
|
-
if (!(source && source.trim() !== '')) {
|
|
51
|
-
return source;
|
|
52
|
-
}
|
|
53
|
-
try {
|
|
54
|
-
cs = loadCoffeeScript();
|
|
55
|
-
if (!(cs && typeof cs.tokens === 'function')) {
|
|
56
|
-
return source;
|
|
57
|
-
}
|
|
58
|
-
rawTokens = cs.tokens(source);
|
|
59
|
-
if (!(rawTokens && rawTokens.length > 0)) {
|
|
60
|
-
return source;
|
|
61
|
-
}
|
|
62
|
-
tokens = rawTokens.map(function(t) {
|
|
63
|
-
var ref, ref1, ref2, ref3;
|
|
64
|
-
return {
|
|
65
|
-
type: t[0],
|
|
66
|
-
value: t[1],
|
|
67
|
-
range: (ref = (ref1 = t[2]) != null ? ref1.range : void 0) != null ? ref : [0, 0],
|
|
68
|
-
generated: !!((ref2 = t[2]) != null ? ref2.generated : void 0),
|
|
69
|
-
originalText: ((ref3 = t[2]) != null ? ref3.range : void 0) && t[2].range[0] < t[2].range[1] ? source.slice(t[2].range[0], t[2].range[1]) : t[1]
|
|
70
|
-
};
|
|
71
|
-
});
|
|
72
|
-
if (hasImplicitTokens(tokens)) {
|
|
73
|
-
return source;
|
|
74
|
-
}
|
|
75
|
-
normalized = normalizeSpacing(tokens, source);
|
|
76
|
-
if (normalized.length > opts.printWidth) {
|
|
77
|
-
return lineWrap(normalized, opts, source);
|
|
78
|
-
}
|
|
79
|
-
return normalized;
|
|
80
|
-
} catch (error) {
|
|
81
|
-
return source;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// ─── Block formatting ─────────────────────────────────────
|
|
86
|
-
export var formatCoffeeScriptBlock = function(source, options = {}) {
|
|
87
|
-
var formatted, lines, opts;
|
|
88
|
-
opts = {...DEFAULT_OPTS, ...options};
|
|
89
|
-
if (!opts.enabled) {
|
|
90
|
-
return source;
|
|
91
|
-
}
|
|
92
|
-
if (!(source && source.trim() !== '')) {
|
|
93
|
-
return source;
|
|
94
|
-
}
|
|
95
|
-
lines = source.split('\n');
|
|
96
|
-
formatted = lines.map(function(line) {
|
|
97
|
-
var formattedExpr, leading, ref, ref1, trimmed;
|
|
98
|
-
trimmed = line.trim();
|
|
99
|
-
if (!trimmed) {
|
|
100
|
-
return '';
|
|
101
|
-
}
|
|
102
|
-
leading = (ref = (ref1 = line.match(/^(\s*)/)) != null ? ref1[1] : void 0) != null ? ref : '';
|
|
103
|
-
try {
|
|
104
|
-
formattedExpr = formatCoffeeScript(trimmed, options);
|
|
105
|
-
return leading + formattedExpr;
|
|
106
|
-
} catch (error) {
|
|
107
|
-
return line;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
return formatted.join('\n');
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// ─── Implicit token detection ─────────────────────────────
|
|
114
|
-
hasImplicitTokens = function(tokens) {
|
|
115
|
-
var j, len, ref, t;
|
|
116
|
-
for (j = 0, len = tokens.length; j < len; j++) {
|
|
117
|
-
t = tokens[j];
|
|
118
|
-
if ((ref = t.type) === 'INDENT' || ref === 'OUTDENT' || ref === 'TERMINATOR') {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (t.generated) {
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
if (t.range && t.range[0] >= t.range[1]) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return false;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
// ─── Spacing normalization ────────────────────────────────
|
|
132
|
-
normalizeSpacing = function(tokens, originalSource = null) {
|
|
133
|
-
var afterPrevIsExprStart, cur, j, len, parts, prevVisible, prevWasAtExprStart, ref, ref1, ref2, text, trimmed;
|
|
134
|
-
parts = [];
|
|
135
|
-
prevVisible = null;
|
|
136
|
-
prevWasAtExprStart = true;
|
|
137
|
-
afterPrevIsExprStart = true;
|
|
138
|
-
for (j = 0, len = tokens.length; j < len; j++) {
|
|
139
|
-
cur = tokens[j];
|
|
140
|
-
// Skip implicit CALL/PARAM tokens
|
|
141
|
-
if ((ref = cur.type) === 'CALL_START' || ref === 'CALL_END') {
|
|
142
|
-
if (cur.generated) {
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
if (cur.range && cur.range[0] >= cur.range[1]) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if ((ref1 = cur.type) === 'PARAM_START' || ref1 === 'PARAM_END') {
|
|
150
|
-
if (cur.generated) {
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (cur.range && cur.range[0] >= cur.range[1]) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
// Handle INDENT — represents inline then/when/else/etc from CoffeeScript
|
|
158
|
-
if (cur.type === 'INDENT') {
|
|
159
|
-
text = getTokenText(cur, originalSource);
|
|
160
|
-
trimmed = text != null ? text.trim() : void 0;
|
|
161
|
-
if (trimmed && trimmed !== '') {
|
|
162
|
-
parts.push(' ' + trimmed + ' ');
|
|
163
|
-
prevWasAtExprStart = false;
|
|
164
|
-
afterPrevIsExprStart = true;
|
|
165
|
-
prevVisible = cur;
|
|
166
|
-
}
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
if (cur.type === 'OUTDENT') {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
// Skip TERMINATOR
|
|
173
|
-
if (cur.type === 'TERMINATOR') {
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
// Space before this token
|
|
177
|
-
if (prevVisible && ((ref2 = prevVisible.type) !== 'INDENT' && ref2 !== 'OUTDENT')) {
|
|
178
|
-
if (needsSpaceBetween(prevVisible, cur, prevWasAtExprStart)) {
|
|
179
|
-
parts.push(' ');
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
parts.push(getTokenText(cur, originalSource));
|
|
183
|
-
prevWasAtExprStart = afterPrevIsExprStart;
|
|
184
|
-
afterPrevIsExprStart = EXPR_STARTERS.has(cur.type);
|
|
185
|
-
prevVisible = cur;
|
|
186
|
-
}
|
|
187
|
-
return parts.join('');
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
getTokenText = function(token, originalSource = null) {
|
|
191
|
-
if (token.generated) {
|
|
192
|
-
return token.value;
|
|
193
|
-
}
|
|
194
|
-
if (!(token.range && token.range[0] < token.range[1])) {
|
|
195
|
-
return token.value;
|
|
196
|
-
}
|
|
197
|
-
if (originalSource) {
|
|
198
|
-
return originalSource.slice(token.range[0], token.range[1]);
|
|
199
|
-
}
|
|
200
|
-
return token.value;
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
needsSpaceBetween = function(prev, cur, prevAtExprStart) {
|
|
204
|
-
var text;
|
|
205
|
-
if (NO_SPACE_AFTER.has(prev.type)) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
if (NO_SPACE_BEFORE.has(cur.type)) {
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
211
|
-
if (prev.type === '@') {
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
if (SPACE_AFTER.has(prev.type)) {
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
if (FOR_KEYWORDS.has(prev.type) || FOR_KEYWORDS.has(cur.type)) {
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
|
-
if (KEYWORD_SPACE_AFTER.has(prev.type)) {
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
|
-
if (prev.type === 'UNARY') {
|
|
224
|
-
text = prev.originalText || prev.value;
|
|
225
|
-
if (text === '!' || text === '!!') {
|
|
226
|
-
return false;
|
|
227
|
-
}
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
if (SPACE_BOTH.has(prev.type) || SPACE_BOTH.has(cur.type)) {
|
|
231
|
-
if (isUnaryOp(prev, prevAtExprStart)) {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
return true;
|
|
235
|
-
}
|
|
236
|
-
if (prev.type === 'IDENTIFIER' && cur.type === 'IDENTIFIER') {
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
return false;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
isUnaryOp = function(prev, prevAtExprStart) {
|
|
243
|
-
var ref;
|
|
244
|
-
if ((ref = prev.type) !== '+' && ref !== '-') {
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
if (prevAtExprStart) {
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
|
-
if (prev.range && prev.range[0] === 0) {
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
return false;
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// ─── Line wrapping ────────────────────────────────────────
|
|
257
|
-
lineWrap = function(source, opts, fallback) {
|
|
258
|
-
if (opts.methodChainAlign && hasMethodChain(source)) {
|
|
259
|
-
return wrapMethodChain(source, opts);
|
|
260
|
-
}
|
|
261
|
-
return fallback;
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
hasMethodChain = function(source) {
|
|
265
|
-
return (source.match(/\.[a-zA-Z_$]/g) || []).length >= 2;
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
wrapMethodChain = function(source, _opts) {
|
|
269
|
-
var ch, chars, current, depth, i, indent, result;
|
|
270
|
-
indent = ' ';
|
|
271
|
-
result = [];
|
|
272
|
-
chars = [...source];
|
|
273
|
-
depth = 0;
|
|
274
|
-
current = '';
|
|
275
|
-
i = 0;
|
|
276
|
-
while (i < chars.length) {
|
|
277
|
-
ch = chars[i];
|
|
278
|
-
if (ch === '(' || ch === '[' || ch === '{') {
|
|
279
|
-
depth++;
|
|
280
|
-
}
|
|
281
|
-
if (ch === ')' || ch === ']' || ch === '}') {
|
|
282
|
-
depth--;
|
|
283
|
-
}
|
|
284
|
-
if (ch === '.' && depth === 0 && i > 0 && chars[i - 1] !== '?' && current.trim().length > 0) {
|
|
285
|
-
if (result.length === 0) {
|
|
286
|
-
result.push(current.trimEnd());
|
|
287
|
-
} else {
|
|
288
|
-
result.push(indent + current.trimEnd());
|
|
289
|
-
}
|
|
290
|
-
current = ch;
|
|
291
|
-
i++;
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
current += ch;
|
|
295
|
-
i++;
|
|
296
|
-
}
|
|
297
|
-
if (current.trim().length > 0) {
|
|
298
|
-
if (result.length === 0) {
|
|
299
|
-
result.push(current.trim());
|
|
300
|
-
} else {
|
|
301
|
-
result.push(indent + current.trim());
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
if (result.length > 1) {
|
|
305
|
-
return result.join('\n');
|
|
306
|
-
} else {
|
|
307
|
-
return source;
|
|
308
|
-
}
|
|
309
|
-
};
|