astx
Version:
super powerful structural search and replace for JavaScript and TypeScript to automate your refactoring
146 lines (131 loc) • 16.3 kB
JavaScript
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import compileReplacement from '../compileReplacement/index.mjs'
import convertToExpression from '../convertReplacement/convertToExpression.mjs'
import convertStatementReplacement from '../convertReplacement/convertStatementReplacement.mjs'
import ensureArray from '../util/ensureArray.mjs'
import Astx from '../Astx.mjs'
import CodeFrameError from '../util/CodeFrameError.mjs'
import { getArrayPlaceholder } from '../compileMatcher/Placeholder.mjs'
function convertQuasis(nodes) {
const captures = {}
const arrayCaptures = {}
const varNames = []
for (let i = 0; i < nodes.length; i++) {
let replacement
if (typeof nodes[i] === 'string') {
replacement = nodes[i]
} else if (Array.isArray(nodes[i])) {
replacement = nodes[i]
.map((n) => (n instanceof Astx ? n.nodes : n))
.flat()
} else if (nodes[i] instanceof Astx) {
const astx = nodes[i]
if (
astx.size > 1 ||
(astx.placeholder && getArrayPlaceholder(astx.placeholder))
) {
replacement = astx.nodes
} else {
replacement = astx.nodes[0]
}
} else if (nodes[i]) {
replacement = nodes[i]
}
if (typeof replacement === 'string') {
varNames.push(replacement)
} else if (Array.isArray(replacement)) {
const name = `$$tpl___${i}`
arrayCaptures[name] = replacement
varNames.push(name)
} else {
const name = `$tpl___${i}`
if (replacement) captures[name] = replacement
varNames.push(name)
}
}
return {
captures,
arrayCaptures,
varNames,
}
}
export function statements(code, ...nodes) {
const { captures, arrayCaptures, varNames } = convertQuasis(nodes)
const src = [...ensureArray(code)].reduce(
(result, elem, i) => result + varNames[i - 1] + elem
)
try {
if (!nodes.length || nodes.every((n) => typeof n === 'string'))
return this.parseStatements(src)
const result = compileReplacement(
this.parseStatements(src).map((n) => new this.t.NodePath(n)),
{
backend: this,
}
).generate({
captures,
arrayCaptures,
})
return ensureArray(result).map(convertStatementReplacement)
} catch (error) {
if (error instanceof Error) {
CodeFrameError.rethrow(error, {
filename: 'statements',
source: src,
})
}
throw error
}
}
export function statement(template, ...nodes) {
const result = this.template.statements(template, ...nodes)
if (result.length !== 1) {
throw new Error(`code is not a statement`)
}
return result[0]
}
export function expression(code, ...nodes) {
const { captures, arrayCaptures, varNames } = convertQuasis(nodes)
const src = [...ensureArray(code)].reduce(
(result, elem, i) => result + varNames[i - 1] + elem
)
try {
if (!nodes.length || nodes.every((n) => typeof n === 'string'))
return this.parseExpression(src)
const result = compileReplacement(
new this.t.NodePath(this.parseExpression(src)),
{
backend: this,
}
).generate({
captures,
arrayCaptures,
})
let expression
if (Array.isArray(result)) {
if (result.length !== 1) {
throw new Error(`code is not an expression: ${src}`)
}
expression = convertToExpression(result[0])
} else {
expression = convertToExpression(result)
}
if (!expression) {
throw new Error(`code is not an expression: ${src}`)
}
return expression
} catch (error) {
if (error instanceof Error) {
CodeFrameError.rethrow(error, {
filename: 'expression',
source: src,
})
}
throw error
}
} //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21waWxlUmVwbGFjZW1lbnQiLCJjb252ZXJ0VG9FeHByZXNzaW9uIiwiY29udmVydFN0YXRlbWVudFJlcGxhY2VtZW50IiwiZW5zdXJlQXJyYXkiLCJBc3R4IiwiQ29kZUZyYW1lRXJyb3IiLCJnZXRBcnJheVBsYWNlaG9sZGVyIiwiY29udmVydFF1YXNpcyIsIm5vZGVzIiwiY2FwdHVyZXMiLCJhcnJheUNhcHR1cmVzIiwidmFyTmFtZXMiLCJpIiwibGVuZ3RoIiwicmVwbGFjZW1lbnQiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJuIiwiZmxhdCIsImFzdHgiLCJzaXplIiwicGxhY2Vob2xkZXIiLCJwdXNoIiwibmFtZSIsInN0YXRlbWVudHMiLCJjb2RlIiwic3JjIiwicmVkdWNlIiwicmVzdWx0IiwiZWxlbSIsImV2ZXJ5IiwicGFyc2VTdGF0ZW1lbnRzIiwidCIsIk5vZGVQYXRoIiwiYmFja2VuZCIsImdlbmVyYXRlIiwiZXJyb3IiLCJFcnJvciIsInJldGhyb3ciLCJmaWxlbmFtZSIsInNvdXJjZSIsInN0YXRlbWVudCIsInRlbXBsYXRlIiwiZXhwcmVzc2lvbiIsInBhcnNlRXhwcmVzc2lvbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iYWNrZW5kL3RlbXBsYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSBGYWNlYm9vaywgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cblxuaW1wb3J0IHsgQmFja2VuZCB9IGZyb20gJy4vQmFja2VuZCdcbmltcG9ydCB7IE5vZGUsIEV4cHJlc3Npb24sIFN0YXRlbWVudCB9IGZyb20gJy4uL3R5cGVzJ1xuaW1wb3J0IGNvbXBpbGVSZXBsYWNlbWVudCBmcm9tICcuLi9jb21waWxlUmVwbGFjZW1lbnQnXG5pbXBvcnQgY29udmVydFRvRXhwcmVzc2lvbiBmcm9tICcuLi9jb252ZXJ0UmVwbGFjZW1lbnQvY29udmVydFRvRXhwcmVzc2lvbidcbmltcG9ydCBjb252ZXJ0U3RhdGVtZW50UmVwbGFjZW1lbnQgZnJvbSAnLi4vY29udmVydFJlcGxhY2VtZW50L2NvbnZlcnRTdGF0ZW1lbnRSZXBsYWNlbWVudCdcbmltcG9ydCBlbnN1cmVBcnJheSBmcm9tICcuLi91dGlsL2Vuc3VyZUFycmF5J1xuaW1wb3J0IEFzdHggZnJvbSAnLi4vQXN0eCdcbmltcG9ydCBDb2RlRnJhbWVFcnJvciBmcm9tICcuLi91dGlsL0NvZGVGcmFtZUVycm9yJ1xuaW1wb3J0IHsgZ2V0QXJyYXlQbGFjZWhvbGRlciB9IGZyb20gJy4uL2NvbXBpbGVNYXRjaGVyL1BsYWNlaG9sZGVyJ1xuXG5mdW5jdGlvbiBjb252ZXJ0UXVhc2lzKG5vZGVzOiBhbnlbXSk6IHtcbiAgY2FwdHVyZXM6IFJlY29yZDxzdHJpbmcsIE5vZGU+XG4gIGFycmF5Q2FwdHVyZXM6IFJlY29yZDxzdHJpbmcsIE5vZGVbXT5cbiAgdmFyTmFtZXM6IHN0cmluZ1tdXG59IHtcbiAgY29uc3QgY2FwdHVyZXM6IFJlY29yZDxzdHJpbmcsIE5vZGU+ID0ge31cbiAgY29uc3QgYXJyYXlDYXB0dXJlczogUmVjb3JkPHN0cmluZywgTm9kZVtdPiA9IHt9XG4gIGNvbnN0IHZhck5hbWVzOiBzdHJpbmdbXSA9IFtdXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgcmVwbGFjZW1lbnQ6IHN0cmluZyB8IE5vZGUgfCBOb2RlW10gfCB1bmRlZmluZWRcbiAgICBpZiAodHlwZW9mIG5vZGVzW2ldID09PSAnc3RyaW5nJykge1xuICAgICAgcmVwbGFjZW1lbnQgPSBub2Rlc1tpXVxuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShub2Rlc1tpXSkpIHtcbiAgICAgIHJlcGxhY2VtZW50ID0gbm9kZXNbaV1cbiAgICAgICAgLm1hcCgobjogYW55KSA9PiAobiBpbnN0YW5jZW9mIEFzdHggPyBuLm5vZGVzIDogbikpXG4gICAgICAgIC5mbGF0KClcbiAgICB9IGVsc2UgaWYgKG5vZGVzW2ldIGluc3RhbmNlb2YgQXN0eCkge1xuICAgICAgY29uc3QgYXN0eCA9IG5vZGVzW2ldXG4gICAgICBpZiAoXG4gICAgICAgIGFzdHguc2l6ZSA+IDEgfHxcbiAgICAgICAgKGFzdHgucGxhY2Vob2xkZXIgJiYgZ2V0QXJyYXlQbGFjZWhvbGRlcihhc3R4LnBsYWNlaG9sZGVyKSlcbiAgICAgICkge1xuICAgICAgICByZXBsYWNlbWVudCA9IGFzdHgubm9kZXNcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcGxhY2VtZW50ID0gYXN0eC5ub2Rlc1swXVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZXNbaV0pIHtcbiAgICAgIHJlcGxhY2VtZW50ID0gbm9kZXNbaV1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlcGxhY2VtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgdmFyTmFtZXMucHVzaChyZXBsYWNlbWVudClcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocmVwbGFjZW1lbnQpKSB7XG4gICAgICBjb25zdCBuYW1lID0gYCQkdHBsX19fJHtpfWBcbiAgICAgIGFycmF5Q2FwdHVyZXNbbmFtZV0gPSByZXBsYWNlbWVudFxuICAgICAgdmFyTmFtZXMucHVzaChuYW1lKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBuYW1lID0gYCR0cGxfX18ke2l9YFxuICAgICAgaWYgKHJlcGxhY2VtZW50KSBjYXB0dXJlc1tuYW1lXSA9IHJlcGxhY2VtZW50XG4gICAgICB2YXJOYW1lcy5wdXNoKG5hbWUpXG4gICAgfVxuICB9XG4gIHJldHVybiB7IGNhcHR1cmVzLCBhcnJheUNhcHR1cmVzLCB2YXJOYW1lcyB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdGF0ZW1lbnRzKFxuICB0aGlzOiBCYWNrZW5kLFxuICBjb2RlOiBUZW1wbGF0ZVN0cmluZ3NBcnJheSB8IHN0cmluZ1tdIHwgc3RyaW5nLFxuICAuLi5ub2RlczogYW55W11cbik6IFN0YXRlbWVudFtdIHtcbiAgY29uc3QgeyBjYXB0dXJlcywgYXJyYXlDYXB0dXJlcywgdmFyTmFtZXMgfSA9IGNvbnZlcnRRdWFzaXMobm9kZXMpXG5cbiAgY29uc3Qgc3JjID0gKFsuLi5lbnN1cmVBcnJheShjb2RlKV0gYXMgc3RyaW5nW10pLnJlZHVjZShcbiAgICAocmVzdWx0OiBzdHJpbmcsIGVsZW06IHN0cmluZywgaTogbnVtYmVyKSA9PiByZXN1bHQgKyB2YXJOYW1lc1tpIC0gMV0gKyBlbGVtXG4gIClcbiAgdHJ5IHtcbiAgICBpZiAoIW5vZGVzLmxlbmd0aCB8fCBub2Rlcy5ldmVyeSgobikgPT4gdHlwZW9mIG4gPT09ICdzdHJpbmcnKSlcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlU3RhdGVtZW50cyhzcmMpXG4gICAgY29uc3QgcmVzdWx0ID0gY29tcGlsZVJlcGxhY2VtZW50KFxuICAgICAgdGhpcy5wYXJzZVN0YXRlbWVudHMoc3JjKS5tYXAoKG4pID0+IG5ldyB0aGlzLnQuTm9kZVBhdGgobikpLFxuICAgICAge1xuICAgICAgICBiYWNrZW5kOiB0aGlzLFxuICAgICAgfVxuICAgICkuZ2VuZXJhdGUoeyBjYXB0dXJlcywgYXJyYXlDYXB0dXJlcyB9KVxuICAgIHJldHVybiBlbnN1cmVBcnJheShyZXN1bHQpLm1hcChjb252ZXJ0U3RhdGVtZW50UmVwbGFjZW1lbnQpIGFzIFN0YXRlbWVudFtdXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIENvZGVGcmFtZUVycm9yLnJldGhyb3coZXJyb3IsIHsgZmlsZW5hbWU6ICdzdGF0ZW1lbnRzJywgc291cmNlOiBzcmMgfSlcbiAgICB9XG4gICAgdGhyb3cgZXJyb3JcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RhdGVtZW50KFxuICB0aGlzOiBCYWNrZW5kLFxuICB0ZW1wbGF0ZTogVGVtcGxhdGVTdHJpbmdzQXJyYXkgfCBzdHJpbmdbXSB8IHN0cmluZyxcbiAgLi4ubm9kZXM6IGFueVtdXG4pOiBTdGF0ZW1lbnQge1xuICBjb25zdCByZXN1bHQgPSB0aGlzLnRlbXBsYXRlLnN0YXRlbWVudHModGVtcGxhdGUsIC4uLm5vZGVzKVxuICBpZiAocmVzdWx0Lmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgY29kZSBpcyBub3QgYSBzdGF0ZW1lbnRgKVxuICB9XG4gIHJldHVybiByZXN1bHRbMF1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cHJlc3Npb24oXG4gIHRoaXM6IEJhY2tlbmQsXG4gIGNvZGU6IFRlbXBsYXRlU3RyaW5nc0FycmF5IHwgc3RyaW5nW10gfCBzdHJpbmcsXG4gIC4uLm5vZGVzOiBhbnlbXVxuKTogRXhwcmVzc2lvbiB7XG4gIGNvbnN0IHsgY2FwdHVyZXMsIGFycmF5Q2FwdHVyZXMsIHZhck5hbWVzIH0gPSBjb252ZXJ0UXVhc2lzKG5vZGVzKVxuXG4gIGNvbnN0IHNyYyA9IChbLi4uZW5zdXJlQXJyYXkoY29kZSldIGFzIHN0cmluZ1tdKS5yZWR1Y2UoXG4gICAgKHJlc3VsdDogc3RyaW5nLCBlbGVtOiBzdHJpbmcsIGk6IG51bWJlcikgPT4gcmVzdWx0ICsgdmFyTmFtZXNbaSAtIDFdICsgZWxlbVxuICApXG4gIHRyeSB7XG4gICAgaWYgKCFub2Rlcy5sZW5ndGggfHwgbm9kZXMuZXZlcnkoKG4pID0+IHR5cGVvZiBuID09PSAnc3RyaW5nJykpXG4gICAgICByZXR1cm4gdGhpcy5wYXJzZUV4cHJlc3Npb24oc3JjKVxuICAgIGNvbnN0IHJlc3VsdCA9IGNvbXBpbGVSZXBsYWNlbWVudChcbiAgICAgIG5ldyB0aGlzLnQuTm9kZVBhdGgodGhpcy5wYXJzZUV4cHJlc3Npb24oc3JjKSksXG4gICAgICB7XG4gICAgICAgIGJhY2tlbmQ6IHRoaXMsXG4gICAgICB9XG4gICAgKS5nZW5lcmF0ZSh7IGNhcHR1cmVzLCBhcnJheUNhcHR1cmVzIH0pXG4gICAgbGV0IGV4cHJlc3Npb25cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICBpZiAocmVzdWx0Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNvZGUgaXMgbm90IGFuIGV4cHJlc3Npb246ICR7c3JjfWApXG4gICAgICB9XG4gICAgICBleHByZXNzaW9uID0gY29udmVydFRvRXhwcmVzc2lvbihyZXN1bHRbMF0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cHJlc3Npb24gPSBjb252ZXJ0VG9FeHByZXNzaW9uKHJlc3VsdClcbiAgICB9XG4gICAgaWYgKCFleHByZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNvZGUgaXMgbm90IGFuIGV4cHJlc3Npb246ICR7c3JjfWApXG4gICAgfVxuICAgIHJldHVybiBleHByZXNzaW9uXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIENvZGVGcmFtZUVycm9yLnJldGhyb3coZXJyb3IsIHsgZmlsZW5hbWU6ICdleHByZXNzaW9uJywgc291cmNlOiBzcmMgfSlcbiAgICB9XG4gICAgdGhyb3cgZXJyb3JcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQSxPQUFPQSxrQkFBUCxNQUErQix1QkFBL0I7QUFDQSxPQUFPQyxtQkFBUCxNQUFnQywyQ0FBaEM7QUFDQSxPQUFPQywyQkFBUCxNQUF3QyxtREFBeEM7QUFDQSxPQUFPQyxXQUFQLE1BQXdCLHFCQUF4QjtBQUNBLE9BQU9DLElBQVAsTUFBaUIsU0FBakI7QUFDQSxPQUFPQyxjQUFQLE1BQTJCLHdCQUEzQjtBQUNBLFNBQVNDLG1CQUFULFFBQW9DLCtCQUFwQzs7QUFFQSxTQUFTQyxhQUFULENBQXVCQyxLQUF2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