Comments (14)
I think we can handle it by parsing it by Esprima and injecting produced AST to given tree before passing AST to Escodegen, right?
@michaelficarra:
How does CoffeeScriptRedux handle it?
from escodegen.
I would prefer to don't have a dependency on Esprima (or any other Javascript parser). I chose Escodegen in the first place because it focuses on doing just one thing :)
The solution I'm using right now is to convert those chunks to CallExpression('eval', [ LiteralExpression(code) ])
, but this obviously means an impact on the runtime performance, which is most of the time the main reason to embed code this way.
from escodegen.
@Constellation: CoffeeScriptRedux does what @drslump describes. That feature of CoffeeScript is highly discouraged, so we don't worry about the performance costs. The method you describe (parsing it with Esprima) was considered a few times, but we would rather avoid that dependency and just produce an eval
. Another option to consider is marking esprima as an optional dependency, only requiring it if you see one of these nodes. It's worth reading the related issue, michaelficarra/CoffeeScriptRedux#71.
from escodegen.
That feature of CoffeeScript is highly discouraged, so we don't worry about the performance costs. The method you describe (parsing it with Esprima) was considered a few times, but we would rather avoid that dependency and just produce an eval.
I see. It's reasonable decision.
@drslump:
Escodegen uses Mozilla JS AST because it considers this representation as Intermediate Representation. By using this IR, we can apply a lot of modules using this IR to your AST, for example, Esmangle can analyze / optimize / minify this AST. And at the same time, this IR keeps Escodegen simple. Escodegen's work is only generating ECMAScript code from Mozilla JS AST, not parsing code & transforming tree.
If we introduce CodeExpression specially, we must throw this benefit. Modules cannot analyze CodeExpression because of lack of structure.
So I would prefer these ways, parsing it by Esprima or transforming it to eval call.
Of cource, eval call makes runtime preformance regression and prevents optimization.
So if you would not like to have dependency on Esprima, you can take eval call. But if you think this performance regression isn't negligible, I recommend to use Esprima. Esprima is very simple and well-modularized, so I think you would like it :)
from escodegen.
@Constellation: I think that's a good decision. Let the consumers of escodegen add esprima as a dependency if that's the functionality they need.
from escodegen.
Unfortunately I cannot easily include Esprima since my compiler runs on .Net, executing escodegen with a Javascript interpreter, which is not the fastest thing on earth, while I work on a native code generation implementation.
I understand your concerns but to IMHO using a code generation library means I should be given as much control as possible about what to place in the output. Even if the resulting AST would not be interoperable with other tools, I might choose to generate one version of the AST for escodegen and a standard one using calls to eval.
With that in mind, perhaps I could present a different alternative which would keep the AST compatible with Mozilla's while at the same time allowing more control when using escodegen.
Instead of defining a new node type, expression node types could support an annotation (similarly to how comments are being implemented right now), which would tell escodegen to use the code string defined there instead of traversing the node.
CallExpression:
callee: Identifier('eval')
arguments: [ Literal('evaled.code = literal.code') ]
x-replace: 'evaled.code == literal.code'
When traversing the AST, if the node contains an x-replace
annotation it will include that in the output instead of processing the node.
from escodegen.
@drslump: How about using the raw
value? We could enhance escodegen to use raw values of any node when it exists instead of just for literals.
from escodegen.
@michaelficarra: +1
from escodegen.
Now Escodegen checks parse(raw) == tree
structurally equal. Because when we modify tree but forget to delete raw
value, this becomes difficult bug to find.
Do you have any ideas to implement above idea properly?
from escodegen.
Since it seems that raw
has some special meaning in Esprima-Escodegen perhaps it's better to use a completely separate annotation. The implementation could be as simple as the following (in generateExpression, above the switch):
if (typeof expr['x-replace'] === 'string') {
result = expr['x-replace'].split(/\r\n|\n/)
for (var i=1; i<result.length; i++)
result[i] = newline + base + result[i];
result = parenthesize(result, Precedence.Assignment, precedence)
return toSourceNode(result, expr)
}
from escodegen.
Nice concept. And I would prefer to pass special name with option, like this,
escodegen.generate(AST, { verbatim: 'x-replace' })
And we should note, if verbatim option is used, we cannot ensure result code is valid JavaScript and modules treating Mozilla AST may not recognize this(for example, Esmangle will be broken when this option is used).
from escodegen.
In the meantime, we enable verbatim of Expression. So indentation is not considered.
from escodegen.
verbatim
options is committed in 582483f 382633f
from escodegen.
Thanks, I've merged.
from escodegen.
Related Issues (20)
- 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
- EcmaVersion 7: Unary minus and exponentiation not working HOT 1
- Attaching inline comments breaks up lines
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.