Comments (19)
In esprima, now we're discussing about attaching comments to AST.
http://code.google.com/p/esprima/issues/detail?id=197
So if it is available, escodegen can attach comments to its output!
from escodegen.
@Constellation: Ah, I didn't notice that issue, thanks for the link. Great news!
from escodegen.
I'd love to see support for comments as well. I just wrote a script to convert our AMD codebase into CommonJS modules, but just when I was done, I realized that I can't use it because the comments will be stripped out : /.
from escodegen.
OK, we'll implement experimental version.
But take care that this is experimental.
If esprima is changed the direction of comment, we maybe follow to it.
So if you use it, we suggest check escodegen and esprima version.
from escodegen.
Oops, sorry, I pushed "Close & comment" button incorrectly.
from escodegen.
Above commit makes statement level comment possible.
Currently, you can use it
var tree = esprima.parse(code, { range: true, token: true, comment: true });
tree = escodegen.attachComments(tree, tree.comments, tree.tokens);
var output = escodegen.generate(tree);
Of cource, this is still development version, so if you have any idea about API, format, multiline comment, expression comment, indentation adjustment of multiline comment and others, I appreciate if you comment your opinion or create pull requests.
from escodegen.
Wow, thanks a lot! I ran it on my project and it seems to work great. Maybe I'll have more comments later.
from escodegen.
I fixed some bugs in above commit and add new option, 'format.indent.adjustMultilineComment'.
If you provide this option, for example,
var tree = esprima.parse(code, { range: true, token: true, comment: true });
tree = escodegen.attachComments(tree, tree.comments, tree.tokens);
var output = escodegen.generate(tree, { format: { indent: { adjustMultilineComment: true } } });
When you convert such a 2-space script to 4-space script,
function test() {
/*
* comment
*/
var i = 20;
}
escodegen automatically adjusts multiline comment base indentation(2-space to 4-space) so output is below.
function test() {
/*
* comment
*/
var i = 20;
}
not following.
function test() {
/*
* comment
*/
var i = 20;
}
from escodegen.
And demonstration. :-)
This is 2-space converted jQuery source code from jQuery development version.
https://gist.github.com/2757675
from escodegen.
Now, escodegen requires option.comment,
If option.comment provided and comment attached, escodegen generate comment attached code.
from escodegen.
We released 0.0.4, but this function is still experimental, so API will change.
Probably, for more precise and good comment attaching, we will require source code text.
So if we change this API, we should write new one to this issue.
from escodegen.
We should add line terminator check to attachComments.
For example,
var i = 10; /*
* this is trailing comment to i = 10
*/
var i2 = 20;
But
var i = 10;
/*
* this is leading comment to var i2 = 20
*/
var i2 = 20;
from escodegen.
What follows might be helpful when generating expression-level comments.
var singleLineComments = [
'//A\n{//B\n}//C\n//D\n',
'//A\n{//B\n42//C\n}//D\n//E\n',
'//A\n[//B\n]//C\n//D\n',
'//A\n[//B\n,//C\n42//D\n]//E\n//F\n',
'//A\n!//B\n{//C\n}//D\n//E\n',
'//A\n!//B\n{//C\n42//D\n://E\n42//F\n,//G\nfoo//H\n://I\n42//J\n}//K\n//L\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\ndefault//G\n://H\n42//I\n}//J\n//K\n',
'//A\n42//B\n;//C\n42//D\n//E\n',
'//A\n!//B\nfunction//C\n(//D\nfoo//E\n,//F\nbar//G\n)//H\n{//I\n}//J\n//K\n',
'//A\n42//B\n,//C\n42//D\n//E\n',
'//A\nfoo//B\n=//C\n42//D\n//E\n',
'//A\n42//B\n?//C\n42//D\n://E\n42//F\n//G\n',
'//A\nfoo//B\n(//C\n42//D\n,//E\n42//F\n)//G\n//H\n',
'//A\nnew//B\nFoo(//C\n42//D\n,//E\n42//F\n)//G\n//H\n',
'//A\n//B\n!//C\n{//D\n42//E\n://F\n42//G\n}//H\n//I\n',
'//A\ndo//B\n{//C\n}//D\nwhile//E\n(//F\n42//G\n)//H\n;//I\n//J\n',
'//A\ntry//B\n{//C\n}//D\ncatch//E\n(//F\nfoo//G\n)//H\n{//I\n}//J\n//K\n',
'//A\nvar//B\nfoo//C\n=//D\n42//E\n//F\n',
'//A\nvar//B\nfoo//C\n,//D\nbar//E\n//F\n',
'//A\ntry//B\n{//C\n}//D\nfinally//E\n{//F\n}//G\n//H\n',
'//A\nswitch//B\n(//C\nfoo//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\nif//I\n(//J\n42//K\n)//L\n{//M\n}//N\n//O\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\n{//I\n}//J\n//K\n',
'//A\nfor//B\n(//C\n;//D\n42//E\n;//F\n42//G\n)//H\n;//I\n//J\n',
'//A\nfor//B\n(//C\nfoo//D\nin//E\n42//F\n)//G\n;//H\n//I\n',
'//A\nwhile//B\n(//C\n42//D\n)//E\n;//F\n//G\n',
'//A\nwith//B\n(//C\n{//D\n}//E\n)//F\n;//G\n//H\n',
'//A\nfoo//B\nin//C\nbar//D\n,//E\n[//F\n]//G\nin//H\n[//I\n]//J\n//K\n',
'//A\nnew//B\nFoo//C\n(//D\n)//E\n,//F\nnew//G\n[//H\n]//I\n(//J\n)//K\n//L\n',
'//A\ntypeof//B\n42//C\n,//D\ntypeof//E\n[//F\n]//G\n//H\n',
'//A\nthrow 42//B\n;//C\nthrow[//D\n]//E\n//F\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\ncase//G\n42//H\n://I\ncase//J\n[//K\n]//L\n://M\n}//N\n//O\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\n42//I\n;//J\nif//K\n(//L\n42//M\n)//N\n{//O\n}//P\nelse//Q\n[//R\n]//S\n;//T\n//U\n',
'//A\nfor//B\n(foo//C\nin//D\n42//E\n)//F\n;//G\nfor//H\n(//I\nfoo//J\nin//K\n[//L\n]//M\n)//N\n;//O\n',
'//A\n!//B\nfunction//C\n(//D\n)//E\n{//F\nreturn 42//H\n}//I\n,//J\nfunction//K\n(//L\n)//M\n{//N\nreturn[//O\n]//P\n}//Q\n//R\n',
'//A\n!//B\nfunction//C\nfoo//D\n(//E\n)//F\n{//G\n}//H\n//I\n',
'//A\n!//B\n{//C\nget//D\n42//E\n(//F\n)//G\n{//H\n}//I\n,//J\nset//K\n42//L\n(//M\nbar//N\n)//O\n{//P\n}//Q\n}//R\n//S\n',
'//A\nfoo//B\n://C\nwhile//D\n(//E\n42//F\n)//G\nbreak foo//H\n;//I\n//J\n',
'//A\nfoo//B\n://C\nwhile//D\n(//E\n42//F\n)//G\ncontinue foo//H\n;//I\n//J\n',
'//A\nvar//B\nfoo//C\n//D\n',
'//A\nfor//B\n(//C\nvar//D\nfoo//E\nin//F\n42)//G\n;//H\n//I\n',
'//A\nfunction//B\nfoo//C\n(//D\n)//E\n{//F\n}//G\n//H\n',
'//A\n(//B\n{//C\n}//D\n)//E\n//F\n',
'//A\n(//B\nfunction//C\n(//D\n)//E\n{//F\n}//G\n)//H\n//I\n',
'//A\n{//B\n42//C\n}//D\n//E\n',
'//A\n[//B\n]//C\n//D\n',
'//A\n[//B\n,//C\n42//D\n]//E\n//F\n',
'//A\n!//B\n{//C\n}//D\n//E\n',
'//A\n!//B\n{//C\n42//D\n://E\n42//F\n,//G\nfoo//H\n://I\n42//J\n}//K\n//L\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\ndefault//G\n://H\n42//I\n}//J\n//K\n',
'//A\n42//B\n;//C\n42//D\n//E\n',
'//A\n!//B\nfunction//C\n(//D\nfoo//E\n,//F\nbar//G\n)//H\n{//I\n}//J\n//K\n',
'//A\n42//B\n,//C\n42//D\n//E\n',
'//A\nfoo//B\n=//C\n42//D\n//E\n',
'//A\n42//B\n?//C\n42//D\n://E\n42//F\n//G\n',
'//A\nfoo//B\n(//C\n42//D\n,//E\n42//F\n)//G\n//H\n',
'//A\nnew//B\nFoo(//C\n42//D\n,//E\n42//F\n)//G\n//H\n',
'//A\n//B\n!//C\n{//D\n42//E\n://F\n42//G\n}//H\n//I\n',
'//A\ndo//B\n{//C\n}//D\nwhile//E\n(//F\n42//G\n)//H\n;//I\n//J\n',
'//A\ntry//B\n{//C\n}//D\ncatch//E\n(//F\nfoo//G\n)//H\n{//I\n}//J\n//K\n',
'//A\nvar//B\nfoo//C\n=//D\n42//E\n//F\n',
'//A\nvar//B\nfoo//C\n,//D\nbar//E\n//F\n',
'//A\ntry//B\n{//C\n}//D\nfinally//E\n{//F\n}//G\n//H\n',
'//A\nswitch//B\n(//C\nfoo//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\n//H\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\nif//I\n(//J\n42//K\n)//L\n{//M\n}//N\n//O\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\n{//I\n}//J\n//K\n',
'//A\nfor//B\n(//C\n;//D\n42//E\n;//F\n42//G\n)//H\n;//I\n//J\n',
'//A\nfor//B\n(//C\nfoo//D\nin//E\n42//F\n)//G\n;//H\n//I\n',
'//A\nwhile//B\n(//C\n42//D\n)//E\n;//F\n//G\n',
'//A\nwith//B\n(//C\n{//D\n}//E\n)//F\n;//G\n//H\n',
'//A\nfoo//B\nin//C\nbar//D\n,//E\n[//F\n]//G\nin//H\n[//I\n]//J\n//K\n',
'//A\nnew//B\nFoo//C\n(//D\n)//E\n,//F\nnew//G\n[//H\n]//I\n(//J\n)//K\n//L\n',
'//A\ntypeof//B\n42//C\n,//D\ntypeof//E\n[//F\n]//G\n//H\n',
'//A\nthrow 42//B\n;//C\nthrow[//D\n]//E\n//F\n',
'//A\nswitch//B\n(//C\n42//D\n)//E\n{//F\ncase//G\n42//H\n://I\ncase//J\n[//K\n]//L\n://M\n}//N\n//O\n',
'//A\nif//B\n(//C\n42//D\n)//E\n{//F\n}//G\nelse//H\n42//I\n;//J\nif//K\n(//L\n42//M\n)//N\n{//O\n}//P\nelse//Q\n[//R\n]//S\n;//T\n//U\n',
'//A\nfor//B\n(foo//C\nin//D\n42//E\n)//F\n;//G\nfor//H\n(//I\nfoo//J\nin//K\n[//L\n]//M\n)//N\n;//O\n',
'//A\n!//B\nfunction//C\n(//D\n)//E\n{//F\nreturn 42//H\n}//I\n,//J\nfunction//K\n(//L\n)//M\n{//N\nreturn[//O\n]//P\n}//Q\n//R\n',
'//A\n!//B\nfunction//C\nfoo//D\n(//E\n)//F\n{//G\n}//H\n//I\n',
'//A\n!//B\n{//C\nget//D\n42//E\n(//F\n)//G\n{//H\n}//I\n,//J\nset//K\n42//L\n(//M\nbar//N\n)//O\n{//P\n}//Q\n}//R\n//S\n',
'//A\nfoo//B\n://C\nwhile//D\n(//E\n42//F\n)//G\nbreak foo//H\n;//I\n//J\n',
'//A\nfoo//B\n://C\nwhile//D\n(//E\n42//F\n)//G\ncontinue foo//H\n;//I\n//J\n',
'//A\nvar//B\nfoo//C\n//D\n',
'//A\nfor//B\n(//C\nvar//D\nfoo//E\nin//F\n42)//G\n;//H\n//I\n',
'//A\nfunction//B\nfoo//C\n(//D\n)//E\n{//F\n}//G\n//H\n',
'//A\n(//B\n{//C\n}//D\n)//E\n//F\n',
'//A\n(//B\nfunction//C\n(//D\n)//E\n{//F\n}//G\n)//H\n//I\n'
];
It might be reasonable to defer testing options.format.compact with comments until expression-level comments are supported and issues #20, #21, and #22 are resolved.
It might be useful to follow the progress on Esprima issue 276.
It would be useful to have a function that returns true
when a statement or an expression for which the code is being generated is preceded by a line separator. For instance:
false/**///
/**/true
would lead to false
for false
and true
for true
. Similarly:
false/**//*
*//**/true
However,
false/**/,/**/false
from escodegen.
Is there a plan to have this change in for 1.1.0, or is it blocked by the AST change?
from escodegen.
Statement level comment is already supported by Escodegen :-)
from escodegen.
It would be useful to be able to only preserve /*! … */
-style license header comments. Should I file a new issue for that?
from escodegen.
var tree = esprima.parse(code, { range: true, token: true, comment: true });
I'm guessing this should be tokens
instead:
var tree = esprima.parse(code, { range: true, tokens: true, comment: true });
Any changes to the syntax for attaching comments or generating code with comments? I'm using [email protected] and [email protected]. It looks like leadingComments
are attached to the tree, but I don't see them in the generated source.
sample code.js
:
var foo;
/**
* @constructor
* @param {string} name Bar.
*/
function Bar(name) {
this.name = name;
}
and parsing/generating:
var fs = require('fs');
var esprima = require('esprima');
var escodegen = require('escodegen');
var code = fs.readFileSync('code.js', 'utf8')
var tree = esprima.parse(code, {range: true, tokens: true, comment: true});
tree = escodegen.attachComments(tree, tree.comments, tree.tokens);
var output = escodegen.generate(tree);
This yields the output: 'var foo;\nfunction Bar(name) {\n this.name = name;\n}'
Also, without the var foo;
before the first comment, the comment is attached as a leadingComment
of the Program
instead of the FunctionDeclaration
.
Thanks for any updates on the status of attaching comments to nodes.
from escodegen.
Ah, should have read the tests first.
I see the parsing/generating bit should be:
var tree = esprima.parse(code, {range: true, tokens: true, comment: true});
tree = escodegen.attachComments(tree, tree.comments, tree.tokens);
var output = escodegen.generate(tree, {comment: true});
I think it is still a valid issue that without the var foo;
at the top of the source, the first comment is not attached as a leadingComment
of the FunctionDeclaration
- I'll search through more recent issues to see if that is mentioned elsewhere.
from escodegen.
FYI: I've submitted a PR which I think would provide a mechanism to address this issue more broadly across all places of the code where they would be valid: #133
from escodegen.
Related Issues (20)
- Comment gets stripped out
- Comment causes wrong indentation
- GBK chaodedracters are automatically encoded HOT 1
- Should be using the directive estree field
- Failes on Line & Block comments
- Support static class fields HOT 5
- Update Node versions in .travis.yml?
- Invalid code is generated with a MemberExpression against an ObjectExpression.
- Can you publish a new version to NPM that includes the latest nullish coalescing operator precedence ??
- Potential Security Vulnerability HOT 9
- Online demo doesn't return the emoji back HOT 3
- {format:{json:true}} option, generate json key without quotes
- Security issue with statement expression parser for identifiers HOT 2
- Update source-map as it's current version 0.6.1 is marked as EOL HOT 1
- `require` of _package.json_ complicates bundling
- Outdated dependency security vulnerability HOT 6
- CVE in 1.14.3 => optionator 0.8.x => word-wrap HOT 1
- word-wrap vulnerable to Regular Expression Denial of Service HOT 4
- "NewExpression" generated without arguments HOT 2
- escodegen expects value in Property key:value pair to have a type; crashes on null
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from escodegen.