Giter VIP home page Giter VIP logo

astring's Introduction

Astring

NPM Version Coverage

🌳 Tiny and fast JavaScript code generator from an ESTree-compliant AST.

🎁 Checkout the live demo.

Key features

Installation

⚠️ Astring relies on String.prototype.repeat(amount) and String.prototype.endsWith(string). If the environment running Astring does not define these methods, use string.prototype.repeat, string.prototype.endsWith or babel-polyfill.

Install with the Node Package Manager:

npm install astring

Or install with JSR:

deno add @davidbonnet/astring

Alternatively, checkout this repository and install the development dependencies to build the module file:

git clone https://github.com/davidbonnet/astring.git
cd astring
npm install

Import

Import it from Deno's third party module repository:

const { generate } = await import('https://deno.land/x/astring/src/astring.js')

With JavaScript 6 modules:

import { generate } from 'astring'

With CommonJS:

const { generate } = require('astring')

A browser-ready minified bundle containing Astring is available at dist/astring.min.js. The module exposes a global variable astring:

<script src="astring.min.js" type="text/javascript"></script>
<script type="text/javascript">
  var generate = astring.generate
</script>

API

The astring module exposes the following properties:

generate(node: object, options: object): string | object

Returns a string representing the rendered code of the provided AST node. However, if an output stream is provided in the options, it writes to that stream and returns it.

The options are:

  • indent: string to use for indentation (defaults to "␣␣")
  • lineEnd: string to use for line endings (defaults to "\n")
  • startingIndentLevel: indent level to start from (defaults to 0)
  • comments: generate comments if true (defaults to false)
  • output: output stream to write the rendered code to (defaults to null)
  • generator: custom code generator (defaults to GENERATOR)
  • sourceMap: source map generator (defaults to null)
  • expressionsPrecedence: custom map of node types and their precedence level (defaults to EXPRESSIONS_PRECEDENCE)

GENERATOR: object

Base generator that can be used to extend Astring.

EXPRESSIONS_PRECEDENCE: object

Mapping of node types and their precedence level to let the generator know when to use parentheses.

NEEDS_PARENTHESES: number

Default precedence level that always triggers the use of parentheses.

baseGenerator: object

⚠️ Deprecated, use GENERATOR instead.

Benchmark

Generating code

Operations per second for generating each sample code from a pre-parsed AST:

code sample (length) escodegen astring uglify babel prettier
tiny code (11) 1,257,527 7,185,642 129,467 156,184 333
everything (8532) 1,366 8,008 0 346 64

Parsing and generating code

Operations per second for parsing and generating each sample code:

code sample (length) acorn + astring meriyah + astring buble sucrase
tiny code (11) 92,578 864,665 25,911 575,370
everything (8532) 706 1,425 132 1,403

Examples

The following examples are written in JavaScript 5 with Astring imported à la CommonJS.

Generating code

This example uses Acorn, a blazingly fast JavaScript AST producer and therefore the perfect companion of Astring.

// Make sure acorn and astring modules are imported

// Set example code
var code = 'let answer = 4 + 7 * 5 + 3;\n'
// Parse it into an AST
var ast = acorn.parse(code, { ecmaVersion: 6 })
// Format it into a code string
var formattedCode = astring.generate(ast)
// Check it
console.log(code === formattedCode ? 'It works!' : 'Something went wrong…')

Generating source maps

This example uses the source map generator from the Source Map module.

// Make sure acorn, sourceMap and astring modules are imported

var code = 'function add(a, b) { return a + b; }\n'
var ast = acorn.parse(code, {
  ecmaVersion: 6,
  sourceType: 'module',
  // Locations are needed in order for the source map generator to work
  locations: true,
})
// Create empty source map generator
var map = new sourceMap.SourceMapGenerator({
  // Source file name must be set and will be used for mappings
  file: 'script.js',
})
var formattedCode = generate(ast, {
  // Enable source maps
  sourceMap: map,
})
// Display generated source map
console.log(map.toString())

Using writable streams

This example for Node shows how to use writable streams to get the rendered code.

// Make sure acorn and astring modules are imported

// Set example code
var code = 'let answer = 4 + 7 * 5 + 3;\n'
// Parse it into an AST
var ast = acorn.parse(code, { ecmaVersion: 6 })
// Format it and write the result to stdout
var stream = astring.generate(ast, {
  output: process.stdout,
})
// The returned value is the output stream
console.log('Does stream equal process.stdout?', stream === process.stdout)

Generating comments

Astring supports comment generation, provided they are stored on the AST nodes. To do so, this example uses Astravel, a fast AST traveller and modifier.

// Make sure acorn, astravel and astring modules are imported

// Set example code
var code =
  [
    '// Compute the answer to everything',
    'let answer = 4 + 7 * 5 + 3;',
    '// Display it',
    'console.log(answer);',
  ].join('\n') + '\n'
// Parse it into an AST and retrieve the list of comments
var comments = []
var ast = acorn.parse(code, {
  ecmaVersion: 6,
  locations: true,
  onComment: comments,
})
// Attach comments to AST nodes
astravel.attachComments(ast, comments)
// Format it into a code string
var formattedCode = astring.generate(ast, {
  comments: true,
})
// Check it
console.log(code === formattedCode ? 'It works!' : 'Something went wrong…')

Extending

Astring can easily be extended by updating or passing a custom code generator. A code generator consists of a mapping of node names and functions that take two arguments: node and state. The node points to the node from which to generate the code and the state exposes the write method that takes generated code strings.

This example shows how to support the await keyword which is part of the asynchronous functions proposal. The corresponding AwaitExpression node is based on this suggested definition.

// Make sure the astring module is imported and that `Object.assign` is defined

// Create a custom generator that inherits from Astring's base generator
var customGenerator = Object.assign({}, astring.GENERATOR, {
  AwaitExpression: function (node, state) {
    state.write('await ')
    var argument = node.argument
    if (argument != null) {
      this[argument.type](argument, state)
    }
  },
})
// Obtain a custom AST somehow (note that this AST is not obtained from a valid code)
var ast = {
  type: 'AwaitExpression',
  argument: {
    type: 'CallExpression',
    callee: {
      type: 'Identifier',
      name: 'callable',
    },
    arguments: [],
  },
}
// Format it
var code = astring.generate(ast, {
  generator: customGenerator,
})
// Check it
console.log(
  code === 'await callable();\n' ? 'It works!' : 'Something went wrong…',
)

Command line interface

The bin/astring utility can be used to convert a JSON-formatted ESTree compliant AST of a JavaScript code. It accepts the following arguments:

  • -i, --indent: string to use as indentation (defaults to "␣␣")
  • -l, --line-end: string to use for line endings (defaults to "\n")
  • -s, --starting-indent-level: indent level to start from (defaults to 0)
  • -h, --help: print a usage message and exit
  • -v, --version: print package version and exit

The utility reads the AST from a provided list of files or from stdin if none is supplied and prints the generated code.

Example

As in the previous example, these examples use Acorn to get the JSON-formatted AST. This command pipes the AST output by Acorn from a script.js file to Astring and writes the formatted JavaScript code into a result.js file:

acorn --ecma6 script.js | astring > result.js

This command does the same, but reads the AST from an intermediary file:

acorn --ecma6 script.js > ast.json
astring ast.json > result.js

This command reads JavaScript 6 code from stdin and outputs a prettified version:

cat | acorn --ecma6 | astring

astring's People

Contributors

alexkozy avatar bjornharrtell avatar compuives avatar connor4312 avatar dario-piotrowicz avatar davidbonnet avatar demoorjasper avatar dependabot-preview[bot] avatar dependabot[bot] avatar devongovett avatar efernandesng avatar greenkeeper[bot] avatar magiblot avatar motiz88 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

astring's Issues

Control of semicolon behaviour

Motivation

I'm using astring as part of an atom plugin to help with code generation. It would be great to be able to control whether semicolons are emitted, so that I can match the current style directives of the current project. Right now, semicolons are implemented as a whole bunch of state.write(';') instances.

It would be awesome to have a config option to control semicolon emission. I'm thinking that you could replace all those writes with a semantic state.terminate(), which can check if it should print a semicolon or not.

The only alternative to control this is to basically fork the entire baseGenerator, so you can remove all those writes.

UnaryExpression doesn't parenthesize correctly

For some reason this is only a problem with arrow functions, and none of the other NEEDS_PARENTHESES nodes.

Using the online demo:


!(() => {});

turns into

!() => {};

which is a syntax error.


typeof (() => {});

turns into

typeof () => {};

which is a syntax error.

Literals use non-standard "raw" property and never "value"

Sorry if I'm wrong about this: Astring seems to rely on the presence of a raw property for Literal nodes, and to ignore the actual value property.

I'm guessing this is usually fine when dealing with parsed input (parsers probably include raw as an extension - right?), but when generating code from scratch using strict ESTree input which lacks raw, this fails silently, emitting undefined instead of the literal's value. I think the correct behavior would be to fall back to something like literal.value.toString() JSON.stringify(literal.value).

An in-range update of prettier is breaking the build 🚨

The devDependency prettier was updated from 1.14.2 to 1.14.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

prettier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Release Notes for 1.14.3

🔗 Changelog

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Incorrect parenthesis in computed callee

Source:

function t() {
    var x = ("abc"+"def").substring(0,4)
    console.log(x) ;
}

astring:

function t() {
    var x = "abc" + "def".substring(0, 4);
    console.log(x);
}

escodegen:

function t() {
    var x = ('abc' + 'def').substring(0, 4);
    console.log(x);
}

The test case (below) uses acorn:

var astring = require('astring') ;
var es = require('escodegen').generate ;
var acorn = require('acorn') ;
var ast = acorn.parse(t.toString()) ;
console.log("astring\n"+astring(ast)) ;
console.log("escodegen\n"+es(ast)) ;

function t() {
    var x = ("abc"+"def").substring(0,4)
    console.log(x) ;
}

Invalid source map generated with multi-line strings

Motivation

Astring generates invalid source maps when the input file has multi-line strings. All lines following the first line of the multi-line string are mapped improperly.

Escodegen generates the correct source map with the same AST, so I know that this is a problem in astring and not the parser.

Example input w/ multi-line string:

var BASE_JS = "var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goo\
g.LOCALE=\"en\";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))t";

// The source map will improperly map this function's source.
function foo() {

}

I noticed the bug while processing Octane's code-load benchmark through astring, which features long multi-line strings.

Expected behavior

The source map should correctly cover the entire file.

Actual behavior

The source map stops mapping the file properly after the first line of the input file.

Test Case

input.js (trimmed down from code-load.js):

var CodeLoad = new BenchmarkSuite('CodeLoad');
var BASE_JS = "var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goo\
g.LOCALE=\"en\";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))t\
hrow Error('Namespace \"'+a+'\" already declared.');delete goog.implicitNamespa";

// Jenkins hash function.
function jenkinsHash(key, len) {
  var hash = 0;
  for(var i = 0; i < len; ++i) {
    hash += key[i];
    hash += (hash << 10);
    hash ^= (hash >> 6);
  }
  hash += (hash << 3);
  hash ^= (hash >> 11);
  hash += (hash << 15);
  return hash;
}

runner.js (Use to run acorn/astring/escodegen on file with node runner.js input.js):

const fs = require('fs');
const acorn = require('acorn');
const sourceMap = require('source-map');
const astring = require('astring');
const escodegen = require('escodegen');

const sourceContent = fs.readFileSync(process.argv[2], 'utf8');
const ast = acorn.parse(sourceContent, {
  ecmaVersion: 5,
  sourceType: 'script',
  // Locations are needed in order for the source map generator to work
  locations: true,
});

{
  // Create empty source map generator
  const map = new sourceMap.SourceMapGenerator({
    // Source file name must be set and will be used for mappings
    file: 'script.js',
  });
  map.setSourceContent('script.js', sourceContent);
  const formattedCode = astring.generate(ast, {
    // Enable source maps
    sourceMap: map,
  })
  fs.writeFileSync('out-astring.js', Buffer.from(formattedCode, 'utf8'));
  fs.writeFileSync('out-astring.map.js', Buffer.from(map.toString(), 'utf8'));
}

{
  const out = escodegen.generate(ast, {
    sourceMap: "out-escodegen.js",
    sourceMapWithCode: true,
    sourceContent: sourceContent
  });
  fs.writeFileSync('out-escodegen.js', Buffer.from(out.code, 'utf8'));
  fs.writeFileSync('out-escodegen.map.js', Buffer.from(out.map.toString(), 'utf8'));
}

Test Case Output

out-astring.js:

var CodeLoad = new BenchmarkSuite('CodeLoad');
var BASE_JS = "var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goo\
g.LOCALE=\"en\";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))t\
hrow Error('Namespace \"'+a+'\" already declared.');delete goog.implicitNamespa";
function jenkinsHash(key, len) {
  var hash = 0;
  for (var i = 0; i < len; ++i) {
    hash += key[i];
    hash += hash << 10;
    hash ^= hash >> 6;
  }
  hash += hash << 3;
  hash ^= hash >> 11;
  hash += hash << 15;
  return hash;
}

out-astring.map.js:

{"version":3,"sources":["script.js"],"names":["CodeLoad","BenchmarkSuite","BASE_JS","key","len","hash","i"],"mappings":"IAAIA,eAAeC,eAAe;IAC9BC,UAAU;AAKd,qBAAqBC,KAAKC;MACpBC,OAAO;WACHC,IAAI,GAAGA,IAAIF,OAAOE;IACxBD,QAAQF,IAAIG;IACZD,QAASA,QAAQ;IACjBA,QAASA,QAAQ;;EAEnBA,QAASA,QAAQ;EACjBA,QAASA,QAAQ;EACjBA,QAASA,QAAQ;SACVA","file":"script.js","sourcesContent":["var CodeLoad = new BenchmarkSuite('CodeLoad');\nvar BASE_JS = \"var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goo\\\ng.LOCALE=\\\"en\\\";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))t\\\nhrow Error('Namespace \\\"'+a+'\\\" already declared.');delete goog.implicitNamespa\";\n\n// Jenkins hash function.\nfunction jenkinsHash(key, len) {\n  var hash = 0;\n  for(var i = 0; i < len; ++i) {\n    hash += key[i];\n    hash += (hash << 10);\n    hash ^= (hash >> 6);\n  }\n  hash += (hash << 3);\n  hash ^= (hash >> 11);\n  hash += (hash << 15);\n  return hash;\n}\n"]}

out-escodegen.js:

var CodeLoad = new BenchmarkSuite('CodeLoad');
var BASE_JS = 'var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goog.LOCALE="en";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))throw Error(\'Namespace "\'+a+\'" already declared.\');delete goog.implicitNamespa';
function jenkinsHash(key, len) {
    var hash = 0;
    for (var i = 0; i < len; ++i) {
        hash += key[i];
        hash += hash << 10;
        hash ^= hash >> 6;
    }
    hash += hash << 3;
    hash ^= hash >> 11;
    hash += hash << 15;
    return hash;
}

out-escodegen.map.js:

{"version":3,"sources":["out-escodegen.js"],"names":["CodeLoad","BenchmarkSuite","BASE_JS","jenkinsHash","key","len","hash","i"],"mappings":"AAAA,IAAIA,QAAA,GAAW,IAAIC,cAAJ,CAAmB,UAAnB,CAAf;AACA,IAAIC,OAAA,GAAU,gOAAd,CADA;AAMA,SAASC,WAAT,CAAqBC,GAArB,EAA0BC,GAA1B,EAA+B;AAAA,IAC7B,IAAIC,IAAA,GAAO,CAAX,CAD6B;AAAA,IAE7B,KAAI,IAAIC,CAAA,GAAI,CAAR,CAAJ,CAAeA,CAAA,GAAIF,GAAnB,EAAwB,EAAEE,CAA1B,EAA6B;AAAA,QAC3BD,IAAA,IAAQF,GAAA,CAAIG,CAAJ,CAAR,CAD2B;AAAA,QAE3BD,IAAA,IAASA,IAAA,IAAQ,EAAjB,CAF2B;AAAA,QAG3BA,IAAA,IAASA,IAAA,IAAQ,CAAjB,CAH2B;AAAA,KAFA;AAAA,IAO7BA,IAAA,IAASA,IAAA,IAAQ,CAAjB,CAP6B;AAAA,IAQ7BA,IAAA,IAASA,IAAA,IAAQ,EAAjB,CAR6B;AAAA,IAS7BA,IAAA,IAASA,IAAA,IAAQ,EAAjB,CAT6B;AAAA,IAU7B,OAAOA,IAAP,CAV6B;AAAA","sourcesContent":["var CodeLoad = new BenchmarkSuite('CodeLoad');\nvar BASE_JS = \"var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!0;goo\\\ng.LOCALE=\\\"en\\\";goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))t\\\nhrow Error('Namespace \\\"'+a+'\\\" already declared.');delete goog.implicitNamespa\";\n\n// Jenkins hash function.\nfunction jenkinsHash(key, len) {\n  var hash = 0;\n  for(var i = 0; i < len; ++i) {\n    hash += key[i];\n    hash += (hash << 10);\n    hash ^= (hash >> 6);\n  }\n  hash += (hash << 3);\n  hash ^= (hash >> 11);\n  hash += (hash << 15);\n  return hash;\n}\n"]}

You can see the problem using the source-map-visualizer tool.

TypeError: this[statement.type] is not a function

Motivation

I am trying to generate a source from @typescript-eslint/parser ast.
For example I take code and generate ast using astexplorer

https://astexplorer.net/#/gist/59cc500b3c114b4ace74b1602127ead2/f967c0bb4a7630e6ce6a08a463856de0d8326e8b

Then I am trying to generate source and getting and error

TypeError: this[statement.type] is not a function
    at Object.Program (/home/sergey/Github/parse-js/node_modules/astring/dist/astring.js:225:27)
    at generate (/home/sergey/Github/parse-js/node_modules/astring/dist/astring.js:1093:29)
    at Object.<anonymous> (/home/sergey/Github/parse-js/diff.js:8447:13)
    at Module._compile (internal/modules/cjs/loader.js:953:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
    at Module.load (internal/modules/cjs/loader.js:812:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
    at internal/main/run_main_module.js:17:11

Expected behavior

Code generated successfully

Actual behavior

Error - TypeError: this[statement.type] is not a function

ConditionalExpression doesn't parenthesize correctly

ConditionalExpression is missing a NEEDS_PARENTHESES check.

Using the online demo:


(() => {}) ? 2 : 3;

turns into

() => {} ? 2 : 3;

which is a syntax error.


({}) ? 2 : 3;

and

({} ? 2 : 3);

turn into

{} ? 2 : 3;

which is a syntax error.


(function() {}) ? 2 : 3;

and

(function() {} ? 2 : 3);

turn into

function() {} ? 2 : 3;

which is a syntax error.


(class {}) ? 2 : 3;

and

(class {} ? 2 : 3);

turn into

class {} ? 2 : 3;

which is a syntax error.

Missing parenthesis for await assignment expression argument

Motivation

Parenthesis need to be inserted around the await argument if it's an assignment expression

Input

Input:

var obj;
async function main() {
	return await (obj = Promise.resolve(1));
}
Script
const acorn = require("acorn");
const astring = require("astring");

const code = `var obj;
async function main() {
	return await (obj = Promise.resolve(1));
}
`;
const ast = acorn.parse(code, { ecmaVersion: 2020 });
const formattedCode = astring.generate(ast);
console.log(formattedCode);

/*

undefined:3
  return await obj = Promise.resolve(1);
         ^^^^^^^^^

SyntaxError: Invalid left-hand side in assignment

*/
eval(formattedCode);

Expected behavior

= same as input

var obj;
async function main() {
	return await (obj = Promise.resolve(1));
}

Actual behavior

var obj;
async function main() {
  return await obj = Promise.resolve(1);
}

Fails to generate SpreadOperator

Motivation

Generated AST code with acorn from this source

var target = {foo : "bar"}
target = {...target, ...{}};

fails

Property: function Property(node, state) {
      
      if (node.method || node.kind[0] !== 'i') {
        // Either a method or of kind `set` or `get` (not `init`)
        this.MethodDefinition(node, state);
      } else {

with node.kind being undefined. I guess it should have never got in there.

Thanks!

UPD.

kind of fixed it with the following, but I am 99% percent sure that it's NOT the right place

Property: function Property(node, state) {
      if ( node.type === "SpreadElement"){
         this.RestElement(node, state)
      } else {
        if (node.method || node.kind[0] !== 'i') {
          // Either a method or of kind `set` or `get` (not `init`)
          this.MethodDefinition(node, state);
        } else {
          if (!node.shorthand) {
            if (node.computed) {
              state.write('[');
              this[node.key.type](node.key, state);
              state.write(']');
            } else {
              this[node.key.type](node.key, state);
            }
            state.write(': ');
          }
          this[node.value.type](node.value, state);
        }
      }
    }

An in-range update of eslint is breaking the build 🚨

The devDependency eslint was updated from 5.13.0 to 5.14.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Release Notes for v5.14.0
  • 85a04b3 Fix: adds conditional for separateRequires in one-var (fixes #10179) (#10980) (Scott Stern)
  • 0c02932 Upgrade: [email protected] (#11401) (Ilya Volodin)
  • 104ae88 Docs: Update governance doc with reviewers status (#11399) (Nicholas C. Zakas)
  • ab8ac6a Fix: Support boundary spread elements in sort-keys (#11158) (Jakub Rożek)
  • a23d197 New: add allowSingleLineBlocks opt. to padded-blocks rule (fixes #7145) (#11243) (richie3366)
  • e25e7aa Fix: comma-spacing ignore comma before closing paren (fixes #11295) (#11374) (Pig Fang)
  • a1f7c44 Docs: fix space-before-blocks correct code for "classes": "never" (#11391) (PoziWorld)
  • 14f58a2 Docs: fix grammar in object-curly-spacing docs (#11389) (PoziWorld)
  • d3e9a27 Docs: fix grammar in “those who says” (#11390) (PoziWorld)
  • ea8e804 Docs: Add note about support for object spread (fixes #11136) (#11395) (Steven Thomas)
  • 95aa3fd Docs: Update README team and sponsors (ESLint Jenkins)
  • 51c4972 Update: Behavior of --init (fixes #11105) (#11332) (Nicholas C. Zakas)
  • ad7a380 Docs: Update README team and sponsors (ESLint Jenkins)
  • 550de1e Update: use default keyword in JSON schema (fixes #9929) (#11288) (Pig Fang)
  • 983c520 Update: Use 'readonly' and 'writable' for globals (fixes #11359) (#11384) (Nicholas C. Zakas)
  • f1d3a7e Upgrade: some deps (fixes #11372) (#11373) (薛定谔的猫)
  • 3e0c417 Docs: Fix grammar in “there’s nothing prevent you” (#11385) (PoziWorld)
  • de988bc Docs: Fix grammar: Spacing improve -> Spacing improves (#11386) (PoziWorld)
  • 1309dfd Revert "Build: fix test failure on Node 11 (#11100)" (#11375) (薛定谔的猫)
  • 1e56897 Docs: “the function actually use”: use -> uses (#11380) (PoziWorld)
  • 5a71bc9 Docs: Update README team and sponsors (ESLint Jenkins)
  • 82a58ce Docs: Update README team and sponsors (ESLint Jenkins)
  • 546d355 Docs: Update README with latest sponsors/team data (#11378) (Nicholas C. Zakas)
  • c0df9fe Docs: ... is not an operator (#11232) (Felix Kling)
  • 7ecfdef Docs: update typescript parser (refs #11368) (#11369) (薛定谔的猫)
  • 3c90dd7 Update: remove prefer-spread autofix (fixes #11330) (#11365) (薛定谔的猫)
  • 5eb3121 Update: add fixer for prefer-destructuring (fixes #11151) (#11301) (golopot)
  • 173eb38 Docs: Clarify ecmaVersion doesn't imply globals (refs #9812) (#11364) (Keith Maxwell)
  • 84ce72f Fix: Remove extraneous linefeeds in one-var fixer (fixes #10741) (#10955) (st-sloth)
  • 389362a Docs: clarify motivation for no-prototype-builtins (#11356) (Teddy Katz)
  • 533d240 Update: no-shadow-restricted-names lets unassigned vars shadow undefined (#11341) (Teddy Katz)
  • d0e823a Update: Make --init run js config files through linter (fixes #9947) (#11337) (Brian Kurek)
  • 92fc2f4 Fix: CircularJSON dependency warning (fixes #11052) (#11314) (Terry)
  • 4dd19a3 Docs: mention 'prefer-spread' in docs of 'no-useless-call' (#11348) (Klaus Meinhardt)
  • 4fd83d5 Docs: fix a misleading example in one-var (#11350) (薛定谔的猫)
  • 9441ce7 Chore: update incorrect tests to fix build failing (#11354) (薛定谔的猫)
Commits

The new version differs by 38 commits.

  • af9688b 5.14.0
  • 0ce3ac7 Build: changelog update for 5.14.0
  • 85a04b3 Fix: adds conditional for separateRequires in one-var (fixes #10179) (#10980)
  • 0c02932 Upgrade: [email protected] (#11401)
  • 104ae88 Docs: Update governance doc with reviewers status (#11399)
  • ab8ac6a Fix: Support boundary spread elements in sort-keys (#11158)
  • a23d197 New: add allowSingleLineBlocks opt. to padded-blocks rule (fixes #7145) (#11243)
  • e25e7aa Fix: comma-spacing ignore comma before closing paren (fixes #11295) (#11374)
  • a1f7c44 Docs: fix space-before-blocks correct code for "classes": "never" (#11391)
  • 14f58a2 Docs: fix grammar in object-curly-spacing docs (#11389)
  • d3e9a27 Docs: fix grammar in “those who says” (#11390)
  • ea8e804 Docs: Add note about support for object spread (fixes #11136) (#11395)
  • 95aa3fd Docs: Update README team and sponsors
  • 51c4972 Update: Behavior of --init (fixes #11105) (#11332)
  • ad7a380 Docs: Update README team and sponsors

There are 38 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of meriyah is breaking the build 🚨

The devDependency meriyah was updated from 1.4.4 to 1.4.5.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

meriyah is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 6 commits.

  • bc86b42 fix(lexer): dedupe some code
  • d58536e fix(parser): fixed LGTM warnings
  • c637ee5 fix(lexer): improved scanner performance
  • 0899ad3 fix(parser): refactored and simplified location tracking
  • 29c1d3d fix(lexer): improved identifier scanning performance
  • f18f5b4 fix(parser): fixed bunch of edge cases

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of babel-preset-minify is breaking the build 🚨

Version 0.4.2 of babel-preset-minify was just published.

Branch Build failing 🚨
Dependency babel-preset-minify
Current Version 0.4.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

babel-preset-minify is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of acorn is breaking the build 🚨

The devDependency acorn was updated from 6.0.7 to 6.1.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

acorn is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

astring is not a function when using via CLI

When executing astring via node_modules/.bin/astring estree.json then I simply get the error message "astring is not a function".
Digging deeper into this, it seems like the node_modules/astring/bin/astring has an error in line 3 where it says:
var astring = require( '../dist/astring' ).default

Taking the information from the README.md on how to programmatically use astring, it should rather say:
var astring = require( '../dist/astring' ).generate

Using "generate" instead of "default" fixes this problem and astring produces the JavaScript output.

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

Motivation

add "use strict";
to astring/bin/astring to eliminate error message from nodejs.

Expected behavior

should run normally

Actual behavior

astring/bin/astring:35
for (let i = 0, length = argv.length; i < length; i++) {
^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Function.Module.runMain (module.js:442:10)
at startup (node.js:136:18)
at node.js:966:3

An in-range update of tap is breaking the build 🚨

The devDependency tap was updated from 12.0.1 to 12.0.2.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

tap is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 3 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of tap is breaking the build 🚨

Version 11.0.1 of tap was just published.

Branch Build failing 🚨
Dependency tap
Current Version 11.0.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

tap is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 4 commits.

  • 94be0a7 v11.0.1
  • 6c3f019 remove badges that are no longer accurate or in use
  • ae562a7 don't ignore coverage doc
  • 9fcfd52 Migrate docs into main repository

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Missing () around Epression passed as UnaryExpression argument

If I have this JavaScript expression:

!(x instanceof Type)

I can generate the following AST with esprima:

{
    "type": "Program",
    "body": [
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "UnaryExpression",
                "operator": "!",
                "argument": {
                    "type": "BinaryExpression",
                    "operator": "instanceof",
                    "left": {
                        "type": "Identifier",
                        "name": "x"
                    },
                    "right": {
                        "type": "Identifier",
                        "name": "Type"
                    }
                },
                "prefix": true
            }
        }
    ]
}

I get the following output from astring:

! x instanceof Type;

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of acorn is breaking the build 🚨

Version 5.6.1 of acorn was just published.

Branch Build failing 🚨
Dependency acorn
Current Version 5.6.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

acorn is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 2 commits.

  • 690cfc7 Mark version 5.6.1
  • e50701d Allow null to be passed as base visitor to walk.recursive

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Semicolon in expressions

Hey,
Great job on this BTW 😄
One quick question. I have below ternary generated from the ast

"safeRound(safeParseFloat(dataTable.item1), 2); < 5000 ? false : true;"

As you can imagine those semis are not in the original code :)

I see on 265 in:
ExpressionStatement( node, state ) { const precedence = EXPRESSIONS_PRECEDENCE[ node.expression.type ] if ( precedence === 17 || ( precedence === 3 && node.expression.left.type[ 0 ] === 'O' ) ) { // Should always have parentheses or is an AssignmentExpression to an ObjectPattern state.write( '(' ) this[ node.expression.type ]( node.expression, state ) state.write( ')' ) } else { this[ node.expression.type ]( node.expression, state ) } state.write( ';' ) }
the last line adds a semi. I there a need? Is it something on my end?

If it's by design but not required I can submit a PR to turn off via an option

I can eval it without the semi :)

An in-range update of ava is breaking the build 🚨

The devDependency ava was updated from 1.2.0 to 1.2.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

ava is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Release Notes for 1.2.1

This is a bug fix release. In very large projects, the options send to worker processes would exceed limits on process argument size. We're now sending the options via the inter-process communication channel. 3078892

All changes 📚

v1.2.0...v1.2.1

Get involved ✌️

We welcome new contributors. AVA is a friendly place to get started in open source. We have a great article on getting started contributing and a comprehensive contributing guide.

Commits

The new version differs by 2 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Individual TemplateElements are not supported

Hello,

The structure of TemplateLiteral is as follows:

imatge

The elements of quasis are TemplateElement nodes. When parsing TemplateLiteral nodes, astring accesses the quasis' content directly:

state.write(quasis[i].value.raw)

This is OK unless you ask astring to parse the TemplateElement node individually. In that case, astring will crash as it doesn't have a specific method for this node type.

I wonder if this was an oversight or if it is intentional. Should I just write my own generator for TemplateElement?

Thank you very much.

Lack or parentheses fails in mixed type expressions

The expression "abc"+(2-1)+"def" requires parenthesis because the operators + and - have the same precedence, their polymorphism (i.e. string/number behaviour) means they are not commutative.

Astring is unaware of the expression nesting which is (correctly) generated by acorn.

Test case:

var astring = require('astring') ;
var es = require('escodegen').generate ;
var acorn = require('acorn') ;
var ast = acorn.parse(t.toString()) ;

var f1 = astring(ast) ;
var f2 = es(ast) ;

console.log("astring",f1+"\n >>> "+(new Function("return "+f1))()()) ;
console.log("escodegen",f2+"\n >>> "+(new Function("return "+f2))()()) ;

function t() {
    return "abc"+(2-1)+"def";
}

Output:

astring function t() {
    return "abc" + 2 - 1 + "def";
}

 >>> NaNdef
escodegen function t() {
    return 'abc' + (2 - 1) + 'def';
}
 >>> abc1def

JSDoc is not generated correctly

Hi! I'm trying to use astring to generate javascript code from an AST. My goal is to be able to modify a previously generated AST and then generate the new code from it.

Everything works accordingly but for the code generation. The comments from the JSDoc are not generated correctly.

Here is my use case:

This is the depenencies in package.json

  "dependencies": {
    "acorn": "^5.1.2",
    "astravel": "^0.4.0",
    "astring": "^1.0.5"
  }

This is the class I want to parse: MyClass.js

/**
 * This is MyClass
 *
 * @name MyClass
 * @class
 */
export default class MyClass {
    constructor() {
        // foo is bar
        this.foo = "bar";
    }
}

This is my code, parsing the file, generating the AST and generating the code from the AST: script.js

var astravel = require("astravel");
var astring = require("astring");
var acorn = require("acorn");
var walk = require("acorn/dist/walk");
var fs = require('fs');

var sourceFileContent = fs.readFileSync(__dirname + "/MyClass.js", {encoding: 'utf-8'});

// Parse it into an AST and retrieve the list of comments
var comments = [];
var ast = acorn.parse(sourceFileContent, {
    ecmaVersion: 6,
    sourceType: "module",
    locations: true,
    onComment: comments
});

// Attach comments to AST nodes
astravel.attachComments(ast, comments);

// Format it into a code string
var formattedCode = astring.generate(ast, {
    lineEnd: '\n',
    comments: true
});

fs.writeFileSync("./formattedClass.js", formattedCode);

And this is what the formatted code looks like: formattedCode.js

/*
*
* This is MyClass
*
* @name MyClass
* @class
*/
export default class MyClass {
	constructor() {
		// foo is bar
		this.foo = "bar";
	}
}

Here you can see how the comments from the JSDoc are not generated correctly...

Are you able to reproduce the bug ? If yes do you have any ideas how to fix it ?

Your work is great and works great, expect for this part ... if you see anything wrong in my code I'd be glad if you point it out as well, thanks.

Here you can see how the comments from the JSDoc are not generated correctly...
/*
*
instead of
/**
*

Are you able to reproduce the bug ? If yes do you have any ideas how to fix it ?

Your work is great and works great, expect for this part ... if you see anything wrong in my code I'd be glad if you point it out as well, thanks.

EDIT: deletion of duplicate content in the description of the issue

Uncaught TypeError: Do not know how to serialize a BigInt if `raw` field missing

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <script src="node_modules/astring/dist/astring.min.js"></script>
    <script>
        // obtained with acorn:
        const a = { 
            bigint: "0", 
            end: 81, 
            raw: "0n", 
            start: 79, 
            type: "Literal", 
            value: 0n
        };

        console.log(astring.generate(a));
        // works

        delete a.raw;
        console.log(a);
        console.log(astring.generate(a));
        // Uncaught TypeError: Do not know how to serialize a BigInt

    </script>
</head>

<body>
</body>

</html>

astring version: 1.4.3

Actual behavior:

The second invocation of astring.generate throws an error.

Desired behavior:

The second invocation of astring.generate should return "0n", like the first invocation.

Motivation:

I'm generating ASTs containing bigint literals, and it would be convenient if I didn't have to set the raw field. Looking at the source code, it seems that it intends to work even if raw is absent:

astring/src/astring.js

Lines 944 to 952 in 92ad965

Literal(node, state) {
if (node.raw != null) {
state.write(node.raw, node)
} else if (node.regex != null) {
this.RegExpLiteral(node, state)
} else {
state.write(stringify(node.value), node)
}
},

but JSON.stringify does not support serializing bigint literals, hence the exception.

docs - instructions for ESM import probably are incorrect

Motivation

In ES Module code cases, readme instructs to consume the generate:

import { generate } from 'astring'

However, if I try that, my Rollup complains generate is not exported:

generate_not_exported

But, when I import whole astring:

import astring from "astring"

Everything works fine, I can see rendered code from things like console.log(astring.generate(tester));

Expected behavior

Readme should instruct:

import astring from "astring";

Actual behavior

Readme currently instructs:

import { generate } from 'astring'

Guys, please confirm which type of import works for you. I know it's small thing but it might be a blocker for new starters who are less familiar with modules' wiring.


BTW, thanks for making this library 🥇 👍

Is there is a way to easily jump a line ?

Hi,

I'm using this lib to generate JavaScript code from a generated AST but i wanted to add some blank line between some of my stmt. Is there is a way to achieve this without having to go in a complicated code that deal with start/end ?

Sorry for the newbie question and thanks for your time !

Best Regards,
Thomas

Parenthesis needed on arrow functions in expressions

Motivation

Expressions like true && (() => {}) require parens around the arrow function as true && () => {} yields SyntaxError: Unexpected token ). Generated string needs to include parenthesis

Expected behavior

const source = `true && (() => {})`;
const ast = acorn.parse(source);
assert.equal(generate(ast), source); //*
//* assume ignoring trailing ';\n'

Actual behavior

Generates: true && () => {}

Testing History

Hi

This looks very interesting.

I'm looking for a package to construct ASTs generated by Esprima.

Escodegen has not been very well maintained. I'm getting errors with ASTs generated by Esprima, as Esprima has full support for ECMAScript 2016 (ECMA-262 7th Edition) and Escodegen appears to have frozen in time around ES2015.

I understand that this would not be a problem with astring. I'm going to be using it in production code in the wild so I was keen to know the extent to which astring has been tested. There weren't any stats on the github site. Also, a benchmark.js site like this one for Esprima would be super helpful!

I'm curious as to how you've achieved such reductions in package size and speed gains over the competitors. Well done.

Any help much appreciated.

Tom

An in-range update of prettier is breaking the build 🚨

Version 1.7.1 of prettier just got published.

Branch Build failing 🚨
Dependency prettier
Current Version 1.7.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As prettier is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Super class (class extends) isn't parenthesized correctly

There is no parenthesis check at all in class extends ....

Using the online demo:


class A extends (a => a) {}

turns into

class A extends a => a {}

which is a syntax error.


function* f() { class A extends (yield) {} }

turns into

function* f() { class A extends yield {} }

which is a syntax error.


async function f() { class A extends (await B) {} }

turns into

async function f() { class A extends await B {} }

which is a syntax error.


class A extends (a++) {}

turns into

class A extends a++ {}

which is a syntax error.


class A extends (1+1) {}

turns into

class A extends 1+1 {}

which is a syntax error.


class A extends (-1) {}

turns into

class A extends -1 {}

which is a syntax error.

Sourcemaps

Hello,

Do you plan to implement sourcemaps ? When ?
This would be a great feature.

Thanks in advance for your answers.

Semicolons Not Emitted in For Loop Headers

Motivation

In the wild, I encountered code similar to the following:

for (p(function(a) {
	var foo = bar();
        (foo.request || foo.requestError) && g.unshift(foo.request, foo.requestError);
}); g.length; ) {}

I would like to transform this code using astring.

Expected behavior

Parsing and then immediately generating the above code should produce the same / equivalent code.

Actual behavior

astring outputs the following:

for (p(function(a) {
	var foo = bar()
        (foo.request || foo.requestError) && g.unshift(foo.request, foo.requestError);
}); g.length; ) {}

The semicolon is of semantic importance here; without it, the JS engine believes the code is doing a function application on the return value of bar().

Likely Cause

The code assumes that no semicolons will appear in the initialization section of the for node, but this is not true when it contains an embedded function expression:

https://github.com/davidbonnet/astring/blob/master/src/astring.js#L413

Suggested Fix

When entering a function declaration or function definition, save the value of noTrailingSemicolon and restore it after the function completes.

I will issue a PR shortly with this fix.

An in-range update of acorn is breaking the build 🚨

Version 5.2.0 of acorn was just published.

Branch Build failing 🚨
Dependency acorn
Current Version 5.1.2
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

acorn is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 15 commits.

  • d54b3a5 Mark version 5.2.0
  • c84f11a Move function comments to their functions
  • fd39391 Add test for let instanceof Foo
  • d38f9d8 Don't pass unused argument
  • 020db63 Simplify parseBindingAtom
  • cedb8a4 ImportDeclarations have no kind property
  • bb4dd2d Update description of ecmaVersion argument
  • 4747645 Extract parseProperty from parseObj
  • 62444e4 Add some missing properties to test cases
  • 0090c67 Fix: super is not PrimaryExpression
  • e70228b Fix shorthand properties named get or set with defaults in object destructuring
  • bf94140 Add directive property to follow ESTree
  • 89ca0d0 [walker] Don't visit nodes multiple times in full / fullAncestor walks
  • bd728e8 Fix incorrect parsing of %*.
  • ccfd59d fix parsing errors about template literals (fixes #575)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Single, double and auto quotes

Motivation

As a developer, I'd like to use astring as a part of a code transformation toolchain and pick the type of quotes that are going to be rendered.

Expected behavior

It should be possible to pass a quotes option that accepts: single | double | auto that change the quotes in the output.

Actual behavior

The library preserves existing quotes automatically (which is how auto mode works).

Implementation notes

The change would be non-breaking as the flag could be set to auto by default.

Add `compact` option

Motivation

Hi. I have plans to migrate my project from escodegen to astring.
Currently, my project heavily uses compact option from escodegen.
It would be amazing to add this option to astring.
When this option is enabled, all spaces (except spaces that cannot be removed without break the code) and line break characters will be removed

An in-range update of cross-env is breaking the build 🚨

Version 5.1.2 of cross-env was just published.

Branch Build failing 🚨
Dependency cross-env
Current Version 5.1.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

cross-env is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes v5.1.2

5.1.2 (2017-12-21)

Bug Fixes

Commits

The new version differs by 1 commits.

  • 7fa5c08 fix: handle escaping and single quotes (#158)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of prettier is breaking the build 🚨

The devDependency prettier was updated from 1.18.1 to 1.18.2.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

prettier is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for 1.18.2

🔗 Changelog

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

this object can't resolve JSXElement ?

Motivation

Describe cases that motivate the implementation of the expected behavior.

Expected behavior

Describe how the feature should work.

Actual behavior

Describe the actual behavior of the feature or remove this section if the feature has not been implemented yet.

Problem generating exponentiation operator with unary operator applied to base

I believe I've found an error in how code is generated when a UnaryExpression is used as the base in an ExponentiationExpression:

(-2)**4

From MDN:

In JavaScript, it is impossible to write an ambiguous exponentiation expression, i.e. you cannot put a unary operator (+/-/~/!/delete/void/typeof) immediately before the base number.

I am using the following AST. I believe this is the correct AST to produce the desired outpput as acorn, cherow, and meriyah all produce the same output for this code. I was not able to test in esprima or espree as this code crashes them.

{
    "type": "Program",
    "sourceType": "script",
    "body": [
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "BinaryExpression",
                "left": {
                    "type": "UnaryExpression",
                    "operator": "+",
                    "argument": {
                        "type": "Literal",
                        "value": 2
                    },
                    "prefix": true
                },
                "right": {
                    "type": "Literal",
                    "value": 4
                },
                "operator": "**"
            }
        }
    ]
}

Expected behavior

Code should be generated with parentheses around the base when a unary operator is applied.

astring.generate(acorn.parse('(+2)**4'))

// Expected Output:
(+2)**4;

Actual behavior

No parentheses are added, leading to invalid code that throws an error when executed.

astring.generate(acorn.parse('(+2)**4'))

// Observed Output:
+2**4;

Error:

+2**4
^^^^

SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence

See also: jquery/esprima#1981

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.