Skip to content
This repository has been archived by the owner on Jan 13, 2024. It is now read-only.

Upgrade eslint + move to eslint-config-airbnb-base #1088

Merged
merged 1 commit into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"extends": [
"airbnb-base",
"prettier"
],
"parser": "@babel/eslint-parser",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"wrap-iife": "off",
"no-bitwise": "off",
"no-continue": "off",
"class-methods-use-this": "off",
"no-await-in-loop": "off",
"no-constant-condition": "off",
"no-param-reassign": "off",
"consistent-return": "off",
"no-restricted-syntax": "off",
"import/prefer-default-export": "off",
"camelcase": "off"
},
"overrides": [{
"files": ["prelude/**/*"],
"rules": {
"strict": "off"
}
}]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ examples/express/node_modules

# Editors
.vscode/
yarn-error.log
4 changes: 2 additions & 2 deletions lib/bin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node

import { exec } from './index.js';
import { log } from './log.js';
import { exec } from './index';
import { log } from './log';

async function main() {
if (process.env.CHDIR && process.env.CHDIR !== process.cwd()) {
Expand Down
189 changes: 105 additions & 84 deletions lib/detector.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,59 @@
/* eslint-disable operator-linebreak */
/* eslint-disable prefer-const */

const common = require('../prelude/common.js');
const generate = require('escodegen').generate;
const babelParser = require('@babel/parser');
const parse = babelParser.parse;
import { generate } from 'escodegen';
import * as babel from '@babel/parser';
import { ALIAS_AS_RELATIVE, ALIAS_AS_RESOLVABLE } from '../prelude/common';

const ALIAS_AS_RELATIVE = common.ALIAS_AS_RELATIVE;
const ALIAS_AS_RESOLVABLE = common.ALIAS_AS_RESOLVABLE;
function reconstructSpecifiers(specs) {
if (!specs || !specs.length) return '';
const defaults = [];

for (const spec of specs) {
if (spec.type === 'ImportDefaultSpecifier') {
defaults.push(spec.local.name);
}
}

const nonDefaults = [];

for (const spec of specs) {
if (spec.type === 'ImportSpecifier') {
if (spec.local.name === spec.imported.name) {
nonDefaults.push(spec.local.name);
} else {
nonDefaults.push(`${spec.imported.name} as ${spec.local.name}`);
}
}
}

if (nonDefaults.length) {
defaults.push(`{ ${nonDefaults.join(', ')} }`);
}

return defaults.join(', ');
}

function reconstruct(node) {
let v = generate(node).replace(/\n/g, '');
let v2;

// eslint-disable-next-line no-constant-condition
while (true) {
v2 = v.replace(/\[ /g, '[').replace(/ \]/g, ']').replace(/ {2}/g, ' ');
if (v2 === v) break;
v = v2;
}

return v2;
}

function forge(pattern, was) {
return pattern
.replace('{c1}', ', ')
.replace('{v1}', '"' + was.v1 + '"')
.replace('{v1}', `"${was.v1}"`)
.replace('{c2}', was.v2 ? ', ' : '')
.replace('{v2}', was.v2 ? '"' + was.v2 + '"' : '')
.replace('{v2}', was.v2 ? `"${was.v2}"` : '')
.replace('{c3}', was.v3 ? ' from ' : '')
.replace('{v3}', was.v3 ? was.v3 : '');
}
Expand Down Expand Up @@ -101,21 +140,24 @@ function visitor_PATH_JOIN(n) {
return { v1: n.arguments[1].value };
}

module.exports.visitor_SUCCESSFUL = function (node, test) {
// eslint-disable-line camelcase
let mustExclude, mayExclude, was;
export function visitor_SUCCESSFUL(node, test) {
let mustExclude;
let mayExclude;
let was;

was = visitor_REQUIRE_RESOLVE(node);
if (was) {
if (test) return forge('require.resolve({v1}{c2}{v2})', was);
if (!valid2(was.v2)) return null;

mustExclude = was.v2 === 'must-exclude';
mayExclude = was.v2 === 'may-exclude';

return {
alias: was.v1,
aliasType: ALIAS_AS_RESOLVABLE,
mustExclude: mustExclude,
mayExclude: mayExclude,
mustExclude,
mayExclude,
};
}

Expand All @@ -128,8 +170,8 @@ module.exports.visitor_SUCCESSFUL = function (node, test) {
return {
alias: was.v1,
aliasType: ALIAS_AS_RESOLVABLE,
mustExclude: mustExclude,
mayExclude: mayExclude,
mustExclude,
mayExclude,
};
}

Expand All @@ -146,12 +188,12 @@ module.exports.visitor_SUCCESSFUL = function (node, test) {
}

return null;
};
}

function visitor_NONLITERAL(n) {
function visitorNonLiteral(n) {
// eslint-disable-line camelcase
return (
(function () {
(() => {
const c = n.callee;
if (!c) return null;
const ci =
Expand All @@ -174,7 +216,7 @@ function visitor_NONLITERAL(n) {
if (!q) return null;
return { v1: reconstruct(n.arguments[0]), v2: n.arguments[1].value };
})() ||
(function () {
(() => {
const c = n.callee;
if (!c) return null;
const ci = c.type === 'Identifier' && c.name === 'require';
Expand All @@ -194,25 +236,27 @@ function visitor_NONLITERAL(n) {
);
}

module.exports.visitor_NONLITERAL = function (node) {
export function visitor_NONLITERAL(node) {
// eslint-disable-line camelcase
let mustExclude, mayExclude, was;
let mustExclude;
let mayExclude;
let was;

was = visitor_NONLITERAL(node);
was = visitorNonLiteral(node);
if (was) {
if (!valid2(was.v2)) return null;
mustExclude = was.v2 === 'must-exclude';
mayExclude = was.v2 === 'may-exclude';
return { alias: was.v1, mustExclude: mustExclude, mayExclude: mayExclude };
return { alias: was.v1, mustExclude, mayExclude };
}

return null;
};
}

function visitor_MALFORMED(n) {
function visitorMalformed(n) {
// eslint-disable-line camelcase
return (
(function () {
(() => {
const c = n.callee;
if (!c) return null;
const ci =
Expand All @@ -227,7 +271,7 @@ function visitor_MALFORMED(n) {
if (!f) return null;
return { v1: reconstruct(n.arguments[0]) };
})() ||
(function () {
(() => {
const c = n.callee;
if (!c) return null;
const ci = c.type === 'Identifier' && c.name === 'require';
Expand All @@ -239,17 +283,17 @@ function visitor_MALFORMED(n) {
);
}

module.exports.visitor_MALFORMED = function (node) {
export function visitor_MALFORMED(node) {
// eslint-disable-line camelcase
let was;

was = visitor_MALFORMED(node);
was = visitorMalformed(node);
if (was) return { alias: was.v1 };

return null;
};
}

function visitor_USESCWD(n) {
function visitorUseCwd(n) {
// eslint-disable-line camelcase
const c = n.callee;
if (!c) return null;
Expand All @@ -264,90 +308,67 @@ function visitor_USESCWD(n) {
return { v1: n.arguments.map(reconstruct).join(', ') };
}

module.exports.visitor_USESCWD = function (node) {
export function visitor_USESCWD(node) {
// eslint-disable-line camelcase
let was;

was = visitor_USESCWD(node);
was = visitorUseCwd(node);
if (was) return { alias: was.v1 };

return null;
};

function reconstructSpecifiers(specs) {
if (!specs || !specs.length) return '';
const defaults = [];
for (const spec of specs) {
if (spec.type === 'ImportDefaultSpecifier') {
defaults.push(spec.local.name);
}
}
const nonDefaults = [];
for (const spec of specs) {
if (spec.type === 'ImportSpecifier') {
if (spec.local.name === spec.imported.name) {
nonDefaults.push(spec.local.name);
} else {
nonDefaults.push(spec.imported.name + ' as ' + spec.local.name);
}
}
}
if (nonDefaults.length) {
defaults.push('{ ' + nonDefaults.join(', ') + ' }');
}
return defaults.join(', ');
}

function reconstruct(node) {
let v = generate(node).replace(/\n/g, '');
let v2;
while (true) {
v2 = v.replace(/\[ /g, '[').replace(/ \]/g, ']').replace(/ {2}/g, ' ');
if (v2 === v) break;
v = v2;
}
return v2;
}

function traverse(ast, visitor) {
// modified esprima-walk to support
// visitor return value and "trying" flag
let stack = [[ast, false]];
let i, j, key;
let len, item, node, trying, child;
let i;
let j;
let key;
let len;
let item;
let node;
let trying;
let child;

for (i = 0; i < stack.length; i += 1) {
item = stack[i];
node = item[0];
[node] = item;

if (node) {
trying = item[1] || node.type === 'TryStatement';

if (visitor(node, trying)) {
for (key in node) {
child = node[key];
if (child instanceof Array) {
len = child.length;
for (j = 0; j < len; j += 1) {
stack.push([child[j], trying]);
if (node[key]) {
child = node[key];

if (child instanceof Array) {
len = child.length;
for (j = 0; j < len; j += 1) {
stack.push([child[j], trying]);
}
} else if (child && typeof child.type === 'string') {
stack.push([child, trying]);
}
} else if (child && typeof child.type === 'string') {
stack.push([child, trying]);
}
}
}
}
}
}

module.exports.parse = function (body) {
return parse(body, {
export function parse(body) {
return babel.parse(body, {
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
ecmaVersion: 8,
plugins: ['estree', 'bigInt', 'classPrivateProperties', 'classProperties'],
});
};
}

module.exports.detect = function (body, visitor) {
const json = module.exports.parse(body);
export function detect(body, visitor) {
const json = parse(body);
if (!json) return;
traverse(json, visitor);
};
}
Loading