slightning-coco-widget
Version:
SLIGHTNING 的 CoCo 控件框架。
76 lines (75 loc) • 3.67 kB
JavaScript
import { methodParamTypeIsMutator, traverseTypes } from "./utils";
export function addTransformMutator(types, widget) {
traverseTypes(types, {
MethodTypes(node) {
if (!node.value.block.some(methodParamTypeIsMutator)) {
return;
}
const { value: method } = node;
let methodParamsCount = 0;
for (let i = 0; i < method.block.length; i++) {
const item = method.block[i];
if (item == undefined) {
continue;
}
if (!methodParamTypeIsMutator(item)) {
if (typeof item == "object") {
methodParamsCount++;
}
continue;
}
let mutatorParamsCount = 0;
for (const mutator of item.type.block) {
if (typeof mutator == "object") {
mutatorParamsCount++;
}
}
const { transformMin, transformMax } = item.type;
for (let j = transformMax; j >= transformMin; j--) {
const key = `__slightning_coco_widget_transform_mutator_${item.key}_${j}__${method.key}`;
const transformedMethod = Object.assign(Object.assign({}, method), { key, block: [...method.block] });
const transformedBlockItems = [];
let isFirst = true;
for (let k = 0; k < j; k++) {
if (isFirst) {
isFirst = false;
}
else {
transformedBlockItems.push(...item.type.separators);
}
transformedBlockItems.push(...item.type.block.map((mutatorItem) => {
if (typeof mutatorItem == "string") {
return mutatorItem;
}
return Object.assign(Object.assign({}, mutatorItem), { key: `__slightning_coco_widget_mutator_param_${item.key}_${k}_item__${mutatorItem.key}` });
}));
}
transformedMethod.block.splice(i, 1, ...transformedBlockItems);
node.insertAfter({ space: 8 }, transformedMethod);
Object.defineProperty(widget.prototype, key, {
value: function (...args) {
const mutatorArgs = args.splice(methodParamsCount, j * mutatorParamsCount);
const transformedMutatorArgs = [];
while (mutatorArgs.length > 0) {
const transformedMutatorArg = {};
for (const mutator of item.type.block) {
if (typeof mutator == "object") {
transformedMutatorArg[mutator.key] = mutatorArgs.shift();
}
}
transformedMutatorArgs.push(transformedMutatorArg);
}
args.splice(methodParamsCount, 0, transformedMutatorArgs);
return this[method.key](...args);
},
writable: true,
enumerable: false,
configurable: true
});
}
break;
}
}
});
return [types, widget];
}