Skip to content
This repository has been archived by the owner on May 5, 2023. It is now read-only.

Commit

Permalink
Remove "generator" output mode (#12)
Browse files Browse the repository at this point in the history
Drops Node v6 support
  • Loading branch information
TooTallNate committed Jul 12, 2021
1 parent b9bc71e commit 7ad1041
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 267 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [6.x, 8.x, 10.x, 12.x]
node-version: [8.x, 10.x, 12.x, 14.x]

runs-on: ${{ matrix.os }}

Expand Down
83 changes: 0 additions & 83 deletions src/generator-to-promise.ts

This file was deleted.

79 changes: 28 additions & 51 deletions src/index.ts
Expand Up @@ -4,9 +4,6 @@ import { parseScript } from 'esprima';
import { visit, namedTypes as n, builders as b } from 'ast-types';
import { Context, RunningScriptOptions, runInNewContext } from 'vm';

import _supportsAsync from './supports-async';
import generatorToPromiseFn from './generator-to-promise';

/**
* Compiles sync JavaScript code into JavaScript with async Functions.
*
Expand All @@ -18,8 +15,7 @@ import generatorToPromiseFn from './generator-to-promise';

function degenerator(
code: string,
_names: degenerator.DegeneratorNames,
{ output = 'async' }: degenerator.DegeneratorOptions = {}
_names: degenerator.DegeneratorNames
): string {
if (!Array.isArray(_names)) {
throw new TypeError('an array of async function "names" is required');
Expand Down Expand Up @@ -76,20 +72,16 @@ function degenerator(
shouldDegenerate = true;
}
return false;
}
},
});

if (!shouldDegenerate) {
return false;
}

// Got a "function" expression/statement,
// convert it into an async or generator function
if (output === 'async') {
path.node.async = true;
} else if (output === 'generator') {
path.node.generator = true;
}
// convert it into an async function
path.node.async = true;

// Add function name to `names` array
if (!checkName(path.node.id.name, names)) {
Expand All @@ -98,7 +90,7 @@ function degenerator(
}

this.traverse(path);
}
},
});
} while (lastNamesLength !== names.length);

Expand All @@ -112,19 +104,10 @@ function degenerator(
const delegate = false;
const {
name,
parent: { node: pNode }
parent: { node: pNode },
} = path;

let expr;
if (output === 'async') {
expr = b.awaitExpression(path.node, delegate);
} else if (output === 'generator') {
expr = b.yieldExpression(path.node, delegate);
} else {
throw new Error(
'Only "async" and "generator" are allowd `output` values'
);
}
const expr = b.awaitExpression(path.node, delegate);

if (n.CallExpression.check(pNode)) {
pNode.arguments[name] = expr;
Expand All @@ -134,7 +117,7 @@ function degenerator(
}

this.traverse(path);
}
},
});

return generate(ast);
Expand All @@ -143,24 +126,16 @@ function degenerator(
namespace degenerator {
export type DegeneratorName = string | RegExp;
export type DegeneratorNames = DegeneratorName[];
export type DegeneratorOutput = 'async' | 'generator';
export interface DegeneratorOptions {
output?: DegeneratorOutput;
}
export interface CompileOptions
extends DegeneratorOptions,
RunningScriptOptions {
export interface CompileOptions extends RunningScriptOptions {
sandbox?: Context;
}
export const supportsAsync = _supportsAsync;
export function compile<T extends Function>(
export function compile<R, A extends any[] = []>(
code: string,
returnName: string,
names: DegeneratorNames,
options: CompileOptions = {}
): T {
const output = _supportsAsync ? 'async' : 'generator';
const compiled = degenerator(code, names, { ...options, output });
): (...args: A) => Promise<R> {
const compiled = degenerator(code, names);
const fn = runInNewContext(
`${compiled};${returnName}`,
options.sandbox,
Expand All @@ -171,23 +146,25 @@ namespace degenerator {
`Expected a "function" to be returned for \`${returnName}\`, but got "${typeof fn}"`
);
}
if (isAsyncFunction(fn)) {
return fn;
} else {
const rtn = (generatorToPromiseFn(fn) as unknown) as T;
Object.defineProperty(rtn, 'toString', {
value: fn.toString.bind(fn),
enumerable: false
});
return rtn;
}
const r = function (this: any, ...args: A): Promise<R> {
try {
const p = fn.apply(this, args);
if (typeof p.then === 'function') {
return p;
}
return Promise.resolve(p);
} catch (err) {
return Promise.reject(err);
}
};
Object.defineProperty(r, 'toString', {
value: fn.toString.bind(fn),
enumerable: false,
});
return r;
}
}

function isAsyncFunction(fn: any): boolean {
return typeof fn === 'function' && fn.constructor.name === 'AsyncFunction';
}

/**
* Returns `true` if `node` has a matching name to one of the entries in the
* `names` array.
Expand Down
12 changes: 0 additions & 12 deletions src/supports-async.ts

This file was deleted.

8 changes: 4 additions & 4 deletions test/assignment.expected.js
Expand Up @@ -3,9 +3,9 @@ var biz = foo;
function foo() {
return 42;
}
function* bar() {
return yield baz();
async function bar() {
return await baz();
}
function* bir() {
return yield biz();
async function bir() {
return await biz();
}
4 changes: 2 additions & 2 deletions test/basic.expected.js
@@ -1,3 +1,3 @@
function* foo() {
return (yield a('bar')) || (yield b());
async function foo() {
return await a('bar') || await b();
}
8 changes: 4 additions & 4 deletions test/get-example.expected.js
@@ -1,7 +1,7 @@
function* myFn() {
var one = yield get('https://google.com');
var two = yield get('http://nodejs.org');
var three = JSON.parse(yield get('http://jsonip.org'));
async function myFn() {
var one = await get('https://google.com');
var two = await get('http://nodejs.org');
var three = JSON.parse(await get('http://jsonip.org'));
return [
one,
two,
Expand Down
12 changes: 6 additions & 6 deletions test/multiple.expected.js
@@ -1,9 +1,9 @@
function* foo() {
return yield baz();
async function foo() {
return await baz();
}
function* bar() {
return yield foo(baz);
async function bar() {
return await foo(baz);
}
function* baz() {
return yield bar();
async function baz() {
return await bar();
}
10 changes: 5 additions & 5 deletions test/pac-resolver-gh-3.expected.js
@@ -1,22 +1,22 @@
function* FindProxyForURL(url, host) {
if (yield isHostInAnySubnet(host, [
async function FindProxyForURL(url, host) {
if (await isHostInAnySubnet(host, [
'10.1.2.0',
'10.1.3.0'
], '255.255.255.0')) {
return 'HTTPS proxy.example.com';
}
if (yield isHostInAnySubnet(host, [
if (await isHostInAnySubnet(host, [
'10.2.2.0',
'10.2.3.0'
], '255.255.255.0')) {
return 'HTTPS proxy.example.com';
}
return 'DIRECT';
}
function* isHostInAnySubnet(host, subnets, mask) {
async function isHostInAnySubnet(host, subnets, mask) {
var subnets_length = subnets.length;
for (i = 0; i < subnets_length; i++) {
if (yield isInNet(host, subnets[i], mask)) {
if (await isInNet(host, subnets[i], mask)) {
return true;
}
}
Expand Down
14 changes: 7 additions & 7 deletions test/partial.expected.js
@@ -1,12 +1,12 @@
function* foo() {
return yield baz();
async function foo() {
return await baz();
}
function* bar() {
return yield foo(baz);
async function bar() {
return await foo(baz);
}
function* baz() {
return yield bar();
async function baz() {
return await bar();
}
function shouldntChange() {
return 42;
}
}

0 comments on commit 7ad1041

Please sign in to comment.