New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dcl

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dcl - npm Package Compare versions

Comparing version 1.1.3 to 2.0.0

.editorconfig

28

advices/counter.js

@@ -1,27 +0,21 @@

(function(factory){
if(typeof define != "undefined"){
define(["../dcl"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("../dcl"));
}else{
dclAdvicesCounter = factory(dcl);
}
})(function(dcl){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['../dcl'], function (dcl) {
'use strict';
var Counter = new dcl(null, {
declaredClass: "dcl/advices/counter/Counter",
constructor: function(){
declaredClass: 'dcl/advices/counter/Counter',
constructor: function () {
this.reset();
},
reset: function(){
reset: function () {
this.calls = this.errors = 0;
},
advice: function(){
advice: function () {
var self = this;
return {
before: function(){
before: function () {
++self.calls;
},
after: function(args, result){
if(result instanceof Error){
after: function (args, result) {
if (result instanceof Error) {
++self.errors;

@@ -28,0 +22,0 @@ }

@@ -1,24 +0,19 @@

(function(factory){
if(typeof define != "undefined"){
define([], factory);
}else if(typeof module != "undefined"){
module.exports = factory();
}else{
dclAdvicesFlow = factory();
}
})(function(){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
var flowStack = [], flowCount = {};
return {
advice: function(name){
advice: function (name) {
return {
before: function(){
before: function () {
flowStack.push(name);
if(flowCount[name]){
if (flowCount[name]) {
++flowCount[name];
}else{
} else {
flowCount[name] = 1;
}
},
after: function(){
after: function () {
--flowCount[name];

@@ -29,9 +24,9 @@ flowStack.pop();

},
inFlowOf: function(name){
inFlowOf: function (name) {
return flowCount[name];
},
getStack: function(){
getStack: function () {
return flowStack;
},
getCount: function(){
getCount: function () {
return flowCount;

@@ -38,0 +33,0 @@ }

@@ -1,60 +0,54 @@

(function(factory){
if(typeof define != "undefined"){
define([], factory);
}else if(typeof module != "undefined"){
module.exports = factory();
}else{
dclAdvicesMemoize = factory();
}
})(function(){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
return {
advice: function(name, keyMaker){
advice: function (name, keyMaker) {
return keyMaker ?
{
around: function(sup){
return function(){
around: function (sup) {
return function () {
var key = keyMaker(this, arguments), cache = this.__memoizerCache, dict;
if(!cache){
if (!cache) {
cache = this.__memoizerCache = {};
}
if(cache.hasOwnProperty(name)){
if (cache.hasOwnProperty(name)) {
dict = cache[name];
}else{
} else {
dict = cache[name] = {};
}
if(dict.hasOwnProperty(key)){
if (dict.hasOwnProperty(key)) {
return dict[key];
}
return dict[key] = sup ? sup.apply(this, arguments) : undefined;
}
return dict[key] = sup ? sup.apply(this, arguments) : void 0;
};
}
} :
{
around: function(sup){
return function(first){
around: function (sup) {
return function (first) {
var cache = this.__memoizerCache, dict;
if(!cache){
if (!cache) {
cache = this.__memoizerCache = {};
}
if(cache.hasOwnProperty(name)){
if (cache.hasOwnProperty(name)) {
dict = cache[name];
}else{
} else {
dict = cache[name] = {};
}
if(dict.hasOwnProperty(first)){
if (dict.hasOwnProperty(first)) {
return dict[first];
}
return dict[first] = sup ? sup.apply(this, arguments) : undefined;
}
};
}
};
},
guard: function(name){
guard: function (name) {
return {
after: function(){
after: function () {
var cache = this.__memoizerCache;
if(cache && name){
delete cache[name]
}else{
if (cache && name) {
delete cache[name];
} else {
this.__memoizerCache = {};

@@ -61,0 +55,0 @@ }

@@ -1,22 +0,17 @@

(function(factory){
if(typeof define != "undefined"){
define([], factory);
}else if(typeof module != "undefined"){
module.exports = factory();
}else{
dclAdvicesTime = factory();
}
})(function(){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
var uniq = 0;
return function(name){
var inCall = 0, label = name || ("Timer #" + uniq++);
return function (name) {
var inCall = 0, label = name || ('Timer #' + uniq++);
return {
before: function(){
if(!(inCall++)){
before: function () {
if (!(inCall++)) {
console.time(label);
}
},
after: function(){
if(!--inCall){
after: function () {
if (!--inCall) {
console.timeEnd(label);

@@ -23,0 +18,0 @@ }

@@ -1,34 +0,31 @@

(function(factory){
if(typeof define != "undefined"){
define([], factory);
}else if(typeof module != "undefined"){
module.exports = factory();
}else{
dclAdvicesTrace = factory();
}
})(function(){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
var lvl = 0;
function rep(ch, n){
if(n < 1){ return ""; }
if(n == 1){ return ch; }
function rep (ch, n) {
if (n < 1) { return ''; }
if (n == 1) { return ch; }
var h = rep(ch, Math.floor(n / 2));
return h + h + ((n & 1) ? ch : "");
return h + h + ((n & 1) ? ch : '');
}
function pad(value, width, ch){
function pad (value, width, ch) {
var v = value.toString();
return v + rep(ch || " ", width - v.length);
return v + rep(ch || ' ', width - v.length);
}
return function(name, level){
return function (name, level) {
return {
before: function(){
before: function () {
++lvl;
console.log((level ? pad(lvl, 2 * lvl) : "") + this + " => " +
name + "(" + Array.prototype.join.call(arguments, ", ") + ")");
console.log((level ? pad(lvl, 2 * lvl) : '') + this + ' => ' +
name + '(' + Array.prototype.join.call(arguments, ', ') + ')');
},
after: function(args, result){
console.log((level ? pad(lvl, 2 * lvl) : "") + this + " => " +
name + (result && result instanceof Error ? " throws" : " returns") +
" " + result);
after: function (args, result) {
console.log((level ? pad(lvl, 2 * lvl) : '') + this + ' => ' +
name + (result && result instanceof Error ? ' throws' : ' returns') +
' ' + result);
--lvl;

@@ -35,0 +32,0 @@ }

@@ -1,116 +0,207 @@

(function(factory){
if(typeof define != "undefined"){
define([], factory);
}else if(typeof module != "undefined"){
module.exports = factory();
}else{
advise = factory();
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
var pname = 'prototype';
function Node (parent) {
this.parent = parent || this;
}
})(function(){
"use strict";
function Node(instance, name){
this.next_before = this.prev_before = this.next_after = this.prev_after =
this.next_around = this.prev_around = this;
this.instance = instance;
this.name = name;
}
var p = Node.prototype = {
add: function(before, after, around, original){
var node = new Node(this.instance, this.name);
node.parent = this;
node.before = before;
this._add("before", node);
node.after = after;
this._add("after", node);
node.around = around;
this._add("around", node, original);
node.original = original;
if(original){ node.around = advise._instantiate(original, node.prev_around.around, this); }
return node;
Node[pname] = {
removeTopic: function (topic) {
var n = 'next_' + topic, p = 'prev_' + topic;
if (this[n] && this[p]) {
this[n][p] = this[p];
this[p][n] = this[n];
}
},
_add: function(topic, node, flag){
if(node[topic] || flag){
var n = "next_" + topic, p = "prev_" + topic;
(node[p] = this[p])[n] = (node[n] = this)[p] = node;
remove: function () {
this.removeTopic('before');
this.removeTopic('around');
// remove & recreate around advices
var parent = this.parent, next = this.next_around;
this.removeTopic('after');
for (; next && next !== parent; next = next.next_around) {
next.around = next.originalAround(next.prev_around.around);
}
},
remove: function(node){
this._remove("before", node);
this._remove("after", node);
this._remove("around", node);
addTopic: function (node, topic) {
var n = 'next_' + topic, p = 'prev_' + topic,
prev = node[p] = this[p] || this;
node[n] = this;
prev[n] = this[p] = node;
},
_remove: function(topic, node){
var n = "next_" + topic, p = "prev_" + topic;
node[n][p] = node[p];
node[p][n] = node[n];
},
destroy: function(){
var around = this.prev_around.around, t = this.next_around, parent = this.parent;
this.remove(this);
if(t !== this){
for(; t !== parent; around = t.around, t = t.next_around){
if(t.original){
t.around = advise._instantiate(t.original, around, this);
}
addAdvice: function (advice, instance, name, type) {
var node = new Node(this);
if (advice.before) {
node.before = advice.before;
this.addTopic(node, 'before');
}
if (advice.around) {
if (typeof advice.around != 'function') {
advise._error('wrong super call', instance, name, type);
}
node.originalAround = advice.around;
this.addTopic(node, 'around');
if (node.prev_around.around && typeof node.prev_around.around != 'function') {
advise._error('wrong super arg', instance, name, type);
}
node.around = advice.around(node.prev_around.around || null);
if (typeof node.around != 'function') {
advise._error('wrong super result', instance, name, type);
}
}
this.instance = 0;
if (advice.after) {
node.after = advice.after;
this.addTopic(node, 'after');
}
return node;
}
};
p.unadvise = p.destroy; // alias
function makeAOPStub(node){
var f = function(){
var p, r, t = this, a = arguments, thrown;
Node[pname].destroy = Node[pname].unadvise = Node[pname].remove;
function addNode (root, topic) {
return function (f) {
var node = new Node(root);
node[topic] = f;
root.addTopic(node, topic);
};
}
function makeStub (value) {
var root = new Node();
if (value) {
if (typeof value.advices == 'object') {
var advices = value.advices;
advices.before.forEach(addNode(root, 'before'));
advices.after. forEach(addNode(root, 'after'));
advices.around && addNode(root, 'around')(advices.around);
} else {
addNode(root, 'around')(value);
}
}
function stub () {
var result, thrown, p;
// running the before chain
for(p = node.prev_before; p !== node; p = p.prev_before){
p.before.apply(t, a);
for (p = root.prev_before; p && p !== root; p = p.prev_before) {
p.before.apply(this, arguments);
}
// running the around chain
try{
if(node.prev_around !== node){ r = node.prev_around.around.apply(t, a); }
}catch(e){
r = e;
thrown = true;
if (root.prev_around && root.prev_around !== root) {
try {
result = root.prev_around.around.apply(this, arguments);
} catch (error) {
result = error;
thrown = true;
}
}
// running the after chain
for(p = node.next_after; p !== node; p = p.next_after){
p.after.call(t, a, r);
for (p = root.next_after; p && p !== root; p = p.next_after) {
p.after.call(this, arguments, result, makeReturn, makeThrow);
}
if(thrown){
throw r;
if (thrown) {
throw result;
}
return r;
return result;
function makeReturn (value) { result = value; thrown = false; }
function makeThrow (value) { result = value; thrown = true; }
};
f.adviceNode = node;
return f;
stub.node = root;
return stub;
}
function advise(instance, name, advice){
var f = instance[name], node;
if(f && f.adviceNode && f.adviceNode instanceof Node){
node = f.adviceNode;
}else{
node = new Node(instance, name);
if(f && f.advices){
f = f.advices;
node.add(f.before, f.after, f.around);
}else{
node.add(0, 0, f);
function convert (value, advice, instance, name, type) {
if (!value || !(value.node instanceof Node)) {
value = makeStub(value);
value.node.instance = instance;
value.node.name = name;
value.node.type = type;
}
var node = value.node.addAdvice(advice, instance, name, type);
return {value: value, handle: node};
}
function combineHandles (handles) {
var handle = {
remove: function () {
handles.forEach(function (handle) { handle.remove(); });
}
instance[name] = makeAOPStub(node);
}
if(typeof advice == "function"){ advice = advice(name, instance); }
return node.add(advice.before, advice.after, 0, advice.around);
handle.unadvise = handle.remove;
return handle;
}
advise.before = function(instance, name, f){ return advise(instance, name, {before: f}); };
advise.after = function(instance, name, f){ return advise(instance, name, {after: f}); };
advise.around = function(instance, name, f){ return advise(instance, name, {around: f}); };
function advise (instance, name, advice) {
var prop = getPropertyDescriptor(instance, name), handles = [];
if (prop) {
if (prop.get || prop.set) {
var result;
if (prop.get && advice.get) {
result = convert(prop.get, advice.get, instance, name, 'get');
prop.get = result.value;
handles.push(result.handle);
}
if (prop.set && advice.set) {
result = convert(prop.set, advice.set, instance, name, 'set');
prop.set = result.value;
handles.push(result.handle);
}
} else {
if (prop.value && advice) {
result = convert(prop.value, advice, instance, name, 'value');
prop.value = result.value;
handles.push(result.handle);
}
}
} else {
prop = {writable: true, configurable: true, enumerable: true};
if (advice.get || advice.set) {
if (advice.get) {
result = convert(null, advice.get, instance, name, 'get');
prop.get = result.value;
handles.push(result.handles);
}
if (advice.set) {
result = convert(null, advice.set, instance, name, 'set');
prop.set = result.value;
handles.push(result.handles);
}
} else {
result = convert(null, advice, instance, name, 'value');
prop.value = result.value;
handles.push(result.handles);
}
}
Object.defineProperty(instance, name, prop);
return combineHandles(handles);
}
// export
// guts, do not use them!
advise._error = function (msg) {
throw new Error(msg);
};
advise.before = function (instance, name, f) { return advise(instance, name, {before: f}); };
advise.after = function (instance, name, f) { return advise(instance, name, {after: f}); };
advise.around = function (instance, name, f) { return advise(instance, name, {around: f}); };
advise.Node = Node;
advise._instantiate = function(advice, previous, node){ return advice(previous); };
return advise;
return advise;
// copied from dcl.js so we can be independent
function getPropertyDescriptor (o, name) {
while (o && o !== Object[pname]) {
if (o.hasOwnProperty(name)) {
return Object.getOwnPropertyDescriptor(o, name);
}
o = Object.getPrototypeOf(o);
}
return; // undefined
}
});

@@ -1,17 +0,11 @@

(function(factory){
if(typeof define != "undefined"){
define(["../mini"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("../mini"));
}else{
dclBasesMixer = factory(dcl);
}
})(function(dcl){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['../dcl'], function (dcl) {
'use strict';
return dcl(null, {
declaredClass: "dcl/bases/Mixer",
constructor: function(x){
dcl.mix(this, x);
declaredClass: 'dcl/bases/Mixer',
constructor: function (x) {
Object.defineProperties(this, dcl.collectPropertyDescriptors({}, x));
}
});
});

@@ -1,21 +0,12 @@

(function(factory){
if(typeof define != "undefined"){
define(["../mini"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("../mini"));
}else{
dclBasesReplacer = factory(dcl);
}
})(function(dcl){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['../dcl'], function (dcl) {
'use strict';
return dcl(null, {
declaredClass: "dcl/bases/Replacer",
constructor: function(x){
var empty = {};
dcl.allKeys(x).forEach(function(name){
if(name in this){
var t = x[name], e = empty[name];
if(t !== e){
this[name] = t;
}
declaredClass: 'dcl/bases/Replacer',
constructor: function (x) {
var props = dcl.collectPropertyDescriptors({}, x);
Object.keys(props).forEach(function (name) {
if (name in this) {
Object.defineProperty(this, name, props[name]);
}

@@ -22,0 +13,0 @@ }, this);

{
"name": "dcl",
"version": "1.1.3",
"description": "Elegant minimalistic implementation of OOP with mixins + AOP.",
"main": "dcl.js",
"authors": [
"Eugene Lazutkin <eugene.lazutkin@gmail.com> (http://www.lazutkin.com/)"
],
"license": "BSD-3-Clause",
"keywords": [
"object-oriented",
"programming",
"aspect-oriented",
"OOP",
"AOP",
"OO"
],
"homepage": "https://github.com/uhop/dcl",
"moduleType": [
"amd",
"globals",
"node"
],
"ignore": [

@@ -6,0 +24,0 @@ "**/.*",

@@ -1,99 +0,728 @@

(function(factory){
if(typeof define != "undefined"){
define(["./mini"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("./mini"));
}else{
dcl = factory(dcl);
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
([], function () {
'use strict';
// set up custom names
var mname = '_meta', pname = 'prototype', cname = 'constructor';
// MODULE: restricted Map shim (used by C3 MRO)
var M; // our map implementation if not defined
if (typeof Map == 'undefined') {
// our fake, inefficient, incomplete, yet totally correct Map
M = function () {
this.list = [];
this.size = 0;
};
M.prototype = {
has: function (key) { return this.get(key); },
get: function (key) {
for (var i = 0, n = this.list.length; i < n; i += 2) {
if (key === this.list[i]) {
return this.list[i + 1];
}
}
// returns undefined if not found
},
set: function (key, value) {
for (var i = 0, n = this.list.length; i < n; i += 2) {
if (key === this.list[i]) {
this.list[i + 1] = value;
return this;
}
}
this.list.push(key, value);
++this.size;
return this;
}
};
} else {
M = Map;
}
})(function(dcl){
"use strict";
function nop(){}
var Advice = dcl(dcl.Super, {
//declaredClass: "dcl.Advice",
constructor: function(){
this.before = this.around.before;
this.after = this.around.after;
this.around = this.around.around;
// MODULE: C3 MRO
function c3mro (bases, props) {
// build a connectivity matrix
var connectivity = new M();
bases.forEach(function (base) {
(base[mname] ? base[mname].bases : [base]).forEach(function (base, index, array) {
if (connectivity.has(base)) {
var value = connectivity.get(base);
++value.counter;
if (index) {
value.links.push(array[index - 1]);
}
} else {
connectivity.set(base, {
links: index ? [array[index - 1]] : [],
counter: index + 1 == array.length ? 0 : 1
});
}
});
});
// Kahn's algorithm
var output = [], unreferenced = [];
// find unreferenced bases
bases.forEach(function (base) {
var last = base[mname] ? base[mname].bases[base[mname].bases.length - 1] : base;
if (!connectivity.get(last).counter) {
unreferenced.push(last);
}
});
while (unreferenced.length) {
var base = unreferenced.pop();
output.push(base);
var value = connectivity.get(base);
value.links.forEach(updateCounter);
}
});
function advise(advice){ return dcl._makeSuper(advice, Advice); }
// final checks and return
if (connectivity.size != output.length) {
dcl._error('cycle', bases, props);
}
return output;
function makeAOPStub(before, after, around){
var beforeChain = before || nop,
afterChain = after || nop,
aroundChain = around || nop,
stub = function(){
var r, thrown;
function updateCounter (base) {
var value = connectivity.get(base);
if (!--value.counter) {
unreferenced.push(base);
}
}
}
// MODULE: handling properties
function updateProps (props, defaults, augmentDescriptor, augmentWritable) {
var augmenter;
if ('configurable' in defaults) {
augmenter = augmentDescriptor('configurable', defaults.configurable);
Object.keys(props).forEach(function (name) { augmenter(props[name], name); });
}
if ('enumerable' in defaults) {
augmenter = augmentDescriptor('enumerable', defaults.enumerable);
Object.keys(props).forEach(function (name) { augmenter(props[name], name); });
}
if ('writable' in defaults) {
augmenter = augmentWritable(defaults.writable);
Object.keys(props).forEach(function (name) { augmenter(props[name], name); });
}
return props;
}
var descriptorProperties = {configurable: 1, enumerable: 1, value: 1, writable: 1, get: 1, set: 1};
function toProperties(x, defaults) {
var props, descriptors;
if (x instanceof dcl.Prop) {
props = x.x;
} else {
Object.getOwnPropertyNames(x).forEach(function(key) {
var prop = Object.getOwnPropertyDescriptor(x, key);
if (prop.get || prop.set) {
// accessor descriptor
descriptors = descriptors || {};
descriptors[key] = prop;
} else {
// data descriptor
var value = prop.value;
if (value instanceof dcl.Prop) {
props = props || {};
props[key] = value.x;
} else {
if (defaults.detectProps && value && typeof value == 'object') {
if (Object.keys(value).every(function (name) { return descriptorProperties[name] === 1; })) {
props = props || {};
props[key] = value;
return;
}
}
descriptors = descriptors || {};
descriptors[key] = prop;
}
}
});
}
if (props) {
props = updateProps(props, defaults, augmentDescriptor, augmentWritable);
}
if (descriptors) {
descriptors = updateProps(descriptors, defaults, replaceDescriptor, replaceWritable);
}
if (descriptors && props) {
Object.keys(props).forEach(function(key) {
descriptors[key] = props[key];
});
}
return descriptors || props || {};
}
function cloneDescriptor (descriptor) { // shallow copy
var newDescriptor = {};
Object.keys(descriptor).forEach(function (name) {
newDescriptor[name] = descriptor[name];
});
return newDescriptor;
}
function augmentDescriptor(type, value) {
return typeof value == 'function' ? value : function(descriptor) {
if (!descriptor.hasOwnProperty(type)) {
descriptor[type] = value;
}
};
}
function augmentWritable(value) {
return typeof value == 'function' ? value : function(descriptor) {
if (!descriptor.get && !descriptor.set && !descriptor.hasOwnProperty('writable')) {
descriptor.writable = value;
}
};
}
function replaceDescriptor(type, value) {
return typeof value == 'function' ? value : function(descriptor) {
descriptor[type] = value;
};
}
function replaceWritable(value) {
return typeof value == 'function' ? value : function(descriptor) {
if (descriptor.hasOwnProperty('value')) {
descriptor.writable = value;
}
};
}
function getPropertyDescriptor (o, name) {
while (o && o !== Object.prototype) {
if (o.hasOwnProperty(name)) {
return Object.getOwnPropertyDescriptor(o, name);
}
o = Object.getPrototypeOf(o);
}
return; // undefined
}
// MODULE: produce properties
function recordProp(props, o, recorded) {
return function (name) {
if (recorded[name] !== 1) {
recorded[name] = 1;
props[name] = Object.getOwnPropertyDescriptor(o, name);
}
};
}
function collectPropertyDescriptors (props, o) {
var recorded = {};
while (o && o !== Object.prototype) {
Object.getOwnPropertyNames(o).forEach(recordProp(props, o, recorded));
o = Object.getPrototypeOf(o);
}
return props;
}
// populate properties with simple properties
function populateProps (props, mixins, special) {
var newSpecial = {};
mixins.forEach(function (base) {
// copy properties for dcl objects
if (base[mname]) {
var baseProps = base[mname].props;
Object.keys(baseProps).forEach(function (name) {
if (special.hasOwnProperty(name)) {
newSpecial[name] = special[name];
} else {
props[name] = baseProps[name];
}
});
return;
}
// copy properties for regular objects
collectPropertyDescriptors(props, base[pname]);
});
return newSpecial;
}
var empty = {};
function weaveProp (name, bases, weaver, props) {
var state = {prop: null, backlog: []};
weaver.start && weaver.start(state);
bases.forEach(function (base, index) {
var prop;
if (base[mname]) {
var baseProps = base[mname].props;
if (baseProps.hasOwnProperty(name)) {
prop = baseProps[name];
}
} else {
prop = getPropertyDescriptor(base[pname], name);
if (!prop && name == cname) {
prop = {configurable: true, enumerable: false, writable: true, value: base};
}
}
if (!prop) {
return;
}
var newProp = cloneDescriptor(prop), prevProp, superArg;
if (prop.get || prop.set) {
// accessor
var superGet = isSuper(prop.get) && prop.get.spr.around,
superSet = isSuper(prop.set) && prop.set.spr.around;
if (superGet || superSet) {
processBacklog(state, weaver);
prevProp = state.prop;
}
if (superGet) {
if (typeof prop.get.spr.around != 'function') {
dcl._error('wrong super get call', base, name, index, props);
}
superArg = null;
if (prevProp) {
superArg = prevProp.get || prevProp.set ?
prevProp.get : adaptValue(prevProp.value);
}
if (superArg && typeof superArg != 'function') {
dcl._error('wrong super get arg', base, name, index, props);
}
newProp.get = prop.get.spr.around(superArg);
if (typeof newProp.get != 'function') {
dcl._error('wrong super get result', base, name, index, props);
}
state.prop = null;
}
if (superSet) {
if (typeof prop.set.spr.around != 'function') {
dcl._error('wrong super set call', base, name, index, props);
}
superArg = prevProp && prevProp.set;
if (superArg && typeof superArg != 'function') {
dcl._error('wrong super set arg', base, name, index, props);
}
newProp.set = prop.set.spr.around(superArg);
if (typeof newProp.set != 'function') {
dcl._error('wrong super set result', base, name, index, props);
}
state.prop = null;
}
if ((!prop.get || isSuper(prop.get) && !prop.get.spr.around) && (!prop.set || isSuper(prop.set) && !prop.set.spr.around)) {
return; // skip descriptor: no actionable value
}
} else {
// data
if (isSuper(prop.value) && prop.value.spr.around) {
processBacklog(state, weaver);
prevProp = state.prop;
if (typeof prop.value.spr.around != 'function') {
dcl._error('wrong super value call', base, name, index, props);
}
if (prevProp) {
superArg = prevProp.get || prevProp.set ?
adaptGet(prevProp.get) : prevProp.value;
} else {
superArg = name !== cname && empty[name];
}
if (superArg && typeof superArg != 'function') {
dcl._error('wrong super value arg', base, name, index, props);
}
newProp.value = prop.value.spr.around(superArg);
if (typeof newProp.value != 'function') {
dcl._error('wrong super value result', base, name, index, props);
}
state.prop = null;
}
if (!prop.value || isSuper(prop.value) && !prop.value.spr.around) {
return; // skip descriptor: no actionable value
}
}
if (state.prop) {
if (newProp.get || newProp.set) {
if (state.backlog.length) {
state.backlog = [];
}
} else {
state.backlog.push(convertToValue(state.prop));
}
}
state.prop = newProp;
});
processBacklog(state, weaver);
return weaver.stop ? weaver.stop(state) : state.prop;
}
var dclUtils = {adaptValue: adaptValue, adaptGet: adaptGet,
convertToValue: convertToValue, cloneDescriptor: cloneDescriptor,
augmentDescriptor: augmentDescriptor, augmentWritable: augmentWritable,
replaceDescriptor: replaceDescriptor, replaceWritable: replaceWritable
};
function processBacklog (state, weaver) {
if (state.backlog.length) {
state.backlog.push(convertToValue(state.prop));
state.prop = weaver.weave(state.backlog, dclUtils);
state.backlog = [];
}
}
function adaptValue (f) {
return f ? function () { return f; } : null;
}
function adaptGet (f) {
return f ? function () { return f.call(this).apply(this, arguments); } : null;
}
function convertToValue (prop) {
if (prop.get || prop.set) {
var newProp = cloneDescriptor(prop);
delete newProp.get;
delete newProp.set;
newProp.value = adaptGet(prop.get);
return newProp;
}
return prop;
}
// dcl helpers
function getAccessorSideAdvices (name, bases, propName) {
var before = [], after = [];
bases.forEach(function (base) {
if (base[mname]) {
var prop = base[mname].props[name];
if (typeof prop == 'object') {
if (prop.get || prop.set) {
var f = prop[propName];
if (isSuper(f)) {
f.spr.before && before.push(f.spr.before);
f.spr.after && after .push(f.spr.after);
}
}
}
}
});
if (before.length > 1) { before.reverse(); }
return {before: before, after: after};
}
function getDataSideAdvices (name, bases) {
var before = [], after = [];
bases.forEach(function (base) {
if (base[mname]) {
var prop = base[mname].props[name];
if (typeof prop == 'object') {
var f = prop.get || prop.set ? prop.get : prop.value;
if (isSuper(f)) {
f.spr.before && before.push(f.spr.before);
f.spr.after && after .push(f.spr.after);
}
}
}
});
if (before.length > 1) { before.reverse(); }
return {before: before, after: after};
}
function makeStub (aroundStub, beforeChain, afterChain) {
var beforeLength = beforeChain.length, afterLength = afterChain.length,
stub = function () {
var result, thrown, i;
// running the before chain
beforeChain.apply(this, arguments);
for (i = 0; i < beforeLength; ++i) {
beforeChain[i].apply(this, arguments);
}
// running the around chain
try{
r = aroundChain.apply(this, arguments);
}catch(e){
r = e;
thrown = true;
if (aroundStub) {
try {
result = aroundStub.apply(this, arguments);
} catch (error) {
result = error;
thrown = true;
}
}
// running the after chain
afterChain.call(this, arguments, r);
if(thrown){
throw r;
for (i = 0; i < afterLength; ++i) {
afterChain[i].call(this, arguments, result, makeReturn, makeThrow);
}
return r;
if (thrown) {
throw result;
}
return result;
function makeReturn (value) { result = value; thrown = false; }
function makeThrow (value) { result = value; thrown = true; }
};
stub.advices = {before: before, after: after, around: around};
stub.advices = {around: aroundStub, before: beforeChain, after: afterChain};
return stub;
}
function chain(id){
return function(ctor, name){
var meta = ctor._meta, rule;
if(meta){
rule = +meta.weaver[name] || 0;
if(rule && rule != id){
dcl._error("set chaining", name, ctor, id, rule);
}
meta.weaver[name] = id;
function makeCtr (baseClass, finalProps, meta) {
var proto = baseClass ?
Object.create(baseClass[pname], finalProps) :
Object.defineProperties({}, finalProps),
ctr = proto[cname];
ctr[mname] = meta;
ctr[pname] = proto;
meta.bases[meta.bases.length - 1] = ctr;
return ctr;
}
// MODULE: weavers
function weaveAround (chain, utils) {
var newProp = utils.cloneDescriptor(chain[chain.length - 1]);
if (newProp.get || newProp.set) {
// convert to value
newProp.value = utils.adaptGet(newProp.get);
delete newProp.get;
delete newProp.set;
}
return newProp;
}
function weaveChain (chain, utils) {
if (this.reverse) {
chain.reverse();
}
var newProp = utils.cloneDescriptor(chain[chain.length - 1]);
// extract functions
chain = chain.map(function (prop) {
return prop.get || prop.set ? utils.adaptGet(prop.get) : prop.value;
});
newProp.value = function () {
for (var i = 0; i < chain.length; ++i) {
chain[i].apply(this, arguments);
}
};
return newProp;
}
dcl.mix(dcl, {
// public API
Advice: Advice,
advise: advise,
// expose helper methods
before: function(f){ return dcl.advise({before: f}); },
after: function(f){ return dcl.advise({after: f}); },
around: dcl.superCall,
// chains
chainBefore: chain(1),
chainAfter: chain(2),
isInstanceOf: function(o, ctor){
if(o instanceof ctor){
return true;
// MODULE: dcl (the main function)
function dcl (superClass, props, options) {
// parse arguments
if (superClass instanceof Array) {
// skip
} else if (typeof superClass == 'function') {
superClass = [superClass];
} else if (!superClass) {
superClass = [];
} else {
options = props;
props = superClass;
superClass = [];
}
props = toProperties(props || {}, options || {});
// find the base class, and mixins
var bases = [], baseClass = superClass[0], mixins = [], baseIndex = -1;
if (superClass.length) {
if (superClass.length > 1) {
bases = c3mro(superClass, props).reverse();
if (baseClass[mname]) {
baseIndex = baseClass[mname].bases.length - 1;
} else {
mixins = bases.slice(1);
baseIndex = 0;
}
} else {
if (baseClass[mname]) {
bases = baseClass[mname].bases.slice(0);
baseIndex = bases.length - 1;
} else {
bases = [baseClass];
baseIndex = 0;
}
}
var t = o.constructor._meta, i;
if(t){
for(t = t.bases, i = t.length - 1; i >= 0; --i){
if(t[i] === ctor){
return true;
if (bases[baseIndex] === baseClass) {
mixins = bases.slice(baseIndex + 1);
} else {
baseClass = null;
mixins = bases.slice(0);
}
}
// add a stand-in for our future constructor
var faux = {}, special = {};
faux[mname] = {bases: bases, props: props, special: special};
dcl.chainAfter(faux, cname);
bases.push(faux);
mixins.push(faux);
// collect meta
// merge from bases
superClass.forEach(function (base) {
if (base[mname]) {
var baseSpecial = base[mname].special;
Object.keys(baseSpecial).forEach(function (name) {
dcl.chainWith(faux, name, baseSpecial[name]);
});
}
});
// inspect own props
Object.keys(props).forEach(function (name) {
if (!special.hasOwnProperty(name)) {
var prop = props[name];
if (prop.get || prop.set) {
if (isSuper(prop.get) || isSuper(prop.set)) {
dcl.chainWith(faux, name, dcl.weaveSuper);
}
} else {
if (isSuper(prop.value)) {
dcl.chainWith(faux, name, dcl.weaveSuper);
}
}
}
return false;
},
// protected API starts with _ (don't use it!)
_stub: /*generic stub*/ function(id, bases, name, chains){
var f = chains[name] = dcl._extractChain(bases, name, "around"),
b = dcl._extractChain(bases, name, "before").reverse(),
a = dcl._extractChain(bases, name, "after");
f = id ? dcl._stubChainSuper(f, id == 1 ? function(f){ return dcl._stubChain(f.reverse()); } : dcl._stubChain, name) : dcl._stubSuper(f, name);
return !b.length && !a.length ? f || function(){} : makeAOPStub(dcl._stubChain(b), dcl._stubChain(a), f);
});
// collect simple props, and a list of special props
var finalProps = {}, finalSpecial = populateProps(finalProps, mixins, special);
if (!finalSpecial.hasOwnProperty(cname)) {
finalSpecial[cname] = special.hasOwnProperty(cname) ? special[cname] : dcl.weaveAfter;
}
// process special props
Object.keys(finalSpecial).forEach(function (name) {
var prop = weaveProp(name, bases, finalSpecial[name], props);
if (!prop) {
prop = {configurable: true, enumerable: false, writable: true, value: function nop () {}};
}
var newProp = cloneDescriptor(prop), advices;
if (prop.get || prop.set) {
// accessor descriptor
advices = getAccessorSideAdvices(name, bases, 'get');
newProp.get = dcl._makeStub(prop.get, advices.before, advices.after);
advices = getAccessorSideAdvices(name, bases, 'set');
newProp.set = dcl._makeStub(prop.set, advices.before, advices.after);
} else {
// data descriptor
advices = getDataSideAdvices(name, bases);
var stub = dcl._makeStub(prop.value, advices.before, advices.after);
advices = getAccessorSideAdvices(name, bases, 'set');
stub.advices.set = advices;
newProp.value = stub;
}
finalProps[name] = newProp;
});
return dcl._makeCtr(baseClass, finalProps, faux[mname]);
}
// build export
// guts, do not use them!
dcl._error = function (msg) {
throw new Error(msg);
};
dcl._makeSuper = makeSuper;
dcl._makeCtr = makeCtr;
dcl._makeStub = makeStub;
// utilities
dcl.collectPropertyDescriptors = collectPropertyDescriptors;
dcl.getPropertyDescriptor = getPropertyDescriptor;
// meta
dcl.Prop = function Prop (x) { this.x = x; };
dcl.prop = function prop(x) { return new dcl.Prop(x); };
dcl.isInstanceOf = function isInstanceOf (o, ctr) {
if (o instanceof ctr) {
return true;
}
if (o && o[cname] && o[cname][mname]) {
for (var bases = o[cname][mname].bases, i = bases.length - 2; i >= 0; --i) {
var base = bases[i];
if (base === ctr || !base[mname] && base[pname] instanceof ctr) {
return true;
}
}
}
return false;
};
// chains
function chainWith (ctr, name, weaver) {
if (ctr && ctr[mname]) {
var special = ctr[mname].special;
if (special.hasOwnProperty(name)) {
var own = special[name];
if (own === weaver || own.name === weaver.name || weaver.name === 'super') {
return true;
}
if (own.name !== 'super') {
dcl._error('different weavers: ' + name, ctr, name, weaver, own);
}
}
special[name] = weaver;
return true;
}
return false;
}
dcl.weaveBefore = {name: 'before', weave: weaveChain, reverse: true};
dcl.weaveAfter = {name: 'after', weave: weaveChain};
dcl.weaveSuper = {name: 'super', weave: weaveAround};
dcl.chainWith = chainWith;
dcl.chainBefore = function (ctr, name) { return dcl.chainWith(ctr, name, dcl.weaveBefore); };
dcl.chainAfter = function (ctr, name) { return dcl.chainWith(ctr, name, dcl.weaveAfter); };
// super & AOP
function makeSuper (advice, S) {
var f = function superNop () {};
f.spr = new S(advice);
return f;
}
function isSuper (f) { return f && f.spr instanceof dcl.Super; }
dcl.Super = function Super (f) { this.around = f; };
dcl.isSuper = isSuper;
dcl.Super[pname].declaredClass = 'dcl.Super';
dcl.Advice = dcl(dcl.Super, {
declaredClass: 'dcl.Advice',
constructor: function () {
this.before = this.around.before;
this.after = this.around.after;
this.around = this.around.around;
}
});
dcl.advise = function (advice) { return dcl._makeSuper(advice, dcl.Advice); };
dcl.superCall = dcl.around = function (f) { return dcl._makeSuper(f, dcl.Super); };
dcl.before = function (f) { return dcl.advise({before: f}); };
dcl.after = function (f) { return dcl.advise({after: f}); };
// export
return dcl;
});

@@ -1,23 +0,14 @@

(function(factory){
if(typeof define != "undefined"){
define(["./mini", "./advise"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("./mini"), require("./advise"));
}else{
dclDebug = factory(dcl, advise);
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['./dcl', './advise'], function (dcl, advise) {
'use strict';
// set up custom names
var mname = '_meta', pname = 'prototype', cname = 'constructor';
function DclError (message) {
this.name = 'DclError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
})(function(dcl, advise){
function DclError(message){
if(Error.captureStackTrace){
Error.captureStackTrace(this, DclError);
}
var e = Error.call(this, message), name;
dcl.allKeys(e).forEach(function(name){
if(e.hasOwnProperty(name)){
this[name] = e[name];
}
});
this.message = message;
}
DclError.prototype = dcl.delegate(Error.prototype);
DclError.prototype = Object.create(Error.prototype);
DclError.prototype.constructor = DclError;

@@ -27,211 +18,159 @@

ChainingError = dcl(DclError, {declaredClass: "dcl/debug/ChainingError"}),
SetChainingError = dcl(DclError, {declaredClass: "dcl/debug/SetChainingError"}),
SuperCallError = dcl(DclError, {declaredClass: "dcl/debug/SuperCallError"}),
SuperError = dcl(DclError, {declaredClass: "dcl/debug/SuperError"}),
SuperResultError = dcl(DclError, {declaredClass: "dcl/debug/SuperResultError"});
SuperError = dcl(DclError, {declaredClass: "dcl/debug/SuperError"});
var chainNames = ["UNCHAINED BUT CONTAINS ADVICE(S)", "CHAINED BEFORE", "CHAINED AFTER",
"ERRONEOUSLY CHAINED BEFORE AND AFTER"];
function chainName(id){
return id >= 0 && id <= 3 ? chainNames[id] : "UNKNOWN (" + id + ")";
}
var noDecls = " (specify 'declaredClass' string in your classes to get better diagnostics)";
advise.around(dcl, "_error", function(/*sup*/){
return function(reason, a1, a2, a3, a4, a5){
var cName, someUnknown, i, base, name, names = [], c = {};
switch(reason){
case "cycle":
cName = a1.hasOwnProperty("declaredClass") && a1.declaredClass;
someUnknown = !cName;
for(i = a2.length - 1; i >= 0; --i){
base = a2[i][0];
name = base.prototype.hasOwnProperty("declaredClass") && base.prototype.declaredClass;
if(!name){
name = "UNNAMED_" + base._uniqueId;
someUnknown = true;
}
if(!c[name]){
names.push(name);
c[name] = 1;
}
}
throw new CycleError("dcl: base class cycle found in: " + (cName || "UNNAMED") +
" - bases: " + names.join(", ") + " are mutually dependent" +
(someUnknown ? noDecls : ""));
case "chain":
cName = a2.prototype.hasOwnProperty("declaredClass") && a2.prototype.declaredClass;
name = a4.prototype.hasOwnProperty("declaredClass") && a4.prototype.declaredClass;
someUnknown = !(cName && name);
throw new ChainingError("dcl: conflicting chain directives from bases found in: " + (cName || ("UNNAMED_" + a2._uniqueId)) +
", method: " + a1 + " - it was " + chainName(a3) + " yet " +
(name || ("UNNAMED_" + a4._uniqueId)) + " sets it to " + chainName(a5) +
(someUnknown ? noDecls : ""));
case "set chaining":
cName = a2.prototype.hasOwnProperty("declaredClass") && a2.prototype.declaredClass;
someUnknown = !cName;
throw new SetChainingError("dcl: attempt to set conflicting chain directives in: " + (cName || ("UNNAMED_" + a2._uniqueId)) +
", method: " + a1 + " - it was " + chainName(a4) + " yet being changed to " + chainName(a3) +
(someUnknown ? noDecls : ""));
case "wrong super call":
cName = a1.prototype.hasOwnProperty("declaredClass") && a1.prototype.declaredClass;
someUnknown = !cName;
throw new SuperCallError("dcl: argument of around advice or supercall decorator should be a function in: " +
(cName || ("UNNAMED_" + a1._uniqueId)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
case "wrong super":
cName = a1.prototype.hasOwnProperty("declaredClass") && a1.prototype.declaredClass;
someUnknown = !cName;
throw new SuperError("dcl: super method should be a function in: " +
(cName || ("UNNAMED_" + a1._uniqueId)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
case "wrong super result":
cName = a1.prototype.hasOwnProperty("declaredClass") && a1.prototype.declaredClass;
someUnknown = !cName;
throw new SuperResultError("dcl: around advice or supercall should return a function in: " +
(cName || ("UNNAMED_" + a1._uniqueId)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
}
throw new DclError("dcl: " + reason);
};
});
advise.after(dcl, "_postprocess", function(args, ctor){
// validate that chaining is consistent
var meta = ctor._meta, weaver = meta.weaver, bases = meta.bases,
name, chain, base, i, rule;
dcl.allKeys(weaver).forEach(function(name){
chain = (+weaver[name] || 0);
for(i = bases.length - 1; i >= 0; --i){
base = bases[i];
meta = base._meta;
if(meta){
rule = (+meta.weaver[name] || 0);
if(chain != rule && (!chain || rule)){
dcl._error("chain", name, ctor, chain, base, rule);
}
advise.around(dcl, '_error', function (sup) {
return function (reason) {
var name, ctr, method, props;
if (reason === 'cycle') {
var bases = arguments[1],
names = bases.map(function (base, index) {
return base[pname].declaredClass || ('UNNAMED_' + index);
});
props = arguments[2];
name = props.declaredClass && props.declaredClass.value;
if (!name || typeof name != 'string') {
name = 'UNNAMED';
}
throw new CycleError('dcl: base class cycle in ' + name +
', bases (' + names.join(', ') + ') are mutually dependent');
}
});
});
advise.around(dcl, "_instantiate", function(/*sup*/){
return function(advice, previous, node){
if(!advice || !advice.spr || typeof advice.spr.around != "function"){
dcl._error("wrong super call", advice.ctr, node);
if (/^different weavers\b/.test(reason)) {
var weaver = arguments[3], own = arguments[4];
ctr = arguments[1];
method = arguments[2];
name = ctr[mname].props.declaredClass && ctr[mname].props.declaredClass.value || 'UNNAMED';
throw new ChainingError('dcl: conflicting chain directives in ' +
name + ' for ' + method + ', was ' + own.name + ', set to ' + weaver.name);
}
if(previous && typeof previous != "function"){
dcl._error("wrong super", advice.ctr, node);
if (/^wrong super\b/.test(reason)) {
var index = arguments[3];
ctr = arguments[1];
method = arguments[2];
props = arguments[4];
name = props.declaredClass && props.declaredClass.value;
if (!name || typeof name != 'string') {
name = 'UNNAMED';
}
var re = /^wrong super (\w+) (\w+)$/.exec(reason),
baseName = ctr[mname].props.declaredClass &&
ctr[mname].props.declaredClass.value ||
('UNNAMED_' + index);
throw new SuperError('dcl: super call error in ' +
name + ', while weaving ' + baseName + ', method ' + method +
' (' + re[1] + ') wrong ' + re[2]);
}
var t = advice.spr.around(previous);
if(typeof t != "function"){
dcl._error("wrong super result", advice.ctr, node);
}
t.ctr = advice.ctr;
return t;
return sup.apply(this, arguments);
};
});
advise(advise, "_instantiate", {
before: function(advice, previous, node){
if(typeof advice != "function"){
dcl._error("wrong super call", node.instance.constructor, node.name);
advise.around(advise, '_error', function (sup) {
return function (reason, instance, method, type) {
var re = /^wrong super (\w+)$/.exec(reason);
if (re) {
var baseName = instance.declaredClass;
if (!baseName || typeof baseName != 'string') {
baseName = 'UNNAMED';
}
throw new SuperError('dcl: super call error in object of ' +
baseName + ', while weaving method ' + method +
' (' + type + ') wrong ' + re[1]);
}
if(previous && typeof previous != "function"){
dcl._error("wrong super", node.instance.constructor, node.name);
}
},
after: function(a, result){
if(typeof result != "function"){
dcl._error("wrong super result", a[2].instance.constructor, a[2].name);
}
}
return sup.apply(this, arguments);
};
});
function logCtor(ctor){
var meta = ctor._meta;
if(!meta){
console.log("*** class does not have meta information compatible with dcl");
function logCtor (ctor) {
var meta = ctor[mname];
if (!meta) {
console.log('*** class does not have meta information compatible with dcl');
return;
}
var weaver = meta.weaver, bases = meta.bases, chains = meta.chains, names = [], base, name, someUnknown, i;
for(i = 0; i < bases.length; ++i){
base = bases[i];
name = base.prototype.hasOwnProperty("declaredClass") && base.prototype.declaredClass;
if(!name){
name = "UNNAMED_" + (base.hasOwnProperty("_uniqueId") ? base._uniqueId : "");
someUnknown = true;
}
names.push(name);
var names = meta.bases.map(function (base, index) {
return base[pname].declaredClass || ('UNNAMED_' + index);
});
console.log('*** class ' + names[names.length - 1] + ' depends on ' +
(names.length - 1) + (names.length == 2 ? ' class' : ' classes') +
(names.length > 1 ? ': ' + names.slice(0, -1).join(', ') : '')
);
var specialKeys = Object.keys(meta.special);
if (specialKeys.length) {
console.log('*** class ' + names[names.length - 1] + ' has ' +
specialKeys.length + (specialKeys.length == 1 ? ' weaver: ' : ' weavers: ') +
specialKeys.map(function (name) {
return name + ': ' + meta.special[name].name;
}).join(', ')
);
}
console.log("*** class " + names[0] + " depends on " + (names.length - 1) + " classes");
if(names.length > 1){
console.log(" dependencies: " + names.slice(1).join(", "));
}
if(someUnknown){
console.log(" " + noDecls);
}
dcl.allKeys(weaver).forEach(function(name){
i = +weaver[name];
if(!isNaN(i)){
var hasStub = typeof ctor.prototype[name].advices == "object";
if(hasStub){
var b = dcl._extractChain(bases, name, "b").length,
f = dcl._extractChain(bases, name, "f").length,
a = dcl._extractChain(bases, name, "a").length;
}
console.log(" class method " + name + " is " + chainName(i) +
(hasStub ?
", and has an AOP stub (before: " + b + ", around: " + f + ", after: " + a + ")" :
" (length: " + chains[name].length + ")" ));
}
});
}
function countAdvices(node, chain){
for(var counter = 0, p = node[chain]; p != node; p = p[chain], ++counter);
return counter;
function logAdvices (advices) {
return 'class-level advice (before ' + advices.before.length +
', after ' + advices.after.length + ')';
}
function log(o, suppressCtor){
switch(typeof o){
case "function":
logCtor(o);
return;
case "object":
var base = o.constructor,
name = base.prototype.hasOwnProperty("declaredClass") && base.prototype.declaredClass;
if(!name){
name = "UNNAMED_" + (base.hasOwnProperty("_uniqueId") ? base._uniqueId : "");
}
console.log("*** object of class " + name);
// log the constructor
if(!suppressCtor){
logCtor(base);
}
// log methods
dcl.allKeys(o).forEach(function(name){
var f = o[name], b, r, a;
if(typeof f == "function"){
if(f.adviceNode && f.adviceNode instanceof advise.Node){
b = countAdvices(f.adviceNode, "pb");
r = countAdvices(f.adviceNode, "pf");
a = countAdvices(f.adviceNode, "pa");
console.log(" object method " + name + " has an AOP stub (before: " +
b + ", around: " + r + ", after: " + a + ")");
function countAdvices (root, chain) {
var total = 0;
for (var node = root[chain]; node && node !== root; node = node[chain], ++total);
return total;
}
function logNode (node) {
return 'object-level advice (before ' + countAdvices(node, 'next_before') +
', after ' + countAdvices(node, 'next_after') + ')';
}
function log (o, suppressCtor) {
if (typeof o == 'function') {
logCtor(o);
} else if (o && typeof o == 'object') {
var base = o[cname];
if (base[pname].declaredClass) {
console.log('*** object of class ' + base[pname].declaredClass);
}
if (!suppressCtor) {
logCtor(base);
}
allKeys(o).forEach(function (name) {
var prop = dcl.getPropertyDescriptor(o, name);
if (prop.get || prop.set) {
if (prop.get) {
if (prop.get.node instanceof advise.Node) {
console.log(' ' + name + ': getter with ' + logNode(prop.get.node));
} else if (typeof prop.get.advices == 'object') {
console.log(' ' + name + ': getter with ' + logAdvices(prop.get.advices));
}
}
});
return;
if (prop.set) {
if (prop.set.node instanceof advise.Node) {
console.log(' ' + name + ': setter with ' + logNode(prop.set.node));
} else if (typeof prop.set.advices == 'object') {
console.log(' ' + name + ': setter with ' + logAdvices(prop.set.advices));
}
}
} else {
if (prop.value.node instanceof advise.Node) {
console.log(' ' + name + ': ' + logNode(prop.value.node));
} else if (typeof prop.value.advices == 'object') {
console.log(' ' + name + ': ' + logAdvices(prop.value.advices));
}
}
});
}
console.log(o);
}
return {
log: log,
DclError: DclError,
CycleError: CycleError,
ChainingError: ChainingError,
SetChainingError: SetChainingError,
SuperCallError: SuperCallError,
SuperError: SuperError,
SuperResultError: SuperResultError
};
dcl.log = log;
dcl.DclError = DclError;
dcl.CycleError = CycleError;
dcl.ChainingError = ChainingError;
dcl.SuperError = SuperError;
return dcl;
function allKeys (o) {
var keys = [];
for (var key in o) {
keys.push(key);
}
return keys;
}
});

@@ -1,23 +0,17 @@

(function(factory){
if(typeof define != "undefined"){
define(["../dcl", "./Destroyable"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("../dcl"), require("./Destroyable"));
}else{
dclMixinsCleanup = factory(dcl, dclMixinsDestroyable);
}
})(function(dcl, Destroyable){
"use strict";
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['../dcl', './Destroyable'], function (dcl, Destroyable) {
'use strict';
return dcl(Destroyable, {
declaredClass: "dcl/mixins/Cleanup",
constructor: function(){
declaredClass: 'dcl/mixins/Cleanup',
constructor: function () {
this.__cleanupStack = [];
},
pushCleanup: function(resource, cleanup){
var f = cleanup ? function(){ cleanup(resource); } : function(){ resource.destroy(); };
pushCleanup: function (resource, cleanup) {
var f = cleanup ? function () { cleanup(resource); } : function () { resource.destroy(); };
this.__cleanupStack.push(f);
return f;
},
popCleanup: function(dontRun){
if(dontRun){
popCleanup: function (dontRun) {
if (dontRun) {
return this.__cleanupStack.pop();

@@ -27,5 +21,5 @@ }

},
removeCleanup: function(f){
for(var i = this.__cleanupStack.length - 1; i >= 0; --i){
if(this.__cleanupStack[i] === f){
removeCleanup: function (f) {
for (var i = this.__cleanupStack.length - 1; i >= 0; --i) {
if (this.__cleanupStack[i] === f) {
this.__cleanupStack.splice(i, 1);

@@ -36,8 +30,8 @@ return true;

},
cleanup: function(){
while(this.__cleanupStack.length){
cleanup: function () {
while (this.__cleanupStack.length) {
this.__cleanupStack.pop()();
}
},
destroy: function(){
destroy: function () {
this.cleanup();

@@ -44,0 +38,0 @@ }

@@ -1,14 +0,9 @@

(function(factory){
if(typeof define != "undefined"){
define(["../dcl"], factory);
}else if(typeof module != "undefined"){
module.exports = factory(require("../dcl"));
}else{
dclMixinsDestroyable = factory(dcl);
}
})(function(dcl){
"use strict";
var Destroyable = dcl(null, {declaredClass: "dcl/mixins/Destroyable"});
dcl.chainBefore(Destroyable, "destroy");
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['../dcl'], function (dcl) {
'use strict';
var Destroyable = dcl(null, {declaredClass: 'dcl/mixins/Destroyable'});
dcl.chainBefore(Destroyable, 'destroy');
return Destroyable;
});
{
"name": "dcl",
"version": "1.1.3",
"version": "2.0.0",
"description": "Elegant minimalistic implementation of OOP with mixins + AOP.",
"author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (http://lazutkin.com/)",
"license": "BSD-3-Clause",
"homepage": "http://www.dcljs.org",

@@ -13,6 +15,8 @@ "bugs": "http://github.com/uhop/dcl/issues",

"devDependencies": {
"heya-unit": ">=0.1"
"heya-unit": ">=0.1",
"heya-globalize": "^1.0.3"
},
"scripts": {
"test": "node tests/tests.js"
"test": "node tests/tests.js",
"dist": "node node_modules/heya-globalize/index.js"
},

@@ -32,15 +36,8 @@ "github": "http://github.com/uhop/dcl",

],
"author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (http://lazutkin.com/)",
"licenses": [
{
"type": "New BSD",
"url": "http://github.com/uhop/dcl/blob/master/LICENSE"
},
{
"type": "AFL 2.1",
"url": "http://github.com/uhop/dcl/blob/master/LICENSE"
}
],
"icon": "http://www.dcljs.org/fav144.png",
"dojoBuild": "package.js"
"browserGlobals": {
"!root": "dcl",
"./dcl": "dcl",
"./advise": "advise",
"./debug": "!dcl"
}
}

@@ -1,2 +0,2 @@

# DCL
# `dcl`

@@ -8,3 +8,2 @@ [![Build status][travis-image]][travis-url]

A minimalistic yet complete JavaScript package for [node.js](http://nodejs.org)

@@ -23,440 +22,236 @@ and modern browsers that implements OOP with mixins + AOP at both "class" and

If you migrate your code from a legacy framework that implements dynamic (rather
than static) supercalls, take a look at the module "inherited" that dispatches
supercalls dynamically trading off the simplicity of the code for some run-time
CPU use, and a little bit less convenient debugging of such calls due to an extra
stub between your methods.
Based on ES5, the `dcl 2.x` works on Node and all ES5-compatible browsers. It fully
supports property descriptors, including AOP advices for getters and setters,
as well as regular values. If your project needs to support legacy browsers,
please consider `dcl 1.x`.
The library includes a small library of useful base classes, mixins, and advices.
The main hub of everything `dcl`-related is [dcljs.org](http://www.dcljs.org/),
which hosts [extensive documentation](http://www.dcljs.org/docs/).
## How to install
# Examples
If you plan to use it in your [node.js](http://nodejs.org) project, install it
like this:
Create simple class:
```js
var A = dcl({
constructor: function (x) { this.x = x; },
m: function () { return this.x; }
});
```
npm install dcl
```
For your browser-based projects I suggest to use [volo.js](http://volojs.org):
Single inheritance:
```
volo install uhop/dcl
```
## How to use
```js
// if you run node.js, or CommonJS-compliant system
var dcl = require("dcl");
var B = dcl(A, {
// no constructor
// constructor of A will be called automatically
// if you use dcl in a browser with AMD (like RequireJS):
require(["dcl"], function(dcl){
// the same code that uses dcl
m: function () { return this.x + 1; }
});
// or when you define your own module:
define(["dcl"], function(dcl){
// your dcl-using code goes here
});
```
### Inheritance, constructors, super calls
Multiple inheritance with mixins:
Let's continue with our coding example:
```js
// declare a class derived from Object:
var Person = dcl(null, {
// (optional, but recommended) name your class:
declaredClass: "Person",
// let's specify a default name as a class-level constant
name: "Anonymous",
// constructor is a method named ... 'constructor'
constructor: function(name){
if(name){
this.name = name;
}
console.log("Person " + this.name + " is constructed");
}
var M = dcl({
sqr: function () { var x = this.m(); return x * x; }
});
// we can derive more classes from it using single inheritance
var Bureaucrat = dcl(Person, {
declaredClass: "Bureaucrat",
constructor: function(name){
console.log("Bureaucrat " + this.name + " is constructed");
},
approve: function(document){
// NEVER!
console.log("Rejected by " + this.name);
return false;
}
});
var AM = dcl([A, M]);
var BM = dcl([B, M]);
var clerk = new Bureaucrat();
// Person Anonymous is constructed
// Bureaucrat Anonymous is constructed
clerk.approve(123);
// Rejected by Anonymous
var am = new AM(2);
console.log(am.sqr()); // 4
var bm = new BM(2);
console.log(bm.sqr()); // 9
```
As you can see it is trivial to define "classes" and derive them using
single inheritance. Constructors are automatically chained and called from
the farthest to the closest with the same arguments. Our Bureaucrat constructor
ignores name, because it knows that Person will take care of it.
Super call:
Now let's do a mixin.
```js
// let's declare one more class that will be used as a mixin
// any normal class would do
var Speaker = dcl(null, {
speak: function(msg){
// a method --- just a simple function
console.log(this.name + ": " + msg);
}
var AMSuper = dcl([A, M], {
m: dcl.superCall(function (sup) {
return function () {
return sup.call(this) + 1;
};
})
});
// now we are ready to create Talker from Person + Speaker
var Talker = dcl([Person, Speaker], {
// no own methods for simplicity
});
var alice = new Talker("Alice");
// Person Alice is constructed
alice.speak("hello!");
// Alice: hello!
var ams = new AMSuper(3);
console.log(ams.sqr()); // 16
```
Now let's call a method of our super class.
AOP advices:
```js
// let's declare another mixin, this time using a super call
var Shouter = dcl(Speaker, {
speak: dcl.superCall(function(sup){
// we use the double function technique to inject
// "sup" --- a method from a super class
return function(msg){
if(sup){
// theoretically it is possible that
// there is no super method --- we can be last in line;
// not in this case, though --- we are based
// on Speaker meaning it will be always pulled in
sup.call(this, msg.toUpperCase());
}
};
})
var C = dcl(AMSuper, {
constructor: dcl.advise({
before: function (x) {
console.log('ctr arg:', x);
},
after: function () {
console.log('this.x:', this.x);
}
}),
m: dcl.after(function (args, result, makeReturn) {
console.log('m() returned:', result);
// let's fix it
makeReturn(5);
})
});
var Sarge = dcl([Talker, Shouter], {
// no own methods for simplicity
});
var bob = new Sarge("Bob");
// Person Bob is constructed
bob.speak("give me twenty!");
// Bob: GIVE ME TWENTY!
var c = new C(1);
// prints:
// ctr arg: 1
// this.x: 1
console.log(c.sqr());
// prints:
// m() returned: 2
// 25
```
The double function technique for a super call allows you to work directly with
a next method in chain --- no intermediaries means that this call is as fast as
it can be, no run-time penalties are involved during method calls, and it greatly
simplifies debugging.
Super call with getters:
And, of course, our "classes" can be absolutely anonymous, like in this one-off "class":
```js
var loudBob = new (dcl([Talker, Shouter], {}))("Loud Bob");
// Person Loud Bob is constructed
loudBob.speak("Anybody home?");
// Loud Bob: ANYBODY HOME?
```
var G = dcl({
constructor: function (x) { this._x = x; },
get x () { return this._x; }
});
### AOP
var g = new G(1);
console.log(g.x); // 1
We can use aspect-oriented advices to create our "classes":
```js
// one more mixin
var Sick = dcl(Person, {
speak: dcl.advise({
before: function(msg){
console.log(this.name + ": *hiccup* *hiccup* *hiccup*");
},
after: function(args, result){
console.log(this.name + ": *sniffle* I am so-o-o sick!");
}
var F = dcl(G, {
x: dcl.prop({
get: dcl.superCall(function (sup) {
return function () {
return sup.call(this) + 1;
};
})
})
});
var SickTalker = dcl([Talker, Sick], {
// no own methods for simplicity
});
var clara = new SickTalker("Clara");
// Person Clara is constructed
clara.speak("I want a glass of water!");
// Clara: *hiccup* *hiccup* *hiccup*
// Clara: I want a glass of water!
// Clara: *sniffle* I am so-o-o sick!
var f = new F(1);
console.log(f.x); // 2
```
Hmm, both `Talker` and `Sick` require the same "class" `Person`. How is it going
to work? Don't worry, all duplicates are going to be eliminated by the underlying
[C3 MRO](http://www.python.org/download/releases/2.3/mro/) algorithm. Read all
about it in [the documentation](http://dcljs.org/docs/).
Advise an object:
Of course we can use an "around" advice as well, and it will behave just like
a super call above. It will require the same double function technique to inject
a method from a super class.
```js
// One more mixin
var Martian = dcl(Speaker, {
speak: dcl.around(function(sup){
return function(msg){
if(sup){
sup.call(this, "beep-beep-beep");
}
};
})
});
function D (x) { this.x = x; }
D.prototype.m = function (y) { return this.x + y; }
// now we are ready for...
var SickMartianSarge = dcl([Sarge, Sick, Martian], {
// no own methods for simplicity
var d = new D(1);
console.log(d.m(2)); // 3
advise(d, 'm', {
before: function (y) { console.log('y:', y); },
around: function (sup) {
return function (y) {
console.log('around');
return 2 * sup.call(this, y + 1);
};
},
after: function (args, result) {
console.log('# of args:', args.length);
console.log('args[0]:', args[0]);
console.log('result:', result);
}
});
var don = new SickMartianSarge("Don");
// Person Don is constructed
don.speak("Doctor? Nurse? Anybody?");
// Don: *hiccup* *hiccup* *hiccup*
// Don: BEEP-BEEP-BEEP
// Don: *sniffle* I am so-o-o sick!
console.log(d.m(2));
// prints:
// y: 2
// around
// # of args: 1
// args[0]: 2
// result: 8
```
For convenience, `dcl` provides shortcuts for singular advices:
Additionally `dcl` provides a small library of predefined
[base classes](http://www.dcljs.org/docs/bases/),
[mixins](http://www.dcljs.org/docs/mixins/),
and [useful advices](http://www.dcljs.org/docs/advices/). Check them out too.
```
// pseudo code
dcl.before(f) == dcl.advise({before: f})
dcl.around(f) == dcl.advise({around: f})
dcl.after (f) == dcl.advise({after: f})
```
For more examples, details, howtos, and why, please read [the docs](http://www.dcljs.org/docs/).
### Chaining
# How to install
While constructors are chained by default you can chain any methods you like.
Usually it works well for lifecycle methods, and event-like methods.
With `npm`:
```js
// waker-upper and sleeper
var BioOrganism = dcl(null, {
// no methods for simplicity
});
dcl.chainAfter(BioOrganism, "wakeUp");
dcl.chainBefore(BioOrganism, "sleep");
// now wakeUp() and sleep() are automatically chained
// our mixins
var SwitchOperator = dcl(null, {
wakeUp: function(){ console.log("turn on lights"); },
sleep: function(){ console.log("turn off lights"); }
});
var TeethBrusher = dcl(null, {
wakeUp: function(){ console.log("brush my teeth"); },
sleep: function(){ console.log("brush my teeth again"); }
});
var SmartDresser = dcl(null, {
wakeUp: function(){ console.log("dress up for work"); },
sleep: function(){ console.log("switch to pajamas"); }
});
// all together now
var OfficeWorker = dcl([BioOrganism, SwitchOperator, TeethBrusher, SmartDresser], {
// no methods for simplicity
});
var ethel = OfficeWorker();
ethel.wakeUp();
// turn on lights
// brush my teeth
// dress up for work
ethel.sleep();
// switch to pajamas
// brush my teeth again
// turn off lights
```
npm install --save dcl
```
### Advising objects
With `yarn`:
While class-level AOP is static, we can always advise any method dynamically,
and unadvise it at will:
```js
// let's implement previous example with object-level AOP
// for that we need to use a new module:
var advise = require("dcl/advise");
// let's use one-off class
var ethel = new (dcl(null, {
wakeUp: function(){ /* nothing */ },
sleep: function(){ /* nothing */ }
}))();
var wakeAd1 = advise(ethel, "wakeUp", {
before: function(){ console.log("turn on lights"); }
});
var wakeAd2 = advise(ethel, "wakeUp", {
before: function(){ console.log("brush my teeth"); }
});
var wakeAd3 = advise(ethel, "wakeUp", {
before: function(){ console.log("dress up for work"); }
});
// notice that after advices attached in the reverse order
var sleepAd1 = advise(ethel, "sleep", {
after: function(){ console.log("switch to pajamas"); }
});
var sleepAd2 = advise(ethel, "sleep", {
after: function(){ console.log("brush my teeth again"); }
});
var sleepAd3 = advise(ethel, "sleep", {
after: function(){ console.log("turn off lights"); }
});
ethel.wakeUp();
// turn on lights
// brush my teeth
// dress up for work
ethel.sleep();
// switch to pajamas
// brush my teeth again
// turn off lights
// let's save on electricity
wakeAd1.unadvise();
// brushing teeth more than once a day is overrated, right?
sleepAd2.unadvise();
// no need to dress up for work either --- Ethel is CEO!
wakeAd3.unadvise();
ethel.wakeUp();
// brush my teeth
ethel.sleep();
// switch to pajamas
// turn off lights
```
yarn add dcl
```
Again, for convenience, `dcl/advise` provides shortcuts for singular advices:
With `bower`:
```
// pseudo code
advise.before(obj, methodName, f) == advise(obj, methodName, {before: f})
advise.around(obj, methodName, f) == advise(obj, methodName, {around: f})
advise.after (obj, methodName, f) == advise(obj, methodName, {after: f})
bower install --save dcl
```
Naturally "around" advices use the same double function technique to be super
light-weight.
## How to use
### Debugging helpers
`dcl` can be installed with `npm`, `yarn`, or `bower` with files available from
`node_modules/` or `bower_components/`. By default, it uses UMD, and ready
to be used with Node's `require()`:
There is a special module `dcl/debug` that adds better error checking and reporting
for your "classes" and objects. All you need is to require it, and it will plug
right in:
```js
var dclDebug = require("dcl/debug");
// if you run node.js, or CommonJS-compliant system
var dcl = require('dcl');
var advise = require('dcl/advise');
```
In order to use it to its fullest, we should include a static class id in our
"class" definitions like so:
It can be used with AMD out of box:
```js
var OurClass = dcl(null, {
declaredClass: "OurClass",
// ... the rest of definitions
// if you use dcl in a browser with AMD (like RequireJS):
require(['dcl'], function (dcl) {
// the same code that uses dcl
});
// or when you define your own module:
define(['dcl'], function (dcl) {
// your dcl-using code goes here
});
```
It is strongly suggested to specify `declaredClass` for every declaration in every
real project.
If you prefer to use globals in a browser, include files with `<script>` from `/dist/`:
This `declaredClass` can be any unique string, but by convention it should be
a human-readable name of your "class", which possibly indicate where this class can
be found. For example, if you follow the convention "one class per file it can be
something like `"myProject/aSubDir/aFileName"`. If you define several "classes"
per file you can use a following schema: `"myProject/SubDirs/FileName/ClassName"`.
Remember that this name is for you, it will be reported in error messages and logs.
```html
<script src='node_modules/dcl/dist/dcl.js'></script>
```
Yes, logs. The debug module can log constructors and objects created by
those constructors:
Alternatively, you can use https://unpkg.com/ with AMD or globals. For example:
```js
var A = dcl(null, {
declaredClass: "A",
sleep: dcl.after(function(){
console.log("*zzzzzzzzzzzzz*");
})
});
```html
<script src='https://unpkg.com/dcl@latest/dist/dcl.js'></script>
```
var B = dcl(A, {
declaredClass: "B",
sleep: function(){
console.log("Time to hit the pillow!");
}
});
# Documentation
var fred = new B();
advise.after(fred, "sleep", function(){
console.log("*ZzZzZzZzZzZzZ*")
});
fred.sleep();
// Time to hit the pillow!
// *zzzzzzzzzzzzz*
// *ZzZzZzZzZzZzZ*
`dcl` is extensively documented in [the docs](http://www.dcljs.org/docs/).
// now we can inspect all our objects:
# Versions
dclDebug.log(A);
// *** class A depends on 0 classes
// class method constructor is CHAINED AFTER (length: 0)
// class method sleep is UNCHAINED BUT CONTAINS ADVICE(S),
// and has an AOP stub (before: 0, around: 0, after: 1)
## 2.x
dclDebug.log(B);
// *** class B depends on 1 classes
// dependencies: A
// class method constructor is CHAINED AFTER (length: 0)
// class method sleep is UNCHAINED BUT CONTAINS ADVICE(S),
// and has an AOP stub (before: 0, around: 1, after: 1)
- 2.0.0 &mdash; *The initial release of 2.x*
dclDebug.log(fred);
// *** object of class B
// *** class B depends on 1 classes
// dependencies: A
// class method constructor is CHAINED AFTER (length: 0)
// class method sleep is UNCHAINED BUT CONTAINS ADVICE(S),
// and has an AOP stub (before: 0, around: 1, after: 1)
// object method sleep has an AOP stub (before: 0, around: 1, after: 2)
```
## 1.x
This way we can always know that we generated correct classes, inspect static
chaining and advices, and even can monitor dynamically attached/removed advices.
- 1.1.3 &mdash; *1.x version before forking for 2.x*
## Summary
# License
Obviously this is a simple readme that was supposed to give an overview of `dcl`.
For more details, please read [the docs](http://www.dcljs.org/docs/).
BSD or AFL &mdash; your choice.
Additionally `dcl` provides a small library of predefined
[base classes](http://www.dcljs.org/docs/bases/),
[mixins](http://www.dcljs.org/docs/mixins/),
and [useful advices](http://www.dcljs.org/docs/advices/). Check them out too.
Happy hacking!
[npm-image]: https://img.shields.io/npm/v/dcl.svg

@@ -467,4 +262,4 @@ [npm-url]: https://npmjs.org/package/dcl

[dev-deps-image]: https://img.shields.io/david/dev/uhop/dcl.svg
[dev-deps-url]: https://david-dm.org/uhop/dcl#info=devDependencies
[dev-deps-url]: https://david-dm.org/uhop/dcl?type=dev
[travis-image]: https://img.shields.io/travis/uhop/dcl.svg
[travis-url]: https://travis-ci.org/uhop/dcl
/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../advise", "../advices/counter", "../advices/flow",
"../advices/time", "../advices/memoize", "../advices/trace"],
function(module, unit, dcl, advise, counter, flow, time, memoize, trace){
(['module', 'heya-unit', '../dcl', '../advise', '../advices/counter', '../advices/flow',
'../advices/time', '../advices/memoize', '../advices/trace'],
function (module, unit, dcl, advise, counter, flow, time, memoize, trace) {
'use strict';
"use strict";
var Ackermann = dcl(null, {
declaredName: "Ackermann",
m0: function(n){
declaredName: 'Ackermann',
m0: function (n) {
return n + 1;
},
n0: function(m){
n0: function (m) {
return this.a(m - 1, 1);
},
a: function(m, n){
if(m == 0){
a: function (m, n) {
if (m == 0) {
return this.m0(n);
}
if(n == 0){
if (n == 0) {
return this.n0(m);

@@ -31,14 +30,12 @@ }

function test_counter(t){
"use strict";
var x = new Ackermann();
var counterM0 = counter();
advise(x, "m0", counterM0.advice());
advise(x, 'm0', counterM0.advice());
var counterN0 = counter();
advise(x, "n0", counterN0.advice());
advise(x, 'n0', counterN0.advice());
var counterA = counter();
advise(x, "a", counterA.advice());
advise(x, 'a', counterA.advice());

@@ -56,10 +53,8 @@ x.a(3, 2);

test: function test_flow(t){
"use strict";
// our advised version:
var AdvisedAckermann = dcl(Ackermann, {
declaredName: "AdvisedAckermann",
m0: dcl.advise(flow.advice("m0")),
n0: dcl.advise(flow.advice("n0")),
a: dcl.advise(flow.advice("a"))
declaredName: 'AdvisedAckermann',
m0: dcl.advise(flow.advice('m0')),
n0: dcl.advise(flow.advice('n0')),
a: dcl.advise(flow.advice('a'))
});

@@ -69,10 +64,10 @@

var InstrumentedAckermann = dcl(AdvisedAckermann, {
declaredName: "InstrumentedAckermann",
m0: dcl.around(function(sup){
return function(n){
t.info("a() called: " + (flow.inFlowOf("a") || 0));
t.info("n0() called: " + (flow.inFlowOf("n0") || 0));
declaredName: 'InstrumentedAckermann',
m0: dcl.around(function (sup) {
return function (n) {
t.info('a() called: ' + (flow.inFlowOf('a') || 0));
t.info('n0() called: ' + (flow.inFlowOf('n0') || 0));
var stack = flow.getStack();
var previous = stack[stack.length - 2] || "(none)";
t.info("m0() called from: " + previous);
var previous = stack[stack.length - 2] || '(none)';
t.info('m0() called from: ' + previous);
return sup.call(this, n);

@@ -87,13 +82,11 @@ }

logs: [
{text: "a() called: 3"},
{text: "n0() called: 1"},
{text: "m0() called from: a"},
{text: "a() called: 2"},
{text: "n0() called: 0"},
{text: "m0() called from: a"}
{text: 'a() called: 3'},
{text: 'n0() called: 1'},
{text: 'm0() called from: a'},
{text: 'a() called: 2'},
{text: 'n0() called: 0'},
{text: 'm0() called from: a'}
]
},
function test_memoize(t){
"use strict";
// TODO: redirect console to ice

@@ -104,3 +97,3 @@

advise(x, "a", time("x.a"));
advise(x, 'a', time('x.a'));

@@ -112,9 +105,9 @@ x.a(3, 3);

advise(y, "m0", memoize.advice("m0"));
advise(y, "n0", memoize.advice("n0"));
advise(y, "a", memoize.advice("a", function(self, args){
return args[0] + "-" + args[1];
advise(y, 'm0', memoize.advice('m0'));
advise(y, 'n0', memoize.advice('n0'));
advise(y, 'a', memoize.advice('a', function (self, args) {
return args[0] + '-' + args[1];
}));
advise(y, "a", time("y.a"));
advise(y, 'a', time('y.a'));

@@ -126,4 +119,2 @@ y.a(3, 3);

function test_trace(t){
"use strict";
// TODO: redirect console to ice

@@ -134,5 +125,5 @@

advise(x, "m0", trace("m0", true));
advise(x, "n0", trace("n0", true));
advise(x, "a", trace("a", true));
advise(x, 'm0', trace('m0', true));
advise(x, 'n0', trace('n0', true));
advise(x, 'a', trace('a', true));

@@ -139,0 +130,0 @@ x.a(1, 1);

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../advise"], function(module, unit, dcl, advise){
(['module', 'heya-unit', '../dcl', '../advise'], function (module, unit, dcl, advise) {
'use strict';
"use strict";
// tests
unit.add(module, [
function test_dclAdvise_with_advise(t){
"use strict";
function test_dclAdvise_with_advise (t) {
'use strict';
var A = dcl(null, {
m1: dcl.advise({
before: function(){
if(!this.a){ this.a = ""; }
this.a += "b";
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'b';
},
after: function(){
if(!this.a){ this.a = ""; }
this.a += "a";
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'a';
}

@@ -25,4 +24,4 @@ })

var B = dcl(A, {
m1: function(x){
if(!this.a){ this.a = ""; }
m1: function (x) {
if (!this.a) { this.a = ''; }
this.a += x;

@@ -33,63 +32,63 @@ }

var x = new B;
x.m1("-");
x.m1('-');
eval(t.TEST('x.a === "b-a"'));
var h1 = advise(x, "m1", {
after: function(){
if(!this.a){ this.a = ""; }
this.a += "A1";
var h1 = advise(x, 'm1', {
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'A1';
}
});
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "b-aA1"'));
var h2 = advise(x, "m1", {
before: function(){
if(!this.a){ this.a = ""; }
this.a += "B1";
var h2 = advise(x, 'm1', {
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'B1';
}
});
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "B1b-aA1"'));
var h3 = advise(x, "m1", {
around: function(sup){
return function(){
if(!this.a){ this.a = ""; }
this.a += "F1";
if(sup){ sup.apply(this, arguments); }
this.a += "F2";
var h3 = advise(x, 'm1', {
around: function (sup) {
return function () {
if (!this.a) { this.a = ''; }
this.a += 'F1';
if (sup) { sup.apply(this, arguments); }
this.a += 'F2';
};
}
});
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "B1bF1-F2aA1"'));
h1.unadvise();
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "B1bF1-F2a"'));
h2.unadvise();
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "bF1-F2a"'));
h3.unadvise();
x.a = "";
x.m1("-");
x.a = '';
x.m1('-');
eval(t.TEST('x.a === "b-a"'));
},
function test_advise(t){
"use strict";
function test_advise (t) {
'use strict';
var x = new (dcl(null, {
constructor: function(){
this.a = "";
constructor: function () {
this.a = '';
},
m1: function(){
this.a += "*";
m1: function () {
this.a += '*';
}

@@ -101,8 +100,8 @@ }));

var h1 = advise(x, "m1", {
around: function(sup){
return function(){
this.a += "b1";
var h1 = advise(x, 'm1', {
around: function (sup) {
return function () {
this.a += 'b1';
sup.call(this);
this.a += "a1";
this.a += 'a1';
};

@@ -112,12 +111,12 @@ }

x.a = "";
x.a = '';
x.m1();
eval(t.TEST('x.a === "b1*a1"'));
var h2 = advise(x, "m1", {
around: function(sup){
return function(){
this.a += "b2";
var h2 = advise(x, 'm1', {
around: function (sup) {
return function () {
this.a += 'b2';
sup.call(this);
this.a += "a2";
this.a += 'a2';
};

@@ -127,12 +126,12 @@ }

x.a = "";
x.a = '';
x.m1();
eval(t.TEST('x.a === "b2b1*a1a2"'));
var h3 = advise(x, "m1", {
around: function(sup){
return function(){
this.a += "b3";
var h3 = advise(x, 'm1', {
around: function (sup) {
return function () {
this.a += 'b3';
sup.call(this);
this.a += "a3";
this.a += 'a3';
};

@@ -142,12 +141,12 @@ }

x.a = "";
x.a = '';
x.m1();
eval(t.TEST('x.a === "b3b2b1*a1a2a3"'));
var h4 = advise(x, "m1", {
around: function(sup){
return function(){
this.a += "b4";
var h4 = advise(x, 'm1', {
around: function (sup) {
return function () {
this.a += 'b4';
sup.call(this);
this.a += "a4";
this.a += 'a4';
};

@@ -157,3 +156,3 @@ }

x.a = "";
x.a = '';
x.m1();

@@ -163,3 +162,3 @@ eval(t.TEST('x.a === "b4b3b2b1*a1a2a3a4"'));

h2.unadvise();
x.a = "";
x.a = '';
x.m1();

@@ -169,3 +168,3 @@ eval(t.TEST('x.a === "b4b3b1*a1a3a4"'));

h1.unadvise();
x.a = "";
x.a = '';
x.m1();

@@ -175,3 +174,3 @@ eval(t.TEST('x.a === "b4b3*a3a4"'));

h3.unadvise();
x.a = "";
x.a = '';
x.m1();

@@ -181,3 +180,3 @@ eval(t.TEST('x.a === "b4*a4"'));

h4.unadvise();
x.a = "";
x.a = '';
x.m1();

@@ -184,0 +183,0 @@ eval(t.TEST('x.a === "*"'));

@@ -1,19 +0,16 @@

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../bases/Mixer", "../bases/Replacer"],
function(module, unit, dcl, Mixer, Replacer){
/* UMD.define */ (typeof define=='function'&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(['module', 'heya-unit', '../dcl', '../bases/Mixer', '../bases/Replacer'],
function (module, unit, dcl, Mixer, Replacer) {
'use strict';
"use strict";
// tests
unit.add(module, [
function test_Mixer(t){
"use strict";
function test_Mixer (t) {
var f = function () {};
var f = function(){}
var A = dcl(Mixer, {
declaredClass: "A",
declaredClass: 'A',
a: 1,
b: "two",
b: 'two',
c: null,

@@ -35,11 +32,9 @@ d: f

},
function test_Replacer(t){
"use strict";
function test_Replacer (t) {
var f = function () {};
var f = function(){}
var A = dcl(Replacer, {
declaredClass: "A",
declaredClass: 'A',
a: 1,
b: "two",
b: 'two',
c: null,

@@ -46,0 +41,0 @@ d: f

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl"], function(module, unit, dcl){
(['module', 'heya-unit', '../dcl'], function (module, unit, dcl) {
'use strict';
"use strict";
// tests
unit.add(module, [
function test_chaining(t){
"use strict";
function test_chaining (t) {
var A = dcl(null, {});
dcl.chainBefore(A, "m1");
dcl.chainAfter(A, "m2");
dcl.chainBefore(A, 'm1');
dcl.chainAfter (A, 'm2');
var B = dcl(null, {
m1: function(){
if(!this.b){ this.b = ""; }
this.b += "B";
m1: function () {
if (!this.b) { this.b = ''; }
this.b += 'B';
},
m2: function(){
if(!this.c){ this.c = ""; }
this.c += "B";
m2: function () {
if (!this.c) { this.c = ''; }
this.c += 'B';
}

@@ -28,9 +25,9 @@ });

var C = dcl(null, {
m1: function(){
if(!this.b){ this.b = ""; }
this.b += "C";
m1: function () {
if (!this.b) { this.b = ''; }
this.b += 'C';
},
m2: function(){
if(!this.c){ this.c = ""; }
this.c += "C";
m2: function () {
if (!this.c) { this.c = ''; }
this.c += 'C';
}

@@ -40,9 +37,9 @@ });

var D = dcl(null, {
m1: function(){
if(!this.b){ this.b = ""; }
this.b += "D";
m1: function () {
if (!this.b) { this.b = ''; }
this.b += 'D';
},
m2: function(){
if(!this.c){ this.c = ""; }
this.c += "D";
m2: function () {
if (!this.c) { this.c = ''; }
this.c += 'D';
}

@@ -59,29 +56,29 @@ });

},
function test_chain_with_super(t){
"use strict";
function test_chain_with_super (t) {
var A = dcl(null, {
constructor: function(){
declaredClass: 'A',
constructor: function () {
this.reset();
this.flag = true;
},
reset: function(){
this.b = this.c = "";
reset: function () {
this.b = this.c = '';
},
m1: function(){
this.b += "A";
m1: function () {
this.b += 'A';
},
m2: function(){
this.c += "A";
m2: function () {
this.c += 'A';
}
});
dcl.chainBefore(A, "m1");
dcl.chainAfter(A, "m2");
dcl.chainBefore(A, 'm1');
dcl.chainAfter (A, 'm2');
var B = dcl(null, {
m1: function(){
this.b += "B";
declaredClass: 'B',
m1: function () {
this.b += 'B';
},
m2: function(){
this.c += "B";
m2: function () {
this.c += 'B';
}

@@ -91,14 +88,15 @@ });

var C = dcl(null, {
m1: dcl.superCall(function(sup){
return function(){
this.b += "Cb";
if(this.flag && sup){ sup.call(this); }
this.b += "Ca";
declaredClass: 'C',
m1: dcl.superCall(function (sup) {
return function () {
this.b += 'Cb';
if (this.flag && sup) { sup.call(this); }
this.b += 'Ca';
};
}),
m2: dcl.superCall(function(sup){
return function(){
this.c += "Cb";
if(this.flag && sup){ sup.call(this); }
this.c += "Ca";
m2: dcl.superCall(function (sup) {
return function () {
this.c += 'Cb';
if (this.flag && sup) { sup.call(this); }
this.c += 'Ca';
};

@@ -109,7 +107,8 @@ })

var D = dcl(null, {
m1: function(){
this.b += "D";
declaredClass: 'D',
m1: function () {
this.b += 'D';
},
m2: function(){
this.c += "D";
m2: function () {
this.c += 'D';
}

@@ -119,7 +118,8 @@ });

var E = dcl(null, {
m1: function(){
this.b += "E";
declaredClass: 'E',
m1: function () {
this.b += 'E';
},
m2: function(){
this.c += "E";
m2: function () {
this.c += 'E';
}

@@ -143,5 +143,3 @@ });

},
function test_isInstanceOf(t){
"use strict";
function test_isInstanceOf (t) {
var A = dcl(null, {});

@@ -167,17 +165,17 @@ var B = dcl(null, {});

},
function test_postscript(t){
function test_postscript (t) {
var A = dcl(null, {
constructor: dcl.advise({
around: function(sup){
return function(){
if(!this.a){ this.a = ""; }
this.a += "A";
around: function (sup) {
return function () {
if (!this.a) { this.a = ''; }
this.a += 'A';
};
},
after: function(){
after: function () {
this.postscript();
}
}),
postscript: function(){
this.b = "A";
postscript: function () {
this.b = 'A';
}

@@ -187,8 +185,8 @@ });

var B = dcl(null, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "B";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'B';
},
postscript: function(){
this.b = "B";
postscript: function () {
this.b = 'B';
}

@@ -198,8 +196,8 @@ });

var C = dcl(null, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "C";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'C';
},
postscript: function(){
this.b = "C";
postscript: function () {
this.b = 'C';
}

@@ -220,20 +218,18 @@ });

},
function test_postscript2(t){
"use strict";
function test_postscript2 (t) {
var A = dcl(null, {
constructor: dcl.advise({
around: function(sup){
return function(){
if(!this.a){ this.a = ""; }
this.a += "A";
around: function (sup) {
return function () {
if (!this.a) { this.a = ''; }
this.a += 'A';
};
},
after: function(){
after: function () {
this.postscript();
}
}),
postscript: function(){
if(!this.a){ this.a = ""; }
this.a += "P";
postscript: function () {
if (!this.a) { this.a = ''; }
this.a += 'P';
}

@@ -243,5 +239,5 @@ });

var B = dcl(null, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "B";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'B';
}

@@ -251,5 +247,5 @@ });

var C = dcl(null, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "C";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'C';
}

@@ -273,10 +269,8 @@ });

},
function test_advise(t){
"use strict";
function test_advise (t) {
var A = dcl(null, {
m1: dcl.advise({
after: function(){
if(!this.a){ this.a = ""; }
this.a += "Aa";
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'Aa';
}

@@ -287,5 +281,5 @@ })

m1: dcl.advise({
before: function(){
if(!this.a){ this.a = ""; }
this.a += "Bb";
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'Bb';
}

@@ -295,10 +289,10 @@ })

var C = dcl(null, {
m1: dcl.superCall(function(sup){
return function(){
if(!this.a){ this.a = ""; }
this.a += "Cfb";
if(sup){
m1: dcl.superCall(function (sup) {
return function () {
if (!this.a) { this.a = ''; }
this.a += 'Cfb';
if (sup) {
sup.apply(this, arguments);
}
this.a += "Cfa";
this.a += 'Cfa';
};

@@ -309,19 +303,19 @@ })

m1: dcl.advise({
before: function(){
if(!this.a){ this.a = ""; }
this.a += "Db";
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'Db';
},
around: function(sup){
return function(){
if(!this.a){ this.a = ""; }
this.a += "Dfb";
if(sup){
around: function (sup) {
return function () {
if (!this.a) { this.a = ''; }
this.a += 'Dfb';
if (sup) {
sup.apply(this, arguments);
}
this.a += "Dfa";
this.a += 'Dfa';
};
},
after: function(){
if(!this.a){ this.a = ""; }
this.a += "Da";
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'Da';
}

@@ -331,5 +325,5 @@ })

var E = dcl(null, {
m1: function(){
if(!this.a){ this.a = ""; }
this.a += "E";
m1: function () {
if (!this.a) { this.a = ''; }
this.a += 'E';
}

@@ -346,14 +340,12 @@ });

},
function test_advise2(t){
"use strict";
function test_advise2 (t) {
var A = dcl(null, {
m1: dcl.advise({
before: function(){
if(!this.a){ this.a = ""; }
this.a += "Ab";
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'Ab';
},
after: function(){
if(!this.a){ this.a = ""; }
this.a += "Aa";
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'Aa';
}

@@ -364,9 +356,9 @@ })

m1: dcl.advise({
before: function(){
if(!this.a){ this.a = ""; }
this.a += "Bb";
before: function () {
if (!this.a) { this.a = ''; }
this.a += 'Bb';
},
after: function(){
if(!this.a){ this.a = ""; }
this.a += "Ba";
after: function () {
if (!this.a) { this.a = ''; }
this.a += 'Ba';
}

@@ -373,0 +365,0 @@ })

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../debug"], function(module, unit, dcl, dclDebug){
(['module', 'heya-unit', '../dcl', '../debug'], function(module, unit, dcl){
"use strict";
'use strict';

@@ -9,93 +9,98 @@ // tests

unit.add(module, [
function test_imposible_cycle(t){
"use strict";
function test_imposible_cycle (t) {
'use strict';
var A = dcl(null, {
declaredClass: "A"
declaredClass: 'A'
});
var B = dcl(null, {
declaredClass: "B"
declaredClass: 'B'
});
var AB = dcl([A, B], {
declaredClass: "AB"
declaredClass: 'AB'
});
var BA = dcl([B, A], {
declaredClass: "BA"
declaredClass: 'BA'
});
try{
try {
var Impossible = dcl([AB, BA], {
declaredClass: "Impossible"
declaredClass: 'Impossible'
});
// we should never be there
t.assert(false, "cycle error should be triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.CycleError'));
t.assert(false, 'cycle error should be triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.CycleError'));
}
},
function test_chaining_conflict(t){
"use strict";
function test_chaining_conflict (t) {
'use strict';
var A = dcl(null, {
declaredClass: "A"
declaredClass: 'A'
});
dcl.chainAfter(A, "m");
dcl.chainAfter(A, 'm');
var B = dcl(null, {
declaredClass: "B"
declaredClass: 'B'
});
dcl.chainBefore(B, "m");
dcl.chainBefore(B, 'm');
try{
try {
var ChainConflict = dcl([A, B], {
declaredClass: "ChainConflict"
declaredClass: 'ChainConflict'
});
// we should never be there
t.assert(false, "chain error is triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.ChainingError'));
t.assert(false, 'chain error is triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.ChainingError'));
}
},
function test_chaining_error(t){
"use strict";
function test_chaining_error (t) {
'use strict';
var A = dcl(null, {
declaredClass: "A"
declaredClass: 'A'
});
dcl.chainAfter(A, "m");
dcl.chainAfter(A, 'm');
try{
dcl.chainBefore(A, "m");
try {
dcl.chainBefore(A, 'm');
// we should never be there
t.assert(false, "set chaining error is triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.SetChainingError'));
t.assert(false, 'set chaining error is triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.ChainingError'));
}
},
function test_superCall_argument_error(t){
"use strict";
try{
function test_superCall_argument_error (t) {
'use strict';
try {
var A = dcl(null, {
declaredClass: "A",
m: dcl.superCall("Should be a function, but it is a string.")
declaredClass: 'A',
m: dcl.superCall('Should be a function, but it is a string.')
});
// we should never be there
t.assert(false, "supercall error is triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.SuperCallError'));
t.assert(false, 'supercall error is triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.SuperError'));
}
},
function test_superCall_super_error(t){
"use strict";
function test_superCall_super_error (t) {
'use strict';
var A = dcl(null, {
declaredClass: "A",
declaredClass: 'A',
m: 42 // not a function
});
try{
try {
var B = dcl(A, {
declaredClass: "B",
declaredClass: 'B',
m: dcl.superCall(function(sup){

@@ -106,22 +111,23 @@ return sup ? sup.call(this) : 0;

// we should never be there
t.assert(false, "super error is triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.SuperError'));
t.assert(false, 'super error is triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.SuperError'));
}
},
function test_superCall_wrapper(t){
"use strict";
try{
function test_superCall_wrapper (t) {
'use strict';
try {
var A = dcl(null, {
declaredClass: "A",
declaredClass: 'A',
m: dcl.superCall(function(sup){
return "Instead of a function I return a string.";
return 'Instead of a function I return a string.';
})
});
// we should never be there
t.assert(false, "super result error is triggered");
}catch(e){
eval(t.TEST('e instanceof dclDebug.DclError'));
eval(t.TEST('e instanceof dclDebug.SuperResultError'));
t.assert(false, 'super result error is triggered');
} catch (e) {
eval(t.TEST('e instanceof dcl.DclError'));
eval(t.TEST('e instanceof dcl.SuperError'));
}

@@ -128,0 +134,0 @@ }

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../mini"], function(module, unit, dcl){
(['module', 'heya-unit', '../dcl'], function (module, unit, dcl) {
'use strict';
"use strict";
function getNames(ctor){
var b = ctor._meta.bases, r = [];
for(var i = 0, l = b.length; i < l; ++i){
r.push(b[i].prototype.declaredClass);
}
return r.join(",");
function getNames(ctr) {
return ctr._meta.bases.map(function (base) {
return base.prototype.declaredClass;
}).join(',');
}

@@ -17,34 +14,32 @@

unit.add(module, [
function test_si(t){
"use strict";
var A = dcl(null, {declaredClass: "A"});
var B = dcl(A, {declaredClass: "B"});
var C = dcl(B, {declaredClass: "C"});
function test_si (t) {
var A = dcl(null, {declaredClass: 'A'});
var B = dcl(A, {declaredClass: 'B'});
var C = dcl(B, {declaredClass: 'C'});
eval(t.TEST('getNames(A) === "A"'));
eval(t.TEST('getNames(B) === "B,A"'));
eval(t.TEST('getNames(C) === "C,B,A"'));
eval(t.TEST('getNames(B) === "A,B"'));
eval(t.TEST('getNames(C) === "A,B,C"'));
},
function test_superCall(t){
"use strict";
function test_superCall (t) {
var A = dcl(null, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "A";
constructor: function () {
if(!this.a){ this.a = ''; }
this.a += 'A';
},
m1: function(){
this.b = "X";
m1: function () {
this.b = 'X';
},
m2: dcl.superCall(function(sup){
return function(){
if(sup){ sup.call(this); }
if(!this.c){ this.c = ""; }
this.c += "1";
m2: dcl.superCall(function (sup) {
return function () {
if (sup) { sup.call(this); }
if (!this.c) { this.c = ''; }
this.c += '1';
};
}),
m3: dcl.superCall(function(sup){
return function(){
if(!this.d){ this.d = ""; }
this.d += "M";
if(sup){ sup.call(this); }
m3: dcl.superCall(function (sup) {
return function () {
if (!this.d) { this.d = ''; }
this.d += 'M';
if (sup) { sup.call(this); }
};

@@ -58,2 +53,3 @@ })

a.m3();
eval(t.TEST('a.a === "A"'));

@@ -65,21 +61,21 @@ eval(t.TEST('a.b === "X"'));

var B = dcl(A, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "B";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'B';
},
m1: function(){
this.b = "Y";
m1: function () {
this.b = 'Y';
},
m2: dcl.superCall(function(sup){
return function(){
if(sup){ sup.call(this); }
if(!this.c){ this.c = ""; }
this.c += "2";
m2: dcl.superCall(function (sup) {
return function () {
if (sup) { sup.call(this); }
if (!this.c) { this.c = ''; }
this.c += '2';
};
}),
m3: dcl.superCall(function(sup){
return function(){
if(!this.d){ this.d = ""; }
this.d += "N";
if(sup){ sup.call(this); }
m3: dcl.superCall(function (sup) {
return function () {
if (!this.d) { this.d = ''; }
this.d += 'N';
if (sup) { sup.call(this); }
};

@@ -93,2 +89,3 @@ })

b.m3();
eval(t.TEST('b.a === "AB"'));

@@ -100,21 +97,21 @@ eval(t.TEST('b.b === "Y"'));

var C = dcl(B, {
constructor: function(){
if(!this.a){ this.a = ""; }
this.a += "C";
constructor: function () {
if (!this.a) { this.a = ''; }
this.a += 'C';
},
m1: function(){
this.b = "Z";
m1: function () {
this.b = 'Z';
},
m2: dcl.superCall(function(sup){
return function(){
if(sup){ sup.call(this); }
if(!this.c){ this.c = ""; }
this.c += "3";
m2: dcl.superCall(function (sup) {
return function () {
if (sup) { sup.call(this); }
if (!this.c) { this.c = ''; }
this.c += '3';
};
}),
m3: dcl.superCall(function(sup){
return function(){
if(!this.d){ this.d = ""; }
this.d += "O";
if(sup){ sup.call(this); }
m3: dcl.superCall(function (sup) {
return function () {
if (!this.d) { this.d = ''; }
this.d += 'O';
if (sup) { sup.call(this); }
};

@@ -128,2 +125,3 @@ })

c.m3();
eval(t.TEST('c.a === "ABC"'));

@@ -134,55 +132,50 @@ eval(t.TEST('c.b === "Z"'));

},
function test_diamonds(t){
"use strict";
function test_diamonds (t) {
var A = dcl(null, {declaredClass: 'A'});
var B = dcl(null, {declaredClass: 'B'});
var C = dcl(null, {declaredClass: 'C'});
var D = dcl(null, {declaredClass: 'D'});
var A = dcl(null, {declaredClass: "A"});
var B = dcl(null, {declaredClass: "B"});
var C = dcl(null, {declaredClass: "C"});
var D = dcl(null, {declaredClass: "D"});
var ABC = dcl([A, B, C], {declaredClass: 'ABC'});
var ADC = dcl([A, D, C], {declaredClass: 'ADC'});
var ABC = dcl([A, B, C], {declaredClass: "ABC"});
var ADC = dcl([A, D, C], {declaredClass: "ADC"});
eval(t.TEST('getNames(ABC) === "A,B,C,ABC"'));
eval(t.TEST('getNames(ADC) === "A,D,C,ADC"'));
eval(t.TEST('getNames(ABC) === "ABC,C,B,A"'));
eval(t.TEST('getNames(ADC) === "ADC,C,D,A"'));
var ABCD1 = dcl([ABC, ADC], {declaredClass: 'ABCD1'});
var ABCD2 = dcl([ADC, ABC], {declaredClass: 'ABCD2'});
var ABCD1 = dcl([ABC, ADC], {declaredClass: "ABCD1"});
var ABCD2 = dcl([ADC, ABC], {declaredClass: "ABCD2"});
eval(t.TEST('getNames(ABCD1) === "ABCD1,ADC,ABC,C,D,B,A"'));
eval(t.TEST('getNames(ABCD2) === "ABCD2,ABC,ADC,C,B,D,A"'));
eval(t.TEST('getNames(ABCD1) === "A,B,D,C,ABC,ADC,ABCD1"'));
eval(t.TEST('getNames(ABCD2) === "A,D,B,C,ADC,ABC,ABCD2"'));
},
function test_triangles(t){
"use strict";
function test_triangles (t) {
var A = dcl(null, {declaredClass: 'A'});
var B = dcl(null, {declaredClass: 'B'});
var C = dcl(null, {declaredClass: 'C'});
var A = dcl(null, {declaredClass: "A"});
var B = dcl(null, {declaredClass: "B"});
var C = dcl(null, {declaredClass: "C"});
var ABC = dcl([A, B, C], {declaredClass: 'ABC'});
var AC = dcl([A, C], {declaredClass: 'AC'});
var BC = dcl([B, C], {declaredClass: 'BC'});
var ABC = dcl([A, B, C], {declaredClass: "ABC"});
var AC = dcl([A, C], {declaredClass: "AC"});
var BC = dcl([B, C], {declaredClass: "BC"});
eval(t.TEST('getNames(ABC) === "A,B,C,ABC"'));
eval(t.TEST('getNames(AC) === "A,C,AC"'));
eval(t.TEST('getNames(BC) === "B,C,BC"'));
eval(t.TEST('getNames(ABC) === "ABC,C,B,A"'));
eval(t.TEST('getNames(AC) === "AC,C,A"'));
eval(t.TEST('getNames(BC) === "BC,C,B"'));
var ABC1 = dcl([ABC, AC], {declaredClass: 'ABC1'});
var ABC2 = dcl([AC, ABC], {declaredClass: 'ABC2'});
var ABC1 = dcl([ABC, AC], {declaredClass: "ABC1"});
var ABC2 = dcl([AC, ABC], {declaredClass: "ABC2"});
eval(t.TEST('getNames(ABC1) === "A,B,C,ABC,AC,ABC1"'));
eval(t.TEST('getNames(ABC2) === "A,B,C,AC,ABC,ABC2"'));
eval(t.TEST('getNames(ABC1) === "ABC1,AC,ABC,C,B,A"'));
eval(t.TEST('getNames(ABC2) === "ABC2,ABC,AC,C,B,A"'));
var ABC3 = dcl([ABC, BC], {declaredClass: 'ABC3'});
var ABC4 = dcl([BC, ABC], {declaredClass: 'ABC4'});
var ABC3 = dcl([ABC, BC], {declaredClass: "ABC3"});
var ABC4 = dcl([BC, ABC], {declaredClass: "ABC4"});
eval(t.TEST('getNames(ABC3) === "ABC3,BC,ABC,C,B,A"'));
eval(t.TEST('getNames(ABC4) === "ABC4,ABC,BC,C,B,A"'));
eval(t.TEST('getNames(ABC3) === "A,B,C,ABC,BC,ABC3"'));
eval(t.TEST('getNames(ABC4) === "A,B,C,BC,ABC,ABC4"'));
},
function test_superCall_int(t){
"use strict";
function test_superCall_int (t) {
var a = new (dcl(null, {
toString: dcl.superCall(function(sup){
return function(){
return "PRE-" + sup.call(this) + "-POST";
toString: dcl.superCall(function (sup) {
return function () {
return 'PRE-' + sup.call(this) + '-POST';
};

@@ -193,17 +186,15 @@ })

},
function test_impossible(t){
"use strict";
function test_impossible (t) {
var A = dcl(null, {declaredClass: 'A'});
var B = dcl(null, {declaredClass: 'B'});
var A = dcl(null, {declaredClass: "A"});
var B = dcl(null, {declaredClass: "B"});
var AB = dcl([A, B], {declaredClass: 'AB'});
var BA = dcl([B, A], {declaredClass: 'BA'});
var AB = dcl([A, B], {declaredClass: "AB"});
var BA = dcl([B, A], {declaredClass: "BA"});
var failed = false;
try{
var X = dcl([AB, BA], {declaredClass: "X"});
}catch(e){
try {
var X = dcl([AB, BA], {declaredClass: 'X'});
} catch (e) {
failed = true;
}finally{
} finally {
eval(t.TEST('failed'));

@@ -210,0 +201,0 @@ }

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../mixins/Cleanup"], function(module, unit, dcl, Cleanup){
(['module', 'heya-unit', '../dcl', '../mixins/Cleanup'], function (module, unit, dcl, Cleanup) {
'use strict';
"use strict";
// tests
unit.add(module, [
function test_Cleanup(t){
"use strict";
function test_Cleanup (t) {
var msgs = [];
var A = dcl(null, {
constructor: function(n){
constructor: function (n) {
this.n = n;
msgs.push(this.n);
},
destroy: function(){
destroy: function () {
msgs.push(-this.n);

@@ -24,3 +21,3 @@ }

var cleanup = function(n){
var cleanup = function (n) {
msgs.push(-n);

@@ -30,3 +27,3 @@ };

var B = dcl(Cleanup, {
constructor: function(){
constructor: function () {
var f1 = this.pushCleanup(new A(1));

@@ -40,4 +37,4 @@ this.f2 = this.pushCleanup(2, cleanup);

},
remove2: function(){
if(this.removeCleanup(this.f2)){
remove2: function () {
if (this.removeCleanup(this.f2)) {
this.f2();

@@ -47,3 +44,3 @@ this.f2 = null;

},
destroy: function(){
destroy: function () {
msgs.push(-99);

@@ -50,0 +47,0 @@ }

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["module", "heya-unit", "../dcl", "../inherited"], function(module, unit, dcl){
(['module', 'heya-unit', '../dcl'], function (module, unit, dcl) {
'use strict';
"use strict";
// tests

@@ -10,8 +9,6 @@

{
test: function test_si(t){
"use strict";
function A(x){ t.info("A: " + x); }
test: function test_si (t) {
function A (x) { t.info('A: ' + x); }
A.prototype = {
m: function(x){ t.info("A.m: " + x); }
m: function (x) { t.info('A.m: ' + x); }
};

@@ -23,7 +20,7 @@

var B = dcl(A, {
constructor: function(x){
t.info("B: " + x);
constructor: function (x) {
t.info('B: ' + x);
},
m: function(x){
t.info("B.m: " + x);
m: function (x) {
t.info('B.m: ' + x);
}

@@ -36,16 +33,14 @@ });

logs: [
{text: "A: 1"},
{text: "A.m: 2"},
{text: "A: 3"},
{text: "B: 3"},
{text: "B.m: 4"}
{text: 'A: 1'},
{text: 'A.m: 2'},
{text: 'A: 3'},
{text: 'B: 3'},
{text: 'B.m: 4'}
]
},
{
test: function test_superCall(t){
"use strict";
function A(x){ t.info("A: " + x); }
test: function test_superCall (t) {
function A (x) { t.info('A: ' + x); }
A.prototype = {
m: function(x){ t.info("A.m: " + x); }
m: function (x) { t.info('A.m: ' + x); }
};

@@ -57,12 +52,12 @@

var B = dcl(A, {
constructor: function(x){
t.info("B: " + x);
constructor: function (x) {
t.info('B: ' + x);
},
m: dcl.superCall(function(sup){
return function(x){
t.info("B.m before: " + x);
m: dcl.superCall(function (sup) {
return function (x) {
t.info('B.m before: ' + x);
sup.apply(this, arguments);
t.info("B.m middle: " + x);
t.info('B.m middle: ' + x);
sup.call(this, x + 1);
t.info("B.m after: " + x);
t.info('B.m after: ' + x);
};

@@ -76,25 +71,23 @@ })

logs: [
{text: "A: 1"},
{text: "A.m: 2"},
{text: "A: 3"},
{text: "B: 3"},
{text: "B.m before: 4"},
{text: "A.m: 4"},
{text: "B.m middle: 4"},
{text: "A.m: 5"},
{text: "B.m after: 4"}
{text: 'A: 1'},
{text: 'A.m: 2'},
{text: 'A: 3'},
{text: 'B: 3'},
{text: 'B.m before: 4'},
{text: 'A.m: 4'},
{text: 'B.m middle: 4'},
{text: 'A.m: 5'},
{text: 'B.m after: 4'}
]
},
function test_superCall_int(t){
"use strict";
function A(x){}
function A (x) {}
A.prototype = {
toString: function(x){ return "[object A]"; }
toString: function (x) { return '[object A]'; }
};
var b = new (dcl(A, {
toString: dcl.superCall(function(sup){
return function(){
return "PRE-" + sup.call(this) + "-POST";
toString: dcl.superCall(function (sup) {
return function () {
return 'PRE-' + sup.call(this) + '-POST';
};

@@ -106,100 +99,43 @@ })

{
test: function test_inherited(t){
"use strict";
function A(x){ t.info("A: " + x); }
A.prototype = {
m: function(x){ t.info("A.m: " + x); }
};
var a = new A(1);
a.m(2);
var B = dcl(A, {
constructor: function(x){
t.info("B: " + x);
},
m: function(x){
t.info("B.m before: " + x);
this.inherited(this.constructor, "m", arguments);
t.info("B.m middle: " + x);
this.inherited(this.constructor, "m", [x + 1]);
t.info("B.m after: " + x);
}
});
var b = new B(3);
b.m(4);
},
logs: [
{text: "A: 1"},
{text: "A.m: 2"},
{text: "A: 3"},
{text: "B: 3"},
{text: "B.m before: 4"},
{text: "A.m: 4"},
{text: "B.m middle: 4"},
{text: "A.m: 5"},
{text: "B.m after: 4"}
]
},
function test_inherited_int(t){
"use strict";
function A(x){}
A.prototype = {
toString: function(x){ return "[object A]"; }
};
var b = new (dcl(A, {
toString: function(){
return "PRE-" + this.inherited(this.constructor, "toString", []) + "-POST";
}
}));
eval(t.TEST('b.toString() === "PRE-[object A]-POST"'));
},
{
test: function test_mi(t){
"use strict";
function A(x){ t.info("A: " + x); }
function A (x) { t.info('A: ' + x); }
A.prototype = {
m1: function(x){ t.info("A.m1: " + x); },
m2: function(x){ t.info("A.m2: " + x); },
m3: function(x){ t.info("A.m3: " + x); }
m1: function (x) { t.info('A.m1: ' + x); },
m2: function (x) { t.info('A.m2: ' + x); },
m3: function (x) { t.info('A.m3: ' + x); }
};
function B(x){ t.info("B: " + x); }
function B (x) { t.info('B: ' + x); }
B.prototype = {
m1: function(x){ t.info("B.m1: " + x); },
m2: function(x){ t.info("B.m2: " + x); },
m3: function(x){ t.info("B.m3: " + x); }
m1: function (x) { t.info('B.m1: ' + x); },
m2: function (x) { t.info('B.m2: ' + x); },
m3: function (x) { t.info('B.m3: ' + x); }
};
function C(x){ t.info("C: " + x); }
function C (x) { t.info('C: ' + x); }
C.prototype = {
m1: function(x){ t.info("C.m1: " + x); },
m2: function(x){ t.info("C.m2: " + x); },
m3: function(x){ t.info("C.m3: " + x); }
m1: function (x) { t.info('C.m1: ' + x); },
m2: function (x) { t.info('C.m2: ' + x); },
m3: function (x) { t.info('C.m3: ' + x); }
};
var abc = new (dcl([A, B, C], {
constructor: function(x){
t.info("abc: " + x);
constructor: function (x) {
t.info('abc: ' + x);
},
m1: dcl.superCall(function(sup){
return function(x){
t.info("abc.m1: " + x);
m1: dcl.superCall(function (sup) {
return function (x) {
t.info('abc.m1: ' + x);
sup.call(this, x);
};
}),
m2: dcl.superCall(function(sup){
return function(x){
t.info("abc.m2: " + x);
m2: dcl.superCall(function (sup) {
return function (x) {
t.info('abc.m2: ' + x);
sup.call(this, x);
};
}),
m3: dcl.superCall(function(sup){
return function(x){
t.info("abc.m3: " + x);
m3: dcl.superCall(function (sup) {
return function (x) {
t.info('abc.m3: ' + x);
sup.call(this, x);

@@ -214,17 +150,17 @@ };

var O = dcl(null, {});
dcl.chainBefore(O, "m1");
dcl.chainAfter(O, "m3");
dcl.chainBefore(O, 'm1');
dcl.chainAfter (O, 'm3');
var oabc = new (dcl([O, A, B, C], {
constructor: function(x){
t.info("oabc: " + x);
constructor: function (x) {
t.info('oabc: ' + x);
},
m1: function(x){
t.info("oabc.m1: " + x);
m1: function (x) {
t.info('oabc.m1: ' + x);
},
m2: function(x){
t.info("oabc.m2: " + x);
m2: function (x) {
t.info('oabc.m2: ' + x);
},
m3: function(x){
t.info("oabc.m3: " + x);
m3: function (x) {
t.info('oabc.m3: ' + x);
}

@@ -238,26 +174,26 @@ }))(0);

// abc
{text: "A: 0"},
{text: "B: 0"},
{text: "C: 0"},
{text: "abc: 0"},
{text: "abc.m1: 1"},
{text: "C.m1: 1"},
{text: "abc.m2: 2"},
{text: "C.m2: 2"},
{text: "abc.m3: 3"},
{text: "C.m3: 3"},
{text: 'A: 0'},
{text: 'B: 0'},
{text: 'C: 0'},
{text: 'abc: 0'},
{text: 'abc.m1: 1'},
{text: 'C.m1: 1'},
{text: 'abc.m2: 2'},
{text: 'C.m2: 2'},
{text: 'abc.m3: 3'},
{text: 'C.m3: 3'},
// oabc
{text: "A: 0"},
{text: "B: 0"},
{text: "C: 0"},
{text: "oabc: 0"},
{text: "oabc.m1: 1"},
{text: "C.m1: 1"},
{text: "B.m1: 1"},
{text: "A.m1: 1"},
{text: "oabc.m2: 2"},
{text: "A.m3: 3"},
{text: "B.m3: 3"},
{text: "C.m3: 3"},
{text: "oabc.m3: 3"}
{text: 'A: 0'},
{text: 'B: 0'},
{text: 'C: 0'},
{text: 'oabc: 0'},
{text: 'oabc.m1: 1'},
{text: 'C.m1: 1'},
{text: 'B.m1: 1'},
{text: 'A.m1: 1'},
{text: 'oabc.m2: 2'},
{text: 'A.m3: 3'},
{text: 'B.m3: 3'},
{text: 'C.m3: 3'},
{text: 'oabc.m3: 3'}
]

@@ -264,0 +200,0 @@ }

/* UMD.define */ (typeof define=="function"&&define||function(d,f,m){m={module:module,require:require};module.exports=f.apply(null,d.map(function(n){return m[n]||require(n)}))})
(["heya-unit", "./test_mini", "./test_dcl", "./test_advise", "./test_inherited", "./test_debug",
"./test_raw", "./test_bases", "./test_mixins", "./test_advices"],
function(unit){
"use strict";
([
'heya-unit',
'./test_mini',
'./test_dcl',
'./test_advise',
'./test_raw',
'./test_bases',
'./test_mixins',
'./test_advices',
'./test_accessors',
'./test_advise_accessors',
'./test_debug'
],
function (unit) {
'use strict';
unit.run();
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc