gentyl
Version:
A Generator That You'll Love
144 lines (143 loc) • 5.99 kB
JavaScript
var Gentyl;
(function (Gentyl) {
(function (ASSOCMODE) {
ASSOCMODE[ASSOCMODE["INHERIT"] = 0] = "INHERIT";
ASSOCMODE[ASSOCMODE["SHARE"] = 1] = "SHARE";
ASSOCMODE[ASSOCMODE["TRACK"] = 2] = "TRACK";
})(Gentyl.ASSOCMODE || (Gentyl.ASSOCMODE = {}));
var ASSOCMODE = Gentyl.ASSOCMODE;
var ResolutionContext = (function () {
function ResolutionContext(host, hostContext, mode) {
this.host = host;
this.mode = mode;
Object.defineProperties(this, {
ownProperties: {
value: {},
writable: false,
enumerable: false,
configurable: false
},
propertyLayerMap: {
value: {},
writable: false,
enumerable: false,
configurable: false
},
closed: {
value: false,
writable: true,
enumerable: false,
configurable: false,
}
});
for (var k in hostContext) {
this.addOwnProperty(k, hostContext[k]);
}
}
ResolutionContext.prototype.prepare = function () {
var layers = this.parseMode(this.mode);
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
switch (layer.mode) {
case (ASSOCMODE.INHERIT): {
this.addInherentLayer(layer.source);
break;
}
default: {
this.addSourceLayer(layer);
break;
}
}
}
};
ResolutionContext.prototype.extract = function () {
return Gentyl.Util.deepCopy(this.ownProperties);
};
ResolutionContext.prototype.parseMode = function (modestr) {
var layers = [];
var splitexp = modestr.split(/\s/);
var validmode = /^[&|=]$/;
var validsource = /^[+_]|[a-zA-Z]+$/;
var validwhole = /^([&|=])([+_]|[a-zA-Z]+)$/;
var i = 0;
if (splitexp[0] === '!') {
this.closed = true;
i = 1;
}
if (splitexp[i] === '' || splitexp[i] == undefined) {
return layers;
}
for (; i < splitexp.length; i += 1) {
var layer = { mode: null, source: null };
var typeSourceKey = splitexp[i];
var match = typeSourceKey.match(validwhole);
if (!match) {
throw Error("Invalid source mode expression " + typeSourceKey + " must fit /^([&\|=])([\+_])$/ ");
}
var tKey = match[1];
var sKey = match[2];
layer.mode = { "&": ASSOCMODE.SHARE, "|": ASSOCMODE.INHERIT, "=": ASSOCMODE.TRACK }[tKey];
layer.source = (sKey == "+" ? this.host.getParent(1) : sKey == "_" ? this.host.getRoot() : this.host.getNominal(sKey)).ctx;
layers.push(layer);
}
return layers;
};
ResolutionContext.prototype.addOwnProperty = function (name, defaultValue) {
this.ownProperties[name] = defaultValue;
this.propertyLayerMap[name] = { source: this, mode: ASSOCMODE.SHARE };
Object.defineProperty(this, name, {
set: this.setItem.bind(this, name),
get: this.getItem.bind(this, name),
enumerable: true,
configurable: true
});
};
ResolutionContext.prototype.setItem = function (key, data) {
var layer = this.propertyLayerMap[key];
if (layer.mode == ASSOCMODE.TRACK) {
throw new Error("Unable to modify key whose source is tracking only");
}
else {
layer.source.ownProperties[key] = data;
}
};
ResolutionContext.prototype.getItem = function (key) {
var layer = this.propertyLayerMap[key];
var result = layer.source.ownProperties[key];
return result;
};
ResolutionContext.prototype.getItemSource = function (key) {
if (key in this.propertyLayerMap) {
return this.propertyLayerMap[key].source;
}
else {
throw new Error("key %s not found in the context");
}
};
ResolutionContext.prototype.addInherentLayer = function (layerctx) {
for (var prop in layerctx.ownProperties) {
var propVal = layerctx.ownProperties[prop];
this.addOwnProperty(prop, propVal);
}
};
ResolutionContext.prototype.addSourceLayer = function (layer) {
for (var prop in layer.source.propertyLayerMap) {
var propVal = layer.source.propertyLayerMap[prop];
if (this.propertyLayerMap[prop] != undefined && (this.propertyLayerMap[prop].mode != propVal.mode || this.propertyLayerMap[prop].source != propVal.source)) {
throw new Error("source layer introduces incompatible source/mode of property");
}
else {
this.propertyLayerMap[prop] = { source: propVal.source, mode: layer.mode };
Object.defineProperty(this, prop, {
set: this.setItem.bind(this, prop),
get: this.getItem.bind(this, prop),
enumerable: true,
configurable: true
});
}
}
};
return ResolutionContext;
}());
Gentyl.ResolutionContext = ResolutionContext;
})(Gentyl || (Gentyl = {}));