UNPKG

4.88 kBJavaScriptView Raw
1import { __extends } from "tslib";
2import { SourceType } from 'coffee-lex';
3import notNull from '../utils/notNull';
4import NodePatcher from './NodePatcher';
5var SharedBlockPatcher = /** @class */ (function (_super) {
6 __extends(SharedBlockPatcher, _super);
7 function SharedBlockPatcher(patcherContext, statements) {
8 var _this = _super.call(this, patcherContext) || this;
9 _this.shouldPatchInline = null;
10 _this.statements = statements;
11 return _this;
12 }
13 /**
14 * Insert statements somewhere in this block.
15 */
16 SharedBlockPatcher.prototype.insertStatementsAtIndex = function (statements, index) {
17 var _this = this;
18 var separator = this.inline() ? '; ' : ';\n';
19 if (index === this.statements.length) {
20 var lastStatement = this.statements[this.statements.length - 1];
21 var terminatorTokenIndex = this.context.sourceTokens.indexOfTokenMatchingPredicate(function (token) { return token.type === SourceType.NEWLINE || token.type === SourceType.SEMICOLON; }, lastStatement.outerEndTokenIndex);
22 var insertionPoint_1 = terminatorTokenIndex
23 ? notNull(this.sourceTokenAtIndex(terminatorTokenIndex)).start
24 : lastStatement.outerEnd;
25 insertionPoint_1 = Math.min(insertionPoint_1, this.getBoundingPatcher().innerEnd);
26 var indent_1 = lastStatement.getIndent();
27 statements.forEach(function (line) {
28 var sep = line.trim().startsWith('//') ? '\n' : separator;
29 _this.insert(insertionPoint_1, "" + sep + indent_1 + line);
30 });
31 }
32 else {
33 var statementToInsertBefore = this.statements[index];
34 var insertionPoint_2 = statementToInsertBefore.outerStart;
35 var indent_2 = statementToInsertBefore.getIndent();
36 statements.forEach(function (line) {
37 var sep = line.trim().startsWith('//') ? '\n' : separator;
38 _this.insert(insertionPoint_2, "" + line + sep + indent_2);
39 });
40 }
41 };
42 /**
43 * Insert a statement before the current block. Since blocks can be patched in
44 * a number of ways, this needs to handle a few cases:
45 * - If it's completely inline, we don't deal with any indentation and just
46 * put a semicolon-separated statement before the start.
47 * - If it's a normal non-inline block, we insert the statement beforehand
48 * with the given indentation. However, `this.outerStart` is the first
49 * non-whitespace character of the first line, so it's already indented, so
50 * if we want to add a line with *less* indentation, it's a lot more tricky.
51 * We handle this by walking backward to the previous newline and inserting
52 * a new line from there. This allows the prepended line to have whatever
53 * indentation level we want.
54 * - In some cases, such as nontrivial loop expressions with an inline body,
55 * the source CoffeeScript is inline, but we want the result to be
56 * non-inline, so we need to be a lot more careful. The normal non-inline
57 * strategy won't work because there's no newline to walk back to in the
58 * source CoffeeScript, so the strategy is to instead always insert at
59 * `this.outerStart`. That means that the indentation for the actual body
60 * needs to be done later, just before the body itself is patched. See the
61 * uses of shouldConvertInlineBodyToNonInline in LoopPatcher for an example.
62 */
63 SharedBlockPatcher.prototype.insertLineBefore = function (statement, indent) {
64 if (indent === void 0) { indent = this.getIndent(); }
65 if (this.inline()) {
66 this.insert(this.outerStart, statement + "; ");
67 }
68 else if (this.node.inline) {
69 this.insert(this.outerStart, "" + indent + statement + ";\n");
70 }
71 else {
72 var insertIndex = this.outerStart;
73 while (insertIndex > 0 && this.context.source[insertIndex] !== '\n') {
74 insertIndex--;
75 }
76 this.insert(insertIndex, "\n" + indent + statement + ";");
77 }
78 };
79 SharedBlockPatcher.prototype.insertLineAfter = function (statement, indent) {
80 if (this.inline()) {
81 this.insert(this.outerEnd, "; " + statement);
82 }
83 else {
84 this.insert(this.outerEnd, "\n" + indent + statement + ";");
85 }
86 };
87 /**
88 * Gets whether this patcher's block is inline (on the same line as the node
89 * that contains it) or not.
90 */
91 SharedBlockPatcher.prototype.inline = function () {
92 if (this.shouldPatchInline !== null) {
93 return this.shouldPatchInline;
94 }
95 return this.node.inline;
96 };
97 return SharedBlockPatcher;
98}(NodePatcher));
99export default SharedBlockPatcher;