UNPKG

decaffeinate-parser

Version:

A better AST for CoffeeScript, inspired by CoffeeScriptRedux.

83 lines (82 loc) 4.18 kB
"use strict"; exports.__esModule = true; var coffee_lex_1 = require("coffee-lex"); var nodes_1 = require("decaffeinate-coffeescript2/lib/coffeescript/nodes"); var util_1 = require("util"); var nodes_2 = require("../nodes"); var getLocation_1 = require("../util/getLocation"); var isCommentOnlyNode_1 = require("../util/isCommentOnlyNode"); var mapAny_1 = require("./mapAny"); function mapBlock(context, node) { var childContext = context; if (context.parseState.isInClassBody()) { // Replicate a bug in CoffeeScript: at any block where we see an // object-style proto assignment, stop considering proto assignments in any // sub-traversals. This is taken from the walkBody implementation. var hasProtoAssignChild = node.expressions.some(function (child) { return child instanceof nodes_1.Value && child.isObject(true); }); if (hasProtoAssignChild) { childContext = childContext.updateState(function (s) { return s.dropCurrentClass(); }); } } var _a = getLocation_1["default"](context, node), line = _a.line, column = _a.column, start = _a.start, end = _a.end, raw = _a.raw; var previousTokenIndex = context.sourceTokens .indexOfTokenNearSourceIndex(start) .previous(); var previousToken = previousTokenIndex ? context.sourceTokens.tokenAtIndex(previousTokenIndex) : null; var inline = previousToken ? previousToken.type !== coffee_lex_1.SourceType.NEWLINE : false; return new nodes_2.Block(line, column, start, end, raw, node.expressions .filter(function (expression) { return !isCommentOnlyNode_1["default"](expression); }) .map(function (expression) { return mapChild(context, childContext, expression); }) .reduce(function (arr, current) { return arr.concat(current); }, []), inline); } exports["default"] = mapBlock; function mapChild(blockContext, childContext, node) { if (blockContext.parseState.isInClassBody() && node instanceof nodes_1.Value && node.isObject(true)) { var obj = node.base; if (!(obj instanceof nodes_1.Obj)) { throw new Error('Expected isObject node to be an object.'); } var statements = []; for (var _i = 0, _a = obj.properties; _i < _a.length; _i++) { var property = _a[_i]; if (isCommentOnlyNode_1["default"](property)) { continue; } if (property instanceof nodes_1.Assign) { var _b = getLocation_1["default"](childContext, property), line = _b.line, column = _b.column, start = _b.start, end = _b.end, raw = _b.raw; var key = mapAny_1["default"](childContext, property.variable); var value = mapAny_1["default"](childContext, property.value); var Node_1 = nodes_2.ClassProtoAssignOp; if (key instanceof nodes_2.Identifier && key.data === 'constructor') { Node_1 = nodes_2.Constructor; } else if (key instanceof nodes_2.MemberAccessOp && key.expression instanceof nodes_2.This) { Node_1 = nodes_2.AssignOp; } var assignment = new Node_1(line, column, start, end, raw, key, value); statements.push(assignment); if (assignment instanceof nodes_2.ClassProtoAssignOp && (assignment.expression instanceof nodes_2.BoundFunction || assignment.expression instanceof nodes_2.BoundGeneratorFunction || assignment.expression instanceof nodes_2.BoundAsyncFunction)) { blockContext.parseState.recordBoundMethod(assignment); } if (assignment instanceof nodes_2.Constructor) { blockContext.parseState.recordConstructor(assignment); } } else { throw new Error("unexpected class assignment: " + util_1.inspect(property)); } } return statements; } return [mapAny_1["default"](childContext, node)]; }