react / react-0.13.3 / examples / basic-commonjs / node_modules / browserify / node_modules / umd / node_modules / ruglify / node_modules / uglify-js / lib / ast.js
80760 views/***********************************************************************12A JavaScript tokenizer / parser / beautifier / compressor.3https://github.com/mishoo/UglifyJS245-------------------------------- (C) ---------------------------------67Author: Mihai Bazon8<[email protected]>9http://mihai.bazon.net/blog1011Distributed under the BSD license:1213Copyright 2012 (c) Mihai Bazon <[email protected]>1415Redistribution and use in source and binary forms, with or without16modification, are permitted provided that the following conditions17are met:1819* Redistributions of source code must retain the above20copyright notice, this list of conditions and the following21disclaimer.2223* Redistributions in binary form must reproduce the above24copyright notice, this list of conditions and the following25disclaimer in the documentation and/or other materials26provided with the distribution.2728THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY29EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE30IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR31PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE32LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,33OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,34PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR35PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY36THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR37TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF38THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF39SUCH DAMAGE.4041***********************************************************************/4243"use strict";4445function DEFNODE(type, props, methods, base) {46if (arguments.length < 4) base = AST_Node;47if (!props) props = [];48else props = props.split(/\s+/);49var self_props = props;50if (base && base.PROPS)51props = props.concat(base.PROPS);52var code = "return function AST_" + type + "(props){ if (props) { ";53for (var i = props.length; --i >= 0;) {54code += "this." + props[i] + " = props." + props[i] + ";";55}56var proto = base && new base;57if (proto && proto.initialize || (methods && methods.initialize))58code += "this.initialize();";59code += "}}";60var ctor = new Function(code)();61if (proto) {62ctor.prototype = proto;63ctor.BASE = base;64}65if (base) base.SUBCLASSES.push(ctor);66ctor.prototype.CTOR = ctor;67ctor.PROPS = props || null;68ctor.SELF_PROPS = self_props;69ctor.SUBCLASSES = [];70if (type) {71ctor.prototype.TYPE = ctor.TYPE = type;72}73if (methods) for (i in methods) if (methods.hasOwnProperty(i)) {74if (/^\$/.test(i)) {75ctor[i.substr(1)] = methods[i];76} else {77ctor.prototype[i] = methods[i];78}79}80ctor.DEFMETHOD = function(name, method) {81this.prototype[name] = method;82};83return ctor;84};8586var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {87}, null);8889var AST_Node = DEFNODE("Node", "start end", {90clone: function() {91return new this.CTOR(this);92},93$documentation: "Base class of all AST nodes",94$propdoc: {95start: "[AST_Token] The first token of this node",96end: "[AST_Token] The last token of this node"97},98_walk: function(visitor) {99return visitor._visit(this);100},101walk: function(visitor) {102return this._walk(visitor); // not sure the indirection will be any help103}104}, null);105106AST_Node.warn_function = null;107AST_Node.warn = function(txt, props) {108if (AST_Node.warn_function)109AST_Node.warn_function(string_template(txt, props));110};111112/* -----[ statements ]----- */113114var AST_Statement = DEFNODE("Statement", null, {115$documentation: "Base class of all statements",116});117118var AST_Debugger = DEFNODE("Debugger", null, {119$documentation: "Represents a debugger statement",120}, AST_Statement);121122var AST_Directive = DEFNODE("Directive", "value scope", {123$documentation: "Represents a directive, like \"use strict\";",124$propdoc: {125value: "[string] The value of this directive as a plain string (it's not an AST_String!)",126scope: "[AST_Scope/S] The scope that this directive affects"127},128}, AST_Statement);129130var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {131$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",132$propdoc: {133body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"134},135_walk: function(visitor) {136return visitor._visit(this, function(){137this.body._walk(visitor);138});139}140}, AST_Statement);141142function walk_body(node, visitor) {143if (node.body instanceof AST_Statement) {144node.body._walk(visitor);145}146else node.body.forEach(function(stat){147stat._walk(visitor);148});149};150151var AST_Block = DEFNODE("Block", "body", {152$documentation: "A body of statements (usually bracketed)",153$propdoc: {154body: "[AST_Statement*] an array of statements"155},156_walk: function(visitor) {157return visitor._visit(this, function(){158walk_body(this, visitor);159});160}161}, AST_Statement);162163var AST_BlockStatement = DEFNODE("BlockStatement", null, {164$documentation: "A block statement",165}, AST_Block);166167var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {168$documentation: "The empty statement (empty block or simply a semicolon)",169_walk: function(visitor) {170return visitor._visit(this);171}172}, AST_Statement);173174var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {175$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",176$propdoc: {177body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"178},179_walk: function(visitor) {180return visitor._visit(this, function(){181this.body._walk(visitor);182});183}184}, AST_Statement);185186var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {187$documentation: "Statement with a label",188$propdoc: {189label: "[AST_Label] a label definition"190},191_walk: function(visitor) {192return visitor._visit(this, function(){193this.label._walk(visitor);194this.body._walk(visitor);195});196}197}, AST_StatementWithBody);198199var AST_DWLoop = DEFNODE("DWLoop", "condition", {200$documentation: "Base class for do/while statements",201$propdoc: {202condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"203},204_walk: function(visitor) {205return visitor._visit(this, function(){206this.condition._walk(visitor);207this.body._walk(visitor);208});209}210}, AST_StatementWithBody);211212var AST_Do = DEFNODE("Do", null, {213$documentation: "A `do` statement",214}, AST_DWLoop);215216var AST_While = DEFNODE("While", null, {217$documentation: "A `while` statement",218}, AST_DWLoop);219220var AST_For = DEFNODE("For", "init condition step", {221$documentation: "A `for` statement",222$propdoc: {223init: "[AST_Node?] the `for` initialization code, or null if empty",224condition: "[AST_Node?] the `for` termination clause, or null if empty",225step: "[AST_Node?] the `for` update clause, or null if empty"226},227_walk: function(visitor) {228return visitor._visit(this, function(){229if (this.init) this.init._walk(visitor);230if (this.condition) this.condition._walk(visitor);231if (this.step) this.step._walk(visitor);232this.body._walk(visitor);233});234}235}, AST_StatementWithBody);236237var AST_ForIn = DEFNODE("ForIn", "init name object", {238$documentation: "A `for ... in` statement",239$propdoc: {240init: "[AST_Node] the `for/in` initialization code",241name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",242object: "[AST_Node] the object that we're looping through"243},244_walk: function(visitor) {245return visitor._visit(this, function(){246this.init._walk(visitor);247this.object._walk(visitor);248this.body._walk(visitor);249});250}251}, AST_StatementWithBody);252253var AST_With = DEFNODE("With", "expression", {254$documentation: "A `with` statement",255$propdoc: {256expression: "[AST_Node] the `with` expression"257},258_walk: function(visitor) {259return visitor._visit(this, function(){260this.expression._walk(visitor);261this.body._walk(visitor);262});263}264}, AST_StatementWithBody);265266/* -----[ scope and functions ]----- */267268var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {269$documentation: "Base class for all statements introducing a lexical scope",270$propdoc: {271directives: "[string*/S] an array of directives declared in this scope",272variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",273functions: "[Object/S] like `variables`, but only lists function declarations",274uses_with: "[boolean/S] tells whether this scope uses the `with` statement",275uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",276parent_scope: "[AST_Scope?/S] link to the parent scope",277enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",278cname: "[integer/S] current index for mangling variables (used internally by the mangler)",279},280}, AST_Block);281282var AST_Toplevel = DEFNODE("Toplevel", "globals", {283$documentation: "The toplevel scope",284$propdoc: {285globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",286},287wrap_commonjs: function(name, export_all) {288var self = this;289var to_export = [];290if (export_all) {291self.figure_out_scope();292self.walk(new TreeWalker(function(node){293if (node instanceof AST_SymbolDeclaration && node.definition().global) {294if (!find_if(function(n){ return n.name == node.name }, to_export))295to_export.push(node);296}297}));298}299var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))";300wrapped_tl = parse(wrapped_tl);301wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){302if (node instanceof AST_SimpleStatement) {303node = node.body;304if (node instanceof AST_String) switch (node.getValue()) {305case "$ORIG":306return MAP.splice(self.body);307case "$EXPORTS":308var body = [];309to_export.forEach(function(sym){310body.push(new AST_SimpleStatement({311body: new AST_Assign({312left: new AST_Sub({313expression: new AST_SymbolRef({ name: "exports" }),314property: new AST_String({ value: sym.name }),315}),316operator: "=",317right: new AST_SymbolRef(sym),318}),319}));320});321return MAP.splice(body);322}323}324}));325return wrapped_tl;326}327}, AST_Scope);328329var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {330$documentation: "Base class for functions",331$propdoc: {332name: "[AST_SymbolDeclaration?] the name of this function",333argnames: "[AST_SymbolFunarg*] array of function arguments",334uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"335},336_walk: function(visitor) {337return visitor._visit(this, function(){338if (this.name) this.name._walk(visitor);339this.argnames.forEach(function(arg){340arg._walk(visitor);341});342walk_body(this, visitor);343});344}345}, AST_Scope);346347var AST_Accessor = DEFNODE("Accessor", null, {348$documentation: "A setter/getter function"349}, AST_Lambda);350351var AST_Function = DEFNODE("Function", null, {352$documentation: "A function expression"353}, AST_Lambda);354355var AST_Defun = DEFNODE("Defun", null, {356$documentation: "A function definition"357}, AST_Lambda);358359/* -----[ JUMPS ]----- */360361var AST_Jump = DEFNODE("Jump", null, {362$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"363}, AST_Statement);364365var AST_Exit = DEFNODE("Exit", "value", {366$documentation: "Base class for “exits” (`return` and `throw`)",367$propdoc: {368value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"369},370_walk: function(visitor) {371return visitor._visit(this, this.value && function(){372this.value._walk(visitor);373});374}375}, AST_Jump);376377var AST_Return = DEFNODE("Return", null, {378$documentation: "A `return` statement"379}, AST_Exit);380381var AST_Throw = DEFNODE("Throw", null, {382$documentation: "A `throw` statement"383}, AST_Exit);384385var AST_LoopControl = DEFNODE("LoopControl", "label", {386$documentation: "Base class for loop control statements (`break` and `continue`)",387$propdoc: {388label: "[AST_LabelRef?] the label, or null if none",389},390_walk: function(visitor) {391return visitor._visit(this, this.label && function(){392this.label._walk(visitor);393});394}395}, AST_Jump);396397var AST_Break = DEFNODE("Break", null, {398$documentation: "A `break` statement"399}, AST_LoopControl);400401var AST_Continue = DEFNODE("Continue", null, {402$documentation: "A `continue` statement"403}, AST_LoopControl);404405/* -----[ IF ]----- */406407var AST_If = DEFNODE("If", "condition alternative", {408$documentation: "A `if` statement",409$propdoc: {410condition: "[AST_Node] the `if` condition",411alternative: "[AST_Statement?] the `else` part, or null if not present"412},413_walk: function(visitor) {414return visitor._visit(this, function(){415this.condition._walk(visitor);416this.body._walk(visitor);417if (this.alternative) this.alternative._walk(visitor);418});419}420}, AST_StatementWithBody);421422/* -----[ SWITCH ]----- */423424var AST_Switch = DEFNODE("Switch", "expression", {425$documentation: "A `switch` statement",426$propdoc: {427expression: "[AST_Node] the `switch` “discriminant”"428},429_walk: function(visitor) {430return visitor._visit(this, function(){431this.expression._walk(visitor);432walk_body(this, visitor);433});434}435}, AST_Block);436437var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {438$documentation: "Base class for `switch` branches",439}, AST_Block);440441var AST_Default = DEFNODE("Default", null, {442$documentation: "A `default` switch branch",443}, AST_SwitchBranch);444445var AST_Case = DEFNODE("Case", "expression", {446$documentation: "A `case` switch branch",447$propdoc: {448expression: "[AST_Node] the `case` expression"449},450_walk: function(visitor) {451return visitor._visit(this, function(){452this.expression._walk(visitor);453walk_body(this, visitor);454});455}456}, AST_SwitchBranch);457458/* -----[ EXCEPTIONS ]----- */459460var AST_Try = DEFNODE("Try", "bcatch bfinally", {461$documentation: "A `try` statement",462$propdoc: {463bcatch: "[AST_Catch?] the catch block, or null if not present",464bfinally: "[AST_Finally?] the finally block, or null if not present"465},466_walk: function(visitor) {467return visitor._visit(this, function(){468walk_body(this, visitor);469if (this.bcatch) this.bcatch._walk(visitor);470if (this.bfinally) this.bfinally._walk(visitor);471});472}473}, AST_Block);474475// XXX: this is wrong according to ECMA-262 (12.4). the catch block476// should introduce another scope, as the argname should be visible477// only inside the catch block. However, doing it this way because of478// IE which simply introduces the name in the surrounding scope. If479// we ever want to fix this then AST_Catch should inherit from480// AST_Scope.481var AST_Catch = DEFNODE("Catch", "argname", {482$documentation: "A `catch` node; only makes sense as part of a `try` statement",483$propdoc: {484argname: "[AST_SymbolCatch] symbol for the exception"485},486_walk: function(visitor) {487return visitor._visit(this, function(){488this.argname._walk(visitor);489walk_body(this, visitor);490});491}492}, AST_Block);493494var AST_Finally = DEFNODE("Finally", null, {495$documentation: "A `finally` node; only makes sense as part of a `try` statement"496}, AST_Block);497498/* -----[ VAR/CONST ]----- */499500var AST_Definitions = DEFNODE("Definitions", "definitions", {501$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",502$propdoc: {503definitions: "[AST_VarDef*] array of variable definitions"504},505_walk: function(visitor) {506return visitor._visit(this, function(){507this.definitions.forEach(function(def){508def._walk(visitor);509});510});511}512}, AST_Statement);513514var AST_Var = DEFNODE("Var", null, {515$documentation: "A `var` statement"516}, AST_Definitions);517518var AST_Const = DEFNODE("Const", null, {519$documentation: "A `const` statement"520}, AST_Definitions);521522var AST_VarDef = DEFNODE("VarDef", "name value", {523$documentation: "A variable declaration; only appears in a AST_Definitions node",524$propdoc: {525name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",526value: "[AST_Node?] initializer, or null of there's no initializer"527},528_walk: function(visitor) {529return visitor._visit(this, function(){530this.name._walk(visitor);531if (this.value) this.value._walk(visitor);532});533}534});535536/* -----[ OTHER ]----- */537538var AST_Call = DEFNODE("Call", "expression args", {539$documentation: "A function call expression",540$propdoc: {541expression: "[AST_Node] expression to invoke as function",542args: "[AST_Node*] array of arguments"543},544_walk: function(visitor) {545return visitor._visit(this, function(){546this.expression._walk(visitor);547this.args.forEach(function(arg){548arg._walk(visitor);549});550});551}552});553554var AST_New = DEFNODE("New", null, {555$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"556}, AST_Call);557558var AST_Seq = DEFNODE("Seq", "car cdr", {559$documentation: "A sequence expression (two comma-separated expressions)",560$propdoc: {561car: "[AST_Node] first element in sequence",562cdr: "[AST_Node] second element in sequence"563},564$cons: function(x, y) {565var seq = new AST_Seq(x);566seq.car = x;567seq.cdr = y;568return seq;569},570$from_array: function(array) {571if (array.length == 0) return null;572if (array.length == 1) return array[0].clone();573var list = null;574for (var i = array.length; --i >= 0;) {575list = AST_Seq.cons(array[i], list);576}577var p = list;578while (p) {579if (p.cdr && !p.cdr.cdr) {580p.cdr = p.cdr.car;581break;582}583p = p.cdr;584}585return list;586},587to_array: function() {588var p = this, a = [];589while (p) {590a.push(p.car);591if (p.cdr && !(p.cdr instanceof AST_Seq)) {592a.push(p.cdr);593break;594}595p = p.cdr;596}597return a;598},599add: function(node) {600var p = this;601while (p) {602if (!(p.cdr instanceof AST_Seq)) {603var cell = AST_Seq.cons(p.cdr, node);604return p.cdr = cell;605}606p = p.cdr;607}608},609_walk: function(visitor) {610return visitor._visit(this, function(){611this.car._walk(visitor);612if (this.cdr) this.cdr._walk(visitor);613});614}615});616617var AST_PropAccess = DEFNODE("PropAccess", "expression property", {618$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",619$propdoc: {620expression: "[AST_Node] the “container” expression",621property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node"622}623});624625var AST_Dot = DEFNODE("Dot", null, {626$documentation: "A dotted property access expression",627_walk: function(visitor) {628return visitor._visit(this, function(){629this.expression._walk(visitor);630});631}632}, AST_PropAccess);633634var AST_Sub = DEFNODE("Sub", null, {635$documentation: "Index-style property access, i.e. `a[\"foo\"]`",636_walk: function(visitor) {637return visitor._visit(this, function(){638this.expression._walk(visitor);639this.property._walk(visitor);640});641}642}, AST_PropAccess);643644var AST_Unary = DEFNODE("Unary", "operator expression", {645$documentation: "Base class for unary expressions",646$propdoc: {647operator: "[string] the operator",648expression: "[AST_Node] expression that this unary operator applies to"649},650_walk: function(visitor) {651return visitor._visit(this, function(){652this.expression._walk(visitor);653});654}655});656657var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, {658$documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"659}, AST_Unary);660661var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {662$documentation: "Unary postfix expression, i.e. `i++`"663}, AST_Unary);664665var AST_Binary = DEFNODE("Binary", "left operator right", {666$documentation: "Binary expression, i.e. `a + b`",667$propdoc: {668left: "[AST_Node] left-hand side expression",669operator: "[string] the operator",670right: "[AST_Node] right-hand side expression"671},672_walk: function(visitor) {673return visitor._visit(this, function(){674this.left._walk(visitor);675this.right._walk(visitor);676});677}678});679680var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", {681$documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",682$propdoc: {683condition: "[AST_Node]",684consequent: "[AST_Node]",685alternative: "[AST_Node]"686},687_walk: function(visitor) {688return visitor._visit(this, function(){689this.condition._walk(visitor);690this.consequent._walk(visitor);691this.alternative._walk(visitor);692});693}694});695696var AST_Assign = DEFNODE("Assign", null, {697$documentation: "An assignment expression — `a = b + 5`",698}, AST_Binary);699700/* -----[ LITERALS ]----- */701702var AST_Array = DEFNODE("Array", "elements", {703$documentation: "An array literal",704$propdoc: {705elements: "[AST_Node*] array of elements"706},707_walk: function(visitor) {708return visitor._visit(this, function(){709this.elements.forEach(function(el){710el._walk(visitor);711});712});713}714});715716var AST_Object = DEFNODE("Object", "properties", {717$documentation: "An object literal",718$propdoc: {719properties: "[AST_ObjectProperty*] array of properties"720},721_walk: function(visitor) {722return visitor._visit(this, function(){723this.properties.forEach(function(prop){724prop._walk(visitor);725});726});727}728});729730var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {731$documentation: "Base class for literal object properties",732$propdoc: {733key: "[string] the property name; it's always a plain string in our AST, no matter if it was a string, number or identifier in original code",734value: "[AST_Node] property value. For setters and getters this is an AST_Function."735},736_walk: function(visitor) {737return visitor._visit(this, function(){738this.value._walk(visitor);739});740}741});742743var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, {744$documentation: "A key: value object property",745}, AST_ObjectProperty);746747var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {748$documentation: "An object setter property",749}, AST_ObjectProperty);750751var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {752$documentation: "An object getter property",753}, AST_ObjectProperty);754755var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {756$propdoc: {757name: "[string] name of this symbol",758scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",759thedef: "[SymbolDef/S] the definition of this symbol"760},761$documentation: "Base class for all symbols",762});763764var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {765$documentation: "The name of a property accessor (setter/getter function)"766}, AST_Symbol);767768var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {769$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",770$propdoc: {771init: "[AST_Node*/S] array of initializers for this declaration."772}773}, AST_Symbol);774775var AST_SymbolVar = DEFNODE("SymbolVar", null, {776$documentation: "Symbol defining a variable",777}, AST_SymbolDeclaration);778779var AST_SymbolConst = DEFNODE("SymbolConst", null, {780$documentation: "A constant declaration"781}, AST_SymbolDeclaration);782783var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {784$documentation: "Symbol naming a function argument",785}, AST_SymbolVar);786787var AST_SymbolDefun = DEFNODE("SymbolDefun", null, {788$documentation: "Symbol defining a function",789}, AST_SymbolDeclaration);790791var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {792$documentation: "Symbol naming a function expression",793}, AST_SymbolDeclaration);794795var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {796$documentation: "Symbol naming the exception in catch",797}, AST_SymbolDeclaration);798799var AST_Label = DEFNODE("Label", "references", {800$documentation: "Symbol naming a label (declaration)",801$propdoc: {802references: "[AST_LabelRef*] a list of nodes referring to this label"803}804}, AST_Symbol);805806var AST_SymbolRef = DEFNODE("SymbolRef", null, {807$documentation: "Reference to some symbol (not definition/declaration)",808}, AST_Symbol);809810var AST_LabelRef = DEFNODE("LabelRef", null, {811$documentation: "Reference to a label symbol",812}, AST_Symbol);813814var AST_This = DEFNODE("This", null, {815$documentation: "The `this` symbol",816}, AST_Symbol);817818var AST_Constant = DEFNODE("Constant", null, {819$documentation: "Base class for all constants",820getValue: function() {821return this.value;822}823});824825var AST_String = DEFNODE("String", "value", {826$documentation: "A string literal",827$propdoc: {828value: "[string] the contents of this string"829}830}, AST_Constant);831832var AST_Number = DEFNODE("Number", "value", {833$documentation: "A number literal",834$propdoc: {835value: "[number] the numeric value"836}837}, AST_Constant);838839var AST_RegExp = DEFNODE("RegExp", "value", {840$documentation: "A regexp literal",841$propdoc: {842value: "[RegExp] the actual regexp"843}844}, AST_Constant);845846var AST_Atom = DEFNODE("Atom", null, {847$documentation: "Base class for atoms",848}, AST_Constant);849850var AST_Null = DEFNODE("Null", null, {851$documentation: "The `null` atom",852value: null853}, AST_Atom);854855var AST_NaN = DEFNODE("NaN", null, {856$documentation: "The impossible value",857value: 0/0858}, AST_Atom);859860var AST_Undefined = DEFNODE("Undefined", null, {861$documentation: "The `undefined` value",862value: (function(){}())863}, AST_Atom);864865var AST_Hole = DEFNODE("Hole", null, {866$documentation: "A hole in an array",867value: (function(){}())868}, AST_Atom);869870var AST_Infinity = DEFNODE("Infinity", null, {871$documentation: "The `Infinity` value",872value: 1/0873}, AST_Atom);874875var AST_Boolean = DEFNODE("Boolean", null, {876$documentation: "Base class for booleans",877}, AST_Atom);878879var AST_False = DEFNODE("False", null, {880$documentation: "The `false` atom",881value: false882}, AST_Boolean);883884var AST_True = DEFNODE("True", null, {885$documentation: "The `true` atom",886value: true887}, AST_Boolean);888889/* -----[ TreeWalker ]----- */890891function TreeWalker(callback) {892this.visit = callback;893this.stack = [];894};895TreeWalker.prototype = {896_visit: function(node, descend) {897this.stack.push(node);898var ret = this.visit(node, descend ? function(){899descend.call(node);900} : noop);901if (!ret && descend) {902descend.call(node);903}904this.stack.pop();905return ret;906},907parent: function(n) {908return this.stack[this.stack.length - 2 - (n || 0)];909},910push: function (node) {911this.stack.push(node);912},913pop: function() {914return this.stack.pop();915},916self: function() {917return this.stack[this.stack.length - 1];918},919find_parent: function(type) {920var stack = this.stack;921for (var i = stack.length; --i >= 0;) {922var x = stack[i];923if (x instanceof type) return x;924}925},926in_boolean_context: function() {927var stack = this.stack;928var i = stack.length, self = stack[--i];929while (i > 0) {930var p = stack[--i];931if ((p instanceof AST_If && p.condition === self) ||932(p instanceof AST_Conditional && p.condition === self) ||933(p instanceof AST_DWLoop && p.condition === self) ||934(p instanceof AST_For && p.condition === self) ||935(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))936{937return true;938}939if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))940return false;941self = p;942}943},944loopcontrol_target: function(label) {945var stack = this.stack;946if (label) {947for (var i = stack.length; --i >= 0;) {948var x = stack[i];949if (x instanceof AST_LabeledStatement && x.label.name == label.name) {950return x.body;951}952}953} else {954for (var i = stack.length; --i >= 0;) {955var x = stack[i];956if (x instanceof AST_Switch957|| x instanceof AST_For958|| x instanceof AST_ForIn959|| x instanceof AST_DWLoop) return x;960}961}962}963};964965966