google / traceur-compiler

Traceur is a JavaScript.next-to-JavaScript-of-today compiler
Apache License 2.0
8.18k stars 580 forks source link

Source Maps on files with export statements have "throw SyntaxError" #749

Open jgable opened 10 years ago

jgable commented 10 years ago

I'm experiencing some source maps being off by about 3-4 lines consistently when compiling modules of non trivial size. A full example can be seen by following directions over at ModuleLoader/es6-module-loader#91 (Note that es6-module-loader uses version 0.0.9 of traceur).

I cloned this repo locally and tried to add a unit test to figure out whether it was this project or maybe a misuse by the module loader but am hitting a roadblock because when parsing a file with an export (or default) keyword there is a syntax error generated in the code.

Example Input

import { hello } from 'test1';

export var things = {
    'one': 1,

    updateThing: function (name, val) {
        this[name] = val;

        if (name === 'bingo') {
            console.log('bingo was his name o');

            this[name] += ' was his name o';
        }
    }
};

export default {
    things: things
};

Output

import 'test1';
(function() {throw SyntaxError("Unexpected token export");})();
var things = {
  'one': 1,
  updateThing: function(name, val) {
    this[name] = val;
    if (name === 'bingo') {
      console.log('bingo was his name o');
      this[name] += ' was his name o';
    }
  }
};
(function() {throw SyntaxError("Unexpected token export");})();
(function() {throw SyntaxError("Unexpected token default");})();
{
  things: things;
}
;

Full unit test I was trying to run is along these lines:

// FILE: /test/unit/codegeneration/SourceMap.js
var fs = require('fs'),
  path = require('path');
test('SingleFileWithExports', function () {
    var filename = 'sourceMap1.js';
    var src = fs.readFileSync(path.join(__dirname, 'fixture', 'sourceMap1.js')).toString();
    var tree = parse(filename, src);

    var generator = new SourceMapGenerator({file: filename});
    var options = {sourceMapGenerator: generator, showLineNumbers: false};
    var actual = TreeWriter.write(tree, options);

    var consumer = new SourceMapConsumer(options.sourceMap);
    //console.log(actual);
    //console.log(consumer);

    var sourceContent = consumer.sourceContentFor(filename);
    assert.equal(sourceContent, src);
  });
arv commented 10 years ago

export is only allowed in Module. Not in Script.

Make sure you are using parser.parseModule and not parser.parseScript.

jgable commented 10 years ago

An import is allowed in a script but an export is not? That seems odd. There is a unit test directly below mine I took as an example that uses an import statement.

arv commented 10 years ago

import was allowed in Script for while. The spec draft no longer allows it but we haven't updated our code yet.

johnjbarton commented 10 years ago

I am reopening this as a way to track:

  1. Can we give a better result than output with throw embedded?
  2. Disallow import in Script.
  3. Can we provide a direct message "export not allowed in Script"? I've hit this several times and I predict it will be the number one problem with new users of modules.
  4. Better api for transcoders.
johnjbarton commented 10 years ago

@jgable how did you get the output you show? It does not seem to come from the unit test code.

jgable commented 10 years ago

@arv The parseModule worked like a charm.

@johnjbarton I just did a console.log(actual) (it's commented out in my unit test example above) and when I ran make test/unit it spits it out.

johnjbarton commented 10 years ago

Issue #753 is item 2 on my list above.