function flatten( ast, scope, depth ) {
	var out = [];
	walk( ast, visit );
	return out;

	/**
	* Callback invoked upon visiting an AST node.
	*
	* @private
	* @param {Node} node - AST node
	* @param {*} state - state
	* @param {Array<Node>} ancestors - ancestor nodes
	*/
	function visit( node, state, ancestors ) {
		var level;
		var type;
		var d;
		var i;
		if ( node !== ast && contains( types, node.type ) ) {
			level = scope;
			d = depth;
			for ( i = 0; i < ancestors.length-1; i++ ) {
				type = ancestors[ i ].type;
				if (
					type === 'FunctionDeclaration' ||
					type === 'FunctionExpression'
				) {
					level += 1;
				} else if (
					type === 'BlockStatement'
				) {
					d += 1;
				}
			}
			node.__scope__ = level; // eslint-disable-line no-underscore-dangle
			node.__depth__ = d; // eslint-disable-line no-underscore-dangle
			out.push( node );
		}
	}
}
Flattens an AST.

@private
@param {Node} ast - AST node
@param {NonNegativeInteger} scope - scope level
@param {NonNegativeInteger} depth - nesting depth
@returns {Array} flattened AST