stylus
Version:
Robust, expressive, and feature-rich CSS superset
133 lines (114 loc) • 2.48 kB
JavaScript
/*!
* Stylus - Stack
* Copyright (c) Automattic <developer.wordpress.com>
* MIT Licensed
*/
module.exports = class Stack extends Array {
/**
* Initialize a new `Stack`.
*
* @api private
*/
constructor() {
super()
Array.apply(this, arguments);
}
/**
* Push the given `frame`.
*
* @param {Frame} frame
* @api public
*/
push(frame) {
frame.stack = this;
frame.parent = this.currentFrame;
return [].push.apply(this, arguments);
};
/**
* Return the current stack `Frame`.
*
* @return {Frame}
* @api private
*/
get currentFrame() {
return this[this.length - 1];
};
/**
* Lookup stack frame for the given `block`.
*
* @param {Block} block
* @return {Frame}
* @api private
*/
getBlockFrame(block) {
for (var i = 0; i < this.length; ++i) {
if (block == this[i].block) {
return this[i];
}
}
};
/**
* Lookup the given local variable `name`, relative
* to the lexical scope of the current frame's `Block`.
*
* When the result of a lookup is an identifier
* a recursive lookup is performed, defaulting to
* returning the identifier itself.
*
* @param {String} name
* @return {Node}
* @api private
*/
lookup(name) {
var block = this.currentFrame.block
, val
, ret;
do {
var frame = this.getBlockFrame(block);
if (frame && (val = frame.lookup(name))) {
return val;
}
} while (block = block.parent);
};
/**
* Custom inspect.
*
* @return {String}
* @api private
*/
inspect() {
return this.reverse().map(function (frame) {
return frame.inspect();
}).join('\n');
};
/**
* Return stack string formatted as:
*
* at <context> (<filename>:<lineno>:<column>)
*
* @return {String}
* @api private
*/
toString() {
var block
, node
, buf = []
, location
, len = this.length;
while (len--) {
block = this[len].block;
if (node = block.node) {
location = '(' + node.filename + ':' + (node.lineno + 1) + ':' + node.column + ')';
switch (node.nodeName) {
case 'function':
buf.push(' at ' + node.name + '() ' + location);
break;
case 'group':
buf.push(' at "' + node.nodes[0].val + '" ' + location);
break;
}
}
}
return buf.join('\n');
};
};