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

attachComments doesn't attach comments found in function signature #23

Open
medikoo opened this issue Feb 3, 2014 · 8 comments
Open

Comments

@medikoo
Copy link

medikoo commented Feb 3, 2014

Code:

var x = function (/* signature comment */) {
    return 'foo' + 'bar';
};
/* raz */
x(function (other) { return other });

Handling:

var ast = esprima.parse(code, { comment: true, range: true, tokens: true });
console.log(ast.comments.length); // 2, both comments are referenced
ast = escodegen.attachComments(ast, ast.comments, ast.tokens);
console.log(escodegen.generate(ast, { comment: true });

Result:

var x = function (foo) {
    return 'foo' + 'raz'
};
/* raz */
x(function (other) {
    return other
})

We miss comment in function signature

@Constellation
Copy link
Member

This is the issue of escodegen.
Since currently escodegen only supports Statement level comment, escodegen drops these comments.
Please file it to escodegen.

@medikoo
Copy link
Author

medikoo commented Feb 6, 2014

@Constellation I don't see it so. attachComments is etraverse method, just referenced by escodegen,

estraverse.attachComments do not attach all comments as expected. Let me fix above example to use estraverse directly

@medikoo
Copy link
Author

medikoo commented Feb 6, 2014

Exact example with output:
example.js

var x = function (/* signature comment */) {
    return 'foo' + 'bar';
};
/* raz */
x(function (other) { return other });

test.js

var esprima    = require('esprima')
  , estraverse = require('estraverse')
  , inspect    = require('util').inspect

  , code = require('fs').readFileSync(__dirname + '/example.js')
  , inspectOpts = { depth: 10, colors: true };

var ast = esprima.parse(code, { comment: true, range: true, tokens: true });

console.log("Comments", inspect(ast.comments, inspectOpts)); // All comments there

ast = estraverse.attachComments(ast, ast.comments, ast.tokens);

console.log("Attached?: ", inspect(ast.body, inspectOpts)); // No comments attached

After running above, with latest node, and latest versions of involved packages, you get following output:

Comments in AST as generated by esprima:

Comments [ { type: 'Block',
    value: ' signature comment ',
    range: [ 18, 41 ] },
  { type: 'Block',
    value: ' raz ',
    range: [ 71, 80 ] } ]

AST after comments being attached:

Attached?:  [ { type: 'VariableDeclaration',
    declarations: 
     [ { type: 'VariableDeclarator',
         id: 
          { type: 'Identifier',
            name: 'x',
            range: [ 4, 5 ] },
         init: 
          { type: 'FunctionExpression',
            id: null,
            params: [],
            defaults: [],
            body: 
             { type: 'BlockStatement',
               body: 
                [ { type: 'ReturnStatement',
                    argument: 
                     { type: 'BinaryExpression',
                       operator: '+',
                       left: 
                        { type: 'Literal',
                          value: 'foo',
                          range: [ 53, 58 ] },
                       right: 
                        { type: 'Literal',
                          value: 'bar',
                          range: [ 61, 66 ] },
                       range: [ 53, 66 ] },
                    range: [ 46, 67 ] } ],
               range: [ 43, 69 ] },
            rest: null,
            generator: false,
            expression: false,
            range: [ 8, 69 ] },
         range: [ 4, 69 ] } ],
    kind: 'var',
    range: [ 0, 70 ] },
  { type: 'ExpressionStatement',
    expression: 
     { type: 'CallExpression',
       callee: 
        { type: 'Identifier',
          name: 'x',
          range: [ 81, 82 ] },
       arguments: 
        [ { type: 'FunctionExpression',
            id: null,
            params: 
             [ { type: 'Identifier',
                 name: 'other',
                 range: [ 93, 98 ] } ],
            defaults: [],
            body: 
             { type: 'BlockStatement',
               body: 
                [ { type: 'ReturnStatement',
                    argument: 
                     { type: 'Identifier',
                       name: 'other',
                       range: [ 109, 114 ] },
                    range: [ 102, 115 ] } ],
               range: [ 100, 116 ] },
            rest: null,
            generator: false,
            expression: false,
            range: [ 83, 116 ] } ],
       range: [ 81, 117 ] },
    range: [ 81, 118 ],
    leadingComments: 
     [ { type: 'Block',
         value: ' raz ',
         range: { '0': 71, '1': 80 },
         extendedRange: [ 70, 81 ] } ] } ]

You can clearly see, that signature comment was not attached by estraverse.attachComments as expected.

@medikoo
Copy link
Author

medikoo commented Feb 6, 2014

So can you please clarify further, or reopen the issue

@Constellation
Copy link
Member

Ah, I missed it. In this case,

var x = function (/* signature comment */) {
    return 'foo' + 'bar';
};
/* raz */
x(function (other) { return other })

We cannot attach /* signature comment */ to some nodes since there's no reasonable leading or trailing node for this comment.
This is severe problem, we're discussing about this on escodegen#133.
/cc @getify @michaelficarra

@medikoo
Copy link
Author

medikoo commented Feb 6, 2014

@Constellation it's only the case if there are no arguments in signature, it all works fine if there is at least one argument, e.g. for following function (/* foo */arg/* bar */) {} arguments will be attached properly.

So is there any chance to have that reopened?

@Constellation Constellation reopened this Feb 6, 2014
@Constellation
Copy link
Member

Reopened.

@Constellation it's only the case if there are no arguments in signature, it all works fine if there is at least one argument, e.g. for following function (/* foo /arg/ bar */) {} arguments will be attached properly.

Right. In this case (there are no arguments), currently I don't have reasonable way to solve this.
We cannot handle the following patterns too.

(function /* comment */ () { });

@gfranko
Copy link

gfranko commented Feb 17, 2014

Is there any update on this?

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

No branches or pull requests

3 participants