From 8ed691e2667708c98fd3cfd21d41c051d2307033 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 26 Jan 2015 17:18:35 +0100 Subject: [PATCH] Fix #3804: Provide list of referenced vars to REPL Supersedes #3805. Here is a comparison of master, #3805 and this commit: # master $ bin/coffee coffee> 1 %% 2 TypeError: Array.prototype.indexOf called on null or undefined # #3805 $ bin/coffee coffee> 1 %% 2 1 coffee> (_results = null; i) for i in [1, 2, 3] TypeError: Cannot call method 'push' of null # this commit $ bin/coffee coffee> 1 %% 2 1 coffee> (_results = null; i) for i in [1, 2, 3] [ 1, 2, 3 ] --- lib/coffee-script/repl.js | 19 ++++++++++++++++--- src/repl.coffee | 12 +++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/coffee-script/repl.js b/lib/coffee-script/repl.js index 4081e1dc..e2083082 100644 --- a/lib/coffee-script/repl.js +++ b/lib/coffee-script/repl.js @@ -19,16 +19,29 @@ historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0, historyMaxInputSize: 10240, "eval": function(input, context, filename, cb) { - var Assign, Block, Literal, Value, ast, err, js, result, _ref1; + var Assign, Block, Literal, Value, ast, err, js, referencedVars, result, token, tokens, _ref1; input = input.replace(/\uFF00/g, '\n'); input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1'); _ref1 = require('./nodes'), Block = _ref1.Block, Assign = _ref1.Assign, Value = _ref1.Value, Literal = _ref1.Literal; try { - ast = CoffeeScript.nodes(input); + tokens = CoffeeScript.tokens(input); + referencedVars = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = tokens.length; _i < _len; _i++) { + token = tokens[_i]; + if (token.variable && token[1].charAt(0) === '_') { + _results.push(token[1]); + } + } + return _results; + })(); + ast = CoffeeScript.nodes(tokens); ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]); js = ast.compile({ bare: true, - locals: Object.keys(context) + locals: Object.keys(context), + referencedVars: referencedVars }); result = context === global ? vm.runInThisContext(js, filename) : vm.runInContext(js, context, filename); return cb(null, result); diff --git a/src/repl.coffee b/src/repl.coffee index a7445852..65cbe1b0 100644 --- a/src/repl.coffee +++ b/src/repl.coffee @@ -20,13 +20,19 @@ replDefaults = {Block, Assign, Value, Literal} = require './nodes' try - # Generate the AST of the clean input. - ast = CoffeeScript.nodes input + # Tokenize the clean input. + tokens = CoffeeScript.tokens input + # Collect referenced variable names just like in `CoffeeScript.compile`. + referencedVars = ( + token[1] for token in tokens when token.variable and token[1].charAt(0) is '_' + ) + # Generate the AST of the tokens. + ast = CoffeeScript.nodes tokens # Add assignment to `_` variable to force the input to be an expression. ast = new Block [ new Assign (new Value new Literal '_'), ast, '=' ] - js = ast.compile bare: yes, locals: Object.keys(context) + js = ast.compile {bare: yes, locals: Object.keys(context), referencedVars} result = if context is global vm.runInThisContext js, filename else