Skip to content

Commit

Permalink
ironing out the wrinkles
Browse files Browse the repository at this point in the history
  • Loading branch information
jsoverson committed Jul 7, 2020
1 parent 59b98d7 commit 2263e70
Show file tree
Hide file tree
Showing 14 changed files with 415 additions and 442 deletions.
69 changes: 16 additions & 53 deletions src/id-generator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {TokenType} = require('shift-parser');
const { TokenType } = require('shift-parser');

const jsKeywords = Object.values(TokenType)
.filter((_: any) => _.name && _.klass.name === 'Keyword')
Expand All @@ -9,14 +9,26 @@ import adjectives from './adjectives';

import seedrandom from 'seedrandom';

export interface IdGenerator extends Iterator<string> {
next(): IteratorResult<string>;
export class BaseIdGenerator implements Iterator<string> {
next() {
return {
done: false,
value: ``,
};
}

*[Symbol.iterator]() {
while (true) {
yield this.next();
}
}
}

export class MemorableIdGenerator implements IdGenerator {
export class MemorableIdGenerator extends BaseIdGenerator {
rng: seedrandom.prng;

constructor(seed = 0) {
super();
this.rng = seedrandom(seed.toString());
}

Expand Down Expand Up @@ -45,52 +57,3 @@ export class MemorableIdGenerator implements IdGenerator {
}
}
}

export class BasicIdGenerator implements IdGenerator {
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
reservedWords: Set<string> = new Set(jsKeywords);
current: number[];

constructor(alphabet: string, reservedWords?: string[]) {
if (alphabet) this.alphabet = alphabet;
if (reservedWords) this.reservedWords = new Set(reservedWords);
this.current = [-1];
}

next() {
this._increment();
const nextId = this.current.reduce((acc, code) => acc + this.alphabet[code], '');
if (!this.reservedWords.has(nextId)) {
return {
done: false,
value: nextId,
};
} else {
this._increment();
return {
done: false,
value: this.current.reduce((acc, code) => acc + this.alphabet[code], ''),
};
}
}

_increment() {
for (let i = this.current.length - 1; i >= 0; i--) {
this.current[i]++;
if (this.current[i] >= this.alphabet.length) {
this.current[i] = 0;
} else {
// if we didn't have to roll over, then return
return;
}
}
// if we rolled over every character, add one more.
this.current.unshift(0);
}

*[Symbol.iterator]() {
while (true) {
yield this.next();
}
}
}
32 changes: 3 additions & 29 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,8 @@ import pluginUnsafe from './refactor-plugin-unsafe';
import pluginCommon from './refactor-plugin-common';

export { RefactorSession } from './refactor-session';
export { RefactorSessionChainable } from './refactor-session-chainable'

const API = RefactorSessionChainable.with(pluginUnsafe).with(pluginCommon);

/**
* Initialization of a RefactorSession via the chainable API
*
* @alpha
*/
export function refactor(input: string | Node, { autoCleanup = true } = {}) {
const globalSession = new RefactorSession(input, { autoCleanup });
const globalChainable = new API(globalSession);

function generateQueryFunction(session: RefactorSession) {
return function $query(selector: string | string[]) {
const subSession = session.subSession(selector);
const subChainable = new API(subSession);
const prototype = Object.getPrototypeOf(subChainable);
const hybridObject = Object.assign(generateQueryFunction(subSession), subChainable);
Object.setPrototypeOf(hybridObject, prototype);
Object.defineProperty(hybridObject, 'length', {
get() { return subSession.length }
});
return hybridObject;
}
}
const prototype = Object.getPrototypeOf(globalChainable);
const hybridObject = Object.assign(generateQueryFunction(globalSession), globalChainable);
Object.setPrototypeOf(hybridObject, prototype);
return hybridObject;
}
// export * as Shift from 'shift-ast';

export { refactor } from './refactor-session-chainable';
30 changes: 11 additions & 19 deletions src/refactor-plugin-common.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import DEBUG from 'debug';
import {
ComputedMemberAssignmentTarget,
BinaryExpression, ComputedMemberAssignmentTarget,
ComputedMemberExpression,
ComputedPropertyName,
IdentifierExpression,
ConditionalExpression,
DebuggerStatement, FunctionBody, IdentifierExpression,
LiteralBooleanExpression,
LiteralStringExpression,
StaticMemberAssignmentTarget,
StaticMemberExpression,
StaticPropertyName,
VariableDeclarator,
Node,
BinaryExpression,
ConditionalExpression,
FunctionBody,
DebuggerStatement,
ReturnStatement,
ReturnStatement, StaticMemberAssignmentTarget,
StaticMemberExpression,
StaticPropertyName
} from 'shift-ast';
import { Declaration, Reference } from 'shift-scope';
import { default as isValid } from 'shift-validator';
import { IdGenerator, MemorableIdGenerator } from './id-generator';
import { RefactorPlugin } from './refactor-plugin';
import { SelectorOrNode } from './types';
import { findNodes, renameScope, isLiteral } from './util';
import DEBUG from 'debug';
import { MemorableIdGenerator } from './id-generator';
import { RefactorSessionChainable } from './refactor-session-chainable';
import { isLiteral, renameScope } from './util';

const debug = DEBUG('shift-refactor:common');

Expand Down Expand Up @@ -168,9 +160,9 @@ export default function pluginCommon() {
return this.session.conditionalCleanup();
},

normalizeIdentifiers(this: RefactorSessionChainable, seed = 1, _Generator: new (seed: number) => IdGenerator = MemorableIdGenerator) {
normalizeIdentifiers(this: RefactorSessionChainable, seed = 1) {
const lookupTable = this.session.getLookupTable();
const idGenerator = new _Generator(seed);
const idGenerator = new MemorableIdGenerator(seed);
renameScope(lookupTable.scope, idGenerator, this.session.parentMap);
return this.session.conditionalCleanup();
}
Expand Down
20 changes: 10 additions & 10 deletions src/refactor-plugin-unsafe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { copy, isLiteral, isStatement } from './util';

export default function pluginUnsafe() {
return {
findPureFunctionCandidates(this: RefactorSessionChainable, options?: PureFunctionAssessmentOptions) {
return new Map(
(this.query('FunctionDeclaration') as FunctionDeclaration[])
.map((fn: FunctionDeclaration) => new PureFunctionAssessment(fn, options))
.filter((assmt: PureFunctionAssessment) => assmt.verdict === PureFunctionVerdict.Probably)
.map((assmt: PureFunctionAssessment) => [assmt.node, assmt]),
);
},
// findPureFunctionCandidates(this: RefactorSessionChainable, options?: PureFunctionAssessmentOptions) {
// return new Map(
// (this.query('FunctionDeclaration') as FunctionDeclaration[])
// .map((fn: FunctionDeclaration) => new PureFunctionAssessment(fn, options))
// .filter((assmt: PureFunctionAssessment) => assmt.verdict === PureFunctionVerdict.Probably)
// .map((assmt: PureFunctionAssessment) => [assmt.node, assmt]),
// );
// },

massRename(this: RefactorSessionChainable, namePairs: string[][]) {
namePairs.forEach(([from, to]) => {
Expand Down Expand Up @@ -47,8 +47,8 @@ export default function pluginUnsafe() {
},

removeDeadVariables(this: RefactorSessionChainable) {
(this
.query('VariableDeclarator, FunctionDeclaration, ClassDeclaration') as (VariableDeclarator | FunctionDeclaration | ClassDeclaration)[])
this
.query('VariableDeclarator, FunctionDeclaration, ClassDeclaration')
.forEach((decl: VariableDeclarator | FunctionDeclaration | ClassDeclaration) => {
let nameNode = decl.type === 'VariableDeclarator' ? decl.binding : decl.name;

Expand Down

0 comments on commit 2263e70

Please sign in to comment.