astx
Version:
super powerful structural search and replace for JavaScript and TypeScript to automate your refactoring
342 lines (304 loc) • 8.77 kB
JavaScript
var _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault')
Object.defineProperty(exports, '__esModule', {
value: true,
})
exports['default'] = compileGenericNodeMatcher
var _defineProperty2 = _interopRequireDefault(
require('@babel/runtime/helpers/defineProperty')
)
var _toConsumableArray2 = _interopRequireDefault(
require('@babel/runtime/helpers/toConsumableArray')
)
var _index = _interopRequireDefault(require('./index'))
var _indentDebug = _interopRequireDefault(require('./indentDebug'))
var _areFieldValuesEqual = _interopRequireDefault(
require('../util/areFieldValuesEqual')
)
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object)
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object)
enumerableOnly &&
(symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable
})),
keys.push.apply(keys, symbols)
}
return keys
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {}
i % 2
? ownKeys(Object(source), !0).forEach(function (key) {
;(0, _defineProperty2['default'])(target, key, source[key])
})
: Object.getOwnPropertyDescriptors
? Object.defineProperties(
target,
Object.getOwnPropertyDescriptors(source)
)
: ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(
target,
key,
Object.getOwnPropertyDescriptor(source, key)
)
})
}
return target
}
function _createForOfIteratorHelper(o, allowArrayLike) {
var it =
(typeof Symbol !== 'undefined' && o[Symbol.iterator]) || o['@@iterator']
if (!it) {
if (
Array.isArray(o) ||
(it = _unsupportedIterableToArray(o)) ||
(allowArrayLike && o && typeof o.length === 'number')
) {
if (it) o = it
var i = 0
var F = function F() {}
return {
s: F,
n: function n() {
if (i >= o.length)
return {
done: true,
}
return {
done: false,
value: o[i++],
}
},
e: function e(_e) {
throw _e
},
f: F,
}
}
throw new TypeError(
'Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'
)
}
var normalCompletion = true,
didErr = false,
err
return {
s: function s() {
it = it.call(o)
},
n: function n() {
var step = it.next()
normalCompletion = step.done
return step
},
e: function e(_e2) {
didErr = true
err = _e2
},
f: function f() {
try {
if (!normalCompletion && it['return'] != null) it['return']()
} finally {
if (didErr) throw err
}
},
}
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return
if (typeof o === 'string') return _arrayLikeToArray(o, minLen)
var n = Object.prototype.toString.call(o).slice(8, -1)
if (n === 'Object' && o.constructor) n = o.constructor.name
if (n === 'Map' || n === 'Set') return Array.from(o)
if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
return _arrayLikeToArray(o, minLen)
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length
for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i]
}
return arr2
}
var equivalenceClassesArray = [
{
nodeTypes: new Set(['ClassDeclaration', 'ClassExpression']),
},
{
nodeTypes: new Set([
'FunctionDeclaration',
'FunctionExpression',
'ArrowFunctionExpression',
'ObjectMethod',
'ClassMethod',
'ClassPrivateMethod',
]),
baseType: 'Function',
},
{
nodeTypes: new Set(['Identifier', 'JSXIdentifier']),
},
]
var equivalenceClasses = {}
for (
var _i = 0, _equivalenceClassesAr = equivalenceClassesArray;
_i < _equivalenceClassesAr.length;
_i++
) {
var klass = _equivalenceClassesAr[_i]
var _iterator = _createForOfIteratorHelper(klass.nodeTypes),
_step
try {
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
var type = _step.value
equivalenceClasses[type] = klass
}
} catch (err) {
_iterator.e(err)
} finally {
_iterator.f()
}
}
var normalizeNull = function normalizeNull(value) {
return value === undefined ? null : value
}
function compileGenericNodeMatcher(path, compileOptions, options) {
var t = compileOptions.backend.t
var pattern = path.node
var _ref = equivalenceClasses[pattern.type] || {},
baseType = _ref.baseType,
nodeTypes = _ref.nodeTypes
var nodeType =
baseType ||
(nodeTypes ? (0, _toConsumableArray2['default'])(nodeTypes) : null) ||
pattern.type
var isType = baseType
? function (node) {
var _baseType
return (_baseType = t.namedTypes[baseType]) === null ||
_baseType === void 0
? void 0
: _baseType.check(node)
}
: null
var isCorrectType = isType
? function (node) {
return isType(node)
}
: nodeTypes
? function (node) {
return nodeTypes.has(
node === null || node === void 0 ? void 0 : node.type
)
}
: function (node) {
return (
(node === null || node === void 0 ? void 0 : node.type) ===
pattern.type
)
}
var debug = compileOptions.debug
var keyMatchers = Object.fromEntries(
t.getFieldNames(pattern).map(function (key) {
var _options$keyMatchers
var custom =
options === null || options === void 0
? void 0
: (_options$keyMatchers = options.keyMatchers) === null ||
_options$keyMatchers === void 0
? void 0
: _options$keyMatchers[key]
if (custom) return [key, custom]
var value = normalizeNull(t.getFieldValue(pattern, key))
var fieldPath = path.get(key)
if (Array.isArray(value) || fieldPath.node === value) {
return [
key,
(0, _index['default'])(
fieldPath,
_objectSpread(
_objectSpread({}, compileOptions),
{},
{
debug: (0, _indentDebug['default'])(debug, 2),
}
)
),
]
} else if (value instanceof Object) {
return [
key,
{
pattern: fieldPath,
match: function match(path, matchSoFar) {
var nodeValue = normalizeNull(path.value)
if ((0, _areFieldValuesEqual['default'])(t, value, nodeValue)) {
debug(' %s === %s', value, nodeValue)
return matchSoFar || {}
} else {
debug(' %s !== %s', value, nodeValue)
return null
}
},
},
]
} else {
return [
key,
{
pattern: fieldPath,
match: function match(path, matchSoFar) {
var nodeValue = normalizeNull(path.value)
if (
value === nodeValue ||
(value === null && nodeValue === false) ||
(value === false && nodeValue === null)
) {
debug(' %s === %s', value, nodeValue)
return matchSoFar || {}
} else {
debug(' %s !== %s', value, nodeValue)
return null
}
},
},
]
}
})
)
return {
pattern: path,
match: function match(path, matchSoFar) {
debug('%s (generic)', pattern.type)
if (Array.isArray(path.value)) return null
if (
isCorrectType(path === null || path === void 0 ? void 0 : path.value)
) {
for (var key in keyMatchers) {
debug(' .%s', key)
var matcher = keyMatchers[key]
matchSoFar = matcher.match(path.get(key), matchSoFar)
if (!matchSoFar) return null
}
return matchSoFar || {}
} else {
var _path$value
debug(
' path?.value?.type (%s) is not compatible with pattern.type (%s)',
path === null || path === void 0
? void 0
: (_path$value = path.value) === null || _path$value === void 0
? void 0
: _path$value.type,
pattern.type
)
return null
}
},
nodeType: nodeType,
}
}