Giter Site home page Giter Site logo

escodegen's Introduction

Escodegen

npm version Build Status Dependency Status devDependency Status

Escodegen (escodegen) is an ECMAScript (also popularly known as JavaScript) code generator from Mozilla's Parser API AST. See the online generator for a demo.

Install

Escodegen can be used in a web browser:

<script src="escodegen.browser.js"></script>

escodegen.browser.js can be found in tagged revisions on GitHub.

Or in a Node.js application via npm:

npm install escodegen

Usage

A simple example: the program

escodegen.generate({
    type: 'BinaryExpression',
    operator: '+',
    left: { type: 'Literal', value: 40 },
    right: { type: 'Literal', value: 2 }
});

produces the string '40 + 2'.

See the API page for options. To run the tests, execute npm test in the root directory.

Building browser bundle / minified browser bundle

At first, execute npm install to install the all dev dependencies. After that,

npm run-script build

will generate escodegen.browser.js, which can be used in browser environments.

And,

npm run-script build-min

will generate the minified file escodegen.browser.min.js.

License

Escodegen

Copyright (C) 2012 Yusuke Suzuki (twitter: @Constellation) and other contributors.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

escodegen's People

Contributors

adamjmcgrath avatar arian avatar ariya avatar bezoerb avatar comp615 avatar constellation avatar drslump avatar ef4 avatar gozala avatar gregglind avatar jkroso avatar johnjbarton avatar juandopazo avatar kennethkufluk avatar kevinbarabash avatar mathiasbynens avatar michaelficarra avatar msridhar avatar papandreou avatar realityking avatar rgustbardon avatar rreverser avatar sanex3339 avatar therajumandapati avatar tolmasky avatar tootallnate avatar toshok avatar twada avatar zaach avatar zjmiller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

escodegen's Issues

undefined appearing in function definitions?

Hi all,

I am using the following code to try out escodegen:

var source = "var hello = function(){return 'hello world!';}; var hello1 = world; function world(hello){return hello;} var number = function(num){return num;}; hello(); var hello2 = 1+1*number(1)"
var res = esprima.parse(source);
escodegen.generate(res)

the output on my end is:

"var hello = function () {
undefinedreturn 'hello world!';
}; 
var hello1 = world;
function world(hello) {
undefinedreturn hello;
}
var number = function (num) {
undefinedreturn num;
};
hello();
var hello2 = 1 + 1 * number(1);"

The problem is with all the "undefined" appearing in the function body. Any help would be appreciated :)

Jason

Make escodegen.attachComments implicit with comment: true

Currently, the following doesn't work:

var ast = esprima.parse(sourceCode, {range: true, tokens: true, comment: true})
console.log('result:', escodegen.generate(ast, {comment: true}));

However, this works:

var ast = esprima.parse(sourceCode, {range: true, tokens: true, comment: true});
ast = escodegen.attachComments(ast, ast.comments, ast.tokens);
console.log('result:', escodegen.generate(ast, {comment: true}));

I don't understand the need for the attachComments call. Passing comment:true should be enough so that comments show up.

Add support for quirks

options.format.quirks or more sophisticated options would allow supporting quirks. These options would take precedence over any other options.

What follows are the quirks supported by the Closure Compiler when it comes to code generation:

  • breaking lines after an arbitrary number of characters (500 characters in the Closure Compiler; 32768 characters in UglifyJS),
  • escaping '-->' as '--\\>',
  • escaping '<!--' as '<\\!--',
  • escaping /<\/script([ \t\n\f\r]*>)/gi as '<\\/script$1',
  • escaping ']]>' as ']]\\>',
  • escaping reserved words used as identifiers (illegal; not supported by Esprima; var \u0069\u0066; would become var \u0069f;),
  • putting a do-while statement of an if statement in a block (if(x)do{foo()}while(y);),
  • putting sole functions in a block (if (true) function foo(){return}),
  • terminating a throw statement with a semicolon (function foo(){throw 'error';}).

See also http://code.google.com/p/closure-compiler/source/browse/trunk/test/com/google/javascript/jscomp/CodePrinterTest.java?r=2027

Spaces in properties names cause problems?

js> print(this.escodegen.generate(Reflect.parse('var a = {}; a["some thing"] = 1')))
var a = {};
a.some thing = 1;

Perhaps Syntax.MemberExpression?

result.push('.' + expr.property.name);

It seems like all of this opens a can of worms, but who knows!

Define a new node type as a chunk of code to output verbatim

Currently I don't see any way to pass a chunk of code to be outputted just as is in the generated source. The use case is when generating an AST from a language that allows to define chunks of code to be placed verbatim in the generated javascript, much like CoffeeScript's backtick notation.

It could work something like this:

{
    type: 'CodeExpression',
    code: 'window.location.href = "http://google.com"'
}

The generator would output the contents of the code with only the following processing performed:

  • Indent first line to the current level if it belongs to ExpressionStatement
  • Indent additional lines to the current level

Since it's impossible to know the precedence order of that node, it should always be assumed that it's very low (Assignment), wrapping it with parens if used in a binary or member expression for example.

Allow safe concatenation with other programs

options.format.safe would make sure that the generated code can be safely followed by another ECMAScript program. The option would take precedence over disabled options.format.semicolons. One can think of the following behavior:

  • If a program ends with a semicolon and, optionally, whitespace characters (7.2; as opposed to line terminators and multi-line comments that include such terminators), the semicolon should be preserved (cf. http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Semicolons). For instance, a semicolon should appear at the end of the code generated given !{}. However, it should not be added if it results in an empty statement that does not exist in the original program. For instance, a semicolon must not appear at the end of the code generated given {}.
  • If a program ends with a single-line comment, the character U+000A should be added at the end of the program.

New Operator Precedence

The expression "new (a().b)()" as parsed by esprima is incorrectly generated as "new a().b()".

Block comment at the start of a file is not attached to the owning syntax node

If a JS file begins with a block comment, attachComments does not attach the block comment to the syntax node that owns the comment.

For example, I used Esprima to parse this file, then called attachComments:

/**
 * @class MyClass
 */
function MyClass() {}

The block comment should be attached to the MyClass declaration. Instead, it is attached to the root node. (See this gist for the complete AST.)

Implement complete automatic semicolon insertion

For the time being, when options.format.semicolons is set to false, only semicolons at the end of programs, blocks, and case blocks are omitted. However, setting this option to false should make complete reliance on automatic semicolon insertion (7.9) possible, e.g.

42;foo;

should result in (with options.format.compact set to false)

42
foo

instead of

42;
foo

Moreover, in the future, with options.format.compact and comments preserved, the input:

42;
/*A
*/
foo;

should result in

42/*A
*/foo

and the input

42;
//A
foo;

should result in

42//A
foo

For pitfalls with regard to reliance on automatic semicolon insertion, see http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Semicolons

Division becomes a single-line comment

With options.format.compact enabled, the problem described at http://code.google.com/p/closure-compiler/issues/detail?id=620 can be observed.

TEMP=$(mktemp)
echo '/ / / / /' | tee "$TEMP"
node <<ENDH
console.log(require("util").inspect(
    require(process.env.HOME + "/github/ariya/esprima/esprima.js").parse(
        "/ / / / /", {comment: true}), null, null))
ENDH
v8 \
  "$HOME/github/ariya/esprima/esprima.js" \
  "$HOME/github/Constellation/escodegen/escodegen.js" \
  /dev/stdin > "$TEMP" <<'ENDH'
print(escodegen.generate(esprima.parse("/ / / / /"), {format: {compact:true}}))
ENDH
cat "$TEMP"
node <<ENDH
console.log(require("util").inspect(
    require(process.env.HOME + "/github/ariya/esprima/esprima.js").parse(
        require("fs").readFileSync("$TEMP"), {comment: true}), null, null))
ENDH

Tested on Ubuntu 12.04 LTS with ariya/esprima@465a4ea and 5de45f6

---x, +++x

{ type: 'UpdateExpression',
  argument:                                                                               
   { type: 'UnaryExpression',
     argument: { type: 'Identifier', name: 'x' },
     operator: '-' },
  operator: '--',
  prefix: true }

produces ---x instead of -(--x) or - --x. I'm preparing a patch.

Throw an error if comments can't be attached

If esprima has been used to generate a tree without any of range, tokens or comment options, I think escodegen can't output the comments. I think escodegen should just throw (or at least console.warn) in these cases to indicate that comments can't be properly outputed.

identifiers that are also keywords are not properly escaped

Identifiers that are also keywords are not properly escaped. This causes escodegen to create invalid programs from valid ASTs. The simplest example:

{ type: 'Identifier', name: 'do' }

Expected output: either d\u006f or \u0064o or (hopefully not, though) \u0064\u006f.

Observed output: do (an invalid program).

fails when ObjectExpression properties don't have a type property

When I parse var a = {a: 2} with acorn, the resulting AST is as follows:

{
  "type": "Program",
  "start": 0,
  "end": 14,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 14,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 4,
          "end": 14,
          "id": {
            "type": "Identifier",
            "start": 4,
            "end": 5,
            "name": "a"
          },
          "init": {
            "type": "ObjectExpression",
            "start": 8,
            "end": 14,
            "properties": [
              {
                "key": {
                  "type": "Identifier",
                  "start": 9,
                  "end": 10,
                  "name": "a"
                },
                "value": {
                  "type": "Literal",
                  "start": 12,
                  "end": 13,
                  "value": 2,
                  "raw": "2"
                },
                "kind": "init"
              }
            ]
          }
        }
      ],
      "kind": "var"
    }
  ]
}

As you can see the properties of the ObjectExpression don't have a type property. This causes escodegen to fail:

/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1385
            throw new Error('Unknown expression type: ' + expr.type);
                  ^
Error: Unknown expression type: undefined
    at generateExpression (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1385:19)
    at result (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1188:28)
    at withIndent (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:592:21)
    at generateExpression (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1187:13)
    at generateStatement (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1512:21)
    at generateExpression.precedence (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1544:42)
    at withIndent (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:592:21)
    at generateStatement (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1537:17)
    at generateStatement (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1757:21)
    at Object.generate (/home/arian/www/wrapup/node_modules/escodegen/escodegen.js:1919:22)

Esprima addes type: "Property", however according to https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API#Expressions this is not required.

remove unnecessary parenthesis around 'in'

Currenlty, for NoIn expression, we always add parenthesis around 'in' operator.

for example,

for (i = (20 in 30) in 40);

should not generate

for (i = 20 in 30 in 40);

Combining multiple ASTs

I have multiple AST trees with location info. They are either generated by CoffeeScriptRedux or esprima.parse() (in case of raw JS files). I want to combine them into one single file with one source-map.

My naive attempt to this was to take the individual parse trees and wrap them into another Program node:

{
    type: 'Program',
    body: [
        {type: 'Program', loc: {source: 'file1.js', start: {line: 1, column: 1}}, body: [...]},
        {type: 'Program', loc: {source: 'file2.coffee', start: {line: 1, column: 1}}, body: [...]},
    ]
}

Unfortunately that doesn't work, you end up with something like this:

 {"version":3,"file":"test.map","sources":["test.map"],"names":[],"mappings":"AAAA,OAAA,IAAA,CAAY,UAAZ,CAAA"}

Is there a another way to concatenate multiple files that could possibly work?

Escodegen support of Moz-style harmony js is incomplete

it needs at least:

ObjectPattern
escodegen.js:350: Error: Numeric literal whose value is negative
escodegen.js:1143: Error: Unknown expression type: YieldExpression
escodegen.js:1611: Error: Unknown statement type: CallExpression

Include comments if available?

I don't know if it's even possible based on the output of require('esprima').parse(str, {comment: true}), but just in case.

I have more use cases for comment-and-whitespace-preserving JavaScript source manipulation than I can count :)

Use estraverse where appropriate

VisitorOption, traverse, and Syntax seem to be available in estraverse, can we include estraverse as a dependency and remove the duplicate code from escodegen?

Support compliance with JSHint

options.format.jshint would make sure that, as far as the code generator is concerned, i.e. without transforming the abstract syntax tree, and with all enforcing options available in JSHint, generated code is JSHint-compliant. Whether the option in question is to be enabled by default is another matter.

Error: Cannot find module 'esprima' when install only escodegen

Step to reproduce

  1. Remove all package from npm global
  2. npm install -g escodegen
  3. 'escodegen file'

Actual Result

Error: Cannot find module 'esprima'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at Object.<anonymous> (npm/lib/node_modules/escodegen/bin/esgenerate.js:29:15)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.