Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

esnext

Package Overview
Dependencies
Maintainers
1
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

esnext - npm Package Compare versions

Comparing version 1.9.2 to 1.10.0

src/utils/hasParens.js

2

package.json
{
"name": "esnext",
"version": "1.9.2",
"version": "1.10.0",
"description": "Update your project to the latest ECMAScript syntax.",

@@ -5,0 +5,0 @@ "main": "dist/esnext.umd.js",

@@ -31,2 +31,7 @@ import MagicString from 'magic-string';

type Range = {
start: number,
end: number
};
export default class Module {

@@ -64,4 +69,20 @@ constructor(id: ?string, source: string) {

tokensInRange(start: number, end: number): Array<Token> {
const result = [];
const tokenRange = this._tokenIndexRangeForSourceRange(start, end);
if (!tokenRange) {
return [];
}
return this.tokens.slice(tokenRange.start, tokenRange.end);
}
tokenRangeForNode(node: Object): ?Range {
return this._tokenIndexRangeForSourceRange(node.range[0], node.range[1]);
}
_tokenIndexRangeForSourceRange(start: number, end: number): ?Range {
let location = null;
let length = 0;
const tokens = this.tokens;
for (let i = 0; i < tokens.length; i++) {

@@ -72,6 +93,12 @@ const { range } = tokens[i];

} else if (range[0] >= start) {
result.push(tokens[i]);
if (location === null) { location = i; }
length++;
}
}
return result;
if (location === null) {
return null;
}
return { start: location, end: location + length };
}

@@ -78,0 +105,0 @@

import BaseContext from '../context';
import clone from '../utils/clone';
import estraverse from 'estraverse';
import hasParens from '../utils/hasParens';
import needsParens from '../utils/needsParens';
import replace from '../utils/replace';
import type Module from '../module';

@@ -19,107 +22,217 @@ import type { ScopeManager } from 'escope';

}
}
export function begin(module: Module): Context {
return new Context(module);
}
export function enter(node: Object, parent: Object, module: Module, context: Context): ?VisitorOption {
if (node.type !== Syntax.FunctionExpression) {
return null;
rewrite(node: Object, parent: Object): boolean {
return (
this.rewriteFunctionExpression(node, parent) ||
this.rewriteCallExpression(node)
);
}
if (node.generator) {
return null;
}
rewriteFunctionExpression(node: Object, parent: Object): boolean {
if (node.type !== Syntax.FunctionExpression) {
return false;
}
if (node.id) {
return null;
}
if (node.generator) {
return false;
}
if (node.body.body.length !== 1) {
return null;
}
if (node.id) {
return false;
}
if (parent.type === Syntax.Property && parent.method) {
return null;
}
if (node.body.body.length !== 1) {
return false;
}
const [ statement ] = node.body.body;
if (parent.type === Syntax.Property && parent.method) {
return false;
}
if (statement.type !== Syntax.ReturnStatement) {
return null;
const [ statement ] = node.body.body;
if (statement.type !== Syntax.ReturnStatement) {
return false;
}
if (referencesThisOrArguments(node, this.module.scopeManager)) {
return false;
}
this._rewriteBlocklessArrowFunction(node, parent);
return true;
}
if (referencesThisOrArguments(node, module.scopeManager)) {
return null;
rewriteCallExpression(node: Object): boolean {
if (node.type !== Syntax.CallExpression) {
return false;
}
const { callee } = node;
if (callee.type !== Syntax.MemberExpression) {
return false;
}
const { object, property } = callee;
if (object.type !== Syntax.FunctionExpression || object.id) {
return false;
}
if (property.type !== Syntax.Identifier || property.name !== 'bind') {
return false;
}
if (node.arguments.length !== 1 || node.arguments[0].type !== Syntax.ThisExpression) {
return false;
}
this._rewriteBlockArrowFunction(object);
// `() => {}.bind(this)` -> `() => {}bind(this)`
// ^
this.module.tokensBetweenNodes(object, property).forEach(token => {
if (token.type === 'Punctuator' && token.value === '.') {
this.remove(...token.range);
}
});
// `() => {}bind(this)` -> `() => {}`
// ^^^^^^^^^^
this.remove(property.range[0], node.range[1]);
replace(node, object);
return true;
}
context.metadata.functions.push(clone(node));
_rewriteBlocklessArrowFunction(node: Object, parent: Object) {
const [ statement ] = node.body.body;
const tokens = module.tokensForNode(node);
let tokenIndex = 0;
const functionToken = tokens[tokenIndex++];
const paramStartParenToken = tokens[tokenIndex++];
let paramEndParenToken;
this.metadata.functions.push(clone(node));
if (node.params.length === 0) {
paramEndParenToken = tokens[tokenIndex++];
} else {
const lastParam = node.params[node.params.length - 1];
while (tokenIndex < tokens.length) {
const token = tokens[tokenIndex++];
if (token.range[0] >= lastParam.range[1] && token.value === ')') {
paramEndParenToken = token;
break;
const tokens = this.module.tokensForNode(node);
let tokenIndex = 0;
const functionToken = tokens[tokenIndex++];
const paramStartParenToken = tokens[tokenIndex++];
let paramEndParenToken;
if (node.params.length === 0) {
paramEndParenToken = tokens[tokenIndex++];
} else {
const lastParam = node.params[node.params.length - 1];
while (tokenIndex < tokens.length) {
const token = tokens[tokenIndex++];
if (token.range[0] >= lastParam.range[1] && token.value === ')') {
paramEndParenToken = token;
break;
}
}
}
}
const paramsNeedsParens = node.params.length !== 1 || node.params[0].type !== 'Identifier';
const paramsNeedsParens = node.params.length !== 1 || node.params[0].type !== Syntax.Identifier;
if (!paramsNeedsParens) {
// `(a)` -> `a`
// ^ ^
context.remove(...paramStartParenToken.range);
context.remove(...paramEndParenToken.range);
}
if (!paramsNeedsParens) {
// `(a)` -> `a`
// ^ ^
this.remove(...paramStartParenToken.range);
this.remove(...paramEndParenToken.range);
}
const blockStartBraceToken = tokens[tokenIndex++];
const blockEndBraceToken = tokens[tokens.length - 1];
const blockStartBraceToken = tokens[tokenIndex++];
const blockEndBraceToken = tokens[tokens.length - 1];
// `function() {` -> `() =>`
// ^^^^^^^^ ^ ^^
context.remove(functionToken.range[0], paramStartParenToken.range[0]);
context.overwrite(...blockStartBraceToken.range, '=>');
// `function() {` -> `() =>`
// ^^^^^^^^ ^ ^^
this.remove(functionToken.range[0], paramStartParenToken.range[0]);
this.overwrite(...blockStartBraceToken.range, '=>');
const contentBetweenBlockStartBraceAndReturn = context.slice(
blockStartBraceToken.range[1],
statement.range[0]
);
const contentBetweenBlockStartBraceAndReturn = this.slice(
blockStartBraceToken.range[1],
statement.range[0]
);
const shouldCollapseToOneLine = /^\s*$/.test(contentBetweenBlockStartBraceAndReturn);
const shouldCollapseToOneLine = /^\s*$/.test(contentBetweenBlockStartBraceAndReturn);
if (shouldCollapseToOneLine) {
// Removes whitespace between `{` and `return` and `foo;` and `}`.
//
// function() {
// return foo;
// }
//
context.overwrite(blockStartBraceToken.range[1], statement.range[0], ' ');
context.remove(statement.range[1], blockEndBraceToken.range[0]);
if (shouldCollapseToOneLine) {
// Removes whitespace between `{` and `return` and `foo;` and `}`.
//
// function() {
// return foo;
// }
//
this.overwrite(blockStartBraceToken.range[1], statement.range[0], ' ');
this.remove(statement.range[1], blockEndBraceToken.range[0]);
}
// `return foo;` -> `foo`
// ^^^^^^^ ^
this.remove(statement.range[0], statement.argument.range[0]);
this.remove(statement.argument.range[1], statement.range[1]);
// `…}` -> `…`
this.remove(...blockEndBraceToken.range);
node.type = Syntax.ArrowFunctionExpression;
node.body = statement.argument;
if (needsParens(node, parent) && !hasParens(node, this.module)) {
this.insert(node.range[0], '(');
this.insert(node.range[1], ')');
}
}
// `return foo;` -> `foo`
// ^^^^^^^ ^
context.remove(statement.range[0], statement.argument.range[0]);
context.remove(statement.argument.range[1], statement.range[1]);
_rewriteBlockArrowFunction(node: Object) {
this.metadata.functions.push(clone(node));
// `…}` -> `…`
context.remove(...blockEndBraceToken.range);
const tokens = this.module.tokensForNode(node);
let tokenIndex = 0;
const functionToken = tokens[tokenIndex++];
const paramStartParenToken = tokens[tokenIndex++];
let paramEndParenToken;
node.type = Syntax.ArrowFunctionExpression;
node.body = statement.argument;
if (node.params.length === 0) {
paramEndParenToken = tokens[tokenIndex++];
} else {
const lastParam = node.params[node.params.length - 1];
while (tokenIndex < tokens.length) {
const token = tokens[tokenIndex++];
if (token.range[0] >= lastParam.range[1] && token.value === ')') {
paramEndParenToken = token;
break;
}
}
}
const paramsNeedsParens = node.params.length !== 1 || node.params[0].type !== Syntax.Identifier;
if (!paramsNeedsParens) {
// `(a)` -> `a`
// ^ ^
this.remove(...paramStartParenToken.range);
this.remove(...paramEndParenToken.range);
}
const blockStartBraceToken = tokens[tokenIndex++];
// `function() {` -> `() =>`
// ^^^^^^^^ ^ ^^
this.remove(functionToken.range[0], paramStartParenToken.range[0]);
this.insert(blockStartBraceToken.range[0], '=> ');
node.type = Syntax.ArrowFunctionExpression;
}
}
export function begin(module: Module): Context {
return new Context(module);
}
export function enter(node: Object, parent: Object, module: Module, context: Context): ?VisitorOption {
context.rewrite(node, parent);
return null;
}
function referencesThisOrArguments(node: Object, scopeManager: ScopeManager): boolean {

@@ -126,0 +239,0 @@ const scope = scopeManager.acquire(node);

@@ -151,67 +151,2 @@ import BaseContext from '../context';

// TODO: test nested template strings
//parts.forEach(part => this.escape('`', part.node.range[0] + 1, part.node.range[1] - 1));
//
//for (let i = 0; i < parts.length - 1; i++) {
// const thisPart = parts[i];
// const thisNode = thisPart.node;
// const nextPart = parts[i + 1];
// const nextNode = nextPart.node;
// if (isString(nextNode)) {
// cooked += nextNode.value;
// raw += nextNode.raw.slice(1, -1);
// } else {
// expressions.push(nextNode);
// quasis.push({
// type: Syntax.TemplateElement,
// tail: false,
// value: { cooked, raw: raw.replace(/`/g, '\\`') }
// });
// cooked = '';
// raw = '';
// }
// if (isString(thisNode)) {
// if (isString(nextNode)) {
// this.remove(
// thisNode.range[1] - 1,
// nextNode.range[0] + 1
// );
// } else {
// this.overwrite(
// thisNode.range[1] - 1,
// nextNode.range[0],
// `\${`
// );
// }
// } else {
// if (isString(nextNode)) {
// this.overwrite(
// thisNode.range[1],
// nextNode.range[0] + 1,
// `}`
// );
// } else {
// this.overwrite(
// thisNode.range[1],
// nextNode.range[0],
// `}\${`
// );
// }
// }
//}
//
//quasis.push({
// type: Syntax.TemplateElement,
// tail: true,
// value: { cooked, raw }
//});
//
//const lastPart = parts[parts.length - 1];
//const lastNode = lastPart.node;
//if (isString(lastNode)) {
// this.overwrite(lastNode.range[1] - 1, node.range[1], '`');
//} else {
// this.overwrite(lastNode.range[1], node.range[1], '}`');
//}
return { type: Syntax.TemplateLiteral, expressions, quasis };

@@ -218,0 +153,0 @@ }

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc