From e1625a0d31158d633262f9c38431e45aab60d28e Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 22 Sep 2018 22:20:58 -0700 Subject: [PATCH 1/9] We don't need to abstract a new helpers file for just three lines of code, there's more code required to pull this in where it's needed than to just duplicate the two lines of code we need in both places where these 'shared' helpers are currently used --- Cakefile | 6 +---- test/abstract_syntax_tree.coffee | 26 +++++++++++++------ .../abstract_syntax_tree_location_data.coffee | 3 ++- .../abstract_syntax_tree_helpers.coffee | 8 ------ 4 files changed, 21 insertions(+), 22 deletions(-) delete mode 100644 test/support/abstract_syntax_tree_helpers.coffee diff --git a/Cakefile b/Cakefile index f8046cd7..c6382a33 100644 --- a/Cakefile +++ b/Cakefile @@ -279,10 +279,7 @@ buildDocTests = (watch = no) -> outputFolder = "docs/v#{majorVersion}" # Included in test.html - readHelpersFile = (basename) -> - fs.readFileSync("test/support/#{basename}.coffee", 'utf-8').replace /exports\./g, '@' - testHelpers = readHelpersFile('helpers') + '\n' - testHelpers += readHelpersFile('abstract_syntax_tree_helpers') + testHelpers = fs.readFileSync('test/support/helpers.coffee', 'utf-8').replace /exports\./g, '@' # Helpers testsInScriptBlocks = -> @@ -421,7 +418,6 @@ runTests = (CoffeeScript) -> onFail description, fn, err helpers.extend global, require './test/support/helpers' - helpers.extend global, require './test/support/abstract_syntax_tree_helpers' # When all the tests have run, collect and print errors. # If a stacktrace is available, output the compiled function source. diff --git a/test/abstract_syntax_tree.coffee b/test/abstract_syntax_tree.coffee index 16906760..4c72d9cb 100644 --- a/test/abstract_syntax_tree.coffee +++ b/test/abstract_syntax_tree.coffee @@ -15,8 +15,25 @@ deepStrictEqualExpectedProperties = (actual, expected) -> eq actual[key], val, white"Property #{key}: expected #{actual[key]} to equal #{val}" actual +# Flag array for loose comparison. See reference to `.loose` in +# `deepStrictEqualExpectedProperties` above. +looseArray = (arr) -> + Object.defineProperty arr, 'loose', + value: yes + enumerable: no + arr + +# Helpers to get AST nodes for a string of code. The root node is always a +# `Block` node, so for brevity in the tests return its children from +# `expressions`. +getAstExpressions = (code) -> + ast = CoffeeScript.compile code, ast: yes + ast.expressions + +getAstExpression = (code) -> getAstExpressions(code)[0] + testExpression = (code, expected) -> - ast = getExpressionAst code + ast = getAstExpression code if expected? deepStrictEqualExpectedProperties ast, expected else @@ -26,13 +43,6 @@ testExpression = (code, expected) -> depth: 10 colors: yes -# Flag array for loose comparision. See reference to `.loose` in -# `deepStrictEqualExpectedProperties` above. -looseArray = (arr) -> - Object.defineProperty arr, 'loose', - value: yes - enumerable: no - arr test 'Confirm functionality of `deepStrictEqualExpectedProperties`', -> actual = diff --git a/test/abstract_syntax_tree_location_data.coffee b/test/abstract_syntax_tree_location_data.coffee index 33735a6f..2d1b546e 100644 --- a/test/abstract_syntax_tree_location_data.coffee +++ b/test/abstract_syntax_tree_location_data.coffee @@ -2,7 +2,8 @@ # --------------------------------- testAstLocationData = (code, expected) -> - testAstNodeLocationData getExpressionAst(code), expected + ast = CoffeeScript.compile code, ast: yes + testAstNodeLocationData ast.expressions[0], expected testAstNodeLocationData = (node, expected, path = '') -> extendPath = (additionalPath) -> diff --git a/test/support/abstract_syntax_tree_helpers.coffee b/test/support/abstract_syntax_tree_helpers.coffee deleted file mode 100644 index 7a5bff08..00000000 --- a/test/support/abstract_syntax_tree_helpers.coffee +++ /dev/null @@ -1,8 +0,0 @@ -# Helpers to get AST nodes for a string of code. The root node is always a -# `Block` node, so for brevity in the tests return its children from -# `expressions`. -getAstExpressions = (code) -> - ast = CoffeeScript.compile code, ast: yes - ast.expressions - -exports.getExpressionAst = (code) -> getAstExpressions(code)[0] From 617a2d5b65459eb072182fdb9783da7dfa487138 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 22 Sep 2018 22:29:02 -0700 Subject: [PATCH 2/9] Don't change style of functions defined with sequential arguments vs options argument; keep the focus of this PR on the AST work, not on unnecessary style changes --- lib/coffeescript/grammar.js | 2 +- lib/coffeescript/helpers.js | 6 +- lib/coffeescript/nodes.js | 2 +- lib/coffeescript/parser.js | 448 ++++++++++++++++++------------------ src/grammar.coffee | 2 +- src/helpers.coffee | 4 +- src/nodes.coffee | 2 +- 7 files changed, 232 insertions(+), 234 deletions(-) diff --git a/lib/coffeescript/grammar.js b/lib/coffeescript/grammar.js index d4f8df1a..dabab425 100644 --- a/lib/coffeescript/grammar.js +++ b/lib/coffeescript/grammar.js @@ -48,7 +48,7 @@ // is added to the first parameter passed in, and the parameter is returned. // If the parameter is not a node, it will just be passed through unaffected. getAddDataToNodeFunctionString = function(first, last) { - return `yy.addDataToNode(yy, {first: @${first}, ${last ? `last: @${last}, ` : ''}})`; + return `yy.addDataToNode(yy, @${first}${last ? `, @${last}` : ''})`; }; action = action.replace(/LOC\(([0-9]*)\)/g, getAddDataToNodeFunctionString('$1')); action = action.replace(/LOC\(([0-9]*),\s*([0-9]*)\)/g, getAddDataToNodeFunctionString('$1', '$2')); diff --git a/lib/coffeescript/helpers.js b/lib/coffeescript/helpers.js index cf6cbac5..3777befe 100644 --- a/lib/coffeescript/helpers.js +++ b/lib/coffeescript/helpers.js @@ -199,14 +199,12 @@ // This returns a function which takes an object as a parameter, and if that // object is an AST node, updates that object's locationData. // The object is returned either way. - exports.addDataToNode = function(parserState, {first, last, forceUpdateLocation = true}) { + exports.addDataToNode = function(parserState, first, last, forceUpdateLocation = true) { return function(obj) { var objHash, ref1; // Add location data. if (((obj != null ? obj.updateLocationDataIfMissing : void 0) != null) && (first != null)) { - obj.updateLocationDataIfMissing(buildLocationData(first, last), { - force: forceUpdateLocation - }); + obj.updateLocationDataIfMissing(buildLocationData(first, last), forceUpdateLocation); } // Add comments, building the dictionary of token data if it hasn’t been // built yet. diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 8a840eba..8aee9911 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -491,7 +491,7 @@ // For this node and all descendents, set the location data to `locationData` // if the location data is not already set. - updateLocationDataIfMissing(locationData, {force} = {}) { + updateLocationDataIfMissing(locationData, force) { if (force) { this.forceUpdateLocation = true; } diff --git a/lib/coffeescript/parser.js b/lib/coffeescript/parser.js index ceecb20d..b0014644 100644 --- a/lib/coffeescript/parser.js +++ b/lib/coffeescript/parser.js @@ -84,16 +84,16 @@ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* actio var $0 = $$.length - 1; switch (yystate) { case 1: -return this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Block); +return this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Block); break; case 2: return this.$ = $$[$0]; break; case 3: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(yy.Block.wrap([$$[$0]])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(yy.Block.wrap([$$[$0]])); break; case 4: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })($$[$0-2].push($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-2].push($$[$0])); break; case 5: this.$ = $$[$0-1]; @@ -102,48 +102,48 @@ case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 14: case 15: cas this.$ = $$[$0]; break; case 13: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.StatementLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.StatementLiteral($$[$0])); break; case 31: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Op($$[$0], +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Op($$[$0], new yy.Value(new yy.Literal('')))); break; case 32: case 356: case 357: case 358: case 360: case 361: case 364: case 387: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0])); break; case 33: case 365: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Op($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Op($$[$0-3], $$[$0-1])); break; case 34: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op($$[$0-2].concat($$[$0-1]), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-2].concat($$[$0-1]), $$[$0])); break; case 35: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Block); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Block); break; case 36: case 90: case 146: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })($$[$0-1]); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-1]); break; case 37: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.IdentifierLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.IdentifierLiteral($$[$0])); break; case 38: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.CSXTag($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.CSXTag($$[$0])); break; case 39: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.PropertyName($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.PropertyName($$[$0])); break; case 40: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.NumberLiteral($$[$0].toString(), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NumberLiteral($$[$0].toString(), { parsedValue: $$[$0].parsedValue })); break; case 42: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.StringLiteral($$[$0].slice(1, - -1), // strip artificial quotes and unwrap to primitive string +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.StringLiteral($$[$0].slice(1, + -1), { quote: $$[$0].quote, initialChunk: $$[$0].initialChunk, @@ -154,398 +154,398 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.StringLite })); break; case 43: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.StringWithInterpolations(yy.Block.wrap($$[$0-1]), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.StringWithInterpolations(yy.Block.wrap($$[$0-1]), { quote: $$[$0-2].quote })); break; case 44: case 107: case 152: case 171: case 192: case 225: case 239: case 243: case 294: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })([$$[$0]]); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])([$$[$0]]); break; case 45: case 240: case 244: case 341: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0-1].concat($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].concat($$[$0])); break; case 46: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Interpolation($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Interpolation($$[$0-1])); break; case 47: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Interpolation($$[$0-2])); +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Interpolation($$[$0-2])); break; case 48: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Interpolation); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Interpolation); break; case 49: case 275: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })($$[$0]); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])($$[$0]); break; case 50: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.RegexLiteral($$[$0].toString(), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.RegexLiteral($$[$0].toString(), { delimiter: $$[$0].delimiter })); break; case 51: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.RegexWithInterpolations($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.RegexWithInterpolations($$[$0-1])); break; case 53: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.PassthroughLiteral($$[$0].toString(), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.PassthroughLiteral($$[$0].toString(), { here: $$[$0].here, generated: $$[$0].generated })); break; case 55: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.UndefinedLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.UndefinedLiteral($$[$0])); break; case 56: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.NullLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NullLiteral($$[$0])); break; case 57: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.BooleanLiteral($$[$0].toString(), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.BooleanLiteral($$[$0].toString(), { originalValue: $$[$0].original })); break; case 58: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.InfinityLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.InfinityLiteral($$[$0])); break; case 59: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.NaNLiteral($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NaNLiteral($$[$0])); break; case 60: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Assign($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0])); break; case 61: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Assign($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0])); break; case 62: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Assign($$[$0-4], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1])); break; case 63: case 122: case 127: case 128: case 130: case 131: case 132: case 133: case 134: case 136: case 292: case 293: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Value($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value($$[$0])); break; case 65: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Assign(yy.addDataToNode(yy, {first: _$[$0-2], })(new yy.Value($$[$0-2])), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object', { - operatorToken: yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Literal($$[$0-1])) + operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) })); break; case 66: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Assign(yy.addDataToNode(yy, {first: _$[$0-4], })(new yy.Value($$[$0-4])), +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object', { - operatorToken: yy.addDataToNode(yy, {first: _$[$0-3], })(new yy.Literal($$[$0-3])) + operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3])) })); break; case 67: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Assign(yy.addDataToNode(yy, {first: _$[$0-2], })(new yy.Value($$[$0-2])), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), $$[$0], null, { - operatorToken: yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Literal($$[$0-1])) + operatorToken: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) })); break; case 68: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Assign(yy.addDataToNode(yy, {first: _$[$0-4], })(new yy.Value($$[$0-4])), +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign(yy.addDataToNode(yy, _$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], null, { - operatorToken: yy.addDataToNode(yy, {first: _$[$0-3], })(new yy.Literal($$[$0-3])) + operatorToken: yy.addDataToNode(yy, _$[$0-3])(new yy.Literal($$[$0-3])) })); break; case 73: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Value(new yy.ComputedPropertyName($$[$0-1]))); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Value(new yy.ComputedPropertyName($$[$0-1]))); break; case 75: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Splat(new yy.Value($$[$0-1]))); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat(new yy.Value($$[$0-1]))); break; case 76: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Splat(new yy.Value($$[$0]))); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat(new yy.Value($$[$0]))); break; case 77: case 120: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Splat($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat($$[$0-1])); break; case 78: case 121: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Splat($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Splat($$[$0])); break; case 84: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.SuperCall(yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Super), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-1])(new yy.Super), $$[$0], false, $$[$0-1])); break; case 85: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Call(new yy.Value($$[$0-1]), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call(new yy.Value($$[$0-1]), $$[$0])); break; case 86: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Call($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Call($$[$0-1], $$[$0])); break; case 87: case 88: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })((new yy.Value($$[$0-1])).add($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])((new yy.Value($$[$0-1])).add($$[$0])); break; case 89: case 139: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Access($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Access($$[$0])); break; case 91: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Return($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Return($$[$0])); break; case 92: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Return(new yy.Value($$[$0-1]))); +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Return(new yy.Value($$[$0-1]))); break; case 93: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Return); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Return); break; case 94: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.YieldReturn($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.YieldReturn($$[$0])); break; case 95: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.YieldReturn); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.YieldReturn); break; case 96: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.AwaitReturn($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.AwaitReturn($$[$0])); break; case 97: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.AwaitReturn); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.AwaitReturn); break; case 98: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Code($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1], - yy.addDataToNode(yy, {first: _$[$0-4], })(new yy.Literal($$[$0-4])))); + yy.addDataToNode(yy, _$[$0-4])(new yy.Literal($$[$0-4])))); break; case 99: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Code([], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1])); break; case 100: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Code($$[$0-3], - yy.addDataToNode(yy, {first: _$[$0], })(yy.Block.wrap([$$[$0]])), +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Code($$[$0-3], + yy.addDataToNode(yy, _$[$0])(yy.Block.wrap([$$[$0]])), $$[$0-1], - yy.addDataToNode(yy, {first: _$[$0-4], })(new yy.Literal($$[$0-4])))); + yy.addDataToNode(yy, _$[$0-4])(new yy.Literal($$[$0-4])))); break; case 101: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Code([], - yy.addDataToNode(yy, {first: _$[$0], })(yy.Block.wrap([$$[$0]])), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Code([], + yy.addDataToNode(yy, _$[$0])(yy.Block.wrap([$$[$0]])), $$[$0-1])); break; case 102: case 103: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.FuncGlyph($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.FuncGlyph($$[$0])); break; case 106: case 151: case 241: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })([]); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])([]); break; case 108: case 153: case 172: case 193: case 226: case 235: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })($$[$0-2].concat($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-2].concat($$[$0])); break; case 109: case 154: case 173: case 194: case 227: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })($$[$0-3].concat($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-3].concat($$[$0])); break; case 110: case 155: case 175: case 196: case 229: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })($$[$0-5].concat($$[$0-2])); +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2])); break; case 111: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Param($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Param($$[$0])); break; case 112: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Param($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true)); break; case 113: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Param($$[$0], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Param($$[$0], null, true)); break; case 114: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Param($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0])); break; case 115: case 233: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Expansion); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Expansion); break; case 123: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0-1].add($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].add($$[$0])); break; case 124: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Value($$[$0-1]).add($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Value($$[$0-1]).add($$[$0])); break; case 137: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Super(yy.addDataToNode(yy, {first: _$[$0], })(new yy.Access($$[$0])), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0])), [], false, $$[$0-2])); break; case 138: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Super(yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Index($$[$0-1])), +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Super(yy.addDataToNode(yy, _$[$0-1])(new yy.Index($$[$0-1])), [], false, $$[$0-3])); break; case 140: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Access($$[$0], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Access($$[$0], { soak: true })); break; case 141: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })([ - yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Access(new yy.PropertyName('prototype'), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([ + yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'), { shorthand: true })), - yy.addDataToNode(yy, {first: _$[$0], })(new yy.Access($$[$0])) + yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0])) ]); break; case 142: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })([ - yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Access(new yy.PropertyName('prototype'), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([ + yy.addDataToNode(yy, _$[$0-1])(new yy.Access(new yy.PropertyName('prototype'), { shorthand: true, soak: true })), - yy.addDataToNode(yy, {first: _$[$0], })(new yy.Access($$[$0])) + yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0])) ]); break; case 143: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Access(new yy.PropertyName('prototype'), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Access(new yy.PropertyName('prototype'), { shorthand: true })); break; case 144: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Access(new yy.PropertyName('prototype'), +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Access(new yy.PropertyName('prototype'), { shorthand: true, soak: true })); break; case 147: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(yy.extend($$[$0], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(yy.extend($$[$0], { soak: true })); break; case 148: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Index($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Index($$[$0])); break; case 149: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Slice($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Slice($$[$0])); break; case 150: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Obj($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated)); break; case 156: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Class); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Class); break; case 157: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Class(null, +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0])); break; case 158: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Class(null, +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class(null, $$[$0])); break; case 159: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Class(null, +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0])); break; case 160: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Class($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Class($$[$0])); break; case 161: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Class($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0])); break; case 162: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Class($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0])); break; case 163: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Class($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0])); break; case 164: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.ImportDeclaration(null, +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ImportDeclaration(null, $$[$0])); break; case 165: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-2], null), $$[$0])); break; case 166: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause(null, +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, $$[$0-2]), $$[$0])); break; case 167: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause(null, +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, new yy.ImportSpecifierList([])), $$[$0])); break; case 168: -this.$ = yy.addDataToNode(yy, {first: _$[$0-6], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause(null, +this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause(null, new yy.ImportSpecifierList($$[$0-4])), $$[$0])); break; case 169: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause($$[$0-4], +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-4], $$[$0-2]), $$[$0])); break; case 170: -this.$ = yy.addDataToNode(yy, {first: _$[$0-8], last: _$[$0], })(new yy.ImportDeclaration(new yy.ImportClause($$[$0-7], +this.$ = yy.addDataToNode(yy, _$[$0-8], _$[$0])(new yy.ImportDeclaration(new yy.ImportClause($$[$0-7], new yy.ImportSpecifierList($$[$0-4])), $$[$0])); break; case 174: case 195: case 208: case 228: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })($$[$0-2]); +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-2]); break; case 176: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.ImportSpecifier($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier($$[$0])); break; case 177: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ImportSpecifier($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier($$[$0-2], $$[$0])); break; case 178: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.ImportSpecifier(new yy.Literal($$[$0]))); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0]))); break; case 179: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ImportSpecifier(new yy.Literal($$[$0-2]), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportSpecifier(new yy.Literal($$[$0-2]), $$[$0])); break; case 180: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.ImportDefaultSpecifier($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ImportDefaultSpecifier($$[$0])); break; case 181: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ImportNamespaceSpecifier(new yy.Literal($$[$0-2]), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ImportNamespaceSpecifier(new yy.Literal($$[$0-2]), $$[$0])); break; case 182: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList([]))); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList([]))); break; case 183: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-2]))); +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-2]))); break; case 184: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.ExportNamedDeclaration($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.ExportNamedDeclaration($$[$0])); break; case 185: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-2], $$[$0], null, { @@ -553,7 +553,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.ExportNa }))); break; case 186: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-3], $$[$0], null, { @@ -561,7 +561,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.ExportNa }))); break; case 187: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-4], +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.ExportNamedDeclaration(new yy.Assign($$[$0-4], $$[$0-1], null, { @@ -569,239 +569,239 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })(new yy.ExportNa }))); break; case 188: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ExportDefaultDeclaration($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportDefaultDeclaration($$[$0])); break; case 189: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.ExportDefaultDeclaration(new yy.Value($$[$0-1]))); +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.ExportDefaultDeclaration(new yy.Value($$[$0-1]))); break; case 190: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.ExportAllDeclaration(new yy.Literal($$[$0-2]), +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.ExportAllDeclaration(new yy.Literal($$[$0-2]), $$[$0])); break; case 191: -this.$ = yy.addDataToNode(yy, {first: _$[$0-6], last: _$[$0], })(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-4]), +this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.ExportNamedDeclaration(new yy.ExportSpecifierList($$[$0-4]), $$[$0])); break; case 197: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.ExportSpecifier($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier($$[$0])); break; case 198: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ExportSpecifier($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], $$[$0])); break; case 199: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ExportSpecifier($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier($$[$0-2], new yy.Literal($$[$0]))); break; case 200: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.ExportSpecifier(new yy.Literal($$[$0]))); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0]))); break; case 201: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.ExportSpecifier(new yy.Literal($$[$0-2]), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.ExportSpecifier(new yy.Literal($$[$0-2]), $$[$0])); break; case 202: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.TaggedTemplateCall($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.TaggedTemplateCall($$[$0-2], $$[$0], $$[$0-1])); break; case 203: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Call($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1])); break; case 204: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.SuperCall(yy.addDataToNode(yy, {first: _$[$0-2], })(new yy.Super), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.SuperCall(yy.addDataToNode(yy, _$[$0-2])(new yy.Super), $$[$0], $$[$0-1], $$[$0-2])); break; case 205: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(false); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(false); break; case 206: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(true); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(true); break; case 207: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })([]); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([]); break; case 209: case 210: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Value(new yy.ThisLiteral($$[$0]))); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Value(new yy.ThisLiteral($$[$0]))); break; case 211: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Value(yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.ThisLiteral($$[$0-1])), - [yy.addDataToNode(yy, {first: _$[$0], })(new yy.Access($$[$0]))], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Value(yy.addDataToNode(yy, _$[$0-1])(new yy.ThisLiteral($$[$0-1])), + [yy.addDataToNode(yy, _$[$0])(new yy.Access($$[$0]))], 'this')); break; case 212: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Arr([])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Arr([])); break; case 213: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Arr($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Arr($$[$0-1])); break; case 214: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Arr([].concat($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Arr([].concat($$[$0-2], $$[$0-1]))); break; case 215: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })('inclusive'); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])('inclusive'); break; case 216: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })('exclusive'); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])('exclusive'); break; case 217: case 218: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Range($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2])); break; case 219: case 221: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Range($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1])); break; case 220: case 222: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Range($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0])); break; case 223: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Range(null, +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1])); break; case 224: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Range(null, +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Range(null, null, $$[$0])); break; case 236: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })($$[$0-3].concat($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-3].concat($$[$0-2], $$[$0])); break; case 237: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })($$[$0-2].concat($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])($$[$0-2].concat($$[$0-1])); break; case 238: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })($$[$0-5].concat($$[$0-4], +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])($$[$0-5].concat($$[$0-4], $$[$0-2], $$[$0-1])); break; case 242: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })([].concat($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([].concat($$[$0])); break; case 245: -this.$ = yy.addDataToNode(yy, {first: _$[$0], last: _$[$0], })(new yy.Elision); +this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.Elision); break; case 248: case 249: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })([].concat($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0])); break; case 250: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Try($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Try($$[$0])); break; case 251: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Try($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1])); break; case 252: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Try($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0])); break; case 253: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Try($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0])); break; case 254: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })([$$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-1], $$[$0]]); break; case 255: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })([yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Value($$[$0-1])), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([yy.addDataToNode(yy, _$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]); break; case 256: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })([null, +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])([null, $$[$0]]); break; case 257: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Throw($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Throw($$[$0])); break; case 258: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Throw(new yy.Value($$[$0-1]))); +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Throw(new yy.Value($$[$0-1]))); break; case 259: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Parens($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Parens($$[$0-1])); break; case 260: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Parens($$[$0-2])); +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Parens($$[$0-2])); break; case 261: case 265: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.While($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0])); break; case 262: case 266: case 267: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.While($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], { guard: $$[$0] })); break; case 263: case 268: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.While($$[$0], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While($$[$0], { invert: true })); break; case 264: case 269: case 270: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.While($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.While($$[$0-2], { invert: true, guard: $$[$0] })); break; case 271: case 272: case 280: case 281: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0-1].addBody($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].addBody($$[$0])); break; case 273: case 274: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0].addBody(yy.addDataToNode(yy, {first: _$[$0-1], })(yy.Block.wrap([$$[$0-1]])))); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0].addBody(yy.addDataToNode(yy, _$[$0-1])(yy.Block.wrap([$$[$0-1]])))); break; case 276: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.While(yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.BooleanLiteral('true'))).addBody($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While(yy.addDataToNode(yy, _$[$0-1])(new yy.BooleanLiteral('true'))).addBody($$[$0])); break; case 277: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.While(yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.BooleanLiteral('true'))).addBody(yy.addDataToNode(yy, {first: _$[$0], })(yy.Block.wrap([$$[$0]])))); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.While(yy.addDataToNode(yy, _$[$0-1])(new yy.BooleanLiteral('true'))).addBody(yy.addDataToNode(yy, _$[$0])(yy.Block.wrap([$$[$0]])))); break; case 278: case 279: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0].addBody($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0].addBody($$[$0-1])); break; case 282: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.For([], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For([], { - source: yy.addDataToNode(yy, {first: _$[$0], })(new yy.Value($$[$0])) + source: yy.addDataToNode(yy, _$[$0])(new yy.Value($$[$0])) })); break; case 283: case 285: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.For([], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.For([], { - source: yy.addDataToNode(yy, {first: _$[$0-2], })(new yy.Value($$[$0-2])), + source: yy.addDataToNode(yy, _$[$0-2])(new yy.Value($$[$0-2])), step: $$[$0] })); break; case 284: case 286: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })($$[$0-1].addSource($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])($$[$0-1].addSource($$[$0])); break; case 287: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.For([], +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.For([], { name: $$[$0][0], index: $$[$0][1] })); break; case 288: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function() { var index, name; [name, @@ -811,12 +811,12 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { name, index, await: true, - awaitTag: yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Literal($$[$0-1])) + awaitTag: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) }); }())); break; case 289: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function() { var index, name; [name, @@ -826,124 +826,124 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { name, index, own: true, - ownTag: yy.addDataToNode(yy, {first: _$[$0-1], })(new yy.Literal($$[$0-1])) + ownTag: yy.addDataToNode(yy, _$[$0-1])(new yy.Literal($$[$0-1])) }); }())); break; case 295: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })([$$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([$$[$0-2], $$[$0]]); break; case 296: case 315: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({ source: $$[$0] }); break; case 297: case 316: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({ source: $$[$0], object: true }); break; case 298: case 299: case 317: case 318: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])({ source: $$[$0-2], guard: $$[$0] }); break; case 300: case 301: case 319: case 320: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])({ source: $$[$0-2], guard: $$[$0], object: true }); break; case 302: case 303: case 321: case 322: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])({ source: $$[$0-2], step: $$[$0] }); break; case 304: case 305: case 306: case 307: case 323: case 324: case 325: case 326: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])({ source: $$[$0-4], guard: $$[$0-2], step: $$[$0] }); break; case 308: case 309: case 310: case 311: case 327: case 328: case 329: case 330: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])({ source: $$[$0-4], step: $$[$0-2], guard: $$[$0] }); break; case 312: case 331: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])({ source: $$[$0], from: true }); break; case 313: case 314: case 332: case 333: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })({ +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])({ source: $$[$0-2], guard: $$[$0], from: true }); break; case 334: case 335: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Switch($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1])); break; case 336: case 337: -this.$ = yy.addDataToNode(yy, {first: _$[$0-6], last: _$[$0], })(new yy.Switch($$[$0-5], +this.$ = yy.addDataToNode(yy, _$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1])); break; case 338: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Switch(null, +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1])); break; case 339: -this.$ = yy.addDataToNode(yy, {first: _$[$0-5], last: _$[$0], })(new yy.Switch(null, +this.$ = yy.addDataToNode(yy, _$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1])); break; case 342: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })([[$$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]); break; case 343: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })([[$$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]); break; case 344: case 350: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.If($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { type: $$[$0-2] })); break; case 345: case 351: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })($$[$0-4].addElse(yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.If($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])($$[$0-4].addElse(yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], { type: $$[$0-2] })))); break; case 347: case 353: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })($$[$0-2].addElse($$[$0])); +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])($$[$0-2].addElse($$[$0])); break; case 348: case 349: case 354: case 355: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.If($$[$0], - yy.addDataToNode(yy, {first: _$[$0-2], })(yy.Block.wrap([$$[$0-2]])), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.If($$[$0], + yy.addDataToNode(yy, _$[$0-2])(yy.Block.wrap([$$[$0-2]])), { type: $$[$0-1], statement: true })); break; case 359: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op($$[$0-1].toString(), +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op($$[$0-1].toString(), $$[$0], void 0, void 0, @@ -952,53 +952,53 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op($$[$0 })); break; case 362: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('-', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('-', $$[$0])); break; case 363: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('+', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('+', $$[$0])); break; case 366: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('--', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', $$[$0])); break; case 367: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('++', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', $$[$0])); break; case 368: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('--', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true)); break; case 369: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Op('++', +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true)); break; case 370: -this.$ = yy.addDataToNode(yy, {first: _$[$0-1], last: _$[$0], })(new yy.Existence($$[$0-1])); +this.$ = yy.addDataToNode(yy, _$[$0-1], _$[$0])(new yy.Existence($$[$0-1])); break; case 371: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op('+', +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0])); break; case 372: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op('-', +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0])); break; case 373: case 374: case 375: case 377: case 378: case 379: case 382: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op($$[$0-1], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0])); break; case 376: case 380: case 381: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op($$[$0-1].toString(), +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Op($$[$0-1].toString(), $$[$0-2], $$[$0], void 0, @@ -1007,7 +1007,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Op($$[$0 })); break; case 383: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])((function() { var ref, ref1; return new yy.Op($$[$0-1].toString(), @@ -1020,7 +1020,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })((function() { }())); break; case 384: -this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Assign($$[$0-2], +this.$ = yy.addDataToNode(yy, _$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1].toString(), { @@ -1028,7 +1028,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-2], last: _$[$0], })(new yy.Assign($ })); break; case 385: -this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Assign($$[$0-4], +this.$ = yy.addDataToNode(yy, _$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3].toString(), { @@ -1036,7 +1036,7 @@ this.$ = yy.addDataToNode(yy, {first: _$[$0-4], last: _$[$0], })(new yy.Assign($ })); break; case 386: -this.$ = yy.addDataToNode(yy, {first: _$[$0-3], last: _$[$0], })(new yy.Assign($$[$0-3], +this.$ = yy.addDataToNode(yy, _$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0], $$[$0-2].toString(), { diff --git a/src/grammar.coffee b/src/grammar.coffee index b68a0ea5..27547209 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -45,7 +45,7 @@ o = (patternString, action, options) -> # is added to the first parameter passed in, and the parameter is returned. # If the parameter is not a node, it will just be passed through unaffected. getAddDataToNodeFunctionString = (first, last) -> - "yy.addDataToNode(yy, {first: @#{first}, #{if last then "last: @#{last}, " else ''}})" + "yy.addDataToNode(yy, @#{first}#{if last then ", @#{last}" else ''})" action = action.replace /LOC\(([0-9]*)\)/g, getAddDataToNodeFunctionString('$1') action = action.replace /LOC\(([0-9]*),\s*([0-9]*)\)/g, getAddDataToNodeFunctionString('$1', '$2') diff --git a/src/helpers.coffee b/src/helpers.coffee index 97a14461..e2c6c407 100644 --- a/src/helpers.coffee +++ b/src/helpers.coffee @@ -136,11 +136,11 @@ buildTokenDataDictionary = (parserState) -> # This returns a function which takes an object as a parameter, and if that # object is an AST node, updates that object's locationData. # The object is returned either way. -exports.addDataToNode = (parserState, {first, last, forceUpdateLocation = yes}) -> +exports.addDataToNode = (parserState, first, last, forceUpdateLocation = yes) -> (obj) -> # Add location data. if obj?.updateLocationDataIfMissing? and first? - obj.updateLocationDataIfMissing buildLocationData(first, last), force: forceUpdateLocation + obj.updateLocationDataIfMissing buildLocationData(first, last), forceUpdateLocation # Add comments, building the dictionary of token data if it hasn’t been # built yet. diff --git a/src/nodes.coffee b/src/nodes.coffee index 34b9b733..7eef3230 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -398,7 +398,7 @@ exports.Base = class Base # For this node and all descendents, set the location data to `locationData` # if the location data is not already set. - updateLocationDataIfMissing: (locationData, {force} = {}) -> + updateLocationDataIfMissing: (locationData, force) -> @forceUpdateLocation = yes if force return this if @locationData and not @forceUpdateLocation delete @forceUpdateLocation From 0be8c5d161f1220db0a92ace8729d2e8009246b9 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 22 Sep 2018 23:56:03 -0700 Subject: [PATCH 3/9] Make AST test output browser-safe; improve output for failing tests; have output follow style of eqJS --- Cakefile | 3 ++- test/abstract_syntax_tree.coffee | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Cakefile b/Cakefile index c6382a33..9c64b5da 100644 --- a/Cakefile +++ b/Cakefile @@ -382,7 +382,8 @@ runTests = (CoffeeScript) -> global.passedTests = 0 global.failures = [] - global[name] = func for name, func of require 'assert' + global[name] = func for name, func of require 'assert' + global.inspect = if global.testingBrowser then console.log else require('util').inspect # Convenience aliases. global.CoffeeScript = CoffeeScript diff --git a/test/abstract_syntax_tree.coffee b/test/abstract_syntax_tree.coffee index 4c72d9cb..73fd08ee 100644 --- a/test/abstract_syntax_tree.coffee +++ b/test/abstract_syntax_tree.coffee @@ -4,19 +4,24 @@ # Recursively compare all values of enumerable properties of `expected` with # those of `actual`. Use `looseArray` helper function to skip array length # comparison. -deepStrictEqualExpectedProperties = (actual, expected) -> - white = (text, values...) -> (text[i] + "#{reset}#{value}#{red}" for value, i in values).join('') + text[i] +deepStrictIncludeExpectedProperties = (actual, expected) -> eq actual.length, expected.length if expected instanceof Array and not expected.loose for key, val of expected if 'object' is typeof val - fail white"Property #{key} expected, but was missing" unless actual[key] - deepStrictEqualExpectedProperties actual[key], val + fail "Property #{reset}#{key}#{red} expected, but was missing" unless actual[key] + deepStrictIncludeExpectedProperties actual[key], val else - eq actual[key], val, white"Property #{key}: expected #{actual[key]} to equal #{val}" + eq actual[key], val, """ + Property #{reset}#{key}#{red}: expected #{reset}#{actual[key]}#{red} to equal #{reset}#{val}#{red} + Expected AST output to include: + #{reset}#{inspect expected, {depth: 10, colors: yes}}#{red} + but instead it was: + #{reset}#{inspect actual, {depth: 10, colors: yes}}#{red} + """ actual # Flag array for loose comparison. See reference to `.loose` in -# `deepStrictEqualExpectedProperties` above. +# `deepStrictIncludeExpectedProperties` above. looseArray = (arr) -> Object.defineProperty arr, 'loose', value: yes @@ -35,16 +40,16 @@ getAstExpression = (code) -> getAstExpressions(code)[0] testExpression = (code, expected) -> ast = getAstExpression code if expected? - deepStrictEqualExpectedProperties ast, expected + deepStrictIncludeExpectedProperties ast, expected else # Convenience for creating new tests; call `testExpression` with no second # parameter to see what the current AST generation is for your input code. - console.log require('util').inspect ast, + console.log inspect ast, depth: 10 colors: yes -test 'Confirm functionality of `deepStrictEqualExpectedProperties`', -> +test 'Confirm functionality of `deepStrictIncludeExpectedProperties`', -> actual = name: 'Name' a: @@ -53,7 +58,7 @@ test 'Confirm functionality of `deepStrictEqualExpectedProperties`', -> x: [1, 2, 3] check = (message, test, expected) -> - test (-> deepStrictEqualExpectedProperties actual, expected), message + test (-> deepStrictIncludeExpectedProperties actual, expected), message check 'Expected property does not match', throws, name: '"Name"' @@ -98,7 +103,7 @@ test 'Confirm functionality of `deepStrictEqualExpectedProperties`', -> # properties are as expected. test "AST as expected for Block node", -> - deepStrictEqualExpectedProperties CoffeeScript.compile('return', ast: yes), + deepStrictIncludeExpectedProperties CoffeeScript.compile('return', ast: yes), type: 'Block' expressions: [ type: 'Return' From 7b251f493d851f0e30d048c4ef20892c5149d82f Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sun, 23 Sep 2018 01:14:55 -0700 Subject: [PATCH 4/9] Make error message for location AST paths connect the path to the property we're comparing --- .../abstract_syntax_tree_location_data.coffee | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/abstract_syntax_tree_location_data.coffee b/test/abstract_syntax_tree_location_data.coffee index 2d1b546e..b02b0a3e 100644 --- a/test/abstract_syntax_tree_location_data.coffee +++ b/test/abstract_syntax_tree_location_data.coffee @@ -17,10 +17,9 @@ testAstNodeLocationData = (node, expected, path = '') -> for expectedItem, index in expectedChild testAstNodeLocationData node[key][index], expectedItem, extendPath "#{key}[#{index}]" else if typeof expectedChild is 'object' - testAstNodeLocationData node[key], expectedChild, extendPath key + testAstNodeLocationData node[key], expectedChild, extendPath(key) -testSingleNodeLocationData = (node, expected, path) -> - pathStr = if path then " at '#{path}'" else '' +testSingleNodeLocationData = (node, expected, path = '') -> # Even though it’s not part of the location data, check the type to ensure # that we’re testing the node we think we are. if expected.type? @@ -28,19 +27,19 @@ testSingleNodeLocationData = (node, expected, path) -> "Expected AST node type #{reset}#{node.type}#{red} to equal #{reset}#{expected.type}#{red}" eq node.start, expected.start, \ - "Expected location start #{reset}#{node.start}#{red} to equal #{reset}#{expected.start}#{red}#{pathStr}" + "Expected #{path}.start: #{reset}#{node.start}#{red} to equal #{reset}#{expected.start}#{red}" eq node.end, expected.end, \ - "Expected location end #{reset}#{node.end}#{red} to equal #{reset}#{expected.end}#{red}#{pathStr}" + "Expected #{path}.end: #{reset}#{node.end}#{red} to equal #{reset}#{expected.end}#{red}" arrayEq node.range, expected.range, \ - "Expected location range #{reset}#{JSON.stringify node.range}#{red} to equal #{reset}#{JSON.stringify expected.range}#{red}#{pathStr}" + "Expected #{path}.range: #{reset}#{JSON.stringify node.range}#{red} to equal #{reset}#{JSON.stringify expected.range}#{red}" eq node.loc.start.line, expected.loc.start.line, \ - "Expected location start line #{reset}#{node.loc.start.line}#{red} to equal #{reset}#{expected.loc.start.line}#{red}#{pathStr}" + "Expected #{path}.loc.start.line: #{reset}#{node.loc.start.line}#{red} to equal #{reset}#{expected.loc.start.line}#{red}" eq node.loc.start.column, expected.loc.start.column, \ - "Expected location start column #{reset}#{node.loc.start.column}#{red} to equal #{reset}#{expected.loc.start.column}#{red}#{pathStr}" + "Expected #{path}.loc.start.column: #{reset}#{node.loc.start.column}#{red} to equal #{reset}#{expected.loc.start.column}#{red}" eq node.loc.end.line, expected.loc.end.line, \ - "Expected location end line #{reset}#{node.loc.end.line}#{red} to equal #{reset}#{expected.loc.end.line}#{red}#{pathStr}" + "Expected #{path}.loc.end.line: #{reset}#{node.loc.end.line}#{red} to equal #{reset}#{expected.loc.end.line}#{red}" eq node.loc.end.column, expected.loc.end.column, \ - "Expected location end column #{reset}#{node.loc.end.column}#{red} to equal #{reset}#{expected.loc.end.column}#{red}#{pathStr}" + "Expected #{path}.loc.end.column: #{reset}#{node.loc.end.column}#{red} to equal #{reset}#{expected.loc.end.column}#{red}" test "AST location data as expected for NumberLiteral node", -> testAstLocationData '42', From ea33c28f1b494f93cce74ed989aad11084eecf56 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sun, 23 Sep 2018 01:15:56 -0700 Subject: [PATCH 5/9] Refactor our helper for merging AST location data to take two locationData objects and return a new, merged one --- src/nodes.coffee | 50 ++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/nodes.coffee b/src/nodes.coffee index 7eef3230..3115f6cf 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -294,17 +294,17 @@ exports.Base = class Base return loc: start: - line: first_line + 1 + line: first_line + 1 column: first_column end: - line: last_line + 1 + line: last_line + 1 column: last_column + 1 range: [ range[0] range[1] ] start: range[0] - end: range[1] + end: range[1] # Passes each child to a function, breaking when the function returns `false`. eachChild: (func) -> @@ -4166,28 +4166,24 @@ makeDelimitedLiteral = (body, options = {}) -> when other then (if options.double then "\\#{other}" else other) "#{options.delimiter}#{body}#{options.delimiter}" -# Extends the location data of an AST node to include the location data from -# another AST node. -mergeAstLocationData = (intoNode, fromNode) -> - {range: intoRange} = intoNode - {range: fromRange} = fromNode - return intoNode unless intoRange and fromRange - if fromRange[0] < intoRange[0] - intoNode.range = intoRange = [ - fromRange[0] - intoRange[1] +# Take two AST nodes, or two AST nodes’ location data objects, and return a new +# location data object that encompasses the location data of both nodes. So the +# new `start` value will be the earlier of the two nodes’ `start` values, the +# new `end` value will be the later of the two nodes’ `end` values, etc. +lesser = (a, b) -> if a < b then a else b +greater = (a, b) -> if a > b then a else b +mergeAstLocationData = (nodeA, nodeB) -> + return + loc: + start: + line: lesser nodeA.loc.start.line, nodeB.loc.start.line + column: lesser nodeA.loc.start.column, nodeB.loc.start.column + end: + line: greater nodeA.loc.end.line, nodeB.loc.end.line + column: greater nodeA.loc.end.column, nodeB.loc.end.column + range: [ + lesser nodeA.range[0], nodeB.range[0] + greater nodeA.range[1], nodeB.range[1] ] - intoNode.start = fromNode.start - intoNode.loc = - start: fromNode.loc.start - end: intoNode.loc.end - if fromRange[1] > intoRange[1] - intoNode.range = [ - intoRange[0] - fromRange[1] - ] - intoNode.end = fromNode.end - intoNode.loc = - start: intoNode.loc.start - end: fromNode.loc.end - intoNode + start: lesser nodeA.start, nodeB.start + end: greater nodeA.end, nodeB.end From 3b1c49240b111583ff2507949572b2d1746a5443 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 24 Sep 2018 21:50:40 -0700 Subject: [PATCH 6/9] Fix inspect helper --- Cakefile | 3 +-- lib/coffeescript/parser.js | 2 +- test/abstract_syntax_tree.coffee | 16 +++++++++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Cakefile b/Cakefile index 9c64b5da..c6382a33 100644 --- a/Cakefile +++ b/Cakefile @@ -382,8 +382,7 @@ runTests = (CoffeeScript) -> global.passedTests = 0 global.failures = [] - global[name] = func for name, func of require 'assert' - global.inspect = if global.testingBrowser then console.log else require('util').inspect + global[name] = func for name, func of require 'assert' # Convenience aliases. global.CoffeeScript = CoffeeScript diff --git a/lib/coffeescript/parser.js b/lib/coffeescript/parser.js index b0014644..adfb6c1e 100644 --- a/lib/coffeescript/parser.js +++ b/lib/coffeescript/parser.js @@ -143,7 +143,7 @@ this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.NumberLiteral($$[$0].toStri break; case 42: this.$ = yy.addDataToNode(yy, _$[$0], _$[$0])(new yy.StringLiteral($$[$0].slice(1, - -1), + -1), // strip artificial quotes and unwrap to primitive string { quote: $$[$0].quote, initialChunk: $$[$0].initialChunk, diff --git a/test/abstract_syntax_tree.coffee b/test/abstract_syntax_tree.coffee index 73fd08ee..35b5dbef 100644 --- a/test/abstract_syntax_tree.coffee +++ b/test/abstract_syntax_tree.coffee @@ -1,6 +1,14 @@ # Astract Syntax Tree generation # ------------------------------ +inspect = (obj) -> + if global.testingBrowser + JSON.stringify obj, null, 2 + else + require('util').inspect obj, + depth: 10 + colors: yes + # Recursively compare all values of enumerable properties of `expected` with # those of `actual`. Use `looseArray` helper function to skip array length # comparison. @@ -14,9 +22,9 @@ deepStrictIncludeExpectedProperties = (actual, expected) -> eq actual[key], val, """ Property #{reset}#{key}#{red}: expected #{reset}#{actual[key]}#{red} to equal #{reset}#{val}#{red} Expected AST output to include: - #{reset}#{inspect expected, {depth: 10, colors: yes}}#{red} + #{reset}#{inspect expected}#{red} but instead it was: - #{reset}#{inspect actual, {depth: 10, colors: yes}}#{red} + #{reset}#{inspect actual}#{red} """ actual @@ -44,9 +52,7 @@ testExpression = (code, expected) -> else # Convenience for creating new tests; call `testExpression` with no second # parameter to see what the current AST generation is for your input code. - console.log inspect ast, - depth: 10 - colors: yes + console.log inspect ast test 'Confirm functionality of `deepStrictIncludeExpectedProperties`', -> From eb22196850555a3729f7457ac57c481a252f822c Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 24 Sep 2018 21:58:05 -0700 Subject: [PATCH 7/9] Globalize helpers --- test/abstract_syntax_tree.coffee | 17 ----------------- test/abstract_syntax_tree_location_data.coffee | 4 ++-- test/support/helpers.coffee | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/test/abstract_syntax_tree.coffee b/test/abstract_syntax_tree.coffee index 35b5dbef..d14b6334 100644 --- a/test/abstract_syntax_tree.coffee +++ b/test/abstract_syntax_tree.coffee @@ -1,14 +1,6 @@ # Astract Syntax Tree generation # ------------------------------ -inspect = (obj) -> - if global.testingBrowser - JSON.stringify obj, null, 2 - else - require('util').inspect obj, - depth: 10 - colors: yes - # Recursively compare all values of enumerable properties of `expected` with # those of `actual`. Use `looseArray` helper function to skip array length # comparison. @@ -36,15 +28,6 @@ looseArray = (arr) -> enumerable: no arr -# Helpers to get AST nodes for a string of code. The root node is always a -# `Block` node, so for brevity in the tests return its children from -# `expressions`. -getAstExpressions = (code) -> - ast = CoffeeScript.compile code, ast: yes - ast.expressions - -getAstExpression = (code) -> getAstExpressions(code)[0] - testExpression = (code, expected) -> ast = getAstExpression code if expected? diff --git a/test/abstract_syntax_tree_location_data.coffee b/test/abstract_syntax_tree_location_data.coffee index b02b0a3e..2b21d006 100644 --- a/test/abstract_syntax_tree_location_data.coffee +++ b/test/abstract_syntax_tree_location_data.coffee @@ -2,8 +2,7 @@ # --------------------------------- testAstLocationData = (code, expected) -> - ast = CoffeeScript.compile code, ast: yes - testAstNodeLocationData ast.expressions[0], expected + testAstNodeLocationData getAstExpression(code), expected testAstNodeLocationData = (node, expected, path = '') -> extendPath = (additionalPath) -> @@ -41,6 +40,7 @@ testSingleNodeLocationData = (node, expected, path = '') -> eq node.loc.end.column, expected.loc.end.column, \ "Expected #{path}.loc.end.column: #{reset}#{node.loc.end.column}#{red} to equal #{reset}#{expected.loc.end.column}#{red}" + test "AST location data as expected for NumberLiteral node", -> testAstLocationData '42', type: 'NumericLiteral' diff --git a/test/support/helpers.coffee b/test/support/helpers.coffee index e715eaee..f73a6051 100644 --- a/test/support/helpers.coffee +++ b/test/support/helpers.coffee @@ -38,3 +38,21 @@ exports.eqJS = (input, expectedOutput, msg) -> ok egal(expectedOutput, actualOutput), msg or diffOutput expectedOutput, actualOutput exports.isWindows = -> process.platform is 'win32' + +exports.inspect = (obj) -> + if global.testingBrowser + JSON.stringify obj, null, 2 + else + require('util').inspect obj, + depth: 10 + colors: if process.env.NODE_DISABLE_COLORS then no else yes + +# Helpers to get AST nodes for a string of code. The root node is always a +# `Block` node, so for brevity in the tests return its children from +# `expressions`. +exports.getAstExpressions = (code) -> + ast = CoffeeScript.compile code, ast: yes + ast.expressions + +# Many tests want just the root node. +exports.getAstExpression = (code) -> getAstExpressions(code)[0] From 6b1e9bb82b5290b4ceabe1cd2f649dd82ccc2426 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 24 Sep 2018 23:28:19 -0700 Subject: [PATCH 8/9] Refactor to use new mergeAstLocationData --- lib/coffeescript/nodes.js | 72 +++++++++++++++++++++------------------ src/nodes.coffee | 20 ++++------- 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 8aee9911..9ffde09b 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -4,7 +4,7 @@ // nodes are created as the result of actions in the [grammar](grammar.html), // but some are created by other nodes as a method of code generation. To convert // the syntax tree into a string of JavaScript code, call `compile()` on the root. - var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXTag, Call, Class, Code, CodeFragment, ComputedPropertyName, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, hasLineComments, indentInitial, isFunction, isLiteralArguments, isLiteralThis, isNumber, isPlainObject, isUnassignable, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility, + var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXTag, Call, Class, Code, CodeFragment, ComputedPropertyName, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HEREGEX_OMIT, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, Interpolation, JS_FORBIDDEN, LEADING_BLANK_LINE, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, SIMPLE_STRING_OMIT, STRING_OMIT, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TRAILING_BLANK_LINE, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, greater, hasLineComments, indentInitial, isFunction, isLiteralArguments, isLiteralThis, isNumber, isPlainObject, isUnassignable, lesser, locationDataToString, makeDelimitedLiteral, merge, mergeAstLocationData, moveComments, multident, replaceUnicodeCodePointEscapes, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility, indexOf = [].indexOf, splice = [].splice, slice1 = [].slice; @@ -1746,17 +1746,15 @@ ref1 = this.properties; for (propIndex = j = 0, len1 = ref1.length; j < len1; propIndex = ++j) { prop = ref1[propIndex]; - ret = mergeAstLocationData(Object.assign({ + ret = { type: 'MemberExpression', object: ret, property: prop.ast(), computed: prop instanceof Index || !(((ref2 = prop.name) != null ? ref2.unwrap() : void 0) instanceof PropertyName), optional: !!prop.soak, shorthand: !!prop.shorthand - }, prop.astLocationData()), ret); - if (propIndex === 0 && this.base instanceof Parens && (this.base.locationData != null)) { - mergeAstLocationData(ret, this.base.astLocationData()); - } + }; + Object.assign(ret, mergeAstLocationData(this.base.astLocationData(), prop.astLocationData())); } return ret; } @@ -6298,36 +6296,42 @@ return `${options.delimiter}${body}${options.delimiter}`; }; - // Extends the location data of an AST node to include the location data from - // another AST node. - mergeAstLocationData = function(intoNode, fromNode) { - var fromRange, intoRange; - ({ - range: intoRange - } = intoNode); - ({ - range: fromRange - } = fromNode); - if (!(intoRange && fromRange)) { - return intoNode; + // Take two AST nodes, or two AST nodes’ location data objects, and return a new + // location data object that encompasses the location data of both nodes. So the + // new `start` value will be the earlier of the two nodes’ `start` values, the + // new `end` value will be the later of the two nodes’ `end` values, etc. + lesser = function(a, b) { + if (a < b) { + return a; + } else { + return b; } - if (fromRange[0] < intoRange[0]) { - intoNode.range = intoRange = [fromRange[0], intoRange[1]]; - intoNode.start = fromNode.start; - intoNode.loc = { - start: fromNode.loc.start, - end: intoNode.loc.end - }; + }; + + greater = function(a, b) { + if (a > b) { + return a; + } else { + return b; } - if (fromRange[1] > intoRange[1]) { - intoNode.range = [intoRange[0], fromRange[1]]; - intoNode.end = fromNode.end; - intoNode.loc = { - start: intoNode.loc.start, - end: fromNode.loc.end - }; - } - return intoNode; + }; + + mergeAstLocationData = function(nodeA, nodeB) { + return { + loc: { + start: { + line: lesser(nodeA.loc.start.line, nodeB.loc.start.line), + column: lesser(nodeA.loc.start.column, nodeB.loc.start.column) + }, + end: { + line: greater(nodeA.loc.end.line, nodeB.loc.end.line), + column: greater(nodeA.loc.end.column, nodeB.loc.end.column) + } + }, + range: [lesser(nodeA.range[0], nodeB.range[0]), greater(nodeA.range[1], nodeB.range[1])], + start: lesser(nodeA.start, nodeB.start), + end: greater(nodeA.end, nodeB.end) + }; }; }).call(this); diff --git a/src/nodes.coffee b/src/nodes.coffee index 3115f6cf..ee6ce8ad 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1154,19 +1154,13 @@ exports.Value = class Value extends Base ret = @base.ast() for prop, propIndex in @properties ret = - mergeAstLocationData( - Object.assign { - type: 'MemberExpression' - object: ret - property: prop.ast() - computed: prop instanceof Index or prop.name?.unwrap() not instanceof PropertyName - optional: !!prop.soak - shorthand: !!prop.shorthand - }, prop.astLocationData() - ret - ) - if propIndex is 0 and @base instanceof Parens and @base.locationData? - mergeAstLocationData ret, @base.astLocationData() + type: 'MemberExpression' + object: ret + property: prop.ast() + computed: prop instanceof Index or prop.name?.unwrap() not instanceof PropertyName + optional: !!prop.soak + shorthand: !!prop.shorthand + Object.assign ret, mergeAstLocationData(@base.astLocationData(), prop.astLocationData()) ret checkNewTarget: (o) -> From 1bbbca6496c093d2bcbc2931b903a21148d44483 Mon Sep 17 00:00:00 2001 From: Julian Rosse Date: Tue, 25 Sep 2018 22:03:40 -0400 Subject: [PATCH 9/9] comment --- lib/coffeescript/nodes.js | 3 +++ src/nodes.coffee | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 9ffde09b..e7eae3bd 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -1754,6 +1754,9 @@ optional: !!prop.soak, shorthand: !!prop.shorthand }; + // When the `Value` has properties, the location data of a `MemberExpression` AST node + // corresponding to a given property should span the location of the `Value`'s `base` + // (including parens if present) through the property's location Object.assign(ret, mergeAstLocationData(this.base.astLocationData(), prop.astLocationData())); } return ret; diff --git a/src/nodes.coffee b/src/nodes.coffee index ee6ce8ad..c583a427 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1160,6 +1160,9 @@ exports.Value = class Value extends Base computed: prop instanceof Index or prop.name?.unwrap() not instanceof PropertyName optional: !!prop.soak shorthand: !!prop.shorthand + # When the `Value` has properties, the location data of a `MemberExpression` AST node + # corresponding to a given property should span the location of the `Value`'s `base` + # (including parens if present) through the property's location Object.assign ret, mergeAstLocationData(@base.astLocationData(), prop.astLocationData()) ret