scope.js 11 KB

1
  1. "use strict";function SymbolDef(d,a,b){this.name=a.name,this.orig=[a],this.init=b,this.eliminated=0,this.scope=d,this.references=[],this.replaced=0,this.global=!1,this.export=!1,this.mangled_name=null,this.undeclared=!1,this.id=SymbolDef.next_id++}SymbolDef.next_id=1,SymbolDef.prototype={unmangleable:function(b){return b||(b={}),this.global&&!b.toplevel||this.export||this.undeclared||!b.eval&&(this.scope.uses_eval||this.scope.uses_with)||b.keep_fnames&&(this.orig[0]instanceof AST_SymbolLambda||this.orig[0]instanceof AST_SymbolDefun)||this.orig[0]instanceof AST_SymbolMethod||b.keep_classnames&&(this.orig[0]instanceof AST_SymbolClass||this.orig[0]instanceof AST_SymbolDefClass)},mangle:function(f){var a=f.cache&&f.cache.props;if(this.global&&a&&a.has(this.name))this.mangled_name=a.get(this.name);else if(!this.mangled_name&&!this.unmangleable(f)){var b=this.scope,c=this.orig[0];f.ie8&&c instanceof AST_SymbolLambda&&(b=b.parent_scope);var d;this.mangled_name=(d=this.redefined())?d.mangled_name||d.name:b.next_mangled(f,this),this.global&&a&&a.set(this.name,this.mangled_name)}},redefined:function(){return this.defun&&this.defun.variables.get(this.name)}},AST_Toplevel.DEFMETHOD("figure_out_scope",function(l){l=defaults(l,{cache:null,ie8:!1,safari10:!1});var a=this,r=a.parent_scope=null,c=new Dictionary,d=null,e=null,f=[],g=new TreeWalker(function(h,a){function b(f,a){if(e){var b=0;do a++;while(g.parent(b++)!==e)}var c=g.parent(a);f.export=c instanceof AST_Export}if(h.is_block_scope()){var i=r;return h.block_scope=r=new AST_Scope(h),r.init_scope_vars(i),h instanceof AST_Scope||(r.uses_with=i.uses_with,r.uses_eval=i.uses_eval,r.directives=i.directives),l.safari10&&(h instanceof AST_For||h instanceof AST_ForIn)&&f.push(r),a(),r=i,!0}if(h instanceof AST_Destructuring)return e=h,a(),e=null,!0;if(h instanceof AST_Scope){h.init_scope_vars(r);var i=r,j=d,k=c;return d=r=h,c=new Dictionary,a(),r=i,d=j,c=k,!0}if(h instanceof AST_LabeledStatement){var m=h.label;if(c.has(m.name))throw new Error(string_template("Label {name} defined twice",m));return c.set(m.name,m),a(),c.del(m.name),!0}if(h instanceof AST_With){for(var n=r;n;n=n.parent_scope)n.uses_with=!0;return}if(h instanceof AST_Symbol&&(h.scope=r),h instanceof AST_Label&&(h.thedef=h,h.references=[]),h instanceof AST_SymbolLambda)d.def_function(h,"arguments"==h.name?void 0:d);else if(h instanceof AST_SymbolDefun)b((h.scope=d.parent_scope.get_defun_scope()).def_function(h,d),1);else if(h instanceof AST_SymbolClass)b(d.def_variable(h,d),1);else if(h instanceof AST_SymbolImport)r.def_variable(h);else if(h instanceof AST_SymbolDefClass)b((h.scope=d.parent_scope).def_function(h,d),1);else if(h instanceof AST_SymbolVar||h instanceof AST_SymbolLet||h instanceof AST_SymbolConst){var o;if(o=h instanceof AST_SymbolBlockDeclaration?r.def_variable(h,null):d.def_variable(h,"SymbolVar"==h.TYPE?null:void 0),all(o.orig,function(b){return b===h||(h instanceof AST_SymbolBlockDeclaration?b instanceof AST_SymbolLambda:!(b instanceof AST_SymbolLet||b instanceof AST_SymbolConst))})||js_error(h.name+" redeclared",h.start.file,h.start.line,h.start.col,h.start.pos),h instanceof AST_SymbolFunarg||b(o,2),o.destructuring=e,d!==r){h.mark_enclosed(l);var o=r.find_variable(h);h.thedef!==o&&(h.thedef=o,h.reference(l))}}else if(h instanceof AST_SymbolCatch)r.def_variable(h).defun=d;else if(h instanceof AST_LabelRef){var p=c.get(h.name);if(!p)throw new Error(string_template("Undefined label {name} [{line},{col}]",{name:h.name,line:h.start.line,col:h.start.col}));h.thedef=p}!(r instanceof AST_Toplevel)&&(h instanceof AST_Export||h instanceof AST_Import)&&js_error(h.TYPE+" statement may only appear at top level",h.start.file,h.start.line,h.start.col,h.start.pos)});a.walk(g),a.globals=new Dictionary;var g=new TreeWalker(function(b){if(b instanceof AST_LoopControl&&b.label)return b.label.thedef.references.push(b),!0;if(b instanceof AST_SymbolRef){var c=b.name;if("eval"==c&&g.parent()instanceof AST_Call)for(var d=b.scope;d&&!d.uses_eval;d=d.parent_scope)d.uses_eval=!0;var e;return g.parent()instanceof AST_NameMapping&&g.parent(1).module_name||!(e=b.scope.find_variable(c))?e=a.def_global(b):e.scope instanceof AST_Lambda&&"arguments"==c&&(e.scope.uses_arguments=!0),b.thedef=e,b.reference(l),b.scope.is_block_scope()&&!(e.orig[0]instanceof AST_SymbolBlockDeclaration)&&(b.scope=b.scope.get_defun_scope()),!0}var f;if(b instanceof AST_SymbolCatch&&(f=b.definition().redefined()))for(var d=b.scope;d&&(push_uniq(d.enclosed,f),d!==f.scope);)d=d.parent_scope});if(a.walk(g),l.ie8&&a.walk(new TreeWalker(function(b){if(b instanceof AST_SymbolCatch){var c=b.name,d=b.thedef.references,e=b.thedef.defun,f=e.find_variable(c)||a.globals.get(c)||e.def_variable(b);return d.forEach(function(a){a.thedef=f,a.reference(l)}),b.thedef=f,b.reference(l),!0}})),l.safari10)for(var r,b=0;b<f.length;b++)r=f[b],r.parent_scope.variables.each(function(b){push_uniq(r.enclosed,b)})}),AST_Toplevel.DEFMETHOD("def_global",function(e){var a=this.globals,b=e.name;if(a.has(b))return a.get(b);var c=new SymbolDef(this,e);return c.undeclared=!0,c.global=!0,a.set(b,c),c}),AST_Scope.DEFMETHOD("init_scope_vars",function(b){this.variables=new Dictionary,this.functions=new Dictionary,this.uses_with=!1,this.uses_eval=!1,this.parent_scope=b,this.enclosed=[],this.cname=-1}),AST_Node.DEFMETHOD("is_block_scope",return_false),AST_Class.DEFMETHOD("is_block_scope",return_false),AST_Lambda.DEFMETHOD("is_block_scope",return_false),AST_Toplevel.DEFMETHOD("is_block_scope",return_false),AST_SwitchBranch.DEFMETHOD("is_block_scope",return_false),AST_Block.DEFMETHOD("is_block_scope",return_true),AST_IterationStatement.DEFMETHOD("is_block_scope",return_true),AST_Lambda.DEFMETHOD("init_scope_vars",function(){AST_Scope.prototype.init_scope_vars.apply(this,arguments),this.uses_arguments=!1,this.def_variable(new AST_SymbolFunarg({name:"arguments",start:this.start,end:this.end}))}),AST_Arrow.DEFMETHOD("init_scope_vars",function(){AST_Scope.prototype.init_scope_vars.apply(this,arguments),this.uses_arguments=!1}),AST_Symbol.DEFMETHOD("mark_enclosed",function(d){for(var e=this.definition(),a=this.scope;a&&(push_uniq(a.enclosed,e),d.keep_fnames&&a.functions.each(function(b){push_uniq(e.scope.enclosed,b)}),a!==e.scope);)a=a.parent_scope}),AST_Symbol.DEFMETHOD("reference",function(b){this.definition().references.push(this),this.mark_enclosed(b)}),AST_Scope.DEFMETHOD("find_variable",function(b){return b instanceof AST_Symbol&&(b=b.name),this.variables.get(b)||this.parent_scope&&this.parent_scope.find_variable(b)}),AST_Scope.DEFMETHOD("def_function",function(d,a){var b=this.def_variable(d,a);return(!b.init||b.init instanceof AST_Defun)&&(b.init=a),this.functions.set(d.name,b),b}),AST_Scope.DEFMETHOD("def_variable",function(d,a){var b=this.variables.get(d.name);return b?(b.orig.push(d),b.init&&(b.scope!==d.scope||b.init instanceof AST_Function)&&(b.init=a)):(b=new SymbolDef(this,d,a),this.variables.set(d.name,b),b.global=!this.parent_scope),d.thedef=b});function next_mangled(h,a){var b=h.enclosed;out:for(;;){var c=base54(++h.cname);if(is_identifier(c)&&!member(c,a.reserved)){for(var d=b.length;0<=--d;){var e=b[d],f=e.mangled_name||e.unmangleable(a)&&e.name;if(c==f)continue out}return c}}}AST_Scope.DEFMETHOD("next_mangled",function(b){return next_mangled(this,b)}),AST_Toplevel.DEFMETHOD("next_mangled",function(c){var a;do a=next_mangled(this,c);while(member(a,this.mangled_names));return a}),AST_Function.DEFMETHOD("next_mangled",function(f,a){for(var b,e=a.orig[0]instanceof AST_SymbolFunarg&&this.name&&this.name.definition(),c=e?e.mangled_name||e.name:null;;)if(b=next_mangled(this,f),!c||c!=b)return b}),AST_Symbol.DEFMETHOD("unmangleable",function(c){var a=this.definition();return!a||a.unmangleable(c)}),AST_Label.DEFMETHOD("unmangleable",return_false),AST_Symbol.DEFMETHOD("unreferenced",function(){return 0==this.definition().references.length&&!(this.scope.uses_eval||this.scope.uses_with)}),AST_Symbol.DEFMETHOD("definition",function(){return this.thedef}),AST_Symbol.DEFMETHOD("global",function(){return this.definition().global}),AST_Toplevel.DEFMETHOD("_default_mangler_options",function(b){return b=defaults(b,{eval:!1,ie8:!1,keep_classnames:!1,keep_fnames:!1,reserved:[],toplevel:!1}),Array.isArray(b.reserved)||(b.reserved=[]),push_uniq(b.reserved,"arguments"),b}),AST_Toplevel.DEFMETHOD("mangle_names",function(i){function a(a){member(a.name,i.reserved)||c.push(a)}i=this._default_mangler_options(i);var b=-1,c=[],d=this.mangled_names=[];i.cache&&(this.globals.each(a),i.cache.props&&i.cache.props.each(function(b){push_uniq(d,b)}));var e=new TreeWalker(function(d,e){if(d instanceof AST_LabeledStatement){var f=b;return e(),b=f,!0}if(d instanceof AST_Scope)return void d.variables.each(a);if(d.is_block_scope())return void d.block_scope.variables.each(a);if(d instanceof AST_Label){var g;do g=base54(++b);while(!is_identifier(g));return d.mangled_name=g,!0}return!i.ie8&&d instanceof AST_SymbolCatch?void c.push(d.definition()):void 0});this.walk(e),c.forEach(function(a){a.mangle(i)})}),AST_Toplevel.DEFMETHOD("find_colliding_names",function(f){function a(b){c[b]=!0}function b(b){var c=b.name;if(b.global&&g&&g.has(c))c=g.get(c);else if(!b.unmangleable(f))return;a(c)}var g=f.cache&&f.cache.props,c=Object.create(null);return f.reserved.forEach(a),this.globals.each(b),this.walk(new TreeWalker(function(c){c instanceof AST_Scope&&c.variables.each(b),c instanceof AST_SymbolCatch&&b(c.definition())})),c}),AST_Toplevel.DEFMETHOD("expand_names",function(f){function a(){var b;do b=base54(d++);while(c[b]||!is_identifier(b));return b}function b(b){if(!(b.global&&f.cache)&&!b.unmangleable(f)&&!member(b.name,f.reserved)){var c=b.redefined();b.name=c?c.name:a(),b.orig.forEach(function(c){c.name=b.name}),b.references.forEach(function(c){c.name=b.name})}}base54.reset(),base54.sort(),f=this._default_mangler_options(f);var c=this.find_colliding_names(f),d=0;this.globals.each(b),this.walk(new TreeWalker(function(c){c instanceof AST_Scope&&c.variables.each(b),c instanceof AST_SymbolCatch&&b(c.definition())}))}),AST_Node.DEFMETHOD("tail_node",return_this),AST_Sequence.DEFMETHOD("tail_node",function(){return this.expressions[this.expressions.length-1]}),AST_Toplevel.DEFMETHOD("compute_char_frequency",function(e){function f(b){b instanceof AST_String?base54.consider(b.value,-1):b instanceof AST_Conditional?(f(b.consequent),f(b.alternative)):b instanceof AST_Sequence&&f(b.tail_node())}e=this._default_mangler_options(e);try{AST_Node.prototype.print=function(a,b){this._print(a,b),this instanceof AST_Symbol&&!this.unmangleable(e)?base54.consider(this.name,-1):e.properties&&(this instanceof AST_Dot?base54.consider(this.property,-1):this instanceof AST_Sub&&f(this.property))},base54.consider(this.print_to_string(),1)}finally{AST_Node.prototype.print=AST_Node.prototype._print}base54.sort()});var base54=function(){function h(){d=Object.create(null),c.forEach(function(b){d[b]=0}),e.forEach(function(b){d[b]=0})}function a(b,c){return d[c]-d[b]}function b(d){var a="",b=54;d++;do d--,a+=i[d%b],d=Math.floor(d/b),b=64;while(0<d);return a}var i,d,c=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","$","_"],e=["0","1","2","3","4","5","6","7","8","9"];return b.consider=function(e,a){for(var b=e.length;0<=--b;)d[e[b]]+=a},b.sort=function(){i=mergeSort(c,a).concat(mergeSort(e,a))},b.reset=h,h(),b}();