UNPKG

slightning-coco-widget

Version:

SLIGHTNING 的 CoCo 控件框架。

305 lines (304 loc) 10.7 kB
import { merge } from "../../utils"; import { FunctionType, MutatorType } from "../type"; import { BlockType, BUILD_IN_ICON_URL_MAP } from "../types"; export function traverseTypes(types, visitors) { if (hasVisitor(visitors.PropertyGroup) || hasVisitor(visitors.PropertyTypes)) { for (const index = { value: 0 }; index.value <= types.properties.length; index.value++) { const property = types.properties[index.value]; if (property == undefined) { continue; } if ("contents" in property) { new PropertyGroupNode({ groupContents: types.properties, index, value: property }).traverse(visitors); continue; } new PropertyTypesNode({ groupContents: types.properties, index, value: property }).traverse(visitors); } } if (hasVisitor(visitors.MethodGroup) || hasVisitor(visitors.MethodTypes) || hasVisitor(visitors.EventTypes) || hasVisitor(visitors.BlockBoxOptions)) { for (const index = { value: 0 }; index.value <= types.methods.length; index.value++) { const method = types.methods[index.value]; if (method == undefined) { continue; } if ("contents" in method) { new MethodGroupNode({ groupContents: types.methods, index, value: method }).traverse(visitors); continue; } if ("type" in method) { switch (method.type) { case BlockType.METHOD: new MethodTypesNode({ groupContents: types.methods, index, value: method }).traverse(visitors); break; case BlockType.EVENT: new EventTypesNode({ groupContents: types.methods, index, value: method }).traverse(visitors); break; } } else { new BlockBoxOptionsNode({ groupContents: types.methods, index, value: method }).traverse(visitors); } } } } export class TypesNode { /** * 节点的积木选项。与`this.value.blockOptions`不同的是,该项包含从组中继承的积木选项。 */ get blockOptions() { var _a, _b, _c; if (this.__blockOptions !== undefined) { return this.__blockOptions; } const { value } = this; return this.__blockOptions = merge({}, (_b = ((_a = this.group) !== null && _a !== void 0 ? _a : {}).blockOptions) !== null && _b !== void 0 ? _b : {}, value != null && typeof value == "object" && "blockOptions" in value ? (_c = value.blockOptions) !== null && _c !== void 0 ? _c : {} : {}); } constructor({ group, groupContents, index, value }) { this.group = group; this.groupContents = groupContents; this.index = index; this.value = value; this.isRemoved = false; } remove() { if (this.isRemoved) { return; } this.groupContents.splice(this.index.value, 1); this.index.value--; this.isRemoved = true; } removeNext() { this.groupContents.splice(this.index.value + 1, 1); } replaceWith(...values) { this.remove(); this.insertAfter(...values); } insertAfter(...values) { this.groupContents.splice(this.index.value + 1, 0, ...values); } } export class PropertyGroupNode extends TypesNode { traverse(visitors) { if (!(hasVisitor(visitors.PropertyGroup) || hasVisitor(visitors.PropertyTypes))) { return; } enterNode(this, visitors.PropertyGroup); for (const index = { value: 0 }; index.value <= this.value.contents.length; index.value++) { const property = this.value.contents[index.value]; if (property == undefined) { continue; } if ("contents" in property) { new PropertyGroupNode({ group: this, groupContents: this.value.contents, index, value: property }).traverse(visitors); continue; } new PropertyTypesNode({ group: this, groupContents: this.value.contents, index, value: property }).traverse(visitors); } exitNode(this, visitors.PropertyGroup); } } export class PropertyTypesNode extends TypesNode { traverse(visitors) { enterNode(this, visitors.PropertyTypes); exitNode(this, visitors.PropertyTypes); } } export class MethodGroupNode extends TypesNode { traverse(visitors) { if (!(hasVisitor(visitors.MethodGroup) || hasVisitor(visitors.MethodTypes) || hasVisitor(visitors.EventTypes) || hasVisitor(visitors.BlockBoxOptions))) { return; } enterNode(this, visitors.MethodGroup); for (const index = { value: 0 }; index.value <= this.value.contents.length; index.value++) { const method = this.value.contents[index.value]; if (method == undefined) { continue; } if ("contents" in method) { new MethodGroupNode({ group: this, groupContents: this.value.contents, index, value: method }).traverse(visitors); continue; } if ("type" in method) { switch (method.type) { case BlockType.METHOD: new MethodTypesNode({ group: this, groupContents: this.value.contents, index, value: method }).traverse(visitors); break; case BlockType.EVENT: new EventTypesNode({ group: this, groupContents: this.value.contents, index, value: method }).traverse(visitors); break; } } else { new BlockBoxOptionsNode({ group: this, groupContents: this.value.contents, index, value: method }).traverse(visitors); } } exitNode(this, visitors.MethodGroup); } } export class MethodTypesNode extends TypesNode { traverse(visitors) { enterNode(this, visitors.MethodTypes); exitNode(this, visitors.MethodTypes); } } export class EventTypesNode extends TypesNode { traverse(visitors) { enterNode(this, visitors.EventTypes); exitNode(this, visitors.EventTypes); } } export class BlockBoxOptionsNode extends TypesNode { traverse(visitors) { enterNode(this, visitors.BlockBoxOptions); exitNode(this, visitors.BlockBoxOptions); } } function hasVisitor(visitor) { return getVisitorCache(visitor, "has", () => (hasEnter(visitor) || hasExit(visitor))); } function hasEnter(visitor) { return getVisitorCache(visitor, "hasEnter", () => (visitor != null && (typeof visitor == "function" || visitor.enter != null || visitor.entry != null))); } function hasExit(visitor) { return getVisitorCache(visitor, "hasExit", () => (visitor != null && typeof visitor != "function" && visitor.exit != null)); } function NULL_TYPES_NODE_VISITOR_FUNCTION() { } function enterNode(node, visitor) { getVisitorCache(visitor, "enter", () => { if (visitor == null) { return NULL_TYPES_NODE_VISITOR_FUNCTION; } if (typeof visitor == "function") { return visitor; } else if (visitor.enter != null) { return visitor.enter; } else if (visitor.entry != null) { return visitor.entry; } return NULL_TYPES_NODE_VISITOR_FUNCTION; })(node); } function exitNode(node, visitor) { getVisitorCache(visitor, "exit", () => { if (visitor != null && typeof visitor == "object" && visitor.exit != null) { return visitor.exit; } return NULL_TYPES_NODE_VISITOR_FUNCTION; })(node); } const NULL_TYPES_NODE_VISITOR_CACHE = { has: false, hasEnter: false, hasExit: false }; function getVisitorCache(visitor, property, loader) { let visitorCache; if (visitor == null) { visitorCache = NULL_TYPES_NODE_VISITOR_CACHE; } else { if (visitor.__slightning_coco_widget_visitor_cache__ == null) { visitor.__slightning_coco_widget_visitor_cache__ = {}; } visitorCache = visitor.__slightning_coco_widget_visitor_cache__; } const value = visitorCache[property]; if (value == null) { return visitorCache[property] = loader(); } return value; } export function methodParamNeedsTransformToEvent(part) { if (typeof part != "object") { return false; } return part.type instanceof FunctionType && !part.type.raw; } export function methodParamNeedsTransformToCodeBlocks(part) { if (typeof part != "object") { return false; } return part.type instanceof FunctionType && !part.type.raw && ((part.type.returns != null && !(part.type.returns.isVoid())) || (part.type.throws != null && !(part.type.throws.isVoid()))); } export function methodParamTypeIsMutator(part) { if (typeof part != "object") { return false; } return part.type instanceof MutatorType; } export function transformIcon(object) { var _a; if (object != null && object.icon != null) { object.icon = (_a = BUILD_IN_ICON_URL_MAP[object.icon]) !== null && _a !== void 0 ? _a : object.icon; } }