@visactor/vgrammar-core
Version:
VGrammar is a visual grammar library
121 lines (115 loc) • 4.75 kB
JavaScript
import { array, EventEmitter, isNil, isString, isValid } from "@visactor/vutils";
import { parseOptions } from "../parse/option";
import { parseFunctionType } from "../parse/util";
import { HOOK_EVENT } from "../graph/enums";
let grammarBaseId = -1;
export class GrammarBase extends EventEmitter {
constructor(view) {
super(), this.spec = {}, this.references = new Map, this.targets = [], this.transforms = [],
this.view = view, this.uid = ++grammarBaseId;
}
parse(spec) {
return this.id(spec.id), this.name(spec.name), this.depend(spec.dependency), this;
}
depend(grammars) {
var _a;
if (null === (_a = this.spec) || void 0 === _a ? void 0 : _a.dependency) {
const lastGrammars = array(this.spec.dependency).map((grammar => isString(grammar) ? this.view.getGrammarById(grammar) : grammar));
this.detach(lastGrammars);
}
this.spec.dependency = grammars;
const currentGrammars = array(grammars).map((grammar => isString(grammar) ? this.view.getGrammarById(grammar) : grammar));
return this.attach(currentGrammars), this.commit(), this;
}
addEventListener(type, handler, options) {
let callback = handler;
return options && !1 === options.trap || (callback = handler, callback.raw = handler),
options && options.target && (callback.target = options.target), this.on(type, callback),
this;
}
removeEventListener(type, handler) {
return handler ? this.off(type, handler) : this.off(type), this;
}
emit(event, ...args) {
var _a, _b;
return null === (_b = null === (_a = this.view) || void 0 === _a ? void 0 : _a.emit) || void 0 === _b || _b.call(_a, event, ...args),
super.emit(event, ...args);
}
emitGrammarEvent(event, ...args) {
return super.emit(event, ...args);
}
evaluateTransform(transforms, upstream, parameters) {
if (!transforms || !transforms.length) return upstream;
let currentUpstreamData = upstream, i = 0;
const n = transforms.length;
for (;i < n; ) {
const task = transforms[i];
this.emit(HOOK_EVENT.BEFORE_TRANSFORM, task.type), currentUpstreamData = task.transform(task.isRawOptions ? task.options : parseOptions(task.options, parameters), currentUpstreamData, parameters, this.view),
i++, this.emit(HOOK_EVENT.AFTER_TRANSFORM, task.type);
}
return currentUpstreamData;
}
set(value) {
return !1;
}
id(id) {
return arguments.length ? (this.view.grammars.unrecord(this), this._id = id, this.view.grammars.record(this),
this) : this._id;
}
name(name) {
return arguments.length ? (this._name = name, this) : this._name;
}
attach(reference, count = 1) {
return array(reference).filter((ref => !isNil(ref))).forEach((ref => {
var _a;
isNil(reference) || (ref.targets.includes(this) || ref.targets.push(this), this.references.set(ref, (null !== (_a = this.references.get(ref)) && void 0 !== _a ? _a : 0) + count));
})), this;
}
detach(reference, count = 1) {
return array(reference).filter((ref => !isNil(ref))).forEach((ref => {
const refCount = this.references.get(ref) - count;
refCount > 0 ? this.references.set(ref, refCount - 1) : (this.references.delete(ref),
ref.targets.includes(this) && (ref.targets = ref.targets.filter((target => target !== this))));
})), this;
}
detachAll() {
this.references.forEach(((count, ref) => {
this.detach(ref, count);
}));
}
link(source) {
this.grammarSource = source;
}
run() {
var _a;
const upstream = null === (_a = this.grammarSource) || void 0 === _a ? void 0 : _a.output(), parameters = this.parameters();
return this.evaluate(upstream, parameters);
}
commit() {
this.view.commit(this);
}
parameters() {
const params = {};
return this.references.forEach(((count, ref) => {
isValid(ref.id()) && (params[ref.id()] = ref.output());
})), params;
}
getSpec() {
return this.spec;
}
reuse(grammar) {
return this;
}
clear() {
this.spec = null, this.view = null;
}
release() {
this.clear();
}
setFunctionSpec(spec, specField) {
return isNil(this.spec[specField]) || this.detach(parseFunctionType(this.spec[specField], this.view)),
this.spec[specField] = spec, this.attach(parseFunctionType(spec, this.view)), this.commit(),
this;
}
}
//# sourceMappingURL=grammar-base.js.map