Comparing version 0.9.9 to 1.0.0
{ | ||
"name": "asty", | ||
"version": "0.9.9", | ||
"version": "1.0.0", | ||
"description": "Abstract Syntax Tree (AST) Data Structure", | ||
@@ -5,0 +5,0 @@ "main": "lib/asty.browser.js", |
@@ -26,10 +26,12 @@ /* | ||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ASTY=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
"use strict";var _prototypeProperties=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},ASTYBase=function(){function e(){}return _prototypeProperties(e,null,{init:{value:function(e){if("undefined"==typeof e)throw new Error("init: invalid argument");return this.ASTy=!0,this.T=e,this.L={L:0,C:0,O:0},this.A={},this.C=[],this.P=null,this},writable:!0,enumerable:!0,configurable:!0},merge:{value:function(e,t,r){if("object"!=typeof e)throw new Error("merge: invalid AST node argument");"undefined"==typeof t&&(t=!1),"undefined"==typeof r&&(r={});var n=this;if(t){var i=e.pos();n.pos(i.L,i.C,i.O)}return e.attrs().forEach(function(t){var i="undefined"!=typeof r[t]?r[t]:t;null!==i&&n.set(i,e.get(t))}),e.childs().forEach(function(e){n.add(e)}),this},writable:!0,enumerable:!0,configurable:!0},type:{value:function(e){if(0===arguments.length)return this.T;if(1===arguments.length)return this.T=e,this;throw new Error("type: invalid number of arguments")},writable:!0,enumerable:!0,configurable:!0},pos:{value:function(e,t,r){if(0===arguments.length)return this.L;if(arguments.length<=3)return this.L.L=e||0,this.L.C=t||0,this.L.O=r||0,this;throw new Error("pos: invalid number of arguments")},writable:!0,enumerable:!0,configurable:!0},set:{value:function(){if(1===arguments.length&&"object"==typeof arguments[0]){var e=this,t=arguments;Object.keys(t[0]).forEach(function(r){e.A[r]=t[0][r]})}else{if(2!==arguments.length)throw new Error("set: invalid arguments");this.A[arguments[0]]=arguments[1]}return this},writable:!0,enumerable:!0,configurable:!0},get:{value:function(e){if(1!==arguments.length)throw new Error("get: invalid number of arguments");if("string"!=typeof e)throw new Error("get: invalid argument");return this.A[e]},writable:!0,enumerable:!0,configurable:!0},attrs:{value:function(){return Object.keys(this.A)},writable:!0,enumerable:!0,configurable:!0},add:{value:function(){if(0===arguments.length)throw new Error("add: missing argument(s)");var e=function(e,t){if(!("object"==typeof t&&"string"==typeof t.T&&"object"==typeof t.L&&"object"==typeof t.A&&"object"==typeof t.P&&"object"==typeof t.C&&t.C instanceof Array))throw new Error("add: invalid AST node: "+JSON.stringify(t));e.C.push(t),t.P=e};if(null!==arguments){var t=this;Array.prototype.slice.call(arguments,0).forEach(function(r){"object"==typeof r&&r instanceof Array?r.forEach(function(r){e(t,r)}):null!==r&&e(t,r)})}return this},writable:!0,enumerable:!0,configurable:!0},del:{value:function(){if(0===arguments.length)throw new Error("del: invalid argument");var e=this;return Array.prototype.slice.call(arguments,0).forEach(function(t){for(var r=!1,n=0;n<e.C.length;n++)if(e.C[n]===t){e.C.splice(n,1),t.P=null,r=!0;break}if(!r)throw new Error("del: child not found")}),this},writable:!0,enumerable:!0,configurable:!0},childs:{value:function(){return this.C},writable:!0,enumerable:!0,configurable:!0},parent:{value:function(){return this.P},writable:!0,enumerable:!0,configurable:!0},walk:{value:function(e,t){"undefined"==typeof t&&(t="downward");var r=function(n,i,a){("downward"===t||"both"===t)&&e.call(null,n,i,a,"downward"),n.C.forEach(function(e){r(e,i+1,n)}),("upward"===t||"both"===t)&&e.call(null,n,i,a,"upward")};return r(this,0,null),this},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYBase; | ||
"use strict";var _prototypeProperties=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},ASTYBase=function(){function e(){}return _prototypeProperties(e,null,{init:{value:function(e,t,r){if("undefined"==typeof e)throw new Error("init: invalid argument");if(this.ASTy=!0,this.T=e,this.L={L:0,C:0,O:0},this.A={},this.C=[],this.P=null,"object"==typeof t)for(var n in t)t.hasOwnProperty(n)&&this.set(n,t[n]);return"object"==typeof r&&r instanceof Array&&this.add(r),this},writable:!0,enumerable:!0,configurable:!0},type:{value:function(e){if(0===arguments.length)return this.T;if(1===arguments.length)return this.T=e,this;throw new Error("type: invalid number of arguments")},writable:!0,enumerable:!0,configurable:!0},pos:{value:function(e,t,r){if(0===arguments.length)return this.L;if(arguments.length<=3)return this.L.L=e||0,this.L.C=t||0,this.L.O=r||0,this;throw new Error("pos: invalid number of arguments")},writable:!0,enumerable:!0,configurable:!0},set:{value:function(){if(1===arguments.length&&"object"==typeof arguments[0]){var e=this,t=arguments;Object.keys(t[0]).forEach(function(r){e.A[r]=t[0][r]})}else{if(2!==arguments.length)throw new Error("set: invalid arguments");this.A[arguments[0]]=arguments[1]}return this},writable:!0,enumerable:!0,configurable:!0},get:{value:function(e){if(1!==arguments.length)throw new Error("get: invalid number of arguments");if("string"!=typeof e)throw new Error("get: invalid argument");return this.A[e]},writable:!0,enumerable:!0,configurable:!0},attrs:{value:function(){return Object.keys(this.A)},writable:!0,enumerable:!0,configurable:!0},add:{value:function(){if(0===arguments.length)throw new Error("add: missing argument(s)");var e=function(e,t){if(!("object"==typeof t&&"string"==typeof t.T&&"object"==typeof t.L&&"object"==typeof t.A&&"object"==typeof t.P&&"object"==typeof t.C&&t.C instanceof Array))throw new Error("add: invalid AST node: "+JSON.stringify(t));e.C.push(t),t.P=e};if(null!==arguments){var t=this;Array.prototype.slice.call(arguments,0).forEach(function(r){"object"==typeof r&&r instanceof Array?r.forEach(function(r){e(t,r)}):null!==r&&e(t,r)})}return this},writable:!0,enumerable:!0,configurable:!0},del:{value:function(){if(0===arguments.length)throw new Error("del: invalid argument");var e=this;return Array.prototype.slice.call(arguments,0).forEach(function(t){for(var r=!1,n=0;n<e.C.length;n++)if(e.C[n]===t){e.C.splice(n,1),t.P=null,r=!0;break}if(!r)throw new Error("del: child not found")}),this},writable:!0,enumerable:!0,configurable:!0},childs:{value:function(){return this.C},writable:!0,enumerable:!0,configurable:!0},parent:{value:function(){return this.P},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYBase; | ||
},{}],2:[function(_dereq_,module,exports){ | ||
"use strict";var _prototypeProperties=function(e,r,t){r&&Object.defineProperties(e,r),t&&Object.defineProperties(e.prototype,t)},ASTYDump=function(){function e(){}return _prototypeProperties(e,null,{dump:{value:function(e){void 0===e&&(e=1/0);var r="";return this.walk(function(t,n){if(!(n>e)){for(var i=0;n>i;i++)r+=" ";r+=t.T+" ";var o=Object.keys(t.A);if(o.length>0){r+="(";var a=!0;o.forEach(function(e){a?a=!1:r+=", ",r+=e+": ";var n=t.A[e];switch(typeof n){case"string":r+='"'+n.replace(/\n/,"\\n").replace(/"/,'\\"')+'"';break;case"object":r+=n instanceof RegExp?"/"+n.toString().replace(/^\//,"").replace(/\/$/,"").replace(/\//g,"\\/")+"/":JSON.stringify(n);break;default:r+=JSON.stringify(n)}}),r+=") "}r+="["+t.L.L+"/"+t.L.C+"]\n"}},"downward"),r},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYDump; | ||
},{}],3:[function(_dereq_,module,exports){ | ||
"use strict";module.exports=function(){for(var t=function(){},r=0;r<arguments.length;r++){var o=arguments[r];"function"==typeof o&&(o=o.prototype);for(var e in o)Object.prototype.hasOwnProperty.call(o,e)&&(t.prototype[e]=o[e])}return t}; | ||
"use strict";var _prototypeProperties=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},ASTYMerge=function(){function e(){}return _prototypeProperties(e,null,{merge:{value:function(e,t,r){if("object"!=typeof e)throw new Error("merge: invalid AST node argument");"undefined"==typeof t&&(t=!1),"undefined"==typeof r&&(r={});var o=this;if(t){var n=e.pos();o.pos(n.L,n.C,n.O)}return e.attrs().forEach(function(t){var n="undefined"!=typeof r[t]?r[t]:t;null!==n&&o.set(n,e.get(t))}),e.childs().forEach(function(e){o.add(e)}),this},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYMerge; | ||
},{}],4:[function(_dereq_,module,exports){ | ||
"use strict";var _inherits=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},ASTYBase=_dereq_("./asty-base.js"),ASTYDump=_dereq_("./asty-dump.js"),mixins=_dereq_("./asty-mixins.js"),ASTY=function(e){function t(){if(this instanceof t)return this.init.apply(this,arguments);var e=new t("");return e.init.apply(e,arguments)}return _inherits(t,e),t}(mixins(ASTYBase,ASTYDump));ASTY.extend=function(e){for(var t in e)ASTY.prototype[t]=e[t]},module.exports=ASTY; | ||
},{"./asty-base.js":1,"./asty-dump.js":2,"./asty-mixins.js":3}]},{},[1,2,3,4])(4) | ||
"use strict";var _prototypeProperties=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},ASTYWalk=function(){function e(){}return _prototypeProperties(e,null,{walk:{value:function(e,t){"undefined"==typeof t&&(t="downward");var r=function(n,o,l){("downward"===t||"both"===t)&&e.call(null,n,o,l,"downward"),n.C.forEach(function(e){r(e,o+1,n)}),("upward"===t||"both"===t)&&e.call(null,n,o,l,"upward")};return r(this,0,null),this},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYWalk; | ||
},{}],5:[function(_dereq_,module,exports){ | ||
"use strict";var _prototypeProperties=function(e,t,r){t&&Object.defineProperties(e,t),r&&Object.defineProperties(e.prototype,r)},ASTYBase=_dereq_("./asty-base.js"),ASTYMerge=_dereq_("./asty-merge.js"),ASTYWalk=_dereq_("./asty-walk.js"),ASTYDump=_dereq_("./asty-dump.js"),ASTYCtx=function(){function e(){var t=this;if(!(this instanceof e))return new e;this.ASTYNode=function(){};var r=[ASTYBase,ASTYMerge,ASTYWalk,ASTYDump];return r.forEach(function(e){for(var r in e.prototype)e.prototype.hasOwnProperty(r)&&(t.ASTYNode.prototype[r]=e.prototype[r])}),this}return _prototypeProperties(e,null,{extend:{value:function(e){for(var t in e)e.hasOwnProperty(t)&&(this.ASTYNode.prototype[t]=e[t]);return this},writable:!0,enumerable:!0,configurable:!0},create:{value:function(e){return(new this.ASTYNode).init(e)},writable:!0,enumerable:!0,configurable:!0},isA:{value:function(e){return"object"==typeof e&&e instanceof this.ASTYNode&&"boolean"==typeof e.ASTy&&e.ASTy===!0},writable:!0,enumerable:!0,configurable:!0}}),e}();module.exports=ASTYCtx; | ||
},{"./asty-base.js":1,"./asty-dump.js":2,"./asty-merge.js":3,"./asty-walk.js":4}]},{},[1,2,3,4,5])(5) | ||
}); | ||
@@ -36,0 +38,0 @@ |
@@ -62,4 +62,4 @@ /* | ||
init: { | ||
/* constructor helper: AST node initialization */ | ||
value: function init(T) { | ||
/* AST node initialization */ | ||
value: function init(T, A, C) { | ||
if (typeof T === "undefined") throw new Error("init: invalid argument"); | ||
@@ -72,27 +72,8 @@ this.ASTy = true; | ||
this.P = null; | ||
return this; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
}, | ||
merge: { | ||
/* merge attributes and childs of an AST node */ | ||
value: function merge(node, takePos, attrMap) { | ||
if (typeof node !== "object") throw new Error("merge: invalid AST node argument"); | ||
if (typeof takePos === "undefined") takePos = false; | ||
if (typeof attrMap === "undefined") attrMap = {}; | ||
var self = this; | ||
if (takePos) { | ||
var pos = node.pos(); | ||
self.pos(pos.L, pos.C, pos.O); | ||
if (typeof A === "object") { | ||
for (var name in A) { | ||
if (A.hasOwnProperty(name)) this.set(name, A[name]); | ||
} | ||
} | ||
node.attrs().forEach(function (attrSource) { | ||
var attrTarget = typeof attrMap[attrSource] !== "undefined" ? attrMap[attrSource] : attrSource; | ||
if (attrTarget !== null) self.set(attrTarget, node.get(attrSource)); | ||
}); | ||
node.childs().forEach(function (child) { | ||
self.add(child); | ||
}); | ||
if (typeof C === "object" && C instanceof Array) this.add(C); | ||
return this; | ||
@@ -238,21 +219,2 @@ }, | ||
configurable: true | ||
}, | ||
walk: { | ||
/* walk the AST recursively */ | ||
value: function walk(cb, when) { | ||
if (typeof when === "undefined") when = "downward"; | ||
var _walk = function (node, depth, parent) { | ||
if (when === "downward" || when === "both") cb.call(null, node, depth, parent, "downward"); | ||
node.C.forEach(function (child) { | ||
_walk(child, depth + 1, node); | ||
}); | ||
if (when === "upward" || when === "both") cb.call(null, node, depth, parent, "upward"); | ||
}; | ||
_walk(this, 0, null); | ||
return this; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
} | ||
@@ -351,2 +313,7 @@ }); | ||
var _prototypeProperties = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
/* | ||
@@ -376,29 +343,104 @@ ** ASTy -- Abstract Syntax Tree (AST) Data Structure | ||
/* little helper function for ES6 style mixin support */ | ||
module.exports = function mixins() { | ||
var cls = function () {}; | ||
for (var i = 0; i < arguments.length; i++) { | ||
var mixin = arguments[i]; | ||
if (typeof mixin === "function") mixin = mixin.prototype; | ||
for (var key in mixin) if (Object.prototype.hasOwnProperty.call(mixin, key)) cls.prototype[key] = mixin[key]; | ||
} | ||
return cls; | ||
}; | ||
var ASTYMerge = (function () { | ||
function ASTYMerge() {} | ||
_prototypeProperties(ASTYMerge, null, { | ||
merge: { | ||
/* merge attributes and childs of an AST node */ | ||
value: function merge(node, takePos, attrMap) { | ||
if (typeof node !== "object") throw new Error("merge: invalid AST node argument"); | ||
if (typeof takePos === "undefined") takePos = false; | ||
if (typeof attrMap === "undefined") attrMap = {}; | ||
var self = this; | ||
if (takePos) { | ||
var pos = node.pos(); | ||
self.pos(pos.L, pos.C, pos.O); | ||
} | ||
node.attrs().forEach(function (attrSource) { | ||
var attrTarget = typeof attrMap[attrSource] !== "undefined" ? attrMap[attrSource] : attrSource; | ||
if (attrTarget !== null) self.set(attrTarget, node.get(attrSource)); | ||
}); | ||
node.childs().forEach(function (child) { | ||
self.add(child); | ||
}); | ||
return this; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
} | ||
}); | ||
return ASTYMerge; | ||
})(); | ||
module.exports = ASTYMerge; | ||
},{}],4:[function(_dereq_,module,exports){ | ||
"use strict"; | ||
var _inherits = function (subClass, superClass) { | ||
if (typeof superClass !== "function" && superClass !== null) { | ||
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); | ||
} | ||
subClass.prototype = Object.create(superClass && superClass.prototype, { | ||
constructor: { | ||
value: subClass, | ||
enumerable: false, | ||
var _prototypeProperties = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
/* | ||
** ASTy -- Abstract Syntax Tree (AST) Data Structure | ||
** Copyright (c) 2014-2015 Ralf S. Engelschall <rse@engelschall.com> | ||
** | ||
** Permission is hereby granted, free of charge, to any person obtaining | ||
** a copy of this software and associated documentation files (the | ||
** "Software"), to deal in the Software without restriction, including | ||
** without limitation the rights to use, copy, modify, merge, publish, | ||
** distribute, sublicense, and/or sell copies of the Software, and to | ||
** permit persons to whom the Software is furnished to do so, subject to | ||
** the following conditions: | ||
** | ||
** The above copyright notice and this permission notice shall be included | ||
** in all copies or substantial portions of the Software. | ||
** | ||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
var ASTYWalk = (function () { | ||
function ASTYWalk() {} | ||
_prototypeProperties(ASTYWalk, null, { | ||
walk: { | ||
/* walk the AST recursively */ | ||
value: function walk(cb, when) { | ||
if (typeof when === "undefined") when = "downward"; | ||
var _walk = function (node, depth, parent) { | ||
if (when === "downward" || when === "both") cb.call(null, node, depth, parent, "downward"); | ||
node.C.forEach(function (child) { | ||
_walk(child, depth + 1, node); | ||
}); | ||
if (when === "upward" || when === "both") cb.call(null, node, depth, parent, "upward"); | ||
}; | ||
_walk(this, 0, null); | ||
return this; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
} | ||
}); | ||
if (superClass) subClass.__proto__ = superClass; | ||
return ASTYWalk; | ||
})(); | ||
module.exports = ASTYWalk; | ||
},{}],5:[function(_dereq_,module,exports){ | ||
"use strict"; | ||
var _prototypeProperties = function (child, staticProps, instanceProps) { | ||
if (staticProps) Object.defineProperties(child, staticProps); | ||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps); | ||
}; | ||
@@ -431,28 +473,55 @@ | ||
var ASTYBase = _dereq_("./asty-base.js"); | ||
var ASTYMerge = _dereq_("./asty-merge.js"); | ||
var ASTYWalk = _dereq_("./asty-walk.js"); | ||
var ASTYDump = _dereq_("./asty-dump.js"); | ||
var mixins = _dereq_("./asty-mixins.js"); | ||
/* the base class */ | ||
var ASTY = (function (_mixins) { | ||
/* the constructor mainly passes control to the init function */ | ||
function ASTY() { | ||
if (!(this instanceof ASTY)) { | ||
var self = new ASTY(""); | ||
return self.init.apply(self, arguments); | ||
} else return this.init.apply(this, arguments); | ||
var ASTYCtx = (function () { | ||
function ASTYCtx() { | ||
var _this = this; | ||
if (!(this instanceof ASTYCtx)) return new ASTYCtx(); | ||
this.ASTYNode = function () {}; | ||
var mixins = [ASTYBase, ASTYMerge, ASTYWalk, ASTYDump]; | ||
mixins.forEach(function (mixin) { | ||
for (var method in mixin.prototype) { | ||
if (mixin.prototype.hasOwnProperty(method)) _this.ASTYNode.prototype[method] = mixin.prototype[method]; | ||
} | ||
}); | ||
return this; | ||
} | ||
_inherits(ASTY, _mixins); | ||
_prototypeProperties(ASTYCtx, null, { | ||
extend: { | ||
value: function extend(mixin) { | ||
for (var method in mixin) { | ||
if (mixin.hasOwnProperty(method)) this.ASTYNode.prototype[method] = mixin[method]; | ||
}return this; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
}, | ||
create: { | ||
value: function create(type) { | ||
return new this.ASTYNode().init(type); | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
}, | ||
isA: { | ||
value: function isA(node) { | ||
return typeof node === "object" && node instanceof this.ASTYNode && typeof node.ASTy === "boolean" && node.ASTy === true; | ||
}, | ||
writable: true, | ||
enumerable: true, | ||
configurable: true | ||
} | ||
}); | ||
return ASTY; | ||
})(mixins(ASTYBase, ASTYDump)); | ||
return ASTYCtx; | ||
})(); | ||
/* static function for extending the class */ | ||
ASTY.extend = function (methods) { | ||
for (var method in methods) ASTY.prototype[method] = methods[method]; | ||
}; | ||
module.exports = ASTYCtx; | ||
module.exports = ASTY; | ||
},{"./asty-base.js":1,"./asty-dump.js":2,"./asty-mixins.js":3}]},{},[1,2,3,4])(4) | ||
},{"./asty-base.js":1,"./asty-dump.js":2,"./asty-merge.js":3,"./asty-walk.js":4}]},{},[1,2,3,4,5])(5) | ||
}); |
{ | ||
"name": "asty", | ||
"version": "0.9.9", | ||
"version": "1.0.0", | ||
"description": "Abstract Syntax Tree (AST) Data Structure", | ||
@@ -5,0 +5,0 @@ "keywords": [ "ast", "abstract", "syntax", "tree", "data", "structure" ], |
@@ -42,55 +42,65 @@ | ||
ASTy provides a class for the construction of a single AST node. The | ||
tree of AST nodes is formed by linking child nodes into a parent node. | ||
The ASTy API, here assumed to be exposed through the variable `ASTY`, | ||
provides the following methods (in a notation somewhat resembling | ||
TypeScript type definitions) is: | ||
ASTy provides a context (`ASTYCtx` below) for the creation of AST node | ||
(`ASTYNode` below). The tree of AST nodes is formed by linking child | ||
AST nodes into a parent AST node. The ASTy API, here assumed to be | ||
exposed through the variable `ASTY`, provides the following methods (in | ||
a notation somewhat resembling TypeScript type definitions): | ||
- `ASTY.extend(object: { [methodName: String]: [methodFunc: Function] }): Void`:<br/> | ||
Extend the ASTY class with additional methods which are then available on each | ||
AST node during instanciation. This actually extends the ASTY prototype and | ||
should be used by extension modules only. | ||
### ASTy Context (ASTYCtx) | ||
- `new ASTY(type: String, attrs?: {[name: String]: [value: Object]}, childs?: ASTY[]): ASTY`:<br/> | ||
Create a new ASTY node and optionally already set attributes and add child nodes. | ||
- `new ASTY(): ASTYCtx`:<br/> | ||
Create a new instance of the ASTy context. | ||
It internally captures the prototype (`ASTYNode`) of the AST nodes to be created. | ||
- `ASTY#merge(node: Node, takePos?: Boolean, attrMap?: {[from: String]: [to: (String|null)})): ASTY`:<br/> | ||
- `ASTYCtx#extend(object: { [methodName: String]: [methodFunc: Function] }): ASTYCtx`:<br/> | ||
Extend the internal ASTYNode prototype with additional methods which are then available on each | ||
ASTYNode instance when created with `ASTYCtx#create`. This should be used by ASTy extension modules only. | ||
- `ASTYCtx#create(type: String, attrs?: {[name: String]: [value: Object]}, childs?: ASTY[]): ASTYNode`:<br/> | ||
Create a new ASTYNode instance of `type` and optionally already set attributes and add child nodes. | ||
- `ASTYCtx#isA(object: Object): Boolean`:<br/> | ||
Check whether `object` is an ASTYNode instance. | ||
### ASTy Node (ASTYNode) | ||
- `ASTYNode#merge(node: Node, takePos?: Boolean, attrMap?: {[from: String]: [to: (String|null)})): ASTYNode`:<br/> | ||
Merge attributes, childs and optionally the position of a node. | ||
The attributes can be renamed or skipped (if mapped onto `null`). | ||
- `ASTY#type(type: String): Boolean`:<br/> | ||
`ASTY#type(): String`:<br/> | ||
- `ASTYNode#type(type: String): Boolean`:<br/> | ||
`ASTYNode#type(): String`:<br/> | ||
Set or get type of node. | ||
- `ASTY#pos(line: Number, column: Number, offset: Number): ASTY`:<br/> | ||
`ASTY#pos(): Object`:<br/> | ||
- `ASTYNode#pos(line: Number, column: Number, offset: Number): ASTYNode`:<br/> | ||
`ASTYNode#pos(): Object`:<br/> | ||
Set or get the position for the node. | ||
- `ASTY#set(name: String, value: Object): ASTY`:<br/> | ||
- `ASTYNode#set(name: String, value: Object): ASTYNode`:<br/> | ||
Set a single attribute `name` to `value`. | ||
- `ASTY#set({ [name: String]: [value: Object] }): ASTY`:<br/> | ||
- `ASTYNode#set({ [name: String]: [value: Object] }): ASTYNode`:<br/> | ||
Set multiple attributes, each consisting of name and value pairs. | ||
- `ASTY#get(name: String): Object`:<br/> | ||
- `ASTYNode#get(name: String): Object`:<br/> | ||
Get value of attribute `name`. | ||
- `ASTY#attrs(): String[]:<br/> | ||
- `ASTYNode#attrs(): String[]:<br/> | ||
Get names of all node attributes. | ||
- `ASTY#add(childs: ASTY[]): ASTY`:<br/> | ||
- `ASTYNode#add(childs: ASTYNode[]): ASTYNode`:<br/> | ||
Add one or more childs to a node. The array `childs` | ||
can either contain ASTY objects or even arrays | ||
of ASTY objects. | ||
can either contain ASTYNode objects or even arrays | ||
of ASTYNode objects. | ||
- `ASTY#del(childs: ASTY[]): ASTY`:<br/> | ||
- `ASTYNode#del(childs: ASTYNode[]): ASTYNode`:<br/> | ||
Delete one or more childs from a node. | ||
- `ASTY#childs(): ASTY[]`:<br/> | ||
- `ASTYNode#childs(): ASTYNode[]`:<br/> | ||
Get a nodes list of childs. | ||
- `ASTY#parent(): ASTY[]`:<br/> | ||
- `ASTYNode#parent(): ASTYNode`:<br/> | ||
Get parent node. | ||
- `ASTY#walk(callback: (node: ASTY, depth: Number, parent: ASTY, when: String) => Void, when?: String): ASTY`:<br/> | ||
- `ASTYNode#walk(callback: (node: ASTYNode, depth: Number, parent: ASTYNode, when: String) => Void, when?: String): ASTYNode`:<br/> | ||
Recursively walk the AST starting at this node (at depth 0). For | ||
@@ -107,3 +117,3 @@ each visited node the `callback` function is called with the | ||
- `ASTY#dump(maxDepth?: Number): String`:<br/> | ||
- `ASTYNode#dump(maxDepth?: Number): String`:<br/> | ||
Returns a textual dump of the AST starting at the current node. By | ||
@@ -110,0 +120,0 @@ default `maxDepth` is `Infinity` and this way the whole AST below the |
@@ -26,4 +26,4 @@ /* | ||
class ASTYBase { | ||
/* constructor helper: AST node initialization */ | ||
init (T) { | ||
/* AST node initialization */ | ||
init (T, A, C) { | ||
if (typeof T === "undefined") | ||
@@ -37,27 +37,9 @@ throw new Error("init: invalid argument") | ||
this.P = null | ||
return this | ||
} | ||
/* merge attributes and childs of an AST node */ | ||
merge (node, takePos, attrMap) { | ||
if (typeof node !== "object") | ||
throw new Error("merge: invalid AST node argument") | ||
if (typeof takePos === "undefined") | ||
takePos = false | ||
if (typeof attrMap === "undefined") | ||
attrMap = {} | ||
var self = this | ||
if (takePos) { | ||
var pos = node.pos() | ||
self.pos(pos.L, pos.C, pos.O) | ||
if (typeof A === "object") { | ||
for (let name in A) | ||
if (A.hasOwnProperty(name)) | ||
this.set(name, A[name]) | ||
} | ||
node.attrs().forEach(function (attrSource) { | ||
var attrTarget = (typeof attrMap[attrSource] !== "undefined" ? | ||
attrMap[attrSource] : attrSource) | ||
if (attrTarget !== null) | ||
self.set(attrTarget, node.get(attrSource)) | ||
}) | ||
node.childs().forEach(function (child) { | ||
self.add(child) | ||
}) | ||
if (typeof C === "object" && C instanceof Array) | ||
this.add(C) | ||
return this | ||
@@ -177,17 +159,2 @@ } | ||
} | ||
/* walk the AST recursively */ | ||
walk (cb, when) { | ||
if (typeof when === "undefined") | ||
when = "downward" | ||
var _walk = function (node, depth, parent) { | ||
if (when === "downward" || when === "both") | ||
cb.call(null, node, depth, parent, "downward") | ||
node.C.forEach(function (child) { _walk(child, depth + 1, node) }) | ||
if (when === "upward" || when === "both") | ||
cb.call(null, node, depth, parent, "upward") | ||
} | ||
_walk(this, 0, null) | ||
return this | ||
} | ||
} | ||
@@ -194,0 +161,0 @@ |
@@ -25,26 +25,40 @@ /* | ||
var ASTYBase = require("./asty-base.js"); | ||
var ASTYDump = require("./asty-dump.js"); | ||
var mixins = require("./asty-mixins.js"); | ||
let ASTYBase = require("./asty-base.js"); | ||
let ASTYMerge = require("./asty-merge.js"); | ||
let ASTYWalk = require("./asty-walk.js"); | ||
let ASTYDump = require("./asty-dump.js"); | ||
/* the base class */ | ||
var ASTY = class ASTY extends mixins(ASTYBase, ASTYDump) { | ||
/* the constructor mainly passes control to the init function */ | ||
let ASTYCtx = class ASTYCtx { | ||
constructor () { | ||
if (!(this instanceof ASTY)) { | ||
var self = new ASTY("") | ||
return self.init.apply(self, arguments); | ||
} | ||
else | ||
return this.init.apply(this, arguments); | ||
if (!(this instanceof ASTYCtx)) | ||
return new ASTYCtx() | ||
this.ASTYNode = () => {} | ||
let mixins = [ ASTYBase, ASTYMerge, ASTYWalk, ASTYDump ] | ||
mixins.forEach((mixin) => { | ||
for (let method in mixin.prototype) | ||
if (mixin.prototype.hasOwnProperty(method)) | ||
this.ASTYNode.prototype[method] = mixin.prototype[method] | ||
}) | ||
return this | ||
} | ||
extend (mixin) { | ||
for (let method in mixin) | ||
if (mixin.hasOwnProperty(method)) | ||
this.ASTYNode.prototype[method] = mixin[method] | ||
return this | ||
} | ||
create (type) { | ||
return (new this.ASTYNode()).init(type) | ||
} | ||
isA (node) { | ||
return ( | ||
typeof node === "object" | ||
&& node instanceof this.ASTYNode | ||
&& typeof node.ASTy === "boolean" | ||
&& node.ASTy === true | ||
) | ||
} | ||
} | ||
/* static function for extending the class */ | ||
ASTY.extend = (methods) => { | ||
for (var method in methods) | ||
ASTY.prototype[method] = methods[method] | ||
} | ||
module.exports = ASTYCtx | ||
module.exports = ASTY | ||
@@ -25,19 +25,22 @@ /* | ||
var ASTy = require("../lib/asty.node.js"); | ||
describe("ASTy Library", function () { | ||
it("node base functionality", function () { | ||
var ASTy = require("../lib/asty.node.js"); | ||
var ast = new ASTy("foo"); | ||
expect(ast).to.be.a("object") | ||
expect(ast).to.include.keys("T", "L", "A", "P", "C") | ||
expect(ast.type()).to.be.equal("foo") | ||
expect(ast).to.respondTo("type") | ||
expect(ast).to.respondTo("dump") | ||
var asty = new ASTy(); | ||
var node = asty.create("foo"); | ||
expect(asty.isA(node)).to.be.true | ||
expect(node).to.be.a("object") | ||
expect(node).to.include.keys("T", "L", "A", "P", "C") | ||
expect(node.type()).to.be.equal("foo") | ||
expect(node).to.respondTo("type") | ||
expect(node).to.respondTo("dump") | ||
}) | ||
it("node tree structure", function () { | ||
var ASTy = require("../lib/asty.node.js"); | ||
var node1 = new ASTy("1"); | ||
var node11 = new ASTy("1.1"); | ||
var node12 = new ASTy("1.2"); | ||
var node121 = new ASTy("1.2.1"); | ||
var node122 = new ASTy("1.2.2"); | ||
var asty = new ASTy(); | ||
var node1 = asty.create("1"); | ||
var node11 = asty.create("1.1"); | ||
var node12 = asty.create("1.2"); | ||
var node121 = asty.create("1.2.1"); | ||
var node122 = asty.create("1.2.2"); | ||
node1.add(node11, node12) | ||
@@ -53,4 +56,4 @@ node12.add(node121, node122) | ||
it("node extension functionality", function () { | ||
var ASTy = require("../lib/asty.node.js"); | ||
ASTy.extend({ | ||
var asty = new ASTy(); | ||
asty.extend({ | ||
foo: function (arg) { | ||
@@ -60,8 +63,8 @@ return "<" + arg + ">" | ||
}) | ||
var ast = new ASTy("foo"); | ||
expect(ast).to.be.a("object") | ||
expect(ast).to.respondTo("foo") | ||
expect(ast.foo("bar")).to.be.equal("<bar>"); | ||
var node = asty.create("foo"); | ||
expect(node).to.be.a("object") | ||
expect(node).to.respondTo("foo") | ||
expect(node.foo("bar")).to.be.equal("<bar>"); | ||
}) | ||
}) | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
80903
17
1145
1
147