Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

globalthis #85

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
37 changes: 37 additions & 0 deletions codemods/globalthis/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import jscodeshift from 'jscodeshift';
import { removeImport } from '../shared.js';

/**
* @typedef {import('../../types.js').Codemod} Codemod
* @typedef {import('../../types.js').CodemodOptions} CodemodOptions
*/

/**
* @param {CodemodOptions} [options]
* @returns {Codemod}
*/
export default function (options) {
return {
name: 'globalthis',
transform: ({ file }) => {
const j = jscodeshift;
const root = j(file.source);
const identifier1 = removeImport('globalthis', root, j).identifier;
const identifier2 = removeImport(
'globalthis/polyfill',
root,
j,
).identifier;
const identifier3 = removeImport('globalthis/shim', root, j).identifier;
const identifier = identifier1 || identifier2 || identifier3;

if (identifier) {
root
.find(j.Identifier, { name: identifier })
.replaceWith(j.identifier('globalThis'));
}

return root.toSource({ quote: 'single' });
},
};
}
109 changes: 101 additions & 8 deletions codemods/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,91 @@ export function removeImport(name, root, j) {
},
});

// Require statements with call expressions like `var globalThis = require('globalthis')()`
const requireCallExpression = root.find(j.VariableDeclarator, {
init: {
callee: {
type: 'CallExpression',
callee: {
name: 'require',
},
arguments: [
{
value: name,
},
],
},
},
});

// Same as above without variable declaration like `require('globalthis')()`
const sideEffectRequireCallExpression = root.find(j.ExpressionStatement, {
expression: {
callee: {
type: 'CallExpression',
callee: {
name: 'require',
},
arguments: [
{
value: name,
},
],
},
},
});

// Require chained call expressions like `var globalThis = require('globalthis').shim()`
const requireMethodCallExpression = root.find(j.VariableDeclarator, {
init: {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'CallExpression',
callee: {
name: 'require',
},
arguments: [
{
value: name,
},
],
},
property: {
type: 'Identifier',
},
},
},
});

// Same as above without variable declaration like `require('globalthis').shim()`
const sideEffectRequireMethodCallExpression = root.find(
j.ExpressionStatement,
{
expression: {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'CallExpression',
callee: {
name: 'require',
},
arguments: [
{
value: name,
},
],
},
property: {
type: 'Identifier',
},
},
},
},
);

// Require statements without declarations like `Object.is = require("object-is");`
const requireAssignment = root.find(j.AssignmentExpression, {
operator: '=',
Expand Down Expand Up @@ -64,17 +149,25 @@ export function removeImport(name, root, j) {

// Return the identifier name, e.g. 'fn' in `import { fn } from 'is-boolean-object'`
// or `var fn = require('is-boolean-object')`
const identifier =
importDeclaration.paths().length > 0
? importDeclaration.get().node.specifiers[0].local.name
: requireDeclaration.paths().length > 0
? requireDeclaration.find(j.Identifier).get().node.name
: requireAssignment.paths().length > 0
? requireAssignment.find(j.Identifier).get().node.name
: null;
let identifier = null;
if (importDeclaration.paths().length > 0) {
identifier = importDeclaration.get().node.specifiers[0].local.name;
} else if (requireDeclaration.paths().length > 0) {
identifier = requireDeclaration.find(j.Identifier).get().node.name;
} else if (requireCallExpression.paths().length > 0) {
identifier = requireCallExpression.find(j.Identifier).get().node.name;
} else if (requireMethodCallExpression.paths().length > 0) {
identifier = requireMethodCallExpression.find(j.Identifier).get().node.name;
} else if (requireAssignment.paths().length > 0) {
identifier = requireAssignment.find(j.Identifier).get().node.name;
}

importDeclaration.remove();
requireDeclaration.remove();
requireCallExpression.remove();
sideEffectRequireCallExpression.remove();
requireMethodCallExpression.remove();
sideEffectRequireMethodCallExpression.remove();
requireAssignment.remove();
sideEffectRequireExpression.remove();

Expand Down
4 changes: 3 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import functionPrototypeName from './codemods/function.prototype.name/index.js';
import functionsHaveNames from './codemods/functions-have-names/index.js';
import getSymbolDescription from './codemods/get-symbol-description/index.js';
import global from './codemods/global/index.js';
import globalthis from './codemods/globalthis/index.js';
import gopd from './codemods/gopd/index.js';
import has from './codemods/has/index.js';
import hasOwnProp from './codemods/has-own-prop/index.js';
Expand Down Expand Up @@ -214,6 +215,7 @@ export const codemods = {
"functions-have-names": functionsHaveNames,
"get-symbol-description": getSymbolDescription,
"global": global,
"globalthis": globalthis,
"gopd": gopd,
"has": has,
"has-own-prop": hasOwnProp,
Expand Down Expand Up @@ -304,4 +306,4 @@ export const codemods = {
"typed-array-length": typedArrayLength,
"typedarray.prototype.slice": typedarrayPrototypeSlice,
"xtend": xtend,
};
};
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-1/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
2 changes: 2 additions & 0 deletions test/fixtures/globalthis/case-1/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var globalThis = require('globalthis')();
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-1/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-2/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
2 changes: 2 additions & 0 deletions test/fixtures/globalthis/case-2/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var globalThis = require('globalthis/polyfill')();
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-2/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-3/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
2 changes: 2 additions & 0 deletions test/fixtures/globalthis/case-3/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var newGlobalThis = require('globalthis')();
newGlobalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-3/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-4/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
2 changes: 2 additions & 0 deletions test/fixtures/globalthis/case-4/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var shimmedGlobal = require('globalthis').shim();
shimmedGlobal.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-4/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-5/after.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
2 changes: 2 additions & 0 deletions test/fixtures/globalthis/case-5/before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var shimmedGlobal = require('globalthis/shim')();
shimmedGlobal.a = 42;
1 change: 1 addition & 0 deletions test/fixtures/globalthis/case-5/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
globalThis.a = 42;
Loading