slightning-coco-widget
Version:
SLIGHTNING 的 CoCo 控件框架。
265 lines (264 loc) • 13.3 kB
JavaScript
import { traverseTypes } from "../decorators";
import { IntegerType, MutatorType, NumberType } from "../type";
import { Color, MethodBlockParam } from "../types";
export function convertToCreationProject2(types, widget) {
return [typesToCreationProject2(types), widget];
}
export function typesToCreationProject2(types) {
var _a;
const defaultPropertiesValues = {};
const result = {
type: types.type,
label: types.info.title,
icon: types.info.icon,
category: (_a = types.info.category) !== null && _a !== void 0 ? _a : undefined,
visibleWidget: types.options.visible,
global: types.options.global,
default: defaultPropertiesValues,
props: [],
methods: [],
emits: []
};
const labels = [];
let showLine = false;
let addSpace = false;
traverseTypes(types, {
PropertyGroup: {
enter(node) {
if (node.value.label != null) {
labels.push(node.value.label);
showLine = true;
}
addSpace = true;
},
exit(node) {
if (node.value.label != null) {
labels.pop();
showLine = true;
}
addSpace = true;
}
},
PropertyTypes(node) {
var _a, _b, _c, _d, _e, _f, _g;
var _h, _j;
const { value: property } = node;
if (property.key == "__width" && (property.type instanceof IntegerType || property.type instanceof NumberType)) {
defaultPropertiesValues.width = property.type.defaultValue;
}
else if (property.key == "__height" && (property.type instanceof IntegerType || property.type instanceof NumberType)) {
defaultPropertiesValues.height = property.type.defaultValue;
}
else {
const getterBlockOption = node.blockOptions.get != null && typeof node.blockOptions.get == "object" ? node.blockOptions.get : {};
const setterBlockOption = node.blockOptions.get != null && typeof node.blockOptions.get == "object" ? node.blockOptions.get : {};
const transformed = Object.assign(Object.assign({ key: property.key, label: property.label }, property.type.toCreationProject2PropValueTypes()), { blockOptions: {
getter: {
generateBlock: node.blockOptions.get != false,
color: (_a = getterBlockOption.color) !== null && _a !== void 0 ? _a : Color.PINK,
inputsInline: (_b = getterBlockOption.inline) !== null && _b !== void 0 ? _b : undefined,
line: typeof showLine == "string" ? showLine : showLine ? labels.join("·") : undefined,
},
setter: {
generateBlock: node.blockOptions.set != false,
color: (_c = setterBlockOption.color) !== null && _c !== void 0 ? _c : Color.PINK,
inputsInline: (_d = setterBlockOption.inline) !== null && _d !== void 0 ? _d : undefined,
line: typeof showLine == "string" ? showLine : showLine ? labels.join("·") : undefined
}
} });
if (addSpace != false) {
(_e = transformed.blockOptions) !== null && _e !== void 0 ? _e : (transformed.blockOptions = {});
(_f = (_h = transformed.blockOptions).getter) !== null && _f !== void 0 ? _f : (_h.getter = {});
(_g = (_j = transformed.blockOptions).setter) !== null && _g !== void 0 ? _g : (_j.setter = {});
transformed.blockOptions.getter.gap = typeof addSpace == "number" ? addSpace : 40;
transformed.blockOptions.setter.gap = typeof addSpace == "number" ? addSpace : 40;
addSpace = false;
}
showLine = false;
result.props.push(transformed);
}
},
MethodGroup: {
enter(node) {
if (node.value.label != null) {
labels.push(node.value.label);
showLine = true;
}
addSpace = true;
},
exit(node) {
if (node.value.label != null) {
labels.pop();
showLine = true;
}
addSpace = true;
}
},
MethodTypes(node) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
const { value: method } = node;
if (method.throws != null && !(method.throws.isVoid())) {
throw new Error(`无法将方法 ${method.label} 的抛出类型转为 Creation Project 类型`);
}
const deprecated = (_b = (_a = method.deprecated) !== null && _a !== void 0 ? _a : node.blockOptions.deprecated) !== null && _b !== void 0 ? _b : false;
const transformed = Object.assign(Object.assign({ key: method.key, params: [] }, (_c = method.returns) === null || _c === void 0 ? void 0 : _c.toCreationProject2MethodValueTypes()), { blockOptions: {
previousStatement: (_d = node.blockOptions.previousStatement) !== null && _d !== void 0 ? _d : undefined,
nextStatement: (_e = node.blockOptions.nextStatement) !== null && _e !== void 0 ? _e : undefined,
prefix: "",
suffix: "",
tooltip: (_f = method.tooltip) !== null && _f !== void 0 ? _f : undefined,
color: deprecated ? Color.GREY : (_g = node.blockOptions.color) !== null && _g !== void 0 ? _g : undefined,
line: typeof showLine == "string" ? showLine : showLine ? labels.join("·") : undefined
} });
(_h = transformed.blockOptions) !== null && _h !== void 0 ? _h : (transformed.blockOptions = {});
if (typeof deprecated == "string") {
if (transformed.blockOptions.tooltip == null) {
transformed.blockOptions.tooltip = `${deprecated}`;
}
else {
transformed.blockOptions.tooltip = `${deprecated}\n\n${transformed.blockOptions.tooltip}`;
}
}
else if (deprecated) {
if (transformed.blockOptions.tooltip == null) {
transformed.blockOptions.tooltip = `该方法已弃用,并且可能在未来版本中移除,请尽快迁移到其他方法`;
}
else {
transformed.blockOptions.tooltip = `该方法已弃用,并且可能在未来版本中移除,请尽快迁移到其他方法\n\n${transformed.blockOptions.tooltip}`;
}
}
const inline = (_j = node.blockOptions.inline) !== null && _j !== void 0 ? _j : true;
if (inline || method.block.includes(MethodBlockParam.BREAK_LINE)) {
let lastParam = null;
let labelsAfterLastParam = [];
function addText(text) {
if (lastParam == null) {
labelsAfterLastParam.unshift(text);
}
else {
if (lastParam.label == null) {
lastParam.label = text;
}
else if (text.endsWith("\n") ||
lastParam.label.startsWith("\n")) {
lastParam.label = text + lastParam.label;
}
else {
lastParam.label = text + " " + lastParam.label;
}
}
}
let i = method.block.length - 1;
for (; i >= 0; i--) {
const part = method.block[i];
if (part == undefined) {
continue;
}
if (part == MethodBlockParam.THIS) {
break;
}
else if (part == MethodBlockParam.METHOD) {
addText(method.label);
}
else if (part == MethodBlockParam.BREAK_LINE) {
addText(inline ? "" : "\n");
}
else if (typeof part == "string") {
addText(part);
}
else {
lastParam = Object.assign({ key: part.key }, part.type.toCreationProject2MethodParamValueTypes());
if (labelsAfterLastParam.length > 0) {
lastParam.labelAfter = labelsAfterLastParam.join(" ");
labelsAfterLastParam = [];
}
transformed.params.unshift(lastParam);
}
}
if (method.block[i] != MethodBlockParam.THIS) {
throw new Error(`方法 ${method.label} 缺少 this 参数`);
}
if (labelsAfterLastParam.length > 0) {
transformed.label = labelsAfterLastParam.join(" ");
}
i--;
let labelsBeforeThis = [];
for (; i >= 0; i--) {
const part = method.block[i];
if (part == undefined) {
continue;
}
if (part == MethodBlockParam.THIS) {
throw new Error(`方法只能有一个 this 参数,而方法 ${method.label} 有多个 this 参数`);
}
else if (part == MethodBlockParam.METHOD) {
labelsBeforeThis.unshift(method.label);
}
else if (part == MethodBlockParam.BREAK_LINE) {
labelsBeforeThis.unshift(inline ? "" : "\n");
}
else if (typeof part == "string") {
labelsBeforeThis.unshift(part);
}
else {
throw new Error(`方法 ${method.label} 的积木 this 参数前存在他参数,不能将其转为 Creation Project 类型`);
}
}
if (deprecated != false) {
labelsBeforeThis.unshift("[已弃用]");
}
transformed.blockOptions.prefix = labelsBeforeThis.join(" ").replace(/( )?\n( )?/g, "\n");
}
else {
if (deprecated != false) {
transformed.blockOptions.prefix = "[已弃用]";
}
transformed.label = method.label;
for (const part of method.block) {
if (typeof part != "object") {
continue;
}
if (part.type instanceof MutatorType) {
const mutatorValueType = part.type.toCreationProject2MethodParamValueTypes();
for (const mutatorParam of (_k = mutatorValueType.mutator) !== null && _k !== void 0 ? _k : []) {
mutatorParam.label = `\n${(_l = mutatorParam.label) !== null && _l !== void 0 ? _l : ""}`;
}
transformed.params.push(Object.assign({ key: part.key }, mutatorValueType));
}
else {
transformed.params.push(Object.assign({ key: part.key, label: `\n${part.label}` }, part.type.toCreationProject2MethodParamValueTypes()));
}
}
}
if (addSpace != false) {
transformed.blockOptions.gap = typeof addSpace == "number" ? addSpace : 40;
addSpace = false;
}
showLine = false;
result.methods.push(transformed);
},
EventTypes(node) {
var _a, _b;
if (node.value.subTypes != null) {
throw new Error("无法将事件的子类型转为 Creation Project 类型");
}
const deprecated = (_b = (_a = node.value.deprecated) !== null && _a !== void 0 ? _a : node.blockOptions.deprecated) !== null && _b !== void 0 ? _b : false;
result.emits.push({
key: node.value.key,
label: deprecated != false ? `[已弃用] ${node.value.label}` : node.value.label,
params: node.value.params.map((param) => {
return Object.assign({ key: param.key, label: param.label }, param.type.toCreationProject2EmitParamValueTypes());
})
});
},
BlockBoxOptions(node) {
if (node.value.space != null) {
addSpace = node.value.space;
}
if (node.value.line != null) {
showLine = node.value.line;
}
}
});
return result;
}