Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug mode for running .coffee scripts #558, #987 #1396

Closed
wants to merge 1 commit into from

Conversation

geraldalewis
Copy link
Contributor

Debug mode for running .coffee scripts #558, #987

Adds a --debug option for .coffee scripts that outputs more helpful error messages (mapping compiled .js lines of code to the input .coffee file's lines).

This branch should be considered experimental at the moment -- it serves as a proof-of-concept and to expose additional issues with adding debugging support to CoffeeScript. I.e., don't merge it into master :)

Current output:

TypeError: string is not a function
    at String.CALL_NON_FUNCTION (native)
    at Object.<anonymous> (/Users/geraldlewis/Work/Interactive/projects/coffee-script/errs/err.coffee:10:3)
    at Module._compile (module.js:420:26)
    at Object.run (/Users/geraldlewis/Work/Interactive/projects/coffee-script/coffee-script/lib/coffee-script.js:68:12)
    at /Users/geraldlewis/Work/Interactive/projects/coffee-script/coffee-script/lib/command.js:120:29
    at /Users/geraldlewis/Work/Interactive/projects/coffee-script/coffee-script/lib/command.js:90:26
    at [object Object].<anonymous> (fs.js:107:5)
    at [object Object].emit (events.js:61:17)
    at afterRead (fs.js:970:12)
    at wrapper (fs.js:245:17)

--debug Output:

  TypeError: string is not a function

  in err.js on line 10
  --------------------
  > 10 |   s();

  in err.coffee on line 10
  ------------------------
   7 | 
   8 | 
   9 | for k,v in [1,2,3]
> 10 |   s()
  11 |   try
  12 |     #log undef

Caveats

  • only works with node.js at the moment
  • only works for running and eval-ed .coffee scripts (see below)
  • needs a lot of testing; I've not tested it with a lot of sample bugs

Here's the branch:
https://github.com/geraldalewis/coffee-script/tree/debug

Here's the commit:
geraldalewis@9d0fa7c

=What works=

Running .coffee files

bin/coffee -d ../errs/err.coffee 

  TypeError: string is not a function

  in err.js on line 11
  --------------------
  > 11 |     s();

  in err.coffee on line 10
  ------------------------
   7 | 
   8 | 
   9 | for k,v in [1,2,3]
> 10 |   s()
  11 |   try
  12 |     #log undef

Eval

...Sort of -- this works:

bin/coffee -bed 'i = 0; undef()'

but this fails for some reason (some bug in the DebugCSFile.error, I think -- seems to happen if < 2 lines of .js)

bin/coffee -bed 'undef()'

What doesn't work

There are a few classes of errors I'm struggling to get debug info from. I have no solutions at the moment, but some ideas below.

Errors in CoffeeScript

@jashkenas 's first question to me was what kind of output he'd see if there was an error in src/scope.coffee. I inserted a bug into Scope's constructor (a call to undef()), recompiled CoffeeScript, and ran coffee -bed 'i = 1'

dev:coffee-script(debugging)$ coffee -bed 'i = 1'
ReferenceError: undef is not defined
    at new Scope (/Users/geraldlewis/Work/interactive/projects/coffee-script/coffee-script/lib/scope.js:10:7)
    ...

Clearly, debug didn't work -- we have the same node.js error message output, instead of the expected:

ReferenceError: undef is not defined

in scope.coffee on line 21
--------------------------
  19 |constructor: (@parent, @expressions, @method) ->
> 21 |  undef()
  22 |  @variables = [{name: 'arguments', type: 'arguments'}]

My mistake was forgetting that coffee uses pre-compiled .js files to run CoffeeScript. debug relies on CoffeeScript compiling a .coffee file -- the .coffee file needs to be present so that the executing .js file's line numbers can be mapped to their CoffeeScript source. Since we no longer have a reference to the original scope.coffee file, we don't have any way of associating the lines of code where an error occured in scope.js.

Compounding the issue: because debug needs to re-compile the source .coffee file(s) (to insert the line-number comments mapping the line of .js to its respective line of .coffee) a bug in the compile pipeline is a bug in debug...

Possible Solutions

  1. cake build ensures a clean, working copy of CoffeeScript is available even if a bug is introduced into its source
  2. introduce a bug into the source of CoffeeScript
    # in source.coffee
    constructor: ()->
      undef()
  1. compile the buggy CoffeeScript via cake build
  2. run a bug-free script to see if an error occurs
    bin/coffee -be 'i = 1'
  1. on error, grab the buggy .js file from the error stack
    at new Scope (coffee-script/lib/scope.js:10:7)
  1. somehow get the .js file's associated .coffee file
    # in scope.js
    //@source_file:coffee-script/src/scope.coffee
  1. and send it to the clean working copy of CoffeeScript
  2. output that debug message...

Docco

Debugging Docco represents a subtly different class of issues than debugging CoffeeScript. Like CoffeeScript, docco.coffee has already been compiled to docco.js when bin/docco requires it:

#!/usr/bin/env node

var path = require('path');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');

process.ARGV = process.argv = process.argv.slice(2, process.argv.length);
require(lib + '/docco.js'); #completely bypasses the .coffee compilation stage

We have the same issue -- since we no longer have a reference to the original .coffee script, we don't have any way of associating the line of JavaScript code with its originating CoffeeScript line.

Possible solutions:

  1. run docco via bin/coffee
  • modify command.coffee run to allow args to be sent via "<" to the running script if the -d option is set:

    coffee -d src/docco.coffee < src/some_project.coffee
    # for the `run`ning src/docco.coffee script, process.ARGV would = process.ARGV[2..]
    
  1. a --debugsource flag (oof?)
  • not sure how this would work exactly, but some loose ideas:

  • debugsource points to the .coffee source file or src/ folder for the running script

  • if an error is encountered in the node.js runtime

  • use process.on 'uncaughtException' to catch it and save details as "stack"

  • run coffee-script.debug ( debugsource, stack ... )

  • (this recompiles the debugsource so that the CoffeeScript lines can be associated with their JS counterparts )

    docco --debugsource=src/docco.coffee src/some_project.coffee

@geraldalewis
Copy link
Contributor Author

@denofevil There's a fundamental flaw in my approach to the issue, namely that it assumes the runtime has access to the original .coffee file. @pmuellr in #558 has some updates on the work being done for WebKit on this issue -- their approach is better. I would not recommend merging this branch into master.

@denofevil
Copy link

@geraldalewis Thank you for your reply. I've read related WebKit/FireFox discussions and most probably we'll try to participate in Source Mapping format process (at least by implementing it in out JS debugger)

@geraldalewis
Copy link
Contributor Author

@denofevil Good luck! I'd love to hear if you make some headway on the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clarify that stack trace line numbers are from generated JS
4 participants