jslint-v8 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,538 +1,3886 @@
1
- // (C)2002 Douglas Crockford
2
- // www.JSLint.com
3
- // Modified from Rhino version by William Howard (stripped runner)
4
- "use strict";var JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,bang={'<':true,'<=':true,'==':true,'===':true,'!==':true,'!=':true,'>':true,'>=':true,'+':true,'-':true,'*':true,'/':true,'%':true},banned={'arguments':true,callee:true,caller:true,constructor:true,'eval':true,prototype:true,stack:true,unwatch:true,valueOf:true,watch:true},boolOptions={adsafe:true,bitwise:true,browser:true,cap:true,css:true,debug:true,devel:true,eqeqeq:true,es5:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,windows:true,strict:true,sub:true,white:true,widget:true},browser={addEventListener:false,blur:false,clearInterval:false,clearTimeout:false,close:false,closed:false,defaultStatus:false,document:false,event:false,focus:false,frames:false,getComputedStyle:false,history:false,Image:false,length:false,location:false,moveBy:false,moveTo:false,name:false,navigator:false,onbeforeunload:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:false,opener:false,Option:false,parent:false,print:false,removeEventListener:false,resizeBy:false,resizeTo:false,screen:false,scroll:false,scrollBy:false,scrollTo:false,setInterval:false,setTimeout:false,status:false,top:false,XMLHttpRequest:false},cssAttributeData,cssAny,cssColorData={"aliceblue":true,"antiquewhite":true,"aqua":true,"aquamarine":true,"azure":true,"beige":true,"bisque":true,"black":true,"blanchedalmond":true,"blue":true,"blueviolet":true,"brown":true,"burlywood":true,"cadetblue":true,"chartreuse":true,"chocolate":true,"coral":true,"cornflowerblue":true,"cornsilk":true,"crimson":true,"cyan":true,"darkblue":true,"darkcyan":true,"darkgoldenrod":true,"darkgray":true,"darkgreen":true,"darkkhaki":true,"darkmagenta":true,"darkolivegreen":true,"darkorange":true,"darkorchid":true,"darkred":true,"darksalmon":true,"darkseagreen":true,"darkslateblue":true,"darkslategray":true,"darkturquoise":true,"darkviolet":true,"deeppink":true,"deepskyblue":true,"dimgray":true,"dodgerblue":true,"firebrick":true,"floralwhite":true,"forestgreen":true,"fuchsia":true,"gainsboro":true,"ghostwhite":true,"gold":true,"goldenrod":true,"gray":true,"green":true,"greenyellow":true,"honeydew":true,"hotpink":true,"indianred":true,"indigo":true,"ivory":true,"khaki":true,"lavender":true,"lavenderblush":true,"lawngreen":true,"lemonchiffon":true,"lightblue":true,"lightcoral":true,"lightcyan":true,"lightgoldenrodyellow":true,"lightgreen":true,"lightpink":true,"lightsalmon":true,"lightseagreen":true,"lightskyblue":true,"lightslategray":true,"lightsteelblue":true,"lightyellow":true,"lime":true,"limegreen":true,"linen":true,"magenta":true,"maroon":true,"mediumaquamarine":true,"mediumblue":true,"mediumorchid":true,"mediumpurple":true,"mediumseagreen":true,"mediumslateblue":true,"mediumspringgreen":true,"mediumturquoise":true,"mediumvioletred":true,"midnightblue":true,"mintcream":true,"mistyrose":true,"moccasin":true,"navajowhite":true,"navy":true,"oldlace":true,"olive":true,"olivedrab":true,"orange":true,"orangered":true,"orchid":true,"palegoldenrod":true,"palegreen":true,"paleturquoise":true,"palevioletred":true,"papayawhip":true,"peachpuff":true,"peru":true,"pink":true,"plum":true,"powderblue":true,"purple":true,"red":true,"rosybrown":true,"royalblue":true,"saddlebrown":true,"salmon":true,"sandybrown":true,"seagreen":true,"seashell":true,"sienna":true,"silver":true,"skyblue":true,"slateblue":true,"slategray":true,"snow":true,"springgreen":true,"steelblue":true,"tan":true,"teal":true,"thistle":true,"tomato":true,"turquoise":true,"violet":true,"wheat":true,"white":true,"whitesmoke":true,"yellow":true,"yellowgreen":true,"activeborder":true,"activecaption":true,"appworkspace":true,"background":true,"buttonface":true,"buttonhighlight":true,"buttonshadow":true,"buttontext":true,"captiontext":true,"graytext":true,"highlight":true,"highlighttext":true,"inactiveborder":true,"inactivecaption":true,"inactivecaptiontext":true,"infobackground":true,"infotext":true,"menu":true,"menutext":true,"scrollbar":true,"threeddarkshadow":true,"threedface":true,"threedhighlight":true,"threedlightshadow":true,"threedshadow":true,"window":true,"windowframe":true,"windowtext":true},cssBorderStyle,cssBreak,cssLengthData={'%':true,'cm':true,'em':true,'ex':true,'in':true,'mm':true,'pc':true,'pt':true,'px':true},cssMedia,cssOverflow,devel={alert:false,confirm:false,console:false,Debug:false,opera:false,prompt:false},escapes={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','/':'\\/','\\':'\\\\'},funct,functionicity=['closure','exception','global','label','outer','unused','var'],functions,global,htmltag={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:' map '},article:{},aside:{},audio:{},b:{},base:{empty:true,parent:' head '},bdo:{},big:{},blockquote:{},body:{parent:' html noframes '},br:{empty:true},button:{},canvas:{parent:' body p div th td '},caption:{parent:' table '},center:{},cite:{},code:{},col:{empty:true,parent:' table colgroup '},colgroup:{parent:' table '},command:{parent:' menu '},datalist:{},dd:{parent:' dl '},del:{},details:{},dialog:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:' dl '},em:{},embed:{},fieldset:{},figure:{},font:{},footer:{},form:{},frame:{empty:true,parent:' frameset '},frameset:{parent:' html frameset '},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:' html '},header:{},hgroup:{},hr:{empty:true},'hta:application':{empty:true,parent:' head '},html:{parent:'*'},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},keygen:{},label:{},legend:{parent:' details fieldset figure '},li:{parent:' dir menu ol ul '},link:{empty:true,parent:' head '},map:{},mark:{},menu:{},meta:{empty:true,parent:' head noframes noscript '},meter:{},nav:{},noframes:{parent:' html body '},noscript:{parent:' body head noframes '},object:{},ol:{},optgroup:{parent:' select '},option:{parent:' optgroup select '},output:{},p:{},param:{empty:true,parent:' applet object '},pre:{},progress:{},q:{},rp:{},rt:{},ruby:{},samp:{},script:{empty:true,parent:' body div frame head iframe p pre span '},section:{},select:{},small:{},span:{},source:{},strong:{},style:{parent:' head ',empty:true},sub:{},sup:{},table:{},tbody:{parent:' table '},td:{parent:' tr '},textarea:{},tfoot:{parent:' table '},th:{parent:' tr '},thead:{parent:' table '},time:{},title:{parent:' head '},tr:{parent:' table tbody thead tfoot '},tt:{},u:{},ul:{},'var':{},video:{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,rhino={defineClass:false,deserialize:false,gc:false,help:false,load:false,loadClass:false,print:false,quit:false,readFile:false,readUrl:false,runCommand:false,seal:false,serialize:false,spawn:false,sync:false,toint32:false,version:false},scope,src,stack,standard={Array:false,Boolean:false,Date:false,decodeURI:false,decodeURIComponent:false,encodeURI:false,encodeURIComponent:false,Error:false,'eval':false,EvalError:false,Function:false,hasOwnProperty:false,isFinite:false,isNaN:false,JSON:false,Math:false,Number:false,Object:false,parseInt:false,parseFloat:false,RangeError:false,ReferenceError:false,RegExp:false,String:false,SyntaxError:false,TypeError:false,URIError:false},standard_member={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,PI:true,POSITIVE_INFINITY:true,SQRT1_2:true,SQRT2:true},strict_mode,syntax={},tab,token,urls,warnings,widget={alert:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},windows={ActiveXObject:false,CScript:false,Debug:false,Enumerator:false,System:false,VBArray:false,WScript:false},xmode,xquote,ax=/@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,nx=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|--/,lx=/\*\/|\/\*/,ix=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,sx=/^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/,ssx=/^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9+\-_\/ ]/,dx=/[\[\]\/\\"'*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){}
5
- if(typeof Object.create!=='function'){Object.create=function(o){F.prototype=o;return new F();};}
6
- function is_own(object,name){return Object.prototype.hasOwnProperty.call(object,name);}
7
- function combine(t,o){var n;for(n in o){if(is_own(o,n)){t[n]=o[n];}}}
8
- String.prototype.entityify=function(){return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');};String.prototype.isAlpha=function(){return(this>='a'&&this<='z\uffff')||(this>='A'&&this<='Z\uffff');};String.prototype.isDigit=function(){return(this>='0'&&this<='9');};String.prototype.supplant=function(o){return this.replace(/\{([^{}]*)\}/g,function(a,b){var r=o[b];return typeof r==='string'||typeof r==='number'?r:a;});};String.prototype.name=function(){if(ix.test(this)){return this;}
9
- if(nx.test(this)){return'"'+this.replace(nxg,function(a){var c=escapes[a];if(c){return c;}
10
- return'\\u'+('0000'+a.charCodeAt().toString(16)).slice(-4);})+'"';}
11
- return'"'+this+'"';};function assume(){if(!option.safe){if(option.rhino){combine(predefined,rhino);}
12
- if(option.devel){combine(predefined,devel);}
13
- if(option.browser){combine(predefined,browser);}
14
- if(option.windows){combine(predefined,windows);}
15
- if(option.widget){combine(predefined,widget);}}}
16
- function quit(m,l,ch){throw{name:'JSLintError',line:l,character:ch,message:m+" ("+Math.floor((l/lines.length)*100)+"% scanned)."};}
17
- function warning(m,t,a,b,c,d){var ch,l,w;t=t||nexttoken;if(t.id==='(end)'){t=token;}
18
- l=t.line||0;ch=t.from||0;w={id:'(error)',raw:m,evidence:lines[l-1]||'',line:l,character:ch,a:a,b:b,c:c,d:d};w.reason=m.supplant(w);JSLINT.errors.push(w);if(option.passfail){quit('Stopping. ',l,ch);}
19
- warnings+=1;if(warnings>=option.maxerr){quit("Too many errors.",l,ch);}
20
- return w;}
21
- function warningAt(m,l,ch,a,b,c,d){return warning(m,{line:l,from:ch},a,b,c,d);}
22
- function error(m,t,a,b,c,d){var w=warning(m,t,a,b,c,d);quit("Stopping, unable to continue.",w.line,w.character);}
23
- function errorAt(m,l,ch,a,b,c,d){return error(m,{line:l,from:ch},a,b,c,d);}
24
- var lex=(function lex(){var character,from,line,s;function nextLine(){var at;if(line>=lines.length){return false;}
25
- character=1;s=lines[line];line+=1;at=s.search(/ \t/);if(at>=0){warningAt("Mixed spaces and tabs.",line,at+1);}
26
- s=s.replace(/\t/g,tab);at=s.search(cx);if(at>=0){warningAt("Unsafe character.",line,at);}
27
- if(option.maxlen&&option.maxlen<s.length){warningAt("Line too long.",line,s.length);}
28
- return true;}
29
- function it(type,value){var i,t;if(type==='(color)'||type==='(range)'){t={type:type};}else if(type==='(punctuator)'||(type==='(identifier)'&&is_own(syntax,value))){t=syntax[value]||syntax['(error)'];}else{t=syntax[type];}
30
- t=Object.create(t);if(type==='(string)'||type==='(range)'){if(jx.test(value)){warningAt("Script URL.",line,from);}}
31
- if(type==='(identifier)'){t.identifier=true;if(value==='__iterator__'||value==='__proto__'){errorAt("Reserved name '{a}'.",line,from,value);}else if(option.nomen&&(value.charAt(0)==='_'||value.charAt(value.length-1)==='_')){warningAt("Unexpected {a} in '{b}'.",line,from,"dangling '_'",value);}}
32
- t.value=value;t.line=line;t.character=character;t.from=from;i=t.id;if(i!=='(endline)'){prereg=i&&(('(,=:[!&|?{};'.indexOf(i.charAt(i.length-1))>=0)||i==='return');}
33
- return t;}
34
- return{init:function(source){if(typeof source==='string'){lines=source.replace(/\r\n/g,'\n').replace(/\r/g,'\n').split('\n');}else{lines=source;}
35
- line=0;nextLine();from=1;},range:function(begin,end){var c,value='';from=character;if(s.charAt(0)!==begin){errorAt("Expected '{a}' and instead saw '{b}'.",line,character,begin,s.charAt(0));}
36
- for(;;){s=s.slice(1);character+=1;c=s.charAt(0);switch(c){case'':errorAt("Missing '{a}'.",line,character,c);break;case end:s=s.slice(1);character+=1;return it('(range)',value);case xquote:case'\\':warningAt("Unexpected '{a}'.",line,character,c);}
37
- value+=c;}},token:function(){var b,c,captures,d,depth,high,i,l,low,q,t;function match(x){var r=x.exec(s),r1;if(r){l=r[0].length;r1=r[1];c=r1.charAt(0);s=s.substr(l);from=character+l-r1.length;character+=l;return r1;}}
38
- function string(x){var c,j,r='';if(jsonmode&&x!=='"'){warningAt("Strings must use doublequote.",line,character);}
39
- if(xquote===x||(xmode==='scriptstring'&&!xquote)){return it('(punctuator)',x);}
40
- function esc(n){var i=parseInt(s.substr(j+1,n),16);j+=n;if(i>=32&&i<=126&&i!==34&&i!==92&&i!==39){warningAt("Unnecessary escapement.",line,character);}
41
- character+=n;c=String.fromCharCode(i);}
42
- j=0;for(;;){while(j>=s.length){j=0;if(xmode!=='html'||!nextLine()){errorAt("Unclosed string.",line,from);}}
43
- c=s.charAt(j);if(c===x){character+=1;s=s.substr(j+1);return it('(string)',r,x);}
44
- if(c<' '){if(c==='\n'||c==='\r'){break;}
45
- warningAt("Control character in string: {a}.",line,character+j,s.slice(0,j));}else if(c===xquote){warningAt("Bad HTML string",line,character+j);}else if(c==='<'){if(option.safe&&xmode==='html'){warningAt("ADsafe string violation.",line,character+j);}else if(s.charAt(j+1)==='/'&&(xmode||option.safe)){warningAt("Expected '<\\/' and instead saw '</'.",line,character);}else if(s.charAt(j+1)==='!'&&(xmode||option.safe)){warningAt("Unexpected '<!' in a string.",line,character);}}else if(c==='\\'){if(xmode==='html'){if(option.safe){warningAt("ADsafe string violation.",line,character+j);}}else if(xmode==='styleproperty'){j+=1;character+=1;c=s.charAt(j);if(c!==x){warningAt("Escapement in style string.",line,character+j);}}else{j+=1;character+=1;c=s.charAt(j);switch(c){case xquote:warningAt("Bad HTML string",line,character+j);break;case'\\':case'\'':case'"':case'/':break;case'b':c='\b';break;case'f':c='\f';break;case'n':c='\n';break;case'r':c='\r';break;case't':c='\t';break;case'u':esc(4);break;case'v':c='\v';break;case'x':if(jsonmode){warningAt("Avoid \\x-.",line,character);}
46
- esc(2);break;default:warningAt("Bad escapement.",line,character);}}}
47
- r+=c;character+=1;j+=1;}}
48
- for(;;){if(!s){return it(nextLine()?'(endline)':'(end)','');}
49
- while(xmode==='outer'){i=s.search(ox);if(i===0){break;}else if(i>0){character+=1;s=s.slice(i);break;}else{if(!nextLine()){return it('(end)','');}}}
50
- t=match(rx[xmode]||tx);if(!t){t='';c='';while(s&&s<'!'){s=s.substr(1);}
51
- if(s){if(xmode==='html'){return it('(error)',s.charAt(0));}else{errorAt("Unexpected '{a}'.",line,character,s.substr(0,1));}}}else{if(c.isAlpha()||c==='_'||c==='$'){return it('(identifier)',t);}
52
- if(c.isDigit()){if(xmode!=='style'&&!isFinite(Number(t))){warningAt("Bad number '{a}'.",line,character,t);}
53
- if(xmode!=='style'&&xmode!=='styleproperty'&&s.substr(0,1).isAlpha()){warningAt("Missing space after '{a}'.",line,character,t);}
54
- if(c==='0'){d=t.substr(1,1);if(d.isDigit()){if(token.id!=='.'&&xmode!=='styleproperty'){warningAt("Don't use extra leading zeros '{a}'.",line,character,t);}}else if(jsonmode&&(d==='x'||d==='X')){warningAt("Avoid 0x-. '{a}'.",line,character,t);}}
55
- if(t.substr(t.length-1)==='.'){warningAt("A trailing decimal point can be confused with a dot '{a}'.",line,character,t);}
56
- return it('(number)',t);}
57
- switch(t){case'"':case"'":return string(t);case'//':if(src||(xmode&&xmode!=='script')){warningAt("Unexpected comment.",line,character);}else if(xmode==='script'&&/<\s*\//i.test(s)){warningAt("Unexpected <\/ in comment.",line,character);}else if((option.safe||xmode==='script')&&ax.test(s)){warningAt("Dangerous comment.",line,character);}
58
- s='';token.comment=true;break;case'/*':if(src||(xmode&&xmode!=='script'&&xmode!=='style'&&xmode!=='styleproperty')){warningAt("Unexpected comment.",line,character);}
59
- if(option.safe&&ax.test(s)){warningAt("ADsafe comment violation.",line,character);}
60
- for(;;){i=s.search(lx);if(i>=0){break;}
61
- if(!nextLine()){errorAt("Unclosed comment.",line,character);}else{if(option.safe&&ax.test(s)){warningAt("ADsafe comment violation.",line,character);}}}
62
- character+=i+2;if(s.substr(i,1)==='/'){errorAt("Nested comment.",line,character);}
63
- s=s.substr(i+2);token.comment=true;break;case'/*members':case'/*member':case'/*jslint':case'/*global':case'*/':return{value:t,type:'special',line:line,character:character,from:from};case'':break;case'/':if(token.id==='/='){errorAt("A regular expression literal can be confused with '/='.",line,from);}
64
- if(prereg){depth=0;captures=0;l=0;for(;;){b=true;c=s.charAt(l);l+=1;switch(c){case'':errorAt("Unclosed regular expression.",line,from);return;case'/':if(depth>0){warningAt("Unescaped '{a}'.",line,from+l,'/');}
65
- c=s.substr(0,l-1);q={g:true,i:true,m:true};while(q[s.charAt(l)]===true){q[s.charAt(l)]=false;l+=1;}
66
- character+=l;s=s.substr(l);q=s.charAt(0);if(q==='/'||q==='*'){errorAt("Confusing regular expression.",line,from);}
67
- return it('(regexp)',c);case'\\':c=s.charAt(l);if(c<' '){warningAt("Unexpected control character in regular expression.",line,from+l);}else if(c==='<'){warningAt("Unexpected escaped character '{a}' in regular expression.",line,from+l,c);}
68
- l+=1;break;case'(':depth+=1;b=false;if(s.charAt(l)==='?'){l+=1;switch(s.charAt(l)){case':':case'=':case'!':l+=1;break;default:warningAt("Expected '{a}' and instead saw '{b}'.",line,from+l,':',s.charAt(l));}}else{captures+=1;}
69
- break;case'|':b=false;break;case')':if(depth===0){warningAt("Unescaped '{a}'.",line,from+l,')');}else{depth-=1;}
70
- break;case' ':q=1;while(s.charAt(l)===' '){l+=1;q+=1;}
71
- if(q>1){warningAt("Spaces are hard to count. Use {{a}}.",line,from+l,q);}
72
- break;case'[':c=s.charAt(l);if(c==='^'){l+=1;if(option.regexp){warningAt("Insecure '{a}'.",line,from+l,c);}else if(s.charAt(l)===']'){errorAt("Unescaped '{a}'.",line,from+l,'^');}}
73
- q=false;if(c===']'){warningAt("Empty class.",line,from+l-1);q=true;}
74
- klass:do{c=s.charAt(l);l+=1;switch(c){case'[':case'^':warningAt("Unescaped '{a}'.",line,from+l,c);q=true;break;case'-':if(q){q=false;}else{warningAt("Unescaped '{a}'.",line,from+l,'-');q=true;}
75
- break;case']':if(!q){warningAt("Unescaped '{a}'.",line,from+l-1,'-');}
76
- break klass;case'\\':c=s.charAt(l);if(c<' '){warningAt("Unexpected control character in regular expression.",line,from+l);}else if(c==='<'){warningAt("Unexpected escaped character '{a}' in regular expression.",line,from+l,c);}
77
- l+=1;q=true;break;case'/':warningAt("Unescaped '{a}'.",line,from+l-1,'/');q=true;break;case'<':if(xmode==='script'){c=s.charAt(l);if(c==='!'||c==='/'){warningAt("HTML confusion in regular expression '<{a}'.",line,from+l,c);}}
78
- q=true;break;default:q=true;}}while(c);break;case'.':if(option.regexp){warningAt("Insecure '{a}'.",line,from+l,c);}
79
- break;case']':case'?':case'{':case'}':case'+':case'*':warningAt("Unescaped '{a}'.",line,from+l,c);break;case'<':if(xmode==='script'){c=s.charAt(l);if(c==='!'||c==='/'){warningAt("HTML confusion in regular expression '<{a}'.",line,from+l,c);}}}
80
- if(b){switch(s.charAt(l)){case'?':case'+':case'*':l+=1;if(s.charAt(l)==='?'){l+=1;}
81
- break;case'{':l+=1;c=s.charAt(l);if(c<'0'||c>'9'){warningAt("Expected a number and instead saw '{a}'.",line,from+l,c);}
82
- l+=1;low=+c;for(;;){c=s.charAt(l);if(c<'0'||c>'9'){break;}
83
- l+=1;low=+c+(low*10);}
84
- high=low;if(c===','){l+=1;high=Infinity;c=s.charAt(l);if(c>='0'&&c<='9'){l+=1;high=+c;for(;;){c=s.charAt(l);if(c<'0'||c>'9'){break;}
85
- l+=1;high=+c+(high*10);}}}
86
- if(s.charAt(l)!=='}'){warningAt("Expected '{a}' and instead saw '{b}'.",line,from+l,'}',c);}else{l+=1;}
87
- if(s.charAt(l)==='?'){l+=1;}
88
- if(low>high){warningAt("'{a}' should not be greater than '{b}'.",line,from+l,low,high);}}}}
89
- c=s.substr(0,l-1);character+=l;s=s.substr(l);return it('(regexp)',c);}
90
- return it('(punctuator)',t);case'<!--':l=line;c=character;for(;;){i=s.indexOf('--');if(i>=0){break;}
91
- i=s.indexOf('<!');if(i>=0){errorAt("Nested HTML comment.",line,character+i);}
92
- if(!nextLine()){errorAt("Unclosed HTML comment.",l,c);}}
93
- l=s.indexOf('<!');if(l>=0&&l<i){errorAt("Nested HTML comment.",line,character+l);}
94
- character+=i;if(s.charAt(i+2)!=='>'){errorAt("Expected -->.",line,character);}
95
- character+=3;s=s.slice(i+3);break;case'#':if(xmode==='html'||xmode==='styleproperty'){for(;;){c=s.charAt(0);if((c<'0'||c>'9')&&(c<'a'||c>'f')&&(c<'A'||c>'F')){break;}
96
- character+=1;s=s.substr(1);t+=c;}
97
- if(t.length!==4&&t.length!==7){warningAt("Bad hex color '{a}'.",line,from+l,t);}
98
- return it('(color)',t);}
99
- return it('(punctuator)',t);default:if(xmode==='outer'&&c==='&'){character+=1;s=s.substr(1);for(;;){c=s.charAt(0);character+=1;s=s.substr(1);if(c===';'){break;}
100
- if(!((c>='0'&&c<='9')||(c>='a'&&c<='z')||c==='#')){errorAt("Bad entity",line,from+l,character);}}
101
- break;}
102
- return it('(punctuator)',t);}}}}};}());function addlabel(t,type){if(option.safe&&funct['(global)']&&typeof predefined[t]!=='boolean'){warning('ADsafe global: '+t+'.',token);}else if(t==='hasOwnProperty'){warning("'hasOwnProperty' is a really bad name.");}
103
- if(is_own(funct,t)&&!funct['(global)']){warning(funct[t]===true?"'{a}' was used before it was defined.":"'{a}' is already defined.",nexttoken,t);}
104
- funct[t]=type;if(funct['(global)']){global[t]=funct;if(is_own(implied,t)){warning("'{a}' was used before it was defined.",nexttoken,t);delete implied[t];}}else{scope[t]=funct;}}
105
- function doOption(){var b,obj,filter,o=nexttoken.value,t,v;switch(o){case'*/':error("Unbegun comment.");break;case'/*members':case'/*member':o='/*members';if(!membersOnly){membersOnly={};}
106
- obj=membersOnly;break;case'/*jslint':if(option.safe){warning("ADsafe restriction.");}
107
- obj=option;filter=boolOptions;break;case'/*global':if(option.safe){warning("ADsafe restriction.");}
108
- obj=predefined;break;default:}
109
- t=lex.token();loop:for(;;){for(;;){if(t.type==='special'&&t.value==='*/'){break loop;}
110
- if(t.id!=='(endline)'&&t.id!==','){break;}
111
- t=lex.token();}
112
- if(t.type!=='(string)'&&t.type!=='(identifier)'&&o!=='/*members'){error("Bad option.",t);}
113
- v=lex.token();if(v.id===':'){v=lex.token();if(obj===membersOnly){error("Expected '{a}' and instead saw '{b}'.",t,'*/',':');}
114
- if(t.value==='indent'&&o==='/*jslint'){b=+v.value;if(typeof b!=='number'||!isFinite(b)||b<=0||Math.floor(b)!==b){error("Expected a small integer and instead saw '{a}'.",v,v.value);}
115
- obj.white=true;obj.indent=b;}else if(t.value==='maxerr'&&o==='/*jslint'){b=+v.value;if(typeof b!=='number'||!isFinite(b)||b<=0||Math.floor(b)!==b){error("Expected a small integer and instead saw '{a}'.",v,v.value);}
116
- obj.maxerr=b;}else if(t.value==='maxlen'&&o==='/*jslint'){b=+v.value;if(typeof b!=='number'||!isFinite(b)||b<=0||Math.floor(b)!==b){error("Expected a small integer and instead saw '{a}'.",v,v.value);}
117
- obj.maxlen=b;}else if(v.value==='true'){obj[t.value]=true;}else if(v.value==='false'){obj[t.value]=false;}else{error("Bad option value.",v);}
118
- t=lex.token();}else{if(o==='/*jslint'){error("Missing option value.",t);}
119
- obj[t.value]=false;t=v;}}
120
- if(filter){assume();}}
121
- function peek(p){var i=p||0,j=0,t;while(j<=i){t=lookahead[j];if(!t){t=lookahead[j]=lex.token();}
122
- j+=1;}
123
- return t;}
124
- function advance(id,t){switch(token.id){case'(number)':if(nexttoken.id==='.'){warning("A dot following a number can be confused with a decimal point.",token);}
125
- break;case'-':if(nexttoken.id==='-'||nexttoken.id==='--'){warning("Confusing minusses.");}
126
- break;case'+':if(nexttoken.id==='+'||nexttoken.id==='++'){warning("Confusing plusses.");}
127
- break;}
128
- if(token.type==='(string)'||token.identifier){anonname=token.value;}
129
- if(id&&nexttoken.id!==id){if(t){if(nexttoken.id==='(end)'){warning("Unmatched '{a}'.",t,t.id);}else{warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",nexttoken,id,t.id,t.line,nexttoken.value);}}else if(nexttoken.type!=='(identifier)'||nexttoken.value!==id){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,id,nexttoken.value);}}
130
- prevtoken=token;token=nexttoken;for(;;){nexttoken=lookahead.shift()||lex.token();if(nexttoken.id==='(end)'||nexttoken.id==='(error)'){return;}
131
- if(nexttoken.type==='special'){doOption();}else{if(nexttoken.id!=='(endline)'){break;}}}}
132
- function parse(rbp,initial){var left;if(nexttoken.id==='(end)'){error("Unexpected early end of program.",token);}
133
- advance();if(option.safe&&typeof predefined[token.value]==='boolean'&&(nexttoken.id!=='('&&nexttoken.id!=='.')){warning('ADsafe violation.',token);}
134
- if(initial){anonname='anonymous';funct['(verb)']=token.value;}
135
- if(initial===true&&token.fud){left=token.fud();}else{if(token.nud){left=token.nud();}else{if(nexttoken.type==='(number)'&&token.id==='.'){warning("A leading decimal point can be confused with a dot: '.{a}'.",token,nexttoken.value);advance();return token;}else{error("Expected an identifier and instead saw '{a}'.",token,token.id);}}
136
- while(rbp<nexttoken.lbp){advance();if(token.led){left=token.led(left);}else{error("Expected an operator and instead saw '{a}'.",token,token.id);}}}
137
- return left;}
138
- function adjacent(left,right){left=left||token;right=right||nexttoken;if(option.white||xmode==='styleproperty'||xmode==='style'){if(left.character!==right.from&&left.line===right.line){warning("Unexpected space after '{a}'.",right,left.value);}}}
139
- function nobreak(left,right){left=left||token;right=right||nexttoken;if(left.character!==right.from||left.line!==right.line){warning("Unexpected space before '{a}'.",right,right.value);}}
140
- function nospace(left,right){left=left||token;right=right||nexttoken;if(option.white&&!left.comment){if(left.line===right.line){adjacent(left,right);}}}
141
- function nonadjacent(left,right){if(option.white){left=left||token;right=right||nexttoken;if(left.line===right.line&&left.character===right.from){warning("Missing space after '{a}'.",nexttoken,left.value);}}}
142
- function nobreaknonadjacent(left,right){left=left||token;right=right||nexttoken;if(!option.laxbreak&&left.line!==right.line){warning("Bad line breaking before '{a}'.",right,right.id);}else if(option.white){left=left||token;right=right||nexttoken;if(left.character===right.from){warning("Missing space after '{a}'.",nexttoken,left.value);}}}
143
- function indentation(bias){var i;if(option.white&&nexttoken.id!=='(end)'){i=indent+(bias||0);if(nexttoken.from!==i){warning("Expected '{a}' to have an indentation at {b} instead at {c}.",nexttoken,nexttoken.value,i,nexttoken.from);}}}
144
- function nolinebreak(t){t=t||token;if(t.line!==nexttoken.line){warning("Line breaking error '{a}'.",t,t.value);}}
145
- function comma(){if(token.line!==nexttoken.line){if(!option.laxbreak){warning("Bad line breaking before '{a}'.",token,nexttoken.id);}}else if(token.character!==nexttoken.from&&option.white){warning("Unexpected space after '{a}'.",nexttoken,token.value);}
146
- advance(',');nonadjacent(token,nexttoken);}
147
- function symbol(s,p){var x=syntax[s];if(!x||typeof x!=='object'){syntax[s]=x={id:s,lbp:p,value:s};}
148
- return x;}
149
- function delim(s){return symbol(s,0);}
150
- function stmt(s,f){var x=delim(s);x.identifier=x.reserved=true;x.fud=f;return x;}
151
- function blockstmt(s,f){var x=stmt(s,f);x.block=true;return x;}
152
- function reserveName(x){var c=x.id.charAt(0);if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){x.identifier=x.reserved=true;}
153
- return x;}
154
- function prefix(s,f){var x=symbol(s,150);reserveName(x);x.nud=(typeof f==='function')?f:function(){this.right=parse(150);this.arity='unary';if(this.id==='++'||this.id==='--'){if(option.plusplus){warning("Unexpected use of '{a}'.",this,this.id);}else if((!this.right.identifier||this.right.reserved)&&this.right.id!=='.'&&this.right.id!=='['){warning("Bad operand.",this);}}
155
- return this;};return x;}
156
- function type(s,f){var x=delim(s);x.type=s;x.nud=f;return x;}
157
- function reserve(s,f){var x=type(s,f);x.identifier=x.reserved=true;return x;}
158
- function reservevar(s,v){return reserve(s,function(){if(typeof v==='function'){v(this);}
159
- return this;});}
160
- function infix(s,f,p,w){var x=symbol(s,p);reserveName(x);x.led=function(left){if(!w){nobreaknonadjacent(prevtoken,token);nonadjacent(token,nexttoken);}
161
- if(typeof f==='function'){return f(left,this);}else{this.left=left;this.right=parse(p);return this;}};return x;}
162
- function relation(s,f){var x=symbol(s,100);x.led=function(left){nobreaknonadjacent(prevtoken,token);nonadjacent(token,nexttoken);var right=parse(100);if((left&&left.id==='NaN')||(right&&right.id==='NaN')){warning("Use the isNaN function to compare with NaN.",this);}else if(f){f.apply(this,[left,right]);}
163
- if(left.id==='!'){warning("Confusing use of '{a}'.",left,'!');}
164
- if(right.id==='!'){warning("Confusing use of '{a}'.",left,'!');}
165
- this.left=left;this.right=right;return this;};return x;}
166
- function isPoorRelation(node){return node&&((node.type==='(number)'&&+node.value===0)||(node.type==='(string)'&&node.value==='')||node.type==='true'||node.type==='false'||node.type==='undefined'||node.type==='null');}
167
- function assignop(s,f){symbol(s,20).exps=true;return infix(s,function(left,that){var l;that.left=left;if(predefined[left.value]===false&&scope[left.value]['(global)']===true){warning("Read only.",left);}else if(left['function']){warning("'{a}' is a function.",left,left.value);}
168
- if(option.safe){l=left;do{if(typeof predefined[l.value]==='boolean'){warning('ADsafe violation.',l);}
169
- l=l.left;}while(l);}
170
- if(left){if(left.id==='.'||left.id==='['){if(!left.left||left.left.value==='arguments'){warning('Bad assignment.',that);}
171
- that.right=parse(19);return that;}else if(left.identifier&&!left.reserved){if(funct[left.value]==='exception'){warning("Do not assign to the exception parameter.",left);}
172
- that.right=parse(19);return that;}
173
- if(left===syntax['function']){warning("Expected an identifier in an assignment and instead saw a function invocation.",token);}}
174
- error("Bad assignment.",that);},20);}
175
- function bitwise(s,f,p){var x=symbol(s,p);reserveName(x);x.led=(typeof f==='function')?f:function(left){if(option.bitwise){warning("Unexpected use of '{a}'.",this,this.id);}
176
- this.left=left;this.right=parse(p);return this;};return x;}
177
- function bitwiseassignop(s){symbol(s,20).exps=true;return infix(s,function(left,that){if(option.bitwise){warning("Unexpected use of '{a}'.",that,that.id);}
178
- nonadjacent(prevtoken,token);nonadjacent(token,nexttoken);if(left){if(left.id==='.'||left.id==='['||(left.identifier&&!left.reserved)){parse(19);return that;}
179
- if(left===syntax['function']){warning("Expected an identifier in an assignment, and instead saw a function invocation.",token);}
180
- return that;}
181
- error("Bad assignment.",that);},20);}
182
- function suffix(s,f){var x=symbol(s,150);x.led=function(left){if(option.plusplus){warning("Unexpected use of '{a}'.",this,this.id);}else if((!left.identifier||left.reserved)&&left.id!=='.'&&left.id!=='['){warning("Bad operand.",this);}
183
- this.left=left;return this;};return x;}
184
- function optionalidentifier(){if(nexttoken.identifier){advance();if(option.safe&&banned[token.value]){warning("ADsafe violation: '{a}'.",token,token.value);}else if(token.reserved&&!option.es5){warning("Expected an identifier and instead saw '{a}' (a reserved word).",token,token.id);}
185
- return token.value;}}
186
- function identifier(){var i=optionalidentifier();if(i){return i;}
187
- if(token.id==='function'&&nexttoken.id==='('){warning("Missing name in function statement.");}else{error("Expected an identifier and instead saw '{a}'.",nexttoken,nexttoken.value);}}
188
- function reachable(s){var i=0,t;if(nexttoken.id!==';'||noreach){return;}
189
- for(;;){t=peek(i);if(t.reach){return;}
190
- if(t.id!=='(endline)'){if(t.id==='function'){warning("Inner functions should be listed at the top of the outer function.",t);break;}
191
- warning("Unreachable '{a}' after '{b}'.",t,t.value,s);break;}
192
- i+=1;}}
193
- function statement(noindent){var i=indent,r,s=scope,t=nexttoken;if(t.id===';'){warning("Unnecessary semicolon.",t);advance(';');return;}
194
- if(t.identifier&&!t.reserved&&peek().id===':'){advance();advance(':');scope=Object.create(s);addlabel(t.value,'label');if(!nexttoken.labelled){warning("Label '{a}' on {b} statement.",nexttoken,t.value,nexttoken.value);}
195
- if(jx.test(t.value+':')){warning("Label '{a}' looks like a javascript url.",t,t.value);}
196
- nexttoken.label=t.value;t=nexttoken;}
197
- if(!noindent){indentation();}
198
- r=parse(0,true);if(!t.block){if(!r||!r.exps){warning("Expected an assignment or function call and instead saw an expression.",token);}else if(r.id==='('&&r.left.id==='new'){warning("Do not use 'new' for side effects.");}
199
- if(nexttoken.id!==';'){warningAt("Missing semicolon.",token.line,token.from+token.value.length);}else{adjacent(token,nexttoken);advance(';');nonadjacent(token,nexttoken);}}
200
- indent=i;scope=s;return r;}
201
- function use_strict(){if(nexttoken.value==='use strict'){advance();advance(';');strict_mode=true;option.newcap=true;option.undef=true;return true;}else{return false;}}
202
- function statements(begin){var a=[],f,p;if(begin&&!use_strict()&&option.strict){warning('Missing "use strict" statement.',nexttoken);}
203
- if(option.adsafe){switch(begin){case'script':if(!adsafe_may){if(nexttoken.value!=='ADSAFE'||peek(0).id!=='.'||(peek(1).value!=='id'&&peek(1).value!=='go')){error('ADsafe violation: Missing ADSAFE.id or ADSAFE.go.',nexttoken);}}
204
- if(nexttoken.value==='ADSAFE'&&peek(0).id==='.'&&peek(1).value==='id'){if(adsafe_may){error('ADsafe violation.',nexttoken);}
205
- advance('ADSAFE');advance('.');advance('id');advance('(');if(nexttoken.value!==adsafe_id){error('ADsafe violation: id does not match.',nexttoken);}
206
- advance('(string)');advance(')');advance(';');adsafe_may=true;}
207
- break;case'lib':if(nexttoken.value==='ADSAFE'){advance('ADSAFE');advance('.');advance('lib');advance('(');advance('(string)');comma();f=parse(0);if(f.id!=='function'){error('The second argument to lib must be a function.',f);}
208
- p=f.funct['(params)'];p=p&&p.join(', ');if(p&&p!=='lib'){error("Expected '{a}' and instead saw '{b}'.",f,'(lib)','('+p+')');}
209
- advance(')');advance(';');return a;}else{error("ADsafe lib violation.");}}}
210
- while(!nexttoken.reach&&nexttoken.id!=='(end)'){if(nexttoken.id===';'){warning("Unnecessary semicolon.");advance(';');}else{a.push(statement());}}
211
- return a;}
212
- function block(f){var a,b=inblock,old_indent=indent,s=scope,t;inblock=f;scope=Object.create(scope);nonadjacent(token,nexttoken);t=nexttoken;if(nexttoken.id==='{'){advance('{');if(nexttoken.id!=='}'||token.line!==nexttoken.line){indent+=option.indent;while(!f&&nexttoken.from>indent){indent+=option.indent;}
213
- if(!f){use_strict();}
214
- a=statements();indent-=option.indent;indentation();}
215
- advance('}',t);indent=old_indent;}else{warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'{',nexttoken.value);noreach=true;a=[statement()];noreach=false;}
216
- funct['(verb)']=null;scope=s;inblock=b;if(f&&(!a||a.length===0)){warning("Empty block.");}
217
- return a;}
218
- function countMember(m){if(membersOnly&&typeof membersOnly[m]!=='boolean'){warning("Unexpected /*member '{a}'.",token,m);}
219
- if(typeof member[m]==='number'){member[m]+=1;}else{member[m]=1;}}
220
- function note_implied(token){var name=token.value,line=token.line,a=implied[name];if(typeof a==='function'){a=false;}
221
- if(!a){a=[line];implied[name]=a;}else if(a[a.length-1]!==line){a.push(line);}}
222
- function cssName(){if(nexttoken.identifier){advance();return true;}}
223
- function cssNumber(){if(nexttoken.id==='-'){advance('-');adjacent();nolinebreak();}
224
- if(nexttoken.type==='(number)'){advance('(number)');return true;}}
225
- function cssString(){if(nexttoken.type==='(string)'){advance();return true;}}
226
- function cssColor(){var i,number,value;if(nexttoken.identifier){value=nexttoken.value;if(value==='rgb'||value==='rgba'){advance();advance('(');for(i=0;i<3;i+=1){if(i){advance(',');}
227
- number=nexttoken.value;if(nexttoken.type!=='(number)'||number<0){warning("Expected a positive number and instead saw '{a}'",nexttoken,number);advance();}else{advance();if(nexttoken.id==='%'){advance('%');if(number>100){warning("Expected a percentage and instead saw '{a}'",token,number);}}else{if(number>255){warning("Expected a small number and instead saw '{a}'",token,number);}}}}
228
- if(value==='rgba'){advance(',');number=+nexttoken.value;if(nexttoken.type!=='(number)'||number<0||number>1){warning("Expected a number between 0 and 1 and instead saw '{a}'",nexttoken,number);}
229
- advance();if(nexttoken.id==='%'){warning("Unexpected '%'.");advance('%');}}
230
- advance(')');return true;}else if(cssColorData[nexttoken.value]===true){advance();return true;}}else if(nexttoken.type==='(color)'){advance();return true;}
231
- return false;}
232
- function cssLength(){if(nexttoken.id==='-'){advance('-');adjacent();nolinebreak();}
233
- if(nexttoken.type==='(number)'){advance();if(nexttoken.type!=='(string)'&&cssLengthData[nexttoken.value]===true){adjacent();advance();}else if(+token.value!==0){warning("Expected a linear unit and instead saw '{a}'.",nexttoken,nexttoken.value);}
234
- return true;}
235
- return false;}
236
- function cssLineHeight(){if(nexttoken.id==='-'){advance('-');adjacent();}
237
- if(nexttoken.type==='(number)'){advance();if(nexttoken.type!=='(string)'&&cssLengthData[nexttoken.value]===true){adjacent();advance();}
238
- return true;}
239
- return false;}
240
- function cssWidth(){if(nexttoken.identifier){switch(nexttoken.value){case'thin':case'medium':case'thick':advance();return true;}}else{return cssLength();}}
241
- function cssMargin(){if(nexttoken.identifier){if(nexttoken.value==='auto'){advance();return true;}}else{return cssLength();}}
242
- function cssAttr(){if(nexttoken.identifier&&nexttoken.value==='attr'){advance();advance('(');if(!nexttoken.identifier){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);}
243
- advance();advance(')');return true;}
244
- return false;}
245
- function cssCommaList(){while(nexttoken.id!==';'){if(!cssName()&&!cssString()){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);}
246
- if(nexttoken.id!==','){return true;}
247
- comma();}}
248
- function cssCounter(){if(nexttoken.identifier&&nexttoken.value==='counter'){advance();advance('(');advance();if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);}
249
- advance();}
250
- advance(')');return true;}
251
- if(nexttoken.identifier&&nexttoken.value==='counters'){advance();advance('(');if(!nexttoken.identifier){warning("Expected a name and instead saw '{a}'.",nexttoken,nexttoken.value);}
252
- advance();if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);}
253
- advance();}
254
- if(nexttoken.id===','){comma();if(nexttoken.type!=='(string)'){warning("Expected a string and instead saw '{a}'.",nexttoken,nexttoken.value);}
255
- advance();}
256
- advance(')');return true;}
257
- return false;}
258
- function cssShape(){var i;if(nexttoken.identifier&&nexttoken.value==='rect'){advance();advance('(');for(i=0;i<4;i+=1){if(!cssLength()){warning("Expected a number and instead saw '{a}'.",nexttoken,nexttoken.value);break;}}
259
- advance(')');return true;}
260
- return false;}
261
- function cssUrl(){var c,url;if(nexttoken.identifier&&nexttoken.value==='url'){nexttoken=lex.range('(',')');url=nexttoken.value;c=url.charAt(0);if(c==='"'||c==='\''){if(url.slice(-1)!==c){warning("Bad url string.");}else{url=url.slice(1,-1);if(url.indexOf(c)>=0){warning("Bad url string.");}}}
262
- if(!url){warning("Missing url.");}
263
- advance();if(option.safe&&ux.test(url)){error("ADsafe URL violation.");}
264
- urls.push(url);return true;}
265
- return false;}
266
- cssAny=[cssUrl,function(){for(;;){if(nexttoken.identifier){switch(nexttoken.value.toLowerCase()){case'url':cssUrl();break;case'expression':warning("Unexpected expression '{a}'.",nexttoken,nexttoken.value);advance();break;default:advance();}}else{if(nexttoken.id===';'||nexttoken.id==='!'||nexttoken.id==='(end)'||nexttoken.id==='}'){return true;}
267
- advance();}}}];cssBorderStyle=['none','dashed','dotted','double','groove','hidden','inset','outset','ridge','solid'];cssBreak=['auto','always','avoid','left','right'];cssMedia={'all':true,'braille':true,'embossed':true,'handheld':true,'print':true,'projection':true,'screen':true,'speech':true,'tty':true,'tv':true};cssOverflow=['auto','hidden','scroll','visible'];cssAttributeData={background:[true,'background-attachment','background-color','background-image','background-position','background-repeat'],'background-attachment':['scroll','fixed'],'background-color':['transparent',cssColor],'background-image':['none',cssUrl],'background-position':[2,[cssLength,'top','bottom','left','right','center']],'background-repeat':['repeat','repeat-x','repeat-y','no-repeat'],'border':[true,'border-color','border-style','border-width'],'border-bottom':[true,'border-bottom-color','border-bottom-style','border-bottom-width'],'border-bottom-color':cssColor,'border-bottom-style':cssBorderStyle,'border-bottom-width':cssWidth,'border-collapse':['collapse','separate'],'border-color':['transparent',4,cssColor],'border-left':[true,'border-left-color','border-left-style','border-left-width'],'border-left-color':cssColor,'border-left-style':cssBorderStyle,'border-left-width':cssWidth,'border-right':[true,'border-right-color','border-right-style','border-right-width'],'border-right-color':cssColor,'border-right-style':cssBorderStyle,'border-right-width':cssWidth,'border-spacing':[2,cssLength],'border-style':[4,cssBorderStyle],'border-top':[true,'border-top-color','border-top-style','border-top-width'],'border-top-color':cssColor,'border-top-style':cssBorderStyle,'border-top-width':cssWidth,'border-width':[4,cssWidth],bottom:[cssLength,'auto'],'caption-side':['bottom','left','right','top'],clear:['both','left','none','right'],clip:[cssShape,'auto'],color:cssColor,content:['open-quote','close-quote','no-open-quote','no-close-quote',cssString,cssUrl,cssCounter,cssAttr],'counter-increment':[cssName,'none'],'counter-reset':[cssName,'none'],cursor:[cssUrl,'auto','crosshair','default','e-resize','help','move','n-resize','ne-resize','nw-resize','pointer','s-resize','se-resize','sw-resize','w-resize','text','wait'],direction:['ltr','rtl'],display:['block','compact','inline','inline-block','inline-table','list-item','marker','none','run-in','table','table-caption','table-cell','table-column','table-column-group','table-footer-group','table-header-group','table-row','table-row-group'],'empty-cells':['show','hide'],'float':['left','none','right'],font:['caption','icon','menu','message-box','small-caption','status-bar',true,'font-size','font-style','font-weight','font-family'],'font-family':cssCommaList,'font-size':['xx-small','x-small','small','medium','large','x-large','xx-large','larger','smaller',cssLength],'font-size-adjust':['none',cssNumber],'font-stretch':['normal','wider','narrower','ultra-condensed','extra-condensed','condensed','semi-condensed','semi-expanded','expanded','extra-expanded'],'font-style':['normal','italic','oblique'],'font-variant':['normal','small-caps'],'font-weight':['normal','bold','bolder','lighter',cssNumber],height:[cssLength,'auto'],left:[cssLength,'auto'],'letter-spacing':['normal',cssLength],'line-height':['normal',cssLineHeight],'list-style':[true,'list-style-image','list-style-position','list-style-type'],'list-style-image':['none',cssUrl],'list-style-position':['inside','outside'],'list-style-type':['circle','disc','square','decimal','decimal-leading-zero','lower-roman','upper-roman','lower-greek','lower-alpha','lower-latin','upper-alpha','upper-latin','hebrew','katakana','hiragana-iroha','katakana-oroha','none'],margin:[4,cssMargin],'margin-bottom':cssMargin,'margin-left':cssMargin,'margin-right':cssMargin,'margin-top':cssMargin,'marker-offset':[cssLength,'auto'],'max-height':[cssLength,'none'],'max-width':[cssLength,'none'],'min-height':cssLength,'min-width':cssLength,opacity:cssNumber,outline:[true,'outline-color','outline-style','outline-width'],'outline-color':['invert',cssColor],'outline-style':['dashed','dotted','double','groove','inset','none','outset','ridge','solid'],'outline-width':cssWidth,overflow:cssOverflow,'overflow-x':cssOverflow,'overflow-y':cssOverflow,padding:[4,cssLength],'padding-bottom':cssLength,'padding-left':cssLength,'padding-right':cssLength,'padding-top':cssLength,'page-break-after':cssBreak,'page-break-before':cssBreak,position:['absolute','fixed','relative','static'],quotes:[8,cssString],right:[cssLength,'auto'],'table-layout':['auto','fixed'],'text-align':['center','justify','left','right'],'text-decoration':['none','underline','overline','line-through','blink'],'text-indent':cssLength,'text-shadow':['none',4,[cssColor,cssLength]],'text-transform':['capitalize','uppercase','lowercase','none'],top:[cssLength,'auto'],'unicode-bidi':['normal','embed','bidi-override'],'vertical-align':['baseline','bottom','sub','super','top','text-top','middle','text-bottom',cssLength],visibility:['visible','hidden','collapse'],'white-space':['normal','nowrap','pre','pre-line','pre-wrap','inherit'],width:[cssLength,'auto'],'word-spacing':['normal',cssLength],'word-wrap':['break-word','normal'],'z-index':['auto',cssNumber]};function styleAttribute(){var v;while(nexttoken.id==='*'||nexttoken.id==='#'||nexttoken.value==='_'){if(!option.css){warning("Unexpected '{a}'.",nexttoken,nexttoken.value);}
268
- advance();}
269
- if(nexttoken.id==='-'){if(!option.css){warning("Unexpected '{a}'.",nexttoken,nexttoken.value);}
270
- advance('-');if(!nexttoken.identifier){warning("Expected a non-standard style attribute and instead saw '{a}'.",nexttoken,nexttoken.value);}
271
- advance();return cssAny;}else{if(!nexttoken.identifier){warning("Excepted a style attribute, and instead saw '{a}'.",nexttoken,nexttoken.value);}else{if(is_own(cssAttributeData,nexttoken.value)){v=cssAttributeData[nexttoken.value];}else{v=cssAny;if(!option.css){warning("Unrecognized style attribute '{a}'.",nexttoken,nexttoken.value);}}}
272
- advance();return v;}}
273
- function styleValue(v){var i=0,n,once,match,round,start=0,vi;switch(typeof v){case'function':return v();case'string':if(nexttoken.identifier&&nexttoken.value===v){advance();return true;}
274
- return false;}
275
- for(;;){if(i>=v.length){return false;}
276
- vi=v[i];i+=1;if(vi===true){break;}else if(typeof vi==='number'){n=vi;vi=v[i];i+=1;}else{n=1;}
277
- match=false;while(n>0){if(styleValue(vi)){match=true;n-=1;}else{break;}}
278
- if(match){return true;}}
279
- start=i;once=[];for(;;){round=false;for(i=start;i<v.length;i+=1){if(!once[i]){if(styleValue(cssAttributeData[v[i]])){match=true;round=true;once[i]=true;break;}}}
280
- if(!round){return match;}}}
281
- function styleChild(){if(nexttoken.id==='(number)'){advance();if(nexttoken.value==='n'&&nexttoken.identifier){adjacent();advance();if(nexttoken.id==='+'){adjacent();advance('+');adjacent();advance('(number)');}}
282
- return;}else{switch(nexttoken.value){case'odd':case'even':if(nexttoken.identifier){advance();return;}}}
283
- warning("Unexpected token '{a}'.",nexttoken,nexttoken.value);}
284
- function substyle(){var v;for(;;){if(nexttoken.id==='}'||nexttoken.id==='(end)'||xquote&&nexttoken.id===xquote){return;}
285
- while(nexttoken.id===';'){warning("Misplaced ';'.");advance(';');}
286
- v=styleAttribute();advance(':');if(nexttoken.identifier&&nexttoken.value==='inherit'){advance();}else{if(!styleValue(v)){warning("Unexpected token '{a}'.",nexttoken,nexttoken.value);advance();}}
287
- if(nexttoken.id==='!'){advance('!');adjacent();if(nexttoken.identifier&&nexttoken.value==='important'){advance();}else{warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'important',nexttoken.value);}}
288
- if(nexttoken.id==='}'||nexttoken.id===xquote){warning("Missing '{a}'.",nexttoken,';');}else{advance(';');}}}
289
- function styleSelector(){if(nexttoken.identifier){if(!is_own(htmltag,option.cap?nexttoken.value.toLowerCase():nexttoken.value)){warning("Expected a tagName, and instead saw {a}.",nexttoken,nexttoken.value);}
290
- advance();}else{switch(nexttoken.id){case'>':case'+':advance();styleSelector();break;case':':advance(':');switch(nexttoken.value){case'active':case'after':case'before':case'checked':case'disabled':case'empty':case'enabled':case'first-child':case'first-letter':case'first-line':case'first-of-type':case'focus':case'hover':case'last-child':case'last-of-type':case'link':case'only-of-type':case'root':case'target':case'visited':advance();break;case'lang':advance();advance('(');if(!nexttoken.identifier){warning("Expected a lang code, and instead saw :{a}.",nexttoken,nexttoken.value);}
291
- advance(')');break;case'nth-child':case'nth-last-child':case'nth-last-of-type':case'nth-of-type':advance();advance('(');styleChild();advance(')');break;case'not':advance();advance('(');if(nexttoken.id===':'&&peek(0).value==='not'){warning("Nested not.");}
292
- styleSelector();advance(')');break;default:warning("Expected a pseudo, and instead saw :{a}.",nexttoken,nexttoken.value);}
293
- break;case'#':advance('#');if(!nexttoken.identifier){warning("Expected an id, and instead saw #{a}.",nexttoken,nexttoken.value);}
294
- advance();break;case'*':advance('*');break;case'.':advance('.');if(!nexttoken.identifier){warning("Expected a class, and instead saw #.{a}.",nexttoken,nexttoken.value);}
295
- advance();break;case'[':advance('[');if(!nexttoken.identifier){warning("Expected an attribute, and instead saw [{a}].",nexttoken,nexttoken.value);}
296
- advance();if(nexttoken.id==='='||nexttoken.value==='~='||nexttoken.value==='$='||nexttoken.value==='|='||nexttoken.id==='*='||nexttoken.id==='^='){advance();if(nexttoken.type!=='(string)'){warning("Expected a string, and instead saw {a}.",nexttoken,nexttoken.value);}
297
- advance();}
298
- advance(']');break;default:error("Expected a CSS selector, and instead saw {a}.",nexttoken,nexttoken.value);}}}
299
- function stylePattern(){if(nexttoken.id==='{'){warning("Expected a style pattern, and instead saw '{a}'.",nexttoken,nexttoken.id);}
300
- for(;;){styleSelector();if(nexttoken.id==='</'||nexttoken.id==='{'||nexttoken.id==='(end)'){return'';}
301
- if(nexttoken.id===','){comma();}}}
302
- function stylelist(){while(nexttoken.id!=='</'&&nexttoken.id!=='(end)'){stylePattern();xmode='styleproperty';if(nexttoken.id===';'){advance(';');}else{advance('{');substyle();xmode='style';advance('}');}}}
303
- function styles(){var i;while(nexttoken.id==='@'){i=peek();advance('@');if(nexttoken.identifier){switch(nexttoken.value){case'import':advance();if(!cssUrl()){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'url',nexttoken.value);advance();}
304
- advance(';');break;case'media':advance();for(;;){if(!nexttoken.identifier||cssMedia[nexttoken.value]===true){error("Expected a CSS media type, and instead saw '{a}'.",nexttoken,nexttoken.id);}
305
- advance();if(nexttoken.id!==','){break;}
306
- advance(',');}
307
- advance('{');stylelist();advance('}');break;default:warning("Expected an at-rule, and instead saw @{a}.",nexttoken,nexttoken.value);}}else{warning("Expected an at-rule, and instead saw '{a}'.",nexttoken,nexttoken.value);}}
308
- stylelist();}
309
- function doBegin(n){if(n!=='html'&&!option.fragment){if(n==='div'&&option.adsafe){error("ADSAFE: Use the fragment option.");}else{error("Expected '{a}' and instead saw '{b}'.",token,'html',n);}}
310
- if(option.adsafe){if(n==='html'){error("Currently, ADsafe does not operate on whole HTML documents. It operates on <div> fragments and .js files.",token);}
311
- if(option.fragment){if(n!=='div'){error("ADsafe violation: Wrap the widget in a div.",token);}}else{error("Use the fragment option.",token);}}
312
- option.browser=true;assume();}
313
- function doAttribute(n,a,v){var u,x;if(a==='id'){u=typeof v==='string'?v.toUpperCase():'';if(ids[u]===true){warning("Duplicate id='{a}'.",nexttoken,v);}
314
- if(!/^[A-Za-z][A-Za-z0-9._:\-]*$/.test(v)){warning("Bad id: '{a}'.",nexttoken,v);}else if(option.adsafe){if(adsafe_id){if(v.slice(0,adsafe_id.length)!==adsafe_id){warning("ADsafe violation: An id must have a '{a}' prefix",nexttoken,adsafe_id);}else if(!/^[A-Z]+_[A-Z]+$/.test(v)){warning("ADSAFE violation: bad id.");}}else{adsafe_id=v;if(!/^[A-Z]+_$/.test(v)){warning("ADSAFE violation: bad id.");}}}
315
- x=v.search(dx);if(x>=0){warning("Unexpected character '{a}' in {b}.",token,v.charAt(x),a);}
316
- ids[u]=true;}else if(a==='class'||a==='type'||a==='name'){x=v.search(qx);if(x>=0){warning("Unexpected character '{a}' in {b}.",token,v.charAt(x),a);}
317
- ids[u]=true;}else if(a==='href'||a==='background'||a==='content'||a==='data'||a.indexOf('src')>=0||a.indexOf('url')>=0){if(option.safe&&ux.test(v)){error("ADsafe URL violation.");}
318
- urls.push(v);}else if(a==='for'){if(option.adsafe){if(adsafe_id){if(v.slice(0,adsafe_id.length)!==adsafe_id){warning("ADsafe violation: An id must have a '{a}' prefix",nexttoken,adsafe_id);}else if(!/^[A-Z]+_[A-Z]+$/.test(v)){warning("ADSAFE violation: bad id.");}}else{warning("ADSAFE violation: bad id.");}}}else if(a==='name'){if(option.adsafe&&v.indexOf('_')>=0){warning("ADsafe name violation.");}}}
319
- function doTag(n,a){var i,t=htmltag[n],x;src=false;if(!t){error("Unrecognized tag '<{a}>'.",nexttoken,n===n.toLowerCase()?n:n+' (capitalization error)');}
320
- if(stack.length>0){if(n==='html'){error("Too many <html> tags.",token);}
321
- x=t.parent;if(x){if(x.indexOf(' '+stack[stack.length-1].name+' ')<0){error("A '<{a}>' must be within '<{b}>'.",token,n,x);}}else if(!option.adsafe&&!option.fragment){i=stack.length;do{if(i<=0){error("A '<{a}>' must be within '<{b}>'.",token,n,'body');}
322
- i-=1;}while(stack[i].name!=='body');}}
323
- switch(n){case'div':if(option.adsafe&&stack.length===1&&!adsafe_id){warning("ADSAFE violation: missing ID_.");}
324
- break;case'script':xmode='script';advance('>');indent=nexttoken.from;if(a.lang){warning("lang is deprecated.",token);}
325
- if(option.adsafe&&stack.length!==1){warning("ADsafe script placement violation.",token);}
326
- if(a.src){if(option.adsafe&&(!adsafe_may||!approved[a.src])){warning("ADsafe unapproved script source.",token);}
327
- if(a.type){warning("type is unnecessary.",token);}}else{if(adsafe_went){error("ADsafe script violation.",token);}
328
- statements('script');}
329
- xmode='html';advance('</');if(!nexttoken.identifier&&nexttoken.value!=='script'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'script',nexttoken.value);}
330
- advance();xmode='outer';break;case'style':xmode='style';advance('>');styles();xmode='html';advance('</');if(!nexttoken.identifier&&nexttoken.value!=='style'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'style',nexttoken.value);}
331
- advance();xmode='outer';break;case'input':switch(a.type){case'radio':case'checkbox':case'button':case'reset':case'submit':break;case'text':case'file':case'password':case'file':case'hidden':case'image':if(option.adsafe&&a.autocomplete!=='off'){warning("ADsafe autocomplete violation.");}
332
- break;default:warning("Bad input type.");}
333
- break;case'applet':case'body':case'embed':case'frame':case'frameset':case'head':case'iframe':case'noembed':case'noframes':case'object':case'param':if(option.adsafe){warning("ADsafe violation: Disallowed tag: "+n);}
334
- break;}}
335
- function closetag(n){return'</'+n+'>';}
336
- function html(){var a,attributes,e,n,q,t,v,w=option.white,wmode;xmode='html';xquote='';stack=null;for(;;){switch(nexttoken.value){case'<':xmode='html';advance('<');attributes={};t=nexttoken;if(!t.identifier){warning("Bad identifier {a}.",t,t.value);}
337
- n=t.value;if(option.cap){n=n.toLowerCase();}
338
- t.name=n;advance();if(!stack){stack=[];doBegin(n);}
339
- v=htmltag[n];if(typeof v!=='object'){error("Unrecognized tag '<{a}>'.",t,n);}
340
- e=v.empty;t.type=n;for(;;){if(nexttoken.id==='/'){advance('/');if(nexttoken.id!=='>'){warning("Expected '{a}' and instead saw '{b}'.",nexttoken,'>',nexttoken.value);}
341
- break;}
342
- if(nexttoken.id&&nexttoken.id.substr(0,1)==='>'){break;}
343
- if(!nexttoken.identifier){if(nexttoken.id==='(end)'||nexttoken.id==='(error)'){error("Missing '>'.",nexttoken);}
344
- warning("Bad identifier.");}
345
- option.white=true;nonadjacent(token,nexttoken);a=nexttoken.value;option.white=w;advance();if(!option.cap&&a!==a.toLowerCase()){warning("Attribute '{a}' not all lower case.",nexttoken,a);}
346
- a=a.toLowerCase();xquote='';if(is_own(attributes,a)){warning("Attribute '{a}' repeated.",nexttoken,a);}
347
- if(a.slice(0,2)==='on'){if(!option.on){warning("Avoid HTML event handlers.");}
348
- xmode='scriptstring';advance('=');q=nexttoken.id;if(q!=='"'&&q!=="'"){error("Missing quote.");}
349
- xquote=q;wmode=option.white;option.white=false;advance(q);statements('on');option.white=wmode;if(nexttoken.id!==q){error("Missing close quote on script attribute.");}
350
- xmode='html';xquote='';advance(q);v=false;}else if(a==='style'){xmode='scriptstring';advance('=');q=nexttoken.id;if(q!=='"'&&q!=="'"){error("Missing quote.");}
351
- xmode='styleproperty';xquote=q;advance(q);substyle();xmode='html';xquote='';advance(q);v=false;}else{if(nexttoken.id==='='){advance('=');v=nexttoken.value;if(!nexttoken.identifier&&nexttoken.id!=='"'&&nexttoken.id!=='\''&&nexttoken.type!=='(string)'&&nexttoken.type!=='(number)'&&nexttoken.type!=='(color)'){warning("Expected an attribute value and instead saw '{a}'.",token,a);}
352
- advance();}else{v=true;}}
353
- attributes[a]=v;doAttribute(n,a,v);}
354
- doTag(n,attributes);if(!e){stack.push(t);}
355
- xmode='outer';advance('>');break;case'</':xmode='html';advance('</');if(!nexttoken.identifier){warning("Bad identifier.");}
356
- n=nexttoken.value;if(option.cap){n=n.toLowerCase();}
357
- advance();if(!stack){error("Unexpected '{a}'.",nexttoken,closetag(n));}
358
- t=stack.pop();if(!t){error("Unexpected '{a}'.",nexttoken,closetag(n));}
359
- if(t.name!==n){error("Expected '{a}' and instead saw '{b}'.",nexttoken,closetag(t.name),closetag(n));}
360
- if(nexttoken.id!=='>'){error("Missing '{a}'.",nexttoken,'>');}
361
- xmode='outer';advance('>');break;case'<!':if(option.safe){warning("ADsafe HTML violation.");}
362
- xmode='html';for(;;){advance();if(nexttoken.id==='>'||nexttoken.id==='(end)'){break;}
363
- if(nexttoken.value.indexOf('--')>=0){error("Unexpected --.");}
364
- if(nexttoken.value.indexOf('<')>=0){error("Unexpected <.");}
365
- if(nexttoken.value.indexOf('>')>=0){error("Unexpected >.");}}
366
- xmode='outer';advance('>');break;case'(end)':return;default:if(nexttoken.id==='(end)'){error("Missing '{a}'.",nexttoken,'</'+stack[stack.length-1].value+'>');}else{advance();}}
367
- if(stack&&stack.length===0&&(option.adsafe||!option.fragment||nexttoken.id==='(end)')){break;}}
368
- if(nexttoken.id!=='(end)'){error("Unexpected material after the end.");}}
369
- type('(number)',function(){return this;});type('(string)',function(){return this;});syntax['(identifier)']={type:'(identifier)',lbp:0,identifier:true,nud:function(){var v=this.value,s=scope[v],f;if(typeof s==='function'){s=undefined;}else if(typeof s==='boolean'){f=funct;funct=functions[0];addlabel(v,'var');s=funct;funct=f;}
370
- if(funct===s){switch(funct[v]){case'unused':funct[v]='var';break;case'unction':funct[v]='function';this['function']=true;break;case'function':this['function']=true;break;case'label':warning("'{a}' is a statement label.",token,v);break;}}else if(funct['(global)']){if(option.undef&&predefined[v]!=='boolean'){warning("'{a}' is not defined.",token,v);}
371
- note_implied(token);}else{switch(funct[v]){case'closure':case'function':case'var':case'unused':warning("'{a}' used out of scope.",token,v);break;case'label':warning("'{a}' is a statement label.",token,v);break;case'outer':case'global':break;default:if(s===true){funct[v]=true;}else if(s===null){warning("'{a}' is not allowed.",token,v);note_implied(token);}else if(typeof s!=='object'){if(option.undef){warning("'{a}' is not defined.",token,v);}else{funct[v]=true;}
372
- note_implied(token);}else{switch(s[v]){case'function':case'unction':this['function']=true;s[v]='closure';funct[v]=s['(global)']?'global':'outer';break;case'var':case'unused':s[v]='closure';funct[v]=s['(global)']?'global':'outer';break;case'closure':case'parameter':funct[v]=s['(global)']?'global':'outer';break;case'label':warning("'{a}' is a statement label.",token,v);}}}}
373
- return this;},led:function(){error("Expected an operator and instead saw '{a}'.",nexttoken,nexttoken.value);}};type('(regexp)',function(){return this;});delim('(endline)');delim('(begin)');delim('(end)').reach=true;delim('</').reach=true;delim('<!');delim('<!--');delim('-->');delim('(error)').reach=true;delim('}').reach=true;delim(')');delim(']');delim('"').reach=true;delim("'").reach=true;delim(';');delim(':').reach=true;delim(',');delim('#');delim('@');reserve('else');reserve('case').reach=true;reserve('catch');reserve('default').reach=true;reserve('finally');reservevar('arguments',function(x){if(strict_mode&&funct['(global)']){warning("Strict violation.",x);}else if(option.safe){warning("ADsafe violation.",x);}});reservevar('eval',function(x){if(option.safe){warning("ADsafe violation.",x);}});reservevar('false');reservevar('Infinity');reservevar('NaN');reservevar('null');reservevar('this',function(x){if(strict_mode&&((funct['(statement)']&&funct['(name)'].charAt(0)>'Z')||funct['(global)'])){warning("Strict violation.",x);}else if(option.safe){warning("ADsafe violation.",x);}});reservevar('true');reservevar('undefined');assignop('=','assign',20);assignop('+=','assignadd',20);assignop('-=','assignsub',20);assignop('*=','assignmult',20);assignop('/=','assigndiv',20).nud=function(){error("A regular expression literal can be confused with '/='.");};assignop('%=','assignmod',20);bitwiseassignop('&=','assignbitand',20);bitwiseassignop('|=','assignbitor',20);bitwiseassignop('^=','assignbitxor',20);bitwiseassignop('<<=','assignshiftleft',20);bitwiseassignop('>>=','assignshiftright',20);bitwiseassignop('>>>=','assignshiftrightunsigned',20);infix('?',function(left,that){that.left=left;that.right=parse(10);advance(':');that['else']=parse(10);return that;},30);infix('||','or',40);infix('&&','and',50);bitwise('|','bitor',70);bitwise('^','bitxor',80);bitwise('&','bitand',90);relation('==',function(left,right){if(option.eqeqeq){warning("Expected '{a}' and instead saw '{b}'.",this,'===','==');}else if(isPoorRelation(left)){warning("Use '{a}' to compare with '{b}'.",this,'===',left.value);}else if(isPoorRelation(right)){warning("Use '{a}' to compare with '{b}'.",this,'===',right.value);}
374
- return this;});relation('===');relation('!=',function(left,right){if(option.eqeqeq){warning("Expected '{a}' and instead saw '{b}'.",this,'!==','!=');}else if(isPoorRelation(left)){warning("Use '{a}' to compare with '{b}'.",this,'!==',left.value);}else if(isPoorRelation(right)){warning("Use '{a}' to compare with '{b}'.",this,'!==',right.value);}
375
- return this;});relation('!==');relation('<');relation('>');relation('<=');relation('>=');bitwise('<<','shiftleft',120);bitwise('>>','shiftright',120);bitwise('>>>','shiftrightunsigned',120);infix('in','in',120);infix('instanceof','instanceof',120);infix('+',function(left,that){var right=parse(130);if(left&&right&&left.id==='(string)'&&right.id==='(string)'){left.value+=right.value;left.character=right.character;if(jx.test(left.value)){warning("JavaScript URL.",left);}
376
- return left;}
377
- that.left=left;that.right=right;return that;},130);prefix('+','num');prefix('+++',function(){warning("Confusing pluses.");this.right=parse(150);this.arity='unary';return this;});infix('+++',function(left){warning("Confusing pluses.");this.left=left;this.right=parse(130);return this;},130);infix('-','sub',130);prefix('-','neg');prefix('---',function(){warning("Confusing minuses.");this.right=parse(150);this.arity='unary';return this;});infix('---',function(left){warning("Confusing minuses.");this.left=left;this.right=parse(130);return this;},130);infix('*','mult',140);infix('/','div',140);infix('%','mod',140);suffix('++','postinc');prefix('++','preinc');syntax['++'].exps=true;suffix('--','postdec');prefix('--','predec');syntax['--'].exps=true;prefix('delete',function(){var p=parse(0);if(!p||(p.id!=='.'&&p.id!=='[')){warning("Variables should not be deleted.");}
378
- this.first=p;return this;}).exps=true;prefix('~',function(){if(option.bitwise){warning("Unexpected '{a}'.",this,'~');}
379
- parse(150);return this;});prefix('!',function(){this.right=parse(150);this.arity='unary';if(bang[this.right.id]===true){warning("Confusing use of '{a}'.",this,'!');}
380
- return this;});prefix('typeof','typeof');prefix('new',function(){var c=parse(155),i;if(c&&c.id!=='function'){if(c.identifier){c['new']=true;switch(c.value){case'Object':warning("Use the object literal notation {}.",token);break;case'Array':if(nexttoken.id!=='('){warning("Use the array literal notation [].",token);}else{advance('(');if(nexttoken.id===')'){warning("Use the array literal notation [].",token);}else{i=parse(0);c.dimension=i;if((i.id==='(number)'&&/[.+\-Ee]/.test(i.value))||(i.id==='-'&&!i.right)||i.id==='(string)'||i.id==='['||i.id==='{'||i.id==='true'||i.id==='false'||i.id==='null'||i.id==='undefined'||i.id==='Infinity'){warning("Use the array literal notation [].",token);}
381
- if(nexttoken.id!==')'){error("Use the array literal notation [].",token);}}
382
- advance(')');}
383
- this.first=c;return this;case'Number':case'String':case'Boolean':case'Math':case'JSON':warning("Do not use {a} as a constructor.",token,c.value);break;case'Function':if(!option.evil){warning("The Function constructor is eval.");}
384
- break;case'Date':case'RegExp':break;default:if(c.id!=='function'){i=c.value.substr(0,1);if(option.newcap&&(i<'A'||i>'Z')){warning("A constructor name should start with an uppercase letter.",token);}}}}else{if(c.id!=='.'&&c.id!=='['&&c.id!=='('){warning("Bad constructor.",token);}}}else{warning("Weird construction. Delete 'new'.",this);}
385
- adjacent(token,nexttoken);if(nexttoken.id!=='('){warning("Missing '()' invoking a constructor.");}
386
- this.first=c;return this;});syntax['new'].exps=true;infix('.',function(left,that){adjacent(prevtoken,token);nobreak();var m=identifier();if(typeof m==='string'){countMember(m);}
387
- that.left=left;that.right=m;if(left&&left.value==='arguments'&&(m==='callee'||m==='caller')){warning("Avoid arguments.{a}.",left,m);}else if(!option.evil&&left&&left.value==='document'&&(m==='write'||m==='writeln')){warning("document.write can be a form of eval.",left);}else if(option.adsafe){if(left&&left.value==='ADSAFE'){if(m==='id'||m==='lib'){warning("ADsafe violation.",that);}else if(m==='go'){if(xmode!=='script'){warning("ADsafe violation.",that);}else if(adsafe_went||nexttoken.id!=='('||peek(0).id!=='(string)'||peek(0).value!==adsafe_id||peek(1).id!==','){error("ADsafe violation: go.",that);}
388
- adsafe_went=true;adsafe_may=false;}}}
389
- if(!option.evil&&(m==='eval'||m==='execScript')){warning('eval is evil.');}else if(option.safe){for(;;){if(banned[m]===true){warning("ADsafe restricted word '{a}'.",token,m);}
390
- if(typeof predefined[left.value]!=='boolean'||nexttoken.id==='('){break;}
391
- if(standard_member[m]===true){if(nexttoken.id==='.'){warning("ADsafe violation.",that);}
392
- break;}
393
- if(nexttoken.id!=='.'){warning("ADsafe violation.",that);break;}
394
- advance('.');token.left=that;token.right=m;that=token;m=identifier();if(typeof m==='string'){countMember(m);}}}
395
- return that;},160,true);infix('(',function(left,that){if(prevtoken.id!=='}'&&prevtoken.id!==')'){nobreak(prevtoken,token);}
396
- nospace();if(option.immed&&!left.immed&&left.id==='function'){warning("Wrap an immediate function invocation in parentheses "+"to assist the reader in understanding that the expression "+"is the result of a function, and not the function itself.");}
397
- var n=0,p=[];if(left){if(left.type==='(identifier)'){if(left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)){if(left.value!=='Number'&&left.value!=='String'&&left.value!=='Boolean'&&left.value!=='Date'){if(left.value==='Math'){warning("Math is not a function.",left);}else if(option.newcap){warning("Missing 'new' prefix when invoking a constructor.",left);}}}}else if(left.id==='.'){if(option.safe&&left.left.value==='Math'&&left.right==='random'){warning("ADsafe violation.",left);}}}
398
- if(nexttoken.id!==')'){for(;;){p[p.length]=parse(10);n+=1;if(nexttoken.id!==','){break;}
399
- comma();}}
400
- advance(')');nospace(prevtoken,token);if(typeof left==='object'){if(left.value==='parseInt'&&n===1){warning("Missing radix parameter.",left);}
401
- if(!option.evil){if(left.value==='eval'||left.value==='Function'||left.value==='execScript'){warning("eval is evil.",left);}else if(p[0]&&p[0].id==='(string)'&&(left.value==='setTimeout'||left.value==='setInterval')){warning("Implied eval is evil. Pass a function instead of a string.",left);}}
402
- if(!left.identifier&&left.id!=='.'&&left.id!=='['&&left.id!=='('&&left.id!=='&&'&&left.id!=='||'&&left.id!=='?'){warning("Bad invocation.",left);}}
403
- that.left=left;return that;},155,true).exps=true;prefix('(',function(){nospace();if(nexttoken.id==='function'){nexttoken.immed=true;}
404
- var v=parse(0);advance(')',this);nospace(prevtoken,token);if(option.immed&&v.id==='function'){if(nexttoken.id==='('){warning("Move the invocation into the parens that contain the function.",nexttoken);}else{warning("Do not wrap function literals in parens unless they are to be immediately invoked.",this);}}
405
- return v;});infix('[',function(left,that){nobreak(prevtoken,token);nospace();var e=parse(0),s;if(e&&e.type==='(string)'){if(option.safe&&banned[e.value]===true){warning("ADsafe restricted word '{a}'.",that,e.value);}else if(!option.evil&&(e.value==='eval'||e.value==='execScript')){warning("eval is evil.",that);}else if(option.safe&&(e.value.charAt(0)==='_'||e.value.charAt(0)==='-')){warning("ADsafe restricted subscript '{a}'.",that,e.value);}
406
- countMember(e.value);if(!option.sub&&ix.test(e.value)){s=syntax[e.value];if(!s||!s.reserved){warning("['{a}'] is better written in dot notation.",e,e.value);}}}else if(!e||e.type!=='(number)'||e.value<0){if(option.safe){warning('ADsafe subscripting.');}}
407
- advance(']',that);nospace(prevtoken,token);that.left=left;that.right=e;return that;},160,true);prefix('[',function(){var b=token.line!==nexttoken.line;this.first=[];if(b){indent+=option.indent;if(nexttoken.from===indent+option.indent){indent+=option.indent;}}
408
- while(nexttoken.id!=='(end)'){while(nexttoken.id===','){warning("Extra comma.");advance(',');}
409
- if(nexttoken.id===']'){break;}
410
- if(b&&token.line!==nexttoken.line){indentation();}
411
- this.first.push(parse(10));if(nexttoken.id===','){comma();if(nexttoken.id===']'&&!option.es5){warning("Extra comma.",token);break;}}else{break;}}
412
- if(b){indent-=option.indent;indentation();}
413
- advance(']',this);return this;},160);function property_name(){var id=optionalidentifier(true);if(!id){if(nexttoken.id==='(string)'){id=nexttoken.value;if(option.adsafe&&(id.charAt(0)==='_'||id.charAt(id.length-1)==='_')){warning("Unexpected {a} in '{b}'.",token,"dangling '_'",id);}
414
- advance();}else if(nexttoken.id==='(number)'){id=nexttoken.value.toString();advance();}}
415
- return id;}
416
- function functionparams(){var i,t=nexttoken,p=[];advance('(');nospace();if(nexttoken.id===')'){advance(')');nospace(prevtoken,token);return;}
417
- for(;;){i=identifier();p.push(i);addlabel(i,'parameter');if(nexttoken.id===','){comma();}else{advance(')',t);nospace(prevtoken,token);return p;}}}
418
- function doFunction(i,statement){var f,s=scope;scope=Object.create(s);funct={'(name)':i||'"'+anonname+'"','(line)':nexttoken.line,'(context)':funct,'(breakage)':0,'(loopage)':0,'(scope)':scope,'(statement)':statement};f=funct;token.funct=funct;functions.push(funct);if(i){addlabel(i,'function');}
419
- funct['(params)']=functionparams();block(false);scope=s;funct['(last)']=token.line;funct=funct['(context)'];return f;}
420
- (function(x){x.nud=function(){var b,f,i,j,p,seen={},t;b=token.line!==nexttoken.line;if(b){indent+=option.indent;if(nexttoken.from===indent+option.indent){indent+=option.indent;}}
421
- for(;;){if(nexttoken.id==='}'){break;}
422
- if(b){indentation();}
423
- if(nexttoken.value==='get'&&peek().id!==':'){advance('get');if(!option.es5){error("get/set are ES5 features.");}
424
- i=property_name();if(!i){error("Missing property name.");}
425
- t=nexttoken;adjacent(token,nexttoken);f=doFunction(i);if(funct['(loopage)']){warning("Don't make functions within a loop.",t);}
426
- p=f['(params)'];if(p){warning("Unexpected parameter '{a}' in get {b} function.",t,p[0],i);}
427
- adjacent(token,nexttoken);advance(',');indentation();advance('set');j=property_name();if(i!==j){error("Expected {a} and instead saw {b}.",token,i,j);}
428
- t=nexttoken;adjacent(token,nexttoken);f=doFunction(i);p=f['(params)'];if(!p||p.length!==1||p[0]!=='value'){warning("Expected (value) in set {a} function.",t,i);}}else{i=property_name();if(typeof i!=='string'){break;}
429
- advance(':');nonadjacent(token,nexttoken);parse(10);}
430
- if(seen[i]===true){warning("Duplicate member '{a}'.",nexttoken,i);}
431
- seen[i]=true;countMember(i);if(nexttoken.id===','){comma();if(nexttoken.id===','){warning("Extra comma.",token);}else if(nexttoken.id==='}'&&!option.es5){warning("Extra comma.",token);}}else{break;}}
432
- if(b){indent-=option.indent;indentation();}
433
- advance('}',this);return this;};x.fud=function(){error("Expected to see a statement and instead saw a block.",token);};}(delim('{')));var varstatement=function varstatement(prefix){var id,name,value;if(funct['(onevar)']&&option.onevar){warning("Too many var statements.");}else if(!funct['(global)']){funct['(onevar)']=true;}
434
- this.first=[];for(;;){nonadjacent(token,nexttoken);id=identifier();if(funct['(global)']&&predefined[id]===false){warning("Redefinition of '{a}'.",token,id);}
435
- addlabel(id,'unused');if(prefix){break;}
436
- name=token;this.first.push(token);if(nexttoken.id==='='){nonadjacent(token,nexttoken);advance('=');nonadjacent(token,nexttoken);if(nexttoken.id==='undefined'){warning("It is not necessary to initialize '{a}' to 'undefined'.",token,id);}
437
- if(peek(0).id==='='&&nexttoken.identifier){error("Variable {a} was not declared correctly.",nexttoken,nexttoken.value);}
438
- value=parse(0);name.first=value;}
439
- if(nexttoken.id!==','){break;}
440
- comma();}
441
- return this;};stmt('var',varstatement).exps=true;blockstmt('function',function(){if(inblock){warning("Function statements cannot be placed in blocks. Use a function expression or move the statement to the top of the outer function.",token);}
442
- var i=identifier();adjacent(token,nexttoken);addlabel(i,'unction');doFunction(i,true);if(nexttoken.id==='('&&nexttoken.line===token.line){error("Function statements are not invocable. Wrap the whole function invocation in parens.");}
443
- return this;});prefix('function',function(){var i=optionalidentifier();if(i){adjacent(token,nexttoken);}else{nonadjacent(token,nexttoken);}
444
- doFunction(i);if(funct['(loopage)']){warning("Don't make functions within a loop.");}
445
- return this;});blockstmt('if',function(){var t=nexttoken;advance('(');nonadjacent(this,t);nospace();parse(20);if(nexttoken.id==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
446
- advance(')',t);nospace(prevtoken,token);block(true);if(nexttoken.id==='else'){nonadjacent(token,nexttoken);advance('else');if(nexttoken.id==='if'||nexttoken.id==='switch'){statement(true);}else{block(true);}}
447
- return this;});blockstmt('try',function(){var b,e,s;if(option.adsafe){warning("ADsafe try violation.",this);}
448
- block(false);if(nexttoken.id==='catch'){advance('catch');nonadjacent(token,nexttoken);advance('(');s=scope;scope=Object.create(s);e=nexttoken.value;if(nexttoken.type!=='(identifier)'){warning("Expected an identifier and instead saw '{a}'.",nexttoken,e);}else{addlabel(e,'exception');}
449
- advance();advance(')');block(false);b=true;scope=s;}
450
- if(nexttoken.id==='finally'){advance('finally');block(false);return;}else if(!b){error("Expected '{a}' and instead saw '{b}'.",nexttoken,'catch',nexttoken.value);}
451
- return this;});blockstmt('while',function(){var t=nexttoken;funct['(breakage)']+=1;funct['(loopage)']+=1;advance('(');nonadjacent(this,t);nospace();parse(20);if(nexttoken.id==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
452
- advance(')',t);nospace(prevtoken,token);block(true);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;}).labelled=true;reserve('with');blockstmt('switch',function(){var t=nexttoken,g=false;funct['(breakage)']+=1;advance('(');nonadjacent(this,t);nospace();this.condition=parse(20);advance(')',t);nospace(prevtoken,token);nonadjacent(token,nexttoken);t=nexttoken;advance('{');nonadjacent(token,nexttoken);indent+=option.indent;this.cases=[];for(;;){switch(nexttoken.id){case'case':switch(funct['(verb)']){case'break':case'case':case'continue':case'return':case'switch':case'throw':break;default:warning("Expected a 'break' statement before 'case'.",token);}
453
- indentation(-option.indent);advance('case');this.cases.push(parse(20));g=true;advance(':');funct['(verb)']='case';break;case'default':switch(funct['(verb)']){case'break':case'continue':case'return':case'throw':break;default:warning("Expected a 'break' statement before 'default'.",token);}
454
- indentation(-option.indent);advance('default');g=true;advance(':');break;case'}':indent-=option.indent;indentation();advance('}',t);if(this.cases.length===1||this.condition.id==='true'||this.condition.id==='false'){warning("This 'switch' should be an 'if'.",this);}
455
- funct['(breakage)']-=1;funct['(verb)']=undefined;return;case'(end)':error("Missing '{a}'.",nexttoken,'}');return;default:if(g){switch(token.id){case',':error("Each value should have its own case label.");return;case':':statements();break;default:error("Missing ':' on a case clause.",token);}}else{error("Expected '{a}' and instead saw '{b}'.",nexttoken,'case',nexttoken.value);}}}}).labelled=true;stmt('debugger',function(){if(!option.debug){warning("All 'debugger' statements should be removed.");}
456
- return this;}).exps=true;(function(){var x=stmt('do',function(){funct['(breakage)']+=1;funct['(loopage)']+=1;this.first=block(true);advance('while');var t=nexttoken;nonadjacent(token,t);advance('(');nospace();parse(20);if(nexttoken.id==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}
457
- advance(')',t);nospace(prevtoken,token);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;});x.labelled=true;x.exps=true;}());blockstmt('for',function(){var f=option.forin,s,t=nexttoken;funct['(breakage)']+=1;funct['(loopage)']+=1;advance('(');nonadjacent(this,t);nospace();if(peek(nexttoken.id==='var'?1:0).id==='in'){if(nexttoken.id==='var'){advance('var');varstatement(true);}else{switch(funct[nexttoken.value]){case'unused':funct[nexttoken.value]='var';break;case'var':break;default:warning("Bad for in variable '{a}'.",nexttoken,nexttoken.value);}
458
- advance();}
459
- advance('in');parse(20);advance(')',t);s=block(true);if(!f&&(s.length>1||typeof s[0]!=='object'||s[0].value!=='if')){warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.",this);}
460
- funct['(breakage)']-=1;funct['(loopage)']-=1;return this;}else{if(nexttoken.id!==';'){if(nexttoken.id==='var'){advance('var');varstatement();}else{for(;;){parse(0,'for');if(nexttoken.id!==','){break;}
461
- comma();}}}
462
- nolinebreak(token);advance(';');if(nexttoken.id!==';'){parse(20);if(nexttoken.id==='='){warning("Expected a conditional expression and instead saw an assignment.");advance('=');parse(20);}}
463
- nolinebreak(token);advance(';');if(nexttoken.id===';'){error("Expected '{a}' and instead saw '{b}'.",nexttoken,')',';');}
464
- if(nexttoken.id!==')'){for(;;){parse(0,'for');if(nexttoken.id!==','){break;}
465
- comma();}}
466
- advance(')',t);nospace(prevtoken,token);block(true);funct['(breakage)']-=1;funct['(loopage)']-=1;return this;}}).labelled=true;stmt('break',function(){var v=nexttoken.value;if(funct['(breakage)']===0){warning("Unexpected '{a}'.",nexttoken,this.value);}
467
- nolinebreak(this);if(nexttoken.id!==';'){if(token.line===nexttoken.line){if(funct[v]!=='label'){warning("'{a}' is not a statement label.",nexttoken,v);}else if(scope[v]!==funct){warning("'{a}' is out of scope.",nexttoken,v);}
468
- this.first=nexttoken;advance();}}
469
- reachable('break');return this;}).exps=true;stmt('continue',function(){var v=nexttoken.value;if(funct['(breakage)']===0){warning("Unexpected '{a}'.",nexttoken,this.value);}
470
- nolinebreak(this);if(nexttoken.id!==';'){if(token.line===nexttoken.line){if(funct[v]!=='label'){warning("'{a}' is not a statement label.",nexttoken,v);}else if(scope[v]!==funct){warning("'{a}' is out of scope.",nexttoken,v);}
471
- this.first=nexttoken;advance();}}else if(!funct['(loopage)']){warning("Unexpected '{a}'.",nexttoken,this.value);}
472
- reachable('continue');return this;}).exps=true;stmt('return',function(){nolinebreak(this);if(nexttoken.id==='(regexp)'){warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");}
473
- if(nexttoken.id!==';'&&!nexttoken.reach){nonadjacent(token,nexttoken);this.first=parse(20);}
474
- reachable('return');return this;}).exps=true;stmt('throw',function(){nolinebreak(this);nonadjacent(token,nexttoken);this.first=parse(20);reachable('throw');return this;}).exps=true;reserve('void');reserve('class');reserve('const');reserve('enum');reserve('export');reserve('extends');reserve('import');reserve('super');reserve('let');reserve('yield');reserve('implements');reserve('interface');reserve('package');reserve('private');reserve('protected');reserve('public');reserve('static');function jsonValue(){function jsonObject(){var o={},t=nexttoken;advance('{');if(nexttoken.id!=='}'){for(;;){if(nexttoken.id==='(end)'){error("Missing '}' to match '{' from line {a}.",nexttoken,t.line);}else if(nexttoken.id==='}'){warning("Unexpected comma.",token);break;}else if(nexttoken.id===','){error("Unexpected comma.",nexttoken);}else if(nexttoken.id!=='(string)'){warning("Expected a string and instead saw {a}.",nexttoken,nexttoken.value);}
475
- if(o[nexttoken.value]===true){warning("Duplicate key '{a}'.",nexttoken,nexttoken.value);}else if(nexttoken.value==='__proto__'){warning("Stupid key '{a}'.",nexttoken,nexttoken.value);}else{o[nexttoken.value]=true;}
476
- advance();advance(':');jsonValue();if(nexttoken.id!==','){break;}
477
- advance(',');}}
478
- advance('}');}
479
- function jsonArray(){var t=nexttoken;advance('[');if(nexttoken.id!==']'){for(;;){if(nexttoken.id==='(end)'){error("Missing ']' to match '[' from line {a}.",nexttoken,t.line);}else if(nexttoken.id===']'){warning("Unexpected comma.",token);break;}else if(nexttoken.id===','){error("Unexpected comma.",nexttoken);}
480
- jsonValue();if(nexttoken.id!==','){break;}
481
- advance(',');}}
482
- advance(']');}
483
- switch(nexttoken.id){case'{':jsonObject();break;case'[':jsonArray();break;case'true':case'false':case'null':case'(number)':case'(string)':advance();break;case'-':advance('-');if(token.character!==nexttoken.from){warning("Unexpected space after '-'.",token);}
484
- adjacent(token,nexttoken);advance('(number)');break;default:error("Expected a JSON value.",nexttoken);}}
485
- var itself=function(s,o){var a,i;JSLINT.errors=[];predefined=Object.create(standard);if(o){a=o.predef;if(a instanceof Array){for(i=0;i<a.length;i+=1){predefined[a[i]]=true;}}
486
- if(o.adsafe){o.safe=true;}
487
- if(o.safe){o.browser=o.css=o.debug=o.devel=o.evil=o.forin=o.on=o.rhino=o.windows=o.sub=o.widget=false;o.eqeqeq=o.nomen=o.safe=o.strict=o.undef=true;predefined.Date=predefined['eval']=predefined.Function=predefined.Object=null;predefined.ADSAFE=predefined.lib=false;}
488
- option=o;}else{option={};}
489
- option.indent=option.indent||4;option.maxerr=option.maxerr||50;adsafe_id='';adsafe_may=false;adsafe_went=false;approved={};if(option.approved){for(i=0;i<option.approved.length;i+=1){approved[option.approved[i]]=option.approved[i];}}else{approved.test='test';}
490
- tab='';for(i=0;i<option.indent;i+=1){tab+=' ';}
491
- indent=1;global=Object.create(predefined);scope=global;funct={'(global)':true,'(name)':'(global)','(scope)':scope,'(breakage)':0,'(loopage)':0};functions=[funct];ids={};urls=[];src=false;xmode=false;stack=null;member={};membersOnly=null;implied={};inblock=false;lookahead=[];jsonmode=false;warnings=0;lex.init(s);prereg=true;strict_mode=false;prevtoken=token=nexttoken=syntax['(begin)'];assume();try{advance();if(nexttoken.value.charAt(0)==='<'){html();if(option.adsafe&&!adsafe_went){warning("ADsafe violation: Missing ADSAFE.go.",this);}}else{switch(nexttoken.id){case'{':case'[':option.laxbreak=true;jsonmode=true;jsonValue();break;case'@':case'*':case'#':case'.':case':':xmode='style';advance();if(token.id!=='@'||!nexttoken.identifier||nexttoken.value!=='charset'||token.line!==1||token.from!==1){error("A css file should begin with @charset 'UTF-8';");}
492
- advance();if(nexttoken.type!=='(string)'&&nexttoken.value!=='UTF-8'){error("A css file should begin with @charset 'UTF-8';");}
493
- advance();advance(';');styles();break;default:if(option.adsafe&&option.fragment){error("Expected '{a}' and instead saw '{b}'.",nexttoken,'<div>',nexttoken.value);}
494
- statements('lib');}}
495
- advance('(end)');}catch(e){if(e){JSLINT.errors.push({reason:e.message,line:e.line||nexttoken.line,character:e.character||nexttoken.from},null);}}
496
- return JSLINT.errors.length===0;};function is_array(o){return Object.prototype.toString.apply(o)==='[object Array]';}
497
- function to_array(o){var a=[],k;for(k in o){if(is_own(o,k)){a.push(k);}}
498
- return a;}
499
- itself.data=function(){var data={functions:[]},fu,globals,implieds=[],f,i,j,members=[],n,unused=[],v;if(itself.errors.length){data.errors=itself.errors;}
500
- if(jsonmode){data.json=true;}
501
- for(n in implied){if(is_own(implied,n)){implieds.push({name:n,line:implied[n]});}}
502
- if(implieds.length>0){data.implieds=implieds;}
503
- if(urls.length>0){data.urls=urls;}
504
- globals=to_array(scope);if(globals.length>0){data.globals=globals;}
505
- for(i=1;i<functions.length;i+=1){f=functions[i];fu={};for(j=0;j<functionicity.length;j+=1){fu[functionicity[j]]=[];}
506
- for(n in f){if(is_own(f,n)&&n.charAt(0)!=='('){v=f[n];if(v==='unction'){v='unused';}
507
- if(is_array(fu[v])){fu[v].push(n);if(v==='unused'){unused.push({name:n,line:f['(line)'],'function':f['(name)']});}}}}
508
- for(j=0;j<functionicity.length;j+=1){if(fu[functionicity[j]].length===0){delete fu[functionicity[j]];}}
509
- fu.name=f['(name)'];fu.param=f['(params)'];fu.line=f['(line)'];fu.last=f['(last)'];data.functions.push(fu);}
510
- if(unused.length>0){data.unused=unused;}
511
- members=[];for(n in member){if(typeof member[n]==='number'){data.member=member;break;}}
512
- return data;};itself.report=function(option){var data=itself.data();var a=[],c,e,err,f,i,k,l,m='',n,o=[],s;function detail(h,array){var b,i,singularity;if(array){o.push('<div><i>'+h+'</i> ');array=array.sort();for(i=0;i<array.length;i+=1){if(array[i]!==singularity){singularity=array[i];o.push((b?', ':'')+singularity);b=true;}}
513
- o.push('</div>');}}
514
- if(data.errors||data.implieds||data.unused){err=true;o.push('<div id=errors><i>Error:</i>');if(data.errors){for(i=0;i<data.errors.length;i+=1){c=data.errors[i];if(c){e=c.evidence||'';o.push('<p>Problem'+(isFinite(c.line)?' at line '+
515
- c.line+' character '+c.character:'')+': '+c.reason.entityify()+'</p><p class=evidence>'+
516
- (e&&(e.length>80?e.slice(0,77)+'...':e).entityify())+'</p>');}}}
517
- if(data.implieds){s=[];for(i=0;i<data.implieds.length;i+=1){s[i]='<code>'+data.implieds[i].name+'</code>&nbsp;<i>'+
518
- data.implieds[i].line+'</i>';}
519
- o.push('<p><i>Implied global:</i> '+s.join(', ')+'</p>');}
520
- if(data.unused){s=[];for(i=0;i<data.unused.length;i+=1){s[i]='<code><u>'+data.unused[i].name+'</u></code>&nbsp;<i>'+
521
- data.unused[i].line+'</i> <code>'+
522
- data.unused[i]['function']+'</code>';}
523
- o.push('<p><i>Unused variable:</i> '+s.join(', ')+'</p>');}
524
- if(data.json){o.push('<p>JSON: bad.</p>');}
525
- o.push('</div>');}
526
- if(!option){o.push('<br><div id=functions>');if(data.urls){detail("URLs<br>",data.urls,'<br>');}
527
- if(xmode==='style'){o.push('<p>CSS.</p>');}else if(data.json&&!err){o.push('<p>JSON: good.</p>');}else if(data.globals){o.push('<div><i>Global</i> '+
528
- data.globals.sort().join(', ')+'</div>');}else{o.push('<div><i>No new global variables introduced.</i></div>');}
529
- for(i=0;i<data.functions.length;i+=1){f=data.functions[i];o.push('<br><div class=function><i>'+f.line+'-'+
530
- f.last+'</i> '+(f.name||'')+'('+
531
- (f.param?f.param.join(', '):'')+')</div>');detail('<big><b>Unused</b></big>',f.unused);detail('Closure',f.closure);detail('Variable',f['var']);detail('Exception',f.exception);detail('Outer',f.outer);detail('Global',f.global);detail('Label',f.label);}
532
- if(data.member){a=to_array(data.member);if(a.length){a=a.sort();m='<br><pre id=members>/*members ';l=10;for(i=0;i<a.length;i+=1){k=a[i];n=k.name();if(l+n.length>72){o.push(m+'<br>');m=' ';l=1;}
533
- l+=n.length+2;if(data.member[k]===1){n='<i>'+n+'</i>';}
534
- if(i<a.length-1){n+=', ';}
535
- m+=n;}
536
- o.push(m+'<br>*/</pre>');}
537
- o.push('</div>');}}
538
- return o.join('');};itself.jslint=itself;itself.edition='2010-11-18';return itself;}());
1
+ /*
2
+ * JSHint, by JSHint Community.
3
+ *
4
+ * Licensed under the same slightly modified MIT license that JSLint is.
5
+ * It stops evil-doers everywhere.
6
+ *
7
+ * JSHint is a derivative work of JSLint:
8
+ *
9
+ * Copyright (c) 2002 Douglas Crockford (www.JSLint.com)
10
+ *
11
+ * Permission is hereby granted, free of charge, to any person obtaining
12
+ * a copy of this software and associated documentation files (the "Software"),
13
+ * to deal in the Software without restriction, including without limitation
14
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
+ * and/or sell copies of the Software, and to permit persons to whom
16
+ * the Software is furnished to do so, subject to the following conditions:
17
+ *
18
+ * The above copyright notice and this permission notice shall be included
19
+ * in all copies or substantial portions of the Software.
20
+ *
21
+ * The Software shall be used for Good, not Evil.
22
+ *
23
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
+ * DEALINGS IN THE SOFTWARE.
30
+ *
31
+ * JSHint was forked from 2010-12-16 edition of JSLint.
32
+ *
33
+ */
34
+
35
+ /*
36
+ JSHINT is a global function. It takes two parameters.
37
+
38
+ var myResult = JSHINT(source, option);
39
+
40
+ The first parameter is either a string or an array of strings. If it is a
41
+ string, it will be split on '\n' or '\r'. If it is an array of strings, it
42
+ is assumed that each string represents one line. The source can be a
43
+ JavaScript text or a JSON text.
44
+
45
+ The second parameter is an optional object of options which control the
46
+ operation of JSHINT. Most of the options are booleans: They are all
47
+ optional and have a default value of false. One of the options, predef,
48
+ can be an array of names, which will be used to declare global variables,
49
+ or an object whose keys are used as global names, with a boolean value
50
+ that determines if they are assignable.
51
+
52
+ If it checks out, JSHINT returns true. Otherwise, it returns false.
53
+
54
+ If false, you can inspect JSHINT.errors to find out the problems.
55
+ JSHINT.errors is an array of objects containing these members:
56
+
57
+ {
58
+ line : The line (relative to 0) at which the lint was found
59
+ character : The character (relative to 0) at which the lint was found
60
+ reason : The problem
61
+ evidence : The text line in which the problem occurred
62
+ raw : The raw message before the details were inserted
63
+ a : The first detail
64
+ b : The second detail
65
+ c : The third detail
66
+ d : The fourth detail
67
+ }
68
+
69
+ If a fatal error was found, a null will be the last element of the
70
+ JSHINT.errors array.
71
+
72
+ You can request a Function Report, which shows all of the functions
73
+ and the parameters and vars that they use. This can be used to find
74
+ implied global variables and other problems. The report is in HTML and
75
+ can be inserted in an HTML <body>.
76
+
77
+ var myReport = JSHINT.report(limited);
78
+
79
+ If limited is true, then the report will be limited to only errors.
80
+
81
+ You can request a data structure which contains JSHint's results.
82
+
83
+ var myData = JSHINT.data();
84
+
85
+ It returns a structure with this form:
86
+
87
+ {
88
+ errors: [
89
+ {
90
+ line: NUMBER,
91
+ character: NUMBER,
92
+ reason: STRING,
93
+ evidence: STRING
94
+ }
95
+ ],
96
+ functions: [
97
+ name: STRING,
98
+ line: NUMBER,
99
+ last: NUMBER,
100
+ param: [
101
+ STRING
102
+ ],
103
+ closure: [
104
+ STRING
105
+ ],
106
+ var: [
107
+ STRING
108
+ ],
109
+ exception: [
110
+ STRING
111
+ ],
112
+ outer: [
113
+ STRING
114
+ ],
115
+ unused: [
116
+ STRING
117
+ ],
118
+ global: [
119
+ STRING
120
+ ],
121
+ label: [
122
+ STRING
123
+ ]
124
+ ],
125
+ globals: [
126
+ STRING
127
+ ],
128
+ member: {
129
+ STRING: NUMBER
130
+ },
131
+ unuseds: [
132
+ {
133
+ name: STRING,
134
+ line: NUMBER
135
+ }
136
+ ],
137
+ implieds: [
138
+ {
139
+ name: STRING,
140
+ line: NUMBER
141
+ }
142
+ ],
143
+ urls: [
144
+ STRING
145
+ ],
146
+ json: BOOLEAN
147
+ }
148
+
149
+ Empty arrays will not be included.
150
+
151
+ */
152
+
153
+ /*jshint
154
+ evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true
155
+ */
156
+
157
+ /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
158
+ "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)",
159
+ "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)",
160
+ "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
161
+ "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
162
+ __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView,
163
+ Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas,
164
+ CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date,
165
+ Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, Drag,
166
+ E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
167
+ Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
168
+ FormField, Frame, Function, Fx, GetObject, Group, Hash, HotKey, HTMLElement,
169
+ HtmlTable, Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array,
170
+ Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
171
+ MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MoveAnimation, MooTools, Native,
172
+ NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, Options, OverText, PI,
173
+ POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, RangeError,
174
+ Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation,
175
+ SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
176
+ ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
177
+ Slick, Slider, Selector, String, Style, SyntaxError, Sortable, Sortables,
178
+ SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
179
+ Timer, Tips, Type, TypeError, Toggle, Try, URI, URIError, URL, VBArray, WSH,
180
+ WScript, Web, Window, XMLDOM, XMLHttpRequest, XPathEvaluator, XPathException,
181
+ XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, "\\", a,
182
+ addEventListener, address, alert, apply, applicationCache, arguments, arity,
183
+ asi, b, bitwise, block, blur, boolOptions, boss, browser, c, call, callee,
184
+ caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout,
185
+ close, closed, closure, comment, condition, confirm, console, constructor,
186
+ content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI,
187
+ decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
188
+ dojo, dijit, dojox, define, edition, else, emit, encodeURI, encodeURIComponent,
189
+ entityify, eqeqeq, eqnull, errors, es5, escape, eval, event, evidence, evil,
190
+ ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus,
191
+ forin, fragment, frames, from, fromCharCode, fud, funct, function, functions,
192
+ g, gc, getComputedStyle, getRow, GLOBAL, global, globals, globalstrict,
193
+ hasOwnProperty, help, history, i, id,
194
+ identifier, immed, implieds, include, indent, indexOf, init, ins, instanceOf,
195
+ isAlpha, isApplicationRunning, isArray, isDigit, isFinite, isNaN, join, jshint,
196
+ JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak,
197
+ latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
198
+ log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy,
199
+ moveTo, mootools, name, navigator, new, newcap, noarg, node, noempty, nomen,
200
+ nonew, nud, onbeforeunload, onblur, onerror, onevar, onfocus, onload, onresize,
201
+ onunload, open, openDatabase, openURL, opener, opera, outer, param, parent,
202
+ parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt,
203
+ prototype, prototypejs, push, quit, range, raw, reach, reason, regexp,
204
+ readFile, readUrl, regexdash, removeEventListener, replace, report, require,
205
+ reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right,
206
+ runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal, send,
207
+ serialize, setInterval, setTimeout, shift, slice, sort,spawn, split, stack,
208
+ status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync,
209
+ test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing, type,
210
+ typeOf, Uint16Array, Uint32Array, Uint8Array, undef, unused, urls, value, valueOf,
211
+ var, version, WebSocket, white, window, Worker, wsh*/
212
+
213
+ /*global exports: false */
214
+
215
+ // We build the application inside a function so that we produce only a single
216
+ // global variable. That function will be invoked immediately, and its return
217
+ // value is the JSHINT function itself.
218
+
219
+ var JSHINT = (function () {
220
+ "use strict";
221
+
222
+ var anonname, // The guessed name for anonymous functions.
223
+
224
+ // These are operators that should not be used with the ! operator.
225
+
226
+ bang = {
227
+ '<' : true,
228
+ '<=' : true,
229
+ '==' : true,
230
+ '===': true,
231
+ '!==': true,
232
+ '!=' : true,
233
+ '>' : true,
234
+ '>=' : true,
235
+ '+' : true,
236
+ '-' : true,
237
+ '*' : true,
238
+ '/' : true,
239
+ '%' : true
240
+ },
241
+
242
+ // These are the JSHint boolean options.
243
+
244
+ boolOptions = {
245
+ asi : true, // if automatic semicolon insertion should be tolerated
246
+ bitwise : true, // if bitwise operators should not be allowed
247
+ boss : true, // if advanced usage of assignments should be allowed
248
+ browser : true, // if the standard browser globals should be predefined
249
+ couch : true, // if CouchDB globals should be predefined
250
+ curly : true, // if curly braces around blocks should be required (even in if/for/while)
251
+ debug : true, // if debugger statements should be allowed
252
+ devel : true, // if logging globals should be predefined (console, alert, etc.)
253
+ dojo : true, // if Dojo Toolkit globals should be predefined
254
+ eqeqeq : true, // if === should be required
255
+ eqnull : true, // if == null comparisons should be tolerated
256
+ es5 : true, // if ES5 syntax should be allowed
257
+ evil : true, // if eval should be allowed
258
+ expr : true, // if ExpressionStatement should be allowed as Programs
259
+ forin : true, // if for in statements must filter
260
+ globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict')
261
+ immed : true, // if immediate invocations must be wrapped in parens
262
+ jquery : true, // if jQuery globals should be predefined
263
+ latedef : true, // if the use before definition should not be tolerated
264
+ laxbreak : true, // if line breaks should not be checked
265
+ loopfunc : true, // if functions should be allowed to be defined within loops
266
+ mootools : true, // if MooTools globals should be predefined
267
+ newcap : true, // if constructor names must be capitalized
268
+ noarg : true, // if arguments.caller and arguments.callee should be disallowed
269
+ node : true, // if the Node.js environment globals should be predefined
270
+ noempty : true, // if empty blocks should be disallowed
271
+ nonew : true, // if using `new` for side-effects should be disallowed
272
+ nomen : true, // if names should be checked
273
+ onevar : true, // if only one var statement per function should be allowed
274
+ passfail : true, // if the scan should stop on first error
275
+ plusplus : true, // if increment/decrement should not be allowed
276
+ prototypejs : true, // if Prototype and Scriptaculous globals should be predefined
277
+ regexdash : true, // if unescaped last dash (-) inside brackets should be tolerated
278
+ regexp : true, // if the . should not be allowed in regexp literals
279
+ rhino : true, // if the Rhino environment globals should be predefined
280
+ undef : true, // if variables should be declared before used
281
+ scripturl : true, // if script-targeted URLs should be tolerated
282
+ shadow : true, // if variable shadowing should be tolerated
283
+ strict : true, // require the "use strict"; pragma
284
+ sub : true, // if all forms of subscript notation are tolerated
285
+ supernew : true, // if `new function () { ... };` and `new Object;` should be tolerated
286
+ trailing : true, // if trailing whitespace rules apply
287
+ white : true, // if strict whitespace rules apply
288
+ wsh : true // if the Windows Scripting Host environment globals should be predefined
289
+ },
290
+
291
+ // browser contains a set of global names which are commonly provided by a
292
+ // web browser environment.
293
+
294
+ browser = {
295
+ ArrayBuffer : false,
296
+ ArrayBufferView : false,
297
+ addEventListener: false,
298
+ applicationCache: false,
299
+ blur : false,
300
+ clearInterval : false,
301
+ clearTimeout : false,
302
+ close : false,
303
+ closed : false,
304
+ DataView : false,
305
+ defaultStatus : false,
306
+ document : false,
307
+ event : false,
308
+ FileReader : false,
309
+ Float32Array : false,
310
+ Float64Array : false,
311
+ focus : false,
312
+ frames : false,
313
+ getComputedStyle: false,
314
+ HTMLElement : false,
315
+ history : false,
316
+ Int16Array : false,
317
+ Int32Array : false,
318
+ Int8Array : false,
319
+ Image : false,
320
+ length : false,
321
+ localStorage : false,
322
+ location : false,
323
+ moveBy : false,
324
+ moveTo : false,
325
+ name : false,
326
+ navigator : false,
327
+ onbeforeunload : true,
328
+ onblur : true,
329
+ onerror : true,
330
+ onfocus : true,
331
+ onload : true,
332
+ onresize : true,
333
+ onunload : true,
334
+ open : false,
335
+ openDatabase : false,
336
+ opener : false,
337
+ Option : false,
338
+ parent : false,
339
+ print : false,
340
+ removeEventListener: false,
341
+ resizeBy : false,
342
+ resizeTo : false,
343
+ screen : false,
344
+ scroll : false,
345
+ scrollBy : false,
346
+ scrollTo : false,
347
+ setInterval : false,
348
+ setTimeout : false,
349
+ status : false,
350
+ top : false,
351
+ Uint16Array : false,
352
+ Uint32Array : false,
353
+ Uint8Array : false,
354
+ WebSocket : false,
355
+ window : false,
356
+ Worker : false,
357
+ XMLHttpRequest : false,
358
+ XPathEvaluator : false,
359
+ XPathException : false,
360
+ XPathExpression : false,
361
+ XPathNamespace : false,
362
+ XPathNSResolver : false,
363
+ XPathResult : false
364
+ },
365
+
366
+ couch = {
367
+ "require" : false,
368
+ respond : false,
369
+ getRow : false,
370
+ emit : false,
371
+ send : false,
372
+ start : false,
373
+ sum : false,
374
+ log : false,
375
+ exports : false,
376
+ module : false
377
+ },
378
+
379
+ devel = {
380
+ alert : false,
381
+ confirm : false,
382
+ console : false,
383
+ Debug : false,
384
+ opera : false,
385
+ prompt : false
386
+ },
387
+
388
+ dojo = {
389
+ dojo : false,
390
+ dijit : false,
391
+ dojox : false,
392
+ define : false,
393
+ "require" : false
394
+ },
395
+
396
+ escapes = {
397
+ '\b': '\\b',
398
+ '\t': '\\t',
399
+ '\n': '\\n',
400
+ '\f': '\\f',
401
+ '\r': '\\r',
402
+ '"' : '\\"',
403
+ '/' : '\\/',
404
+ '\\': '\\\\'
405
+ },
406
+
407
+ funct, // The current function
408
+
409
+ functionicity = [
410
+ 'closure', 'exception', 'global', 'label',
411
+ 'outer', 'unused', 'var'
412
+ ],
413
+
414
+ functions, // All of the functions
415
+
416
+ global, // The global scope
417
+ implied, // Implied globals
418
+ inblock,
419
+ indent,
420
+ jsonmode,
421
+
422
+ jquery = {
423
+ '$' : false,
424
+ jQuery : false
425
+ },
426
+
427
+ lines,
428
+ lookahead,
429
+ member,
430
+ membersOnly,
431
+
432
+ mootools = {
433
+ '$' : false,
434
+ '$$' : false,
435
+ Assets : false,
436
+ Browser : false,
437
+ Chain : false,
438
+ Class : false,
439
+ Color : false,
440
+ Cookie : false,
441
+ Core : false,
442
+ Document : false,
443
+ DomReady : false,
444
+ DOMReady : false,
445
+ Drag : false,
446
+ Element : false,
447
+ Elements : false,
448
+ Event : false,
449
+ Events : false,
450
+ Fx : false,
451
+ Group : false,
452
+ Hash : false,
453
+ HtmlTable : false,
454
+ Iframe : false,
455
+ IframeShim : false,
456
+ InputValidator : false,
457
+ instanceOf : false,
458
+ Keyboard : false,
459
+ Locale : false,
460
+ Mask : false,
461
+ MooTools : false,
462
+ Native : false,
463
+ Options : false,
464
+ OverText : false,
465
+ Request : false,
466
+ Scroller : false,
467
+ Slick : false,
468
+ Slider : false,
469
+ Sortables : false,
470
+ Spinner : false,
471
+ Swiff : false,
472
+ Tips : false,
473
+ Type : false,
474
+ typeOf : false,
475
+ URI : false,
476
+ Window : false
477
+ },
478
+
479
+ nexttoken,
480
+
481
+ node = {
482
+ __filename : false,
483
+ __dirname : false,
484
+ exports : false,
485
+ Buffer : false,
486
+ GLOBAL : false,
487
+ global : false,
488
+ module : false,
489
+ process : false,
490
+ require : false
491
+ },
492
+
493
+ noreach,
494
+ option,
495
+ predefined, // Global variables defined by option
496
+ prereg,
497
+ prevtoken,
498
+
499
+ prototypejs = {
500
+ '$' : false,
501
+ '$$' : false,
502
+ '$A' : false,
503
+ '$F' : false,
504
+ '$H' : false,
505
+ '$R' : false,
506
+ '$break' : false,
507
+ '$continue' : false,
508
+ '$w' : false,
509
+ Abstract : false,
510
+ Ajax : false,
511
+ Class : false,
512
+ Enumerable : false,
513
+ Element : false,
514
+ Event : false,
515
+ Field : false,
516
+ Form : false,
517
+ Hash : false,
518
+ Insertion : false,
519
+ ObjectRange : false,
520
+ PeriodicalExecuter: false,
521
+ Position : false,
522
+ Prototype : false,
523
+ Selector : false,
524
+ Template : false,
525
+ Toggle : false,
526
+ Try : false,
527
+ Autocompleter : false,
528
+ Builder : false,
529
+ Control : false,
530
+ Draggable : false,
531
+ Draggables : false,
532
+ Droppables : false,
533
+ Effect : false,
534
+ Sortable : false,
535
+ SortableObserver : false,
536
+ Sound : false,
537
+ Scriptaculous : false
538
+ },
539
+
540
+ rhino = {
541
+ defineClass : false,
542
+ deserialize : false,
543
+ gc : false,
544
+ help : false,
545
+ load : false,
546
+ loadClass : false,
547
+ print : false,
548
+ quit : false,
549
+ readFile : false,
550
+ readUrl : false,
551
+ runCommand : false,
552
+ seal : false,
553
+ serialize : false,
554
+ spawn : false,
555
+ sync : false,
556
+ toint32 : false,
557
+ version : false
558
+ },
559
+
560
+ scope, // The current scope
561
+ src,
562
+ stack,
563
+
564
+ // standard contains the global names that are provided by the
565
+ // ECMAScript standard.
566
+
567
+ standard = {
568
+ Array : false,
569
+ Boolean : false,
570
+ Date : false,
571
+ decodeURI : false,
572
+ decodeURIComponent : false,
573
+ encodeURI : false,
574
+ encodeURIComponent : false,
575
+ Error : false,
576
+ 'eval' : false,
577
+ EvalError : false,
578
+ Function : false,
579
+ hasOwnProperty : false,
580
+ isFinite : false,
581
+ isNaN : false,
582
+ JSON : false,
583
+ Math : false,
584
+ Number : false,
585
+ Object : false,
586
+ parseInt : false,
587
+ parseFloat : false,
588
+ RangeError : false,
589
+ ReferenceError : false,
590
+ RegExp : false,
591
+ String : false,
592
+ SyntaxError : false,
593
+ TypeError : false,
594
+ URIError : false
595
+ },
596
+
597
+ standard_member = {
598
+ E : true,
599
+ LN2 : true,
600
+ LN10 : true,
601
+ LOG2E : true,
602
+ LOG10E : true,
603
+ MAX_VALUE : true,
604
+ MIN_VALUE : true,
605
+ NEGATIVE_INFINITY : true,
606
+ PI : true,
607
+ POSITIVE_INFINITY : true,
608
+ SQRT1_2 : true,
609
+ SQRT2 : true
610
+ },
611
+
612
+ strict_mode,
613
+ syntax = {},
614
+ tab,
615
+ token,
616
+ urls,
617
+ warnings,
618
+
619
+ wsh = {
620
+ ActiveXObject : true,
621
+ Enumerator : true,
622
+ GetObject : true,
623
+ ScriptEngine : true,
624
+ ScriptEngineBuildVersion : true,
625
+ ScriptEngineMajorVersion : true,
626
+ ScriptEngineMinorVersion : true,
627
+ VBArray : true,
628
+ WSH : true,
629
+ WScript : true
630
+ },
631
+
632
+ // Regular expressions. Some of these are stupidly long.
633
+
634
+ // unsafe comment or string
635
+ ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i,
636
+ // unsafe characters that are silently deleted by one or more browsers
637
+ cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
638
+ // token
639
+ tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
640
+ // characters in strings that need escapement
641
+ nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
642
+ nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
643
+ // star slash
644
+ lx = /\*\/|\/\*/,
645
+ // identifier
646
+ ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,
647
+ // javascript url
648
+ jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,
649
+ // catches /* falls through */ comments
650
+ ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
651
+
652
+ function F() {} // Used by Object.create
653
+
654
+ function is_own(object, name) {
655
+
656
+ // The object.hasOwnProperty method fails when the property under consideration
657
+ // is named 'hasOwnProperty'. So we have to use this more convoluted form.
658
+
659
+ return Object.prototype.hasOwnProperty.call(object, name);
660
+ }
661
+
662
+ // Provide critical ES5 functions to ES3.
663
+
664
+ if (typeof Array.isArray !== 'function') {
665
+ Array.isArray = function (o) {
666
+ return Object.prototype.toString.apply(o) === '[object Array]';
667
+ };
668
+ }
669
+
670
+ if (typeof Object.create !== 'function') {
671
+ Object.create = function (o) {
672
+ F.prototype = o;
673
+ return new F();
674
+ };
675
+ }
676
+
677
+ if (typeof Object.keys !== 'function') {
678
+ Object.keys = function (o) {
679
+ var a = [], k;
680
+ for (k in o) {
681
+ if (is_own(o, k)) {
682
+ a.push(k);
683
+ }
684
+ }
685
+ return a;
686
+ };
687
+ }
688
+
689
+ // Non standard methods
690
+
691
+ if (typeof String.prototype.entityify !== 'function') {
692
+ String.prototype.entityify = function () {
693
+ return this
694
+ .replace(/&/g, '&amp;')
695
+ .replace(/</g, '&lt;')
696
+ .replace(/>/g, '&gt;');
697
+ };
698
+ }
699
+
700
+ if (typeof String.prototype.isAlpha !== 'function') {
701
+ String.prototype.isAlpha = function () {
702
+ return (this >= 'a' && this <= 'z\uffff') ||
703
+ (this >= 'A' && this <= 'Z\uffff');
704
+ };
705
+ }
706
+
707
+ if (typeof String.prototype.isDigit !== 'function') {
708
+ String.prototype.isDigit = function () {
709
+ return (this >= '0' && this <= '9');
710
+ };
711
+ }
712
+
713
+ if (typeof String.prototype.supplant !== 'function') {
714
+ String.prototype.supplant = function (o) {
715
+ return this.replace(/\{([^{}]*)\}/g, function (a, b) {
716
+ var r = o[b];
717
+ return typeof r === 'string' || typeof r === 'number' ? r : a;
718
+ });
719
+ };
720
+ }
721
+
722
+ if (typeof String.prototype.name !== 'function') {
723
+ String.prototype.name = function () {
724
+
725
+ // If the string looks like an identifier, then we can return it as is.
726
+ // If the string contains no control characters, no quote characters, and no
727
+ // backslash characters, then we can simply slap some quotes around it.
728
+ // Otherwise we must also replace the offending characters with safe
729
+ // sequences.
730
+
731
+ if (ix.test(this)) {
732
+ return this;
733
+ }
734
+ if (nx.test(this)) {
735
+ return '"' + this.replace(nxg, function (a) {
736
+ var c = escapes[a];
737
+ if (c) {
738
+ return c;
739
+ }
740
+ return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4);
741
+ }) + '"';
742
+ }
743
+ return '"' + this + '"';
744
+ };
745
+ }
746
+
747
+
748
+ function combine(t, o) {
749
+ var n;
750
+ for (n in o) {
751
+ if (is_own(o, n)) {
752
+ t[n] = o[n];
753
+ }
754
+ }
755
+ }
756
+
757
+ function assume() {
758
+ if (option.couch)
759
+ combine(predefined, couch);
760
+
761
+ if (option.rhino)
762
+ combine(predefined, rhino);
763
+
764
+ if (option.prototypejs)
765
+ combine(predefined, prototypejs);
766
+
767
+ if (option.node)
768
+ combine(predefined, node);
769
+
770
+ if (option.devel)
771
+ combine(predefined, devel);
772
+
773
+ if (option.dojo)
774
+ combine(predefined, dojo);
775
+
776
+ if (option.browser)
777
+ combine(predefined, browser);
778
+
779
+ if (option.jquery)
780
+ combine(predefined, jquery);
781
+
782
+ if (option.mootools)
783
+ combine(predefined, mootools);
784
+
785
+ if (option.wsh)
786
+ combine(predefined, wsh);
787
+
788
+ if (option.globalstrict && option.strict !== false)
789
+ option.strict = true;
790
+ }
791
+
792
+
793
+ // Produce an error warning.
794
+
795
+ function quit(message, line, chr) {
796
+ var percentage = Math.floor((line / lines.length) * 100);
797
+
798
+ throw {
799
+ name: 'JSHintError',
800
+ line: line,
801
+ character: chr,
802
+ message: message + " (" + percentage + "% scanned)."
803
+ };
804
+ }
805
+
806
+ function warning(m, t, a, b, c, d) {
807
+ var ch, l, w;
808
+ t = t || nexttoken;
809
+ if (t.id === '(end)') { // `~
810
+ t = token;
811
+ }
812
+ l = t.line || 0;
813
+ ch = t.from || 0;
814
+ w = {
815
+ id: '(error)',
816
+ raw: m,
817
+ evidence: lines[l - 1] || '',
818
+ line: l,
819
+ character: ch,
820
+ a: a,
821
+ b: b,
822
+ c: c,
823
+ d: d
824
+ };
825
+ w.reason = m.supplant(w);
826
+ JSHINT.errors.push(w);
827
+ if (option.passfail) {
828
+ quit('Stopping. ', l, ch);
829
+ }
830
+ warnings += 1;
831
+ if (warnings >= option.maxerr) {
832
+ quit("Too many errors.", l, ch);
833
+ }
834
+ return w;
835
+ }
836
+
837
+ function warningAt(m, l, ch, a, b, c, d) {
838
+ return warning(m, {
839
+ line: l,
840
+ from: ch
841
+ }, a, b, c, d);
842
+ }
843
+
844
+ function error(m, t, a, b, c, d) {
845
+ var w = warning(m, t, a, b, c, d);
846
+ quit("Stopping, unable to continue.", w.line, w.character);
847
+ }
848
+
849
+ function errorAt(m, l, ch, a, b, c, d) {
850
+ return error(m, {
851
+ line: l,
852
+ from: ch
853
+ }, a, b, c, d);
854
+ }
855
+
856
+
857
+
858
+ // lexical analysis and token construction
859
+
860
+ var lex = (function lex() {
861
+ var character, from, line, s;
862
+
863
+ // Private lex methods
864
+
865
+ function nextLine() {
866
+ var at,
867
+ tw; // trailing whitespace check
868
+
869
+ if (line >= lines.length)
870
+ return false;
871
+
872
+ character = 1;
873
+ s = lines[line];
874
+ line += 1;
875
+ at = s.search(/ \t/);
876
+
877
+ if (at >= 0)
878
+ warningAt("Mixed spaces and tabs.", line, at + 1);
879
+
880
+ s = s.replace(/\t/g, tab);
881
+ at = s.search(cx);
882
+
883
+ if (at >= 0)
884
+ warningAt("Unsafe character.", line, at);
885
+
886
+ if (option.maxlen && option.maxlen < s.length)
887
+ warningAt("Line too long.", line, s.length);
888
+
889
+ // Check for trailing whitespaces
890
+ tw = s.search(/\s+$/);
891
+ if (option.trailing && ~tw && !~s.search(/^\s+$/))
892
+ warningAt("Trailing whitespace.", line, tw);
893
+
894
+ return true;
895
+ }
896
+
897
+ // Produce a token object. The token inherits from a syntax symbol.
898
+
899
+ function it(type, value) {
900
+ var i, t;
901
+ if (type === '(color)' || type === '(range)') {
902
+ t = {type: type};
903
+ } else if (type === '(punctuator)' ||
904
+ (type === '(identifier)' && is_own(syntax, value))) {
905
+ t = syntax[value] || syntax['(error)'];
906
+ } else {
907
+ t = syntax[type];
908
+ }
909
+ t = Object.create(t);
910
+ if (type === '(string)' || type === '(range)') {
911
+ if (!option.scripturl && jx.test(value)) {
912
+ warningAt("Script URL.", line, from);
913
+ }
914
+ }
915
+ if (type === '(identifier)') {
916
+ t.identifier = true;
917
+ if (value === '__iterator__' || value === '__proto__') {
918
+ errorAt("Reserved name '{a}'.",
919
+ line, from, value);
920
+ } else if (option.nomen &&
921
+ (value.charAt(0) === '_' ||
922
+ value.charAt(value.length - 1) === '_')) {
923
+ warningAt("Unexpected {a} in '{b}'.", line, from,
924
+ "dangling '_'", value);
925
+ }
926
+ }
927
+ t.value = value;
928
+ t.line = line;
929
+ t.character = character;
930
+ t.from = from;
931
+ i = t.id;
932
+ if (i !== '(endline)') {
933
+ prereg = i &&
934
+ (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) ||
935
+ i === 'return');
936
+ }
937
+ return t;
938
+ }
939
+
940
+ // Public lex methods
941
+
942
+ return {
943
+ init: function (source) {
944
+ if (typeof source === 'string') {
945
+ lines = source
946
+ .replace(/\r\n/g, '\n')
947
+ .replace(/\r/g, '\n')
948
+ .split('\n');
949
+ } else {
950
+ lines = source;
951
+ }
952
+
953
+ // If the first line is a shebang (#!), make it a blank and move on.
954
+ // Shebangs are used by Node scripts.
955
+ if (lines[0] && lines[0].substr(0, 2) == '#!')
956
+ lines[0] = '';
957
+
958
+ line = 0;
959
+ nextLine();
960
+ from = 1;
961
+ },
962
+
963
+ range: function (begin, end) {
964
+ var c, value = '';
965
+ from = character;
966
+ if (s.charAt(0) !== begin) {
967
+ errorAt("Expected '{a}' and instead saw '{b}'.",
968
+ line, character, begin, s.charAt(0));
969
+ }
970
+ for (;;) {
971
+ s = s.slice(1);
972
+ character += 1;
973
+ c = s.charAt(0);
974
+ switch (c) {
975
+ case '':
976
+ errorAt("Missing '{a}'.", line, character, c);
977
+ break;
978
+ case end:
979
+ s = s.slice(1);
980
+ character += 1;
981
+ return it('(range)', value);
982
+ case '\\':
983
+ warningAt("Unexpected '{a}'.", line, character, c);
984
+ }
985
+ value += c;
986
+ }
987
+
988
+ },
989
+
990
+ // token -- this is called by advance to get the next token.
991
+
992
+ token: function () {
993
+ var b, c, captures, d, depth, high, i, l, low, q, t;
994
+
995
+ function match(x) {
996
+ var r = x.exec(s), r1;
997
+ if (r) {
998
+ l = r[0].length;
999
+ r1 = r[1];
1000
+ c = r1.charAt(0);
1001
+ s = s.substr(l);
1002
+ from = character + l - r1.length;
1003
+ character += l;
1004
+ return r1;
1005
+ }
1006
+ }
1007
+
1008
+ function string(x) {
1009
+ var c, j, r = '';
1010
+
1011
+ if (jsonmode && x !== '"') {
1012
+ warningAt("Strings must use doublequote.",
1013
+ line, character);
1014
+ }
1015
+
1016
+ function esc(n) {
1017
+ var i = parseInt(s.substr(j + 1, n), 16);
1018
+ j += n;
1019
+ if (i >= 32 && i <= 126 &&
1020
+ i !== 34 && i !== 92 && i !== 39) {
1021
+ warningAt("Unnecessary escapement.", line, character);
1022
+ }
1023
+ character += n;
1024
+ c = String.fromCharCode(i);
1025
+ }
1026
+ j = 0;
1027
+ for (;;) {
1028
+ while (j >= s.length) {
1029
+ j = 0;
1030
+ if (!nextLine()) {
1031
+ errorAt("Unclosed string.", line, from);
1032
+ }
1033
+ }
1034
+ c = s.charAt(j);
1035
+ if (c === x) {
1036
+ character += 1;
1037
+ s = s.substr(j + 1);
1038
+ return it('(string)', r, x);
1039
+ }
1040
+ if (c < ' ') {
1041
+ if (c === '\n' || c === '\r') {
1042
+ break;
1043
+ }
1044
+ warningAt("Control character in string: {a}.",
1045
+ line, character + j, s.slice(0, j));
1046
+ } else if (c === '\\') {
1047
+ j += 1;
1048
+ character += 1;
1049
+ c = s.charAt(j);
1050
+ switch (c) {
1051
+ case '\\':
1052
+ case '"':
1053
+ case '/':
1054
+ break;
1055
+ case '\'':
1056
+ if (jsonmode) {
1057
+ warningAt("Avoid \\'.", line, character);
1058
+ }
1059
+ break;
1060
+ case 'b':
1061
+ c = '\b';
1062
+ break;
1063
+ case 'f':
1064
+ c = '\f';
1065
+ break;
1066
+ case 'n':
1067
+ c = '\n';
1068
+ break;
1069
+ case 'r':
1070
+ c = '\r';
1071
+ break;
1072
+ case 't':
1073
+ c = '\t';
1074
+ break;
1075
+ case 'u':
1076
+ esc(4);
1077
+ break;
1078
+ case 'v':
1079
+ if (jsonmode) {
1080
+ warningAt("Avoid \\v.", line, character);
1081
+ }
1082
+ c = '\v';
1083
+ break;
1084
+ case 'x':
1085
+ if (jsonmode) {
1086
+ warningAt("Avoid \\x-.", line, character);
1087
+ }
1088
+ esc(2);
1089
+ break;
1090
+ default:
1091
+ warningAt("Bad escapement.", line, character);
1092
+ }
1093
+ }
1094
+ r += c;
1095
+ character += 1;
1096
+ j += 1;
1097
+ }
1098
+ }
1099
+
1100
+ for (;;) {
1101
+ if (!s) {
1102
+ return it(nextLine() ? '(endline)' : '(end)', '');
1103
+ }
1104
+ t = match(tx);
1105
+ if (!t) {
1106
+ t = '';
1107
+ c = '';
1108
+ while (s && s < '!') {
1109
+ s = s.substr(1);
1110
+ }
1111
+ if (s) {
1112
+ errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
1113
+ }
1114
+ } else {
1115
+
1116
+ // identifier
1117
+
1118
+ if (c.isAlpha() || c === '_' || c === '$') {
1119
+ return it('(identifier)', t);
1120
+ }
1121
+
1122
+ // number
1123
+
1124
+ if (c.isDigit()) {
1125
+ if (!isFinite(Number(t))) {
1126
+ warningAt("Bad number '{a}'.",
1127
+ line, character, t);
1128
+ }
1129
+ if (s.substr(0, 1).isAlpha()) {
1130
+ warningAt("Missing space after '{a}'.",
1131
+ line, character, t);
1132
+ }
1133
+ if (c === '0') {
1134
+ d = t.substr(1, 1);
1135
+ if (d.isDigit()) {
1136
+ if (token.id !== '.') {
1137
+ warningAt("Don't use extra leading zeros '{a}'.",
1138
+ line, character, t);
1139
+ }
1140
+ } else if (jsonmode && (d === 'x' || d === 'X')) {
1141
+ warningAt("Avoid 0x-. '{a}'.",
1142
+ line, character, t);
1143
+ }
1144
+ }
1145
+ if (t.substr(t.length - 1) === '.') {
1146
+ warningAt(
1147
+ "A trailing decimal point can be confused with a dot '{a}'.", line, character, t);
1148
+ }
1149
+ return it('(number)', t);
1150
+ }
1151
+ switch (t) {
1152
+
1153
+ // string
1154
+
1155
+ case '"':
1156
+ case "'":
1157
+ return string(t);
1158
+
1159
+ // // comment
1160
+
1161
+ case '//':
1162
+ if (src) {
1163
+ warningAt("Unexpected comment.", line, character);
1164
+ }
1165
+ s = '';
1166
+ token.comment = true;
1167
+ break;
1168
+
1169
+ // /* comment
1170
+
1171
+ case '/*':
1172
+ if (src) {
1173
+ warningAt("Unexpected comment.", line, character);
1174
+ }
1175
+ for (;;) {
1176
+ i = s.search(lx);
1177
+ if (i >= 0) {
1178
+ break;
1179
+ }
1180
+ if (!nextLine()) {
1181
+ errorAt("Unclosed comment.", line, character);
1182
+ }
1183
+ }
1184
+ character += i + 2;
1185
+ if (s.substr(i, 1) === '/') {
1186
+ errorAt("Nested comment.", line, character);
1187
+ }
1188
+ s = s.substr(i + 2);
1189
+ token.comment = true;
1190
+ break;
1191
+
1192
+ // /*members /*jshint /*global
1193
+
1194
+ case '/*members':
1195
+ case '/*member':
1196
+ case '/*jshint':
1197
+ case '/*jslint':
1198
+ case '/*global':
1199
+ case '*/':
1200
+ return {
1201
+ value: t,
1202
+ type: 'special',
1203
+ line: line,
1204
+ character: character,
1205
+ from: from
1206
+ };
1207
+
1208
+ case '':
1209
+ break;
1210
+ // /
1211
+ case '/':
1212
+ if (token.id === '/=') {
1213
+ errorAt(
1214
+ "A regular expression literal can be confused with '/='.", line, from);
1215
+ }
1216
+ if (prereg) {
1217
+ depth = 0;
1218
+ captures = 0;
1219
+ l = 0;
1220
+ for (;;) {
1221
+ b = true;
1222
+ c = s.charAt(l);
1223
+ l += 1;
1224
+ switch (c) {
1225
+ case '':
1226
+ errorAt("Unclosed regular expression.",
1227
+ line, from);
1228
+ return;
1229
+ case '/':
1230
+ if (depth > 0) {
1231
+ warningAt("Unescaped '{a}'.",
1232
+ line, from + l, '/');
1233
+ }
1234
+ c = s.substr(0, l - 1);
1235
+ q = {
1236
+ g: true,
1237
+ i: true,
1238
+ m: true
1239
+ };
1240
+ while (q[s.charAt(l)] === true) {
1241
+ q[s.charAt(l)] = false;
1242
+ l += 1;
1243
+ }
1244
+ character += l;
1245
+ s = s.substr(l);
1246
+ q = s.charAt(0);
1247
+ if (q === '/' || q === '*') {
1248
+ errorAt("Confusing regular expression.",
1249
+ line, from);
1250
+ }
1251
+ return it('(regexp)', c);
1252
+ case '\\':
1253
+ c = s.charAt(l);
1254
+ if (c < ' ') {
1255
+ warningAt(
1256
+ "Unexpected control character in regular expression.", line, from + l);
1257
+ } else if (c === '<') {
1258
+ warningAt(
1259
+ "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1260
+ }
1261
+ l += 1;
1262
+ break;
1263
+ case '(':
1264
+ depth += 1;
1265
+ b = false;
1266
+ if (s.charAt(l) === '?') {
1267
+ l += 1;
1268
+ switch (s.charAt(l)) {
1269
+ case ':':
1270
+ case '=':
1271
+ case '!':
1272
+ l += 1;
1273
+ break;
1274
+ default:
1275
+ warningAt(
1276
+ "Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l));
1277
+ }
1278
+ } else {
1279
+ captures += 1;
1280
+ }
1281
+ break;
1282
+ case '|':
1283
+ b = false;
1284
+ break;
1285
+ case ')':
1286
+ if (depth === 0) {
1287
+ warningAt("Unescaped '{a}'.",
1288
+ line, from + l, ')');
1289
+ } else {
1290
+ depth -= 1;
1291
+ }
1292
+ break;
1293
+ case ' ':
1294
+ q = 1;
1295
+ while (s.charAt(l) === ' ') {
1296
+ l += 1;
1297
+ q += 1;
1298
+ }
1299
+ if (q > 1) {
1300
+ warningAt(
1301
+ "Spaces are hard to count. Use {{a}}.", line, from + l, q);
1302
+ }
1303
+ break;
1304
+ case '[':
1305
+ c = s.charAt(l);
1306
+ if (c === '^') {
1307
+ l += 1;
1308
+ if (option.regexp) {
1309
+ warningAt("Insecure '{a}'.",
1310
+ line, from + l, c);
1311
+ } else if (s.charAt(l) === ']') {
1312
+ errorAt("Unescaped '{a}'.",
1313
+ line, from + l, '^');
1314
+ }
1315
+ }
1316
+ q = false;
1317
+ if (c === ']') {
1318
+ warningAt("Empty class.", line,
1319
+ from + l - 1);
1320
+ q = true;
1321
+ }
1322
+ klass: do {
1323
+ c = s.charAt(l);
1324
+ l += 1;
1325
+ switch (c) {
1326
+ case '[':
1327
+ case '^':
1328
+ warningAt("Unescaped '{a}'.",
1329
+ line, from + l, c);
1330
+ q = true;
1331
+ break;
1332
+ case '-':
1333
+ if (q) {
1334
+ q = false;
1335
+ } else {
1336
+ warningAt("Unescaped '{a}'.",
1337
+ line, from + l, '-');
1338
+ q = true;
1339
+ }
1340
+ break;
1341
+ case ']':
1342
+ if (!q && !option.regexdash) {
1343
+ warningAt("Unescaped '{a}'.",
1344
+ line, from + l - 1, '-');
1345
+ }
1346
+ break klass;
1347
+ case '\\':
1348
+ c = s.charAt(l);
1349
+ if (c < ' ') {
1350
+ warningAt(
1351
+ "Unexpected control character in regular expression.", line, from + l);
1352
+ } else if (c === '<') {
1353
+ warningAt(
1354
+ "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1355
+ }
1356
+ l += 1;
1357
+ q = true;
1358
+ break;
1359
+ case '/':
1360
+ warningAt("Unescaped '{a}'.",
1361
+ line, from + l - 1, '/');
1362
+ q = true;
1363
+ break;
1364
+ case '<':
1365
+ q = true;
1366
+ break;
1367
+ default:
1368
+ q = true;
1369
+ }
1370
+ } while (c);
1371
+ break;
1372
+ case '.':
1373
+ if (option.regexp) {
1374
+ warningAt("Insecure '{a}'.", line,
1375
+ from + l, c);
1376
+ }
1377
+ break;
1378
+ case ']':
1379
+ case '?':
1380
+ case '{':
1381
+ case '}':
1382
+ case '+':
1383
+ case '*':
1384
+ warningAt("Unescaped '{a}'.", line,
1385
+ from + l, c);
1386
+ }
1387
+ if (b) {
1388
+ switch (s.charAt(l)) {
1389
+ case '?':
1390
+ case '+':
1391
+ case '*':
1392
+ l += 1;
1393
+ if (s.charAt(l) === '?') {
1394
+ l += 1;
1395
+ }
1396
+ break;
1397
+ case '{':
1398
+ l += 1;
1399
+ c = s.charAt(l);
1400
+ if (c < '0' || c > '9') {
1401
+ warningAt(
1402
+ "Expected a number and instead saw '{a}'.", line, from + l, c);
1403
+ }
1404
+ l += 1;
1405
+ low = +c;
1406
+ for (;;) {
1407
+ c = s.charAt(l);
1408
+ if (c < '0' || c > '9') {
1409
+ break;
1410
+ }
1411
+ l += 1;
1412
+ low = +c + (low * 10);
1413
+ }
1414
+ high = low;
1415
+ if (c === ',') {
1416
+ l += 1;
1417
+ high = Infinity;
1418
+ c = s.charAt(l);
1419
+ if (c >= '0' && c <= '9') {
1420
+ l += 1;
1421
+ high = +c;
1422
+ for (;;) {
1423
+ c = s.charAt(l);
1424
+ if (c < '0' || c > '9') {
1425
+ break;
1426
+ }
1427
+ l += 1;
1428
+ high = +c + (high * 10);
1429
+ }
1430
+ }
1431
+ }
1432
+ if (s.charAt(l) !== '}') {
1433
+ warningAt(
1434
+ "Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c);
1435
+ } else {
1436
+ l += 1;
1437
+ }
1438
+ if (s.charAt(l) === '?') {
1439
+ l += 1;
1440
+ }
1441
+ if (low > high) {
1442
+ warningAt(
1443
+ "'{a}' should not be greater than '{b}'.", line, from + l, low, high);
1444
+ }
1445
+ }
1446
+ }
1447
+ }
1448
+ c = s.substr(0, l - 1);
1449
+ character += l;
1450
+ s = s.substr(l);
1451
+ return it('(regexp)', c);
1452
+ }
1453
+ return it('(punctuator)', t);
1454
+
1455
+ // punctuator
1456
+
1457
+ case '#':
1458
+ return it('(punctuator)', t);
1459
+ default:
1460
+ return it('(punctuator)', t);
1461
+ }
1462
+ }
1463
+ }
1464
+ }
1465
+ };
1466
+ }());
1467
+
1468
+
1469
+ function addlabel(t, type) {
1470
+
1471
+ if (t === 'hasOwnProperty') {
1472
+ warning("'hasOwnProperty' is a really bad name.");
1473
+ }
1474
+
1475
+ // Define t in the current function in the current scope.
1476
+
1477
+ if (is_own(funct, t) && !funct['(global)']) {
1478
+ if (funct[t] === true) {
1479
+ if (option.latedef)
1480
+ warning("'{a}' was used before it was defined.", nexttoken, t);
1481
+ } else {
1482
+ if (!option.shadow)
1483
+ warning("'{a}' is already defined.", nexttoken, t);
1484
+ }
1485
+ }
1486
+
1487
+ funct[t] = type;
1488
+ if (funct['(global)']) {
1489
+ global[t] = funct;
1490
+ if (is_own(implied, t)) {
1491
+ if (option.latedef)
1492
+ warning("'{a}' was used before it was defined.", nexttoken, t);
1493
+ delete implied[t];
1494
+ }
1495
+ } else {
1496
+ scope[t] = funct;
1497
+ }
1498
+ }
1499
+
1500
+
1501
+ function doOption() {
1502
+ var b, obj, filter, o = nexttoken.value, t, v;
1503
+ switch (o) {
1504
+ case '*/':
1505
+ error("Unbegun comment.");
1506
+ break;
1507
+ case '/*members':
1508
+ case '/*member':
1509
+ o = '/*members';
1510
+ if (!membersOnly) {
1511
+ membersOnly = {};
1512
+ }
1513
+ obj = membersOnly;
1514
+ break;
1515
+ case '/*jshint':
1516
+ case '/*jslint':
1517
+ obj = option;
1518
+ filter = boolOptions;
1519
+ break;
1520
+ case '/*global':
1521
+ obj = predefined;
1522
+ break;
1523
+ default:
1524
+ error("What?");
1525
+ }
1526
+ t = lex.token();
1527
+ loop: for (;;) {
1528
+ for (;;) {
1529
+ if (t.type === 'special' && t.value === '*/') {
1530
+ break loop;
1531
+ }
1532
+ if (t.id !== '(endline)' && t.id !== ',') {
1533
+ break;
1534
+ }
1535
+ t = lex.token();
1536
+ }
1537
+ if (t.type !== '(string)' && t.type !== '(identifier)' &&
1538
+ o !== '/*members') {
1539
+ error("Bad option.", t);
1540
+ }
1541
+ v = lex.token();
1542
+ if (v.id === ':') {
1543
+ v = lex.token();
1544
+ if (obj === membersOnly) {
1545
+ error("Expected '{a}' and instead saw '{b}'.",
1546
+ t, '*/', ':');
1547
+ }
1548
+ if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) {
1549
+ b = +v.value;
1550
+ if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
1551
+ Math.floor(b) !== b) {
1552
+ error("Expected a small integer and instead saw '{a}'.",
1553
+ v, v.value);
1554
+ }
1555
+ obj.white = true;
1556
+ obj.indent = b;
1557
+ } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) {
1558
+ b = +v.value;
1559
+ if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
1560
+ Math.floor(b) !== b) {
1561
+ error("Expected a small integer and instead saw '{a}'.",
1562
+ v, v.value);
1563
+ }
1564
+ obj.maxerr = b;
1565
+ } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) {
1566
+ b = +v.value;
1567
+ if (typeof b !== 'number' || !isFinite(b) || b <= 0 ||
1568
+ Math.floor(b) !== b) {
1569
+ error("Expected a small integer and instead saw '{a}'.",
1570
+ v, v.value);
1571
+ }
1572
+ obj.maxlen = b;
1573
+ } else if (v.value === 'true') {
1574
+ obj[t.value] = true;
1575
+ } else if (v.value === 'false') {
1576
+ obj[t.value] = false;
1577
+ } else {
1578
+ error("Bad option value.", v);
1579
+ }
1580
+ t = lex.token();
1581
+ } else {
1582
+ if (o === '/*jshint' || o === '/*jslint') {
1583
+ error("Missing option value.", t);
1584
+ }
1585
+ obj[t.value] = false;
1586
+ t = v;
1587
+ }
1588
+ }
1589
+ if (filter) {
1590
+ assume();
1591
+ }
1592
+ }
1593
+
1594
+
1595
+ // We need a peek function. If it has an argument, it peeks that much farther
1596
+ // ahead. It is used to distinguish
1597
+ // for ( var i in ...
1598
+ // from
1599
+ // for ( var i = ...
1600
+
1601
+ function peek(p) {
1602
+ var i = p || 0, j = 0, t;
1603
+
1604
+ while (j <= i) {
1605
+ t = lookahead[j];
1606
+ if (!t) {
1607
+ t = lookahead[j] = lex.token();
1608
+ }
1609
+ j += 1;
1610
+ }
1611
+ return t;
1612
+ }
1613
+
1614
+
1615
+
1616
+ // Produce the next token. It looks for programming errors.
1617
+
1618
+ function advance(id, t) {
1619
+ switch (token.id) {
1620
+ case '(number)':
1621
+ if (nexttoken.id === '.') {
1622
+ warning("A dot following a number can be confused with a decimal point.", token);
1623
+ }
1624
+ break;
1625
+ case '-':
1626
+ if (nexttoken.id === '-' || nexttoken.id === '--') {
1627
+ warning("Confusing minusses.");
1628
+ }
1629
+ break;
1630
+ case '+':
1631
+ if (nexttoken.id === '+' || nexttoken.id === '++') {
1632
+ warning("Confusing plusses.");
1633
+ }
1634
+ break;
1635
+ }
1636
+ if (token.type === '(string)' || token.identifier) {
1637
+ anonname = token.value;
1638
+ }
1639
+
1640
+ if (id && nexttoken.id !== id) {
1641
+ if (t) {
1642
+ if (nexttoken.id === '(end)') {
1643
+ warning("Unmatched '{a}'.", t, t.id);
1644
+ } else {
1645
+ warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
1646
+ nexttoken, id, t.id, t.line, nexttoken.value);
1647
+ }
1648
+ } else if (nexttoken.type !== '(identifier)' ||
1649
+ nexttoken.value !== id) {
1650
+ warning("Expected '{a}' and instead saw '{b}'.",
1651
+ nexttoken, id, nexttoken.value);
1652
+ }
1653
+ }
1654
+ prevtoken = token;
1655
+ token = nexttoken;
1656
+ for (;;) {
1657
+ nexttoken = lookahead.shift() || lex.token();
1658
+ if (nexttoken.id === '(end)' || nexttoken.id === '(error)') {
1659
+ return;
1660
+ }
1661
+ if (nexttoken.type === 'special') {
1662
+ doOption();
1663
+ } else {
1664
+ if (nexttoken.id !== '(endline)') {
1665
+ break;
1666
+ }
1667
+ }
1668
+ }
1669
+ }
1670
+
1671
+
1672
+ // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
1673
+ // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
1674
+ // like .nud except that it is only used on the first token of a statement.
1675
+ // Having .fud makes it much easier to define statement-oriented languages like
1676
+ // JavaScript. I retained Pratt's nomenclature.
1677
+
1678
+ // .nud Null denotation
1679
+ // .fud First null denotation
1680
+ // .led Left denotation
1681
+ // lbp Left binding power
1682
+ // rbp Right binding power
1683
+
1684
+ // They are elements of the parsing method called Top Down Operator Precedence.
1685
+
1686
+ function expression(rbp, initial) {
1687
+ var left, isArray = false;
1688
+
1689
+ if (nexttoken.id === '(end)')
1690
+ error("Unexpected early end of program.", token);
1691
+
1692
+ advance();
1693
+ if (initial) {
1694
+ anonname = 'anonymous';
1695
+ funct['(verb)'] = token.value;
1696
+ }
1697
+ if (initial === true && token.fud) {
1698
+ left = token.fud();
1699
+ } else {
1700
+ if (token.nud) {
1701
+ left = token.nud();
1702
+ } else {
1703
+ if (nexttoken.type === '(number)' && token.id === '.') {
1704
+ warning("A leading decimal point can be confused with a dot: '.{a}'.",
1705
+ token, nexttoken.value);
1706
+ advance();
1707
+ return token;
1708
+ } else {
1709
+ error("Expected an identifier and instead saw '{a}'.",
1710
+ token, token.id);
1711
+ }
1712
+ }
1713
+ while (rbp < nexttoken.lbp) {
1714
+ isArray = token.value == 'Array';
1715
+ advance();
1716
+ if (isArray && token.id == '(' && nexttoken.id == ')')
1717
+ warning("Use the array literal notation [].", token);
1718
+ if (token.led) {
1719
+ left = token.led(left);
1720
+ } else {
1721
+ error("Expected an operator and instead saw '{a}'.",
1722
+ token, token.id);
1723
+ }
1724
+ }
1725
+ }
1726
+ return left;
1727
+ }
1728
+
1729
+
1730
+ // Functions for conformance of style.
1731
+
1732
+ function adjacent(left, right) {
1733
+ left = left || token;
1734
+ right = right || nexttoken;
1735
+ if (option.white) {
1736
+ if (left.character !== right.from && left.line === right.line) {
1737
+ warning("Unexpected space after '{a}'.", right, left.value);
1738
+ }
1739
+ }
1740
+ }
1741
+
1742
+ function nobreak(left, right) {
1743
+ left = left || token;
1744
+ right = right || nexttoken;
1745
+ if (option.white && (left.character !== right.from || left.line !== right.line)) {
1746
+ warning("Unexpected space before '{a}'.", right, right.value);
1747
+ }
1748
+ }
1749
+
1750
+ function nospace(left, right) {
1751
+ left = left || token;
1752
+ right = right || nexttoken;
1753
+ if (option.white && !left.comment) {
1754
+ if (left.line === right.line) {
1755
+ adjacent(left, right);
1756
+ }
1757
+ }
1758
+ }
1759
+
1760
+ function nonadjacent(left, right) {
1761
+ if (option.white) {
1762
+ left = left || token;
1763
+ right = right || nexttoken;
1764
+ if (left.line === right.line && left.character === right.from) {
1765
+ warning("Missing space after '{a}'.",
1766
+ nexttoken, left.value);
1767
+ }
1768
+ }
1769
+ }
1770
+
1771
+ function nobreaknonadjacent(left, right) {
1772
+ left = left || token;
1773
+ right = right || nexttoken;
1774
+ if (!option.laxbreak && left.line !== right.line) {
1775
+ warning("Bad line breaking before '{a}'.", right, right.id);
1776
+ } else if (option.white) {
1777
+ left = left || token;
1778
+ right = right || nexttoken;
1779
+ if (left.character === right.from) {
1780
+ warning("Missing space after '{a}'.",
1781
+ nexttoken, left.value);
1782
+ }
1783
+ }
1784
+ }
1785
+
1786
+ function indentation(bias) {
1787
+ var i;
1788
+ if (option.white && nexttoken.id !== '(end)') {
1789
+ i = indent + (bias || 0);
1790
+ if (nexttoken.from !== i) {
1791
+ warning(
1792
+ "Expected '{a}' to have an indentation at {b} instead at {c}.",
1793
+ nexttoken, nexttoken.value, i, nexttoken.from);
1794
+ }
1795
+ }
1796
+ }
1797
+
1798
+ function nolinebreak(t) {
1799
+ t = t || token;
1800
+ if (t.line !== nexttoken.line) {
1801
+ warning("Line breaking error '{a}'.", t, t.value);
1802
+ }
1803
+ }
1804
+
1805
+
1806
+ function comma() {
1807
+ if (token.line !== nexttoken.line) {
1808
+ if (!option.laxbreak) {
1809
+ warning("Bad line breaking before '{a}'.", token, nexttoken.id);
1810
+ }
1811
+ } else if (token.character !== nexttoken.from && option.white) {
1812
+ warning("Unexpected space after '{a}'.", nexttoken, token.value);
1813
+ }
1814
+ advance(',');
1815
+ nonadjacent(token, nexttoken);
1816
+ }
1817
+
1818
+
1819
+ // Functional constructors for making the symbols that will be inherited by
1820
+ // tokens.
1821
+
1822
+ function symbol(s, p) {
1823
+ var x = syntax[s];
1824
+ if (!x || typeof x !== 'object') {
1825
+ syntax[s] = x = {
1826
+ id: s,
1827
+ lbp: p,
1828
+ value: s
1829
+ };
1830
+ }
1831
+ return x;
1832
+ }
1833
+
1834
+
1835
+ function delim(s) {
1836
+ return symbol(s, 0);
1837
+ }
1838
+
1839
+
1840
+ function stmt(s, f) {
1841
+ var x = delim(s);
1842
+ x.identifier = x.reserved = true;
1843
+ x.fud = f;
1844
+ return x;
1845
+ }
1846
+
1847
+
1848
+ function blockstmt(s, f) {
1849
+ var x = stmt(s, f);
1850
+ x.block = true;
1851
+ return x;
1852
+ }
1853
+
1854
+
1855
+ function reserveName(x) {
1856
+ var c = x.id.charAt(0);
1857
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
1858
+ x.identifier = x.reserved = true;
1859
+ }
1860
+ return x;
1861
+ }
1862
+
1863
+
1864
+ function prefix(s, f) {
1865
+ var x = symbol(s, 150);
1866
+ reserveName(x);
1867
+ x.nud = (typeof f === 'function') ? f : function () {
1868
+ this.right = expression(150);
1869
+ this.arity = 'unary';
1870
+ if (this.id === '++' || this.id === '--') {
1871
+ if (option.plusplus) {
1872
+ warning("Unexpected use of '{a}'.", this, this.id);
1873
+ } else if ((!this.right.identifier || this.right.reserved) &&
1874
+ this.right.id !== '.' && this.right.id !== '[') {
1875
+ warning("Bad operand.", this);
1876
+ }
1877
+ }
1878
+ return this;
1879
+ };
1880
+ return x;
1881
+ }
1882
+
1883
+
1884
+ function type(s, f) {
1885
+ var x = delim(s);
1886
+ x.type = s;
1887
+ x.nud = f;
1888
+ return x;
1889
+ }
1890
+
1891
+
1892
+ function reserve(s, f) {
1893
+ var x = type(s, f);
1894
+ x.identifier = x.reserved = true;
1895
+ return x;
1896
+ }
1897
+
1898
+
1899
+ function reservevar(s, v) {
1900
+ return reserve(s, function () {
1901
+ if (typeof v === 'function') {
1902
+ v(this);
1903
+ }
1904
+ return this;
1905
+ });
1906
+ }
1907
+
1908
+
1909
+ function infix(s, f, p, w) {
1910
+ var x = symbol(s, p);
1911
+ reserveName(x);
1912
+ x.led = function (left) {
1913
+ if (!w) {
1914
+ nobreaknonadjacent(prevtoken, token);
1915
+ nonadjacent(token, nexttoken);
1916
+ }
1917
+ if (typeof f === 'function') {
1918
+ return f(left, this);
1919
+ } else {
1920
+ this.left = left;
1921
+ this.right = expression(p);
1922
+ return this;
1923
+ }
1924
+ };
1925
+ return x;
1926
+ }
1927
+
1928
+
1929
+ function relation(s, f) {
1930
+ var x = symbol(s, 100);
1931
+ x.led = function (left) {
1932
+ nobreaknonadjacent(prevtoken, token);
1933
+ nonadjacent(token, nexttoken);
1934
+ var right = expression(100);
1935
+ if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) {
1936
+ warning("Use the isNaN function to compare with NaN.", this);
1937
+ } else if (f) {
1938
+ f.apply(this, [left, right]);
1939
+ }
1940
+ if (left.id === '!') {
1941
+ warning("Confusing use of '{a}'.", left, '!');
1942
+ }
1943
+ if (right.id === '!') {
1944
+ warning("Confusing use of '{a}'.", left, '!');
1945
+ }
1946
+ this.left = left;
1947
+ this.right = right;
1948
+ return this;
1949
+ };
1950
+ return x;
1951
+ }
1952
+
1953
+
1954
+ function isPoorRelation(node) {
1955
+ return node &&
1956
+ ((node.type === '(number)' && +node.value === 0) ||
1957
+ (node.type === '(string)' && node.value === '') ||
1958
+ (node.type === 'null' && !option.eqnull) ||
1959
+ node.type === 'true' ||
1960
+ node.type === 'false' ||
1961
+ node.type === 'undefined');
1962
+ }
1963
+
1964
+
1965
+ function assignop(s, f) {
1966
+ symbol(s, 20).exps = true;
1967
+ return infix(s, function (left, that) {
1968
+ var l;
1969
+ that.left = left;
1970
+ if (predefined[left.value] === false &&
1971
+ scope[left.value]['(global)'] === true) {
1972
+ warning("Read only.", left);
1973
+ } else if (left['function']) {
1974
+ warning("'{a}' is a function.", left, left.value);
1975
+ }
1976
+ if (left) {
1977
+ if (left.id === '.' || left.id === '[') {
1978
+ if (!left.left || left.left.value === 'arguments') {
1979
+ warning('Bad assignment.', that);
1980
+ }
1981
+ that.right = expression(19);
1982
+ return that;
1983
+ } else if (left.identifier && !left.reserved) {
1984
+ if (funct[left.value] === 'exception') {
1985
+ warning("Do not assign to the exception parameter.", left);
1986
+ }
1987
+ that.right = expression(19);
1988
+ return that;
1989
+ }
1990
+ if (left === syntax['function']) {
1991
+ warning(
1992
+ "Expected an identifier in an assignment and instead saw a function invocation.",
1993
+ token);
1994
+ }
1995
+ }
1996
+ error("Bad assignment.", that);
1997
+ }, 20);
1998
+ }
1999
+
2000
+
2001
+ function bitwise(s, f, p) {
2002
+ var x = symbol(s, p);
2003
+ reserveName(x);
2004
+ x.led = (typeof f === 'function') ? f : function (left) {
2005
+ if (option.bitwise) {
2006
+ warning("Unexpected use of '{a}'.", this, this.id);
2007
+ }
2008
+ this.left = left;
2009
+ this.right = expression(p);
2010
+ return this;
2011
+ };
2012
+ return x;
2013
+ }
2014
+
2015
+
2016
+ function bitwiseassignop(s) {
2017
+ symbol(s, 20).exps = true;
2018
+ return infix(s, function (left, that) {
2019
+ if (option.bitwise) {
2020
+ warning("Unexpected use of '{a}'.", that, that.id);
2021
+ }
2022
+ nonadjacent(prevtoken, token);
2023
+ nonadjacent(token, nexttoken);
2024
+ if (left) {
2025
+ if (left.id === '.' || left.id === '[' ||
2026
+ (left.identifier && !left.reserved)) {
2027
+ expression(19);
2028
+ return that;
2029
+ }
2030
+ if (left === syntax['function']) {
2031
+ warning(
2032
+ "Expected an identifier in an assignment, and instead saw a function invocation.",
2033
+ token);
2034
+ }
2035
+ return that;
2036
+ }
2037
+ error("Bad assignment.", that);
2038
+ }, 20);
2039
+ }
2040
+
2041
+
2042
+ function suffix(s, f) {
2043
+ var x = symbol(s, 150);
2044
+ x.led = function (left) {
2045
+ if (option.plusplus) {
2046
+ warning("Unexpected use of '{a}'.", this, this.id);
2047
+ } else if ((!left.identifier || left.reserved) &&
2048
+ left.id !== '.' && left.id !== '[') {
2049
+ warning("Bad operand.", this);
2050
+ }
2051
+ this.left = left;
2052
+ return this;
2053
+ };
2054
+ return x;
2055
+ }
2056
+
2057
+
2058
+ // fnparam means that this identifier is being defined as a function
2059
+ // argument (see identifier())
2060
+ function optionalidentifier(fnparam) {
2061
+ if (nexttoken.identifier) {
2062
+ advance();
2063
+ if (token.reserved && !option.es5) {
2064
+ // `undefined` as a function param is a common pattern to protect
2065
+ // against the case when somebody does `undefined = true` and
2066
+ // help with minification. More info: https://gist.github.com/315916
2067
+ if (!fnparam || token.value != 'undefined') {
2068
+ warning("Expected an identifier and instead saw '{a}' (a reserved word).",
2069
+ token, token.id);
2070
+ }
2071
+ }
2072
+ return token.value;
2073
+ }
2074
+ }
2075
+
2076
+ // fnparam means that this identifier is being defined as a function
2077
+ // argument
2078
+ function identifier(fnparam) {
2079
+ var i = optionalidentifier(fnparam);
2080
+ if (i) {
2081
+ return i;
2082
+ }
2083
+ if (token.id === 'function' && nexttoken.id === '(') {
2084
+ warning("Missing name in function declaration.");
2085
+ } else {
2086
+ error("Expected an identifier and instead saw '{a}'.",
2087
+ nexttoken, nexttoken.value);
2088
+ }
2089
+ }
2090
+
2091
+
2092
+ function reachable(s) {
2093
+ var i = 0, t;
2094
+ if (nexttoken.id !== ';' || noreach) {
2095
+ return;
2096
+ }
2097
+ for (;;) {
2098
+ t = peek(i);
2099
+ if (t.reach) {
2100
+ return;
2101
+ }
2102
+ if (t.id !== '(endline)') {
2103
+ if (t.id === 'function') {
2104
+ warning(
2105
+ "Inner functions should be listed at the top of the outer function.", t);
2106
+ break;
2107
+ }
2108
+ warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
2109
+ break;
2110
+ }
2111
+ i += 1;
2112
+ }
2113
+ }
2114
+
2115
+
2116
+ function statement(noindent) {
2117
+ var i = indent, r, s = scope, t = nexttoken;
2118
+
2119
+ // We don't like the empty statement.
2120
+
2121
+ if (t.id === ';') {
2122
+ warning("Unnecessary semicolon.", t);
2123
+ advance(';');
2124
+ return;
2125
+ }
2126
+
2127
+ // Is this a labelled statement?
2128
+
2129
+ if (t.identifier && !t.reserved && peek().id === ':') {
2130
+ advance();
2131
+ advance(':');
2132
+ scope = Object.create(s);
2133
+ addlabel(t.value, 'label');
2134
+ if (!nexttoken.labelled) {
2135
+ warning("Label '{a}' on {b} statement.",
2136
+ nexttoken, t.value, nexttoken.value);
2137
+ }
2138
+ if (jx.test(t.value + ':')) {
2139
+ warning("Label '{a}' looks like a javascript url.",
2140
+ t, t.value);
2141
+ }
2142
+ nexttoken.label = t.value;
2143
+ t = nexttoken;
2144
+ }
2145
+
2146
+ // Parse the statement.
2147
+
2148
+ if (!noindent) {
2149
+ indentation();
2150
+ }
2151
+ r = expression(0, true);
2152
+
2153
+ // Look for the final semicolon.
2154
+
2155
+ if (!t.block) {
2156
+ if (!option.expr && (!r || !r.exps)) {
2157
+ warning("Expected an assignment or function call and instead saw an expression.", token);
2158
+ } else if (option.nonew && r.id === '(' && r.left.id === 'new') {
2159
+ warning("Do not use 'new' for side effects.");
2160
+ }
2161
+ if (nexttoken.id !== ';') {
2162
+ if (!option.asi && !(option.lastsemic && nexttoken.id == '}' && nexttoken.line == token.line)) {
2163
+ warningAt("Missing semicolon.", token.line, token.from + token.value.length);
2164
+ }
2165
+ } else {
2166
+ adjacent(token, nexttoken);
2167
+ advance(';');
2168
+ nonadjacent(token, nexttoken);
2169
+ }
2170
+ }
2171
+
2172
+ // Restore the indentation.
2173
+
2174
+ indent = i;
2175
+ scope = s;
2176
+ return r;
2177
+ }
2178
+
2179
+
2180
+ function use_strict() {
2181
+ if (nexttoken.value === 'use strict') {
2182
+ if (strict_mode) {
2183
+ warning("Unnecessary \"use strict\".");
2184
+ }
2185
+ advance();
2186
+ advance(';');
2187
+ strict_mode = true;
2188
+ option.newcap = true;
2189
+ option.undef = true;
2190
+ return true;
2191
+ } else {
2192
+ return false;
2193
+ }
2194
+ }
2195
+
2196
+
2197
+ function statements(begin) {
2198
+ var a = [], f, p;
2199
+
2200
+ while (!nexttoken.reach && nexttoken.id !== '(end)') {
2201
+ if (nexttoken.id === ';') {
2202
+ warning("Unnecessary semicolon.");
2203
+ advance(';');
2204
+ } else {
2205
+ a.push(statement());
2206
+ }
2207
+ }
2208
+ return a;
2209
+ }
2210
+
2211
+
2212
+ /*
2213
+ * Parses a single block. A block is a sequence of statements wrapped in
2214
+ * braces.
2215
+ *
2216
+ * ordinary - true for everything but function bodies and try blocks.
2217
+ * stmt - true if block can be a single statement (e.g. in if/for/while).
2218
+ */
2219
+ function block(ordinary, stmt) {
2220
+ var a,
2221
+ b = inblock,
2222
+ old_indent = indent,
2223
+ m = strict_mode,
2224
+ s = scope,
2225
+ t;
2226
+
2227
+ inblock = ordinary;
2228
+ scope = Object.create(scope);
2229
+ nonadjacent(token, nexttoken);
2230
+ t = nexttoken;
2231
+
2232
+ if (nexttoken.id === '{') {
2233
+ advance('{');
2234
+ if (nexttoken.id !== '}' || token.line !== nexttoken.line) {
2235
+ indent += option.indent;
2236
+ while (!ordinary && nexttoken.from > indent) {
2237
+ indent += option.indent;
2238
+ }
2239
+ if (!ordinary && !use_strict() && !m && option.strict &&
2240
+ funct['(context)']['(global)']) {
2241
+ warning("Missing \"use strict\" statement.");
2242
+ }
2243
+ a = statements();
2244
+ strict_mode = m;
2245
+ indent -= option.indent;
2246
+ indentation();
2247
+ }
2248
+ advance('}', t);
2249
+ indent = old_indent;
2250
+ } else if (!ordinary) {
2251
+ error("Expected '{a}' and instead saw '{b}'.",
2252
+ nexttoken, '{', nexttoken.value);
2253
+ } else {
2254
+ if (!stmt || option.curly)
2255
+ warning("Expected '{a}' and instead saw '{b}'.",
2256
+ nexttoken, '{', nexttoken.value);
2257
+
2258
+ noreach = true;
2259
+ a = [statement()];
2260
+ noreach = false;
2261
+ }
2262
+ funct['(verb)'] = null;
2263
+ scope = s;
2264
+ inblock = b;
2265
+ if (ordinary && option.noempty && (!a || a.length === 0)) {
2266
+ warning("Empty block.");
2267
+ }
2268
+ return a;
2269
+ }
2270
+
2271
+
2272
+ function countMember(m) {
2273
+ if (membersOnly && typeof membersOnly[m] !== 'boolean') {
2274
+ warning("Unexpected /*member '{a}'.", token, m);
2275
+ }
2276
+ if (typeof member[m] === 'number') {
2277
+ member[m] += 1;
2278
+ } else {
2279
+ member[m] = 1;
2280
+ }
2281
+ }
2282
+
2283
+
2284
+ function note_implied(token) {
2285
+ var name = token.value, line = token.line, a = implied[name];
2286
+ if (typeof a === 'function') {
2287
+ a = false;
2288
+ }
2289
+ if (!a) {
2290
+ a = [line];
2291
+ implied[name] = a;
2292
+ } else if (a[a.length - 1] !== line) {
2293
+ a.push(line);
2294
+ }
2295
+ }
2296
+
2297
+ // Build the syntax table by declaring the syntactic elements of the language.
2298
+
2299
+ type('(number)', function () {
2300
+ return this;
2301
+ });
2302
+ type('(string)', function () {
2303
+ return this;
2304
+ });
2305
+
2306
+ syntax['(identifier)'] = {
2307
+ type: '(identifier)',
2308
+ lbp: 0,
2309
+ identifier: true,
2310
+ nud: function () {
2311
+ var v = this.value,
2312
+ s = scope[v],
2313
+ f;
2314
+ if (typeof s === 'function') {
2315
+
2316
+ // Protection against accidental inheritance.
2317
+
2318
+ s = undefined;
2319
+ } else if (typeof s === 'boolean') {
2320
+ f = funct;
2321
+ funct = functions[0];
2322
+ addlabel(v, 'var');
2323
+ s = funct;
2324
+ funct = f;
2325
+ }
2326
+
2327
+ // The name is in scope and defined in the current function.
2328
+
2329
+ if (funct === s) {
2330
+
2331
+ // Change 'unused' to 'var', and reject labels.
2332
+
2333
+ switch (funct[v]) {
2334
+ case 'unused':
2335
+ funct[v] = 'var';
2336
+ break;
2337
+ case 'unction':
2338
+ funct[v] = 'function';
2339
+ this['function'] = true;
2340
+ break;
2341
+ case 'function':
2342
+ this['function'] = true;
2343
+ break;
2344
+ case 'label':
2345
+ warning("'{a}' is a statement label.", token, v);
2346
+ break;
2347
+ }
2348
+
2349
+ // The name is not defined in the function. If we are in the global scope,
2350
+ // then we have an undefined variable.
2351
+ //
2352
+ // Operators typeof and delete do not raise runtime errors even if the base
2353
+ // object of a reference is null so no need to display warning if we're
2354
+ // inside of typeof or delete.
2355
+
2356
+ } else if (funct['(global)']) {
2357
+ if (anonname != 'typeof' && anonname != 'delete' &&
2358
+ option.undef && typeof predefined[v] !== 'boolean') {
2359
+ warning("'{a}' is not defined.", token, v);
2360
+ }
2361
+ note_implied(token);
2362
+
2363
+ // If the name is already defined in the current
2364
+ // function, but not as outer, then there is a scope error.
2365
+
2366
+ } else {
2367
+ switch (funct[v]) {
2368
+ case 'closure':
2369
+ case 'function':
2370
+ case 'var':
2371
+ case 'unused':
2372
+ warning("'{a}' used out of scope.", token, v);
2373
+ break;
2374
+ case 'label':
2375
+ warning("'{a}' is a statement label.", token, v);
2376
+ break;
2377
+ case 'outer':
2378
+ case 'global':
2379
+ break;
2380
+ default:
2381
+
2382
+ // If the name is defined in an outer function, make an outer entry, and if
2383
+ // it was unused, make it var.
2384
+
2385
+ if (s === true) {
2386
+ funct[v] = true;
2387
+ } else if (s === null) {
2388
+ warning("'{a}' is not allowed.", token, v);
2389
+ note_implied(token);
2390
+ } else if (typeof s !== 'object') {
2391
+
2392
+ // Operators typeof and delete do not raise runtime errors even if the base object of
2393
+ // a reference is null so no need to display warning if we're inside of typeof or delete.
2394
+
2395
+ if (anonname != 'typeof' && anonname != 'delete' && option.undef) {
2396
+ warning("'{a}' is not defined.", token, v);
2397
+ } else {
2398
+ funct[v] = true;
2399
+ }
2400
+ note_implied(token);
2401
+ } else {
2402
+ switch (s[v]) {
2403
+ case 'function':
2404
+ case 'unction':
2405
+ this['function'] = true;
2406
+ s[v] = 'closure';
2407
+ funct[v] = s['(global)'] ? 'global' : 'outer';
2408
+ break;
2409
+ case 'var':
2410
+ case 'unused':
2411
+ s[v] = 'closure';
2412
+ funct[v] = s['(global)'] ? 'global' : 'outer';
2413
+ break;
2414
+ case 'closure':
2415
+ case 'parameter':
2416
+ funct[v] = s['(global)'] ? 'global' : 'outer';
2417
+ break;
2418
+ case 'label':
2419
+ warning("'{a}' is a statement label.", token, v);
2420
+ }
2421
+ }
2422
+ }
2423
+ }
2424
+ return this;
2425
+ },
2426
+ led: function () {
2427
+ error("Expected an operator and instead saw '{a}'.",
2428
+ nexttoken, nexttoken.value);
2429
+ }
2430
+ };
2431
+
2432
+ type('(regexp)', function () {
2433
+ return this;
2434
+ });
2435
+
2436
+
2437
+ // ECMAScript parser
2438
+
2439
+ delim('(endline)');
2440
+ delim('(begin)');
2441
+ delim('(end)').reach = true;
2442
+ delim('</').reach = true;
2443
+ delim('<!');
2444
+ delim('<!--');
2445
+ delim('-->');
2446
+ delim('(error)').reach = true;
2447
+ delim('}').reach = true;
2448
+ delim(')');
2449
+ delim(']');
2450
+ delim('"').reach = true;
2451
+ delim("'").reach = true;
2452
+ delim(';');
2453
+ delim(':').reach = true;
2454
+ delim(',');
2455
+ delim('#');
2456
+ delim('@');
2457
+ reserve('else');
2458
+ reserve('case').reach = true;
2459
+ reserve('catch');
2460
+ reserve('default').reach = true;
2461
+ reserve('finally');
2462
+ reservevar('arguments', function (x) {
2463
+ if (strict_mode && funct['(global)']) {
2464
+ warning("Strict violation.", x);
2465
+ }
2466
+ });
2467
+ reservevar('eval');
2468
+ reservevar('false');
2469
+ reservevar('Infinity');
2470
+ reservevar('NaN');
2471
+ reservevar('null');
2472
+ reservevar('this', function (x) {
2473
+ if (strict_mode && ((funct['(statement)'] &&
2474
+ funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) {
2475
+ warning("Strict violation.", x);
2476
+ }
2477
+ });
2478
+ reservevar('true');
2479
+ reservevar('undefined');
2480
+ assignop('=', 'assign', 20);
2481
+ assignop('+=', 'assignadd', 20);
2482
+ assignop('-=', 'assignsub', 20);
2483
+ assignop('*=', 'assignmult', 20);
2484
+ assignop('/=', 'assigndiv', 20).nud = function () {
2485
+ error("A regular expression literal can be confused with '/='.");
2486
+ };
2487
+ assignop('%=', 'assignmod', 20);
2488
+ bitwiseassignop('&=', 'assignbitand', 20);
2489
+ bitwiseassignop('|=', 'assignbitor', 20);
2490
+ bitwiseassignop('^=', 'assignbitxor', 20);
2491
+ bitwiseassignop('<<=', 'assignshiftleft', 20);
2492
+ bitwiseassignop('>>=', 'assignshiftright', 20);
2493
+ bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20);
2494
+ infix('?', function (left, that) {
2495
+ that.left = left;
2496
+ that.right = expression(10);
2497
+ advance(':');
2498
+ that['else'] = expression(10);
2499
+ return that;
2500
+ }, 30);
2501
+
2502
+ infix('||', 'or', 40);
2503
+ infix('&&', 'and', 50);
2504
+ bitwise('|', 'bitor', 70);
2505
+ bitwise('^', 'bitxor', 80);
2506
+ bitwise('&', 'bitand', 90);
2507
+ relation('==', function (left, right) {
2508
+ var eqnull = option.eqnull &&
2509
+ (left.value == 'null' || right.value == 'null');
2510
+
2511
+ if (!eqnull && option.eqeqeq) {
2512
+ warning("Expected '{a}' and instead saw '{b}'.",
2513
+ this, '===', '==');
2514
+ } else if (isPoorRelation(left)) {
2515
+ warning("Use '{a}' to compare with '{b}'.",
2516
+ this, '===', left.value);
2517
+ } else if (isPoorRelation(right)) {
2518
+ warning("Use '{a}' to compare with '{b}'.",
2519
+ this, '===', right.value);
2520
+ }
2521
+ return this;
2522
+ });
2523
+ relation('===');
2524
+ relation('!=', function (left, right) {
2525
+ if (option.eqeqeq) {
2526
+ warning("Expected '{a}' and instead saw '{b}'.",
2527
+ this, '!==', '!=');
2528
+ } else if (isPoorRelation(left)) {
2529
+ warning("Use '{a}' to compare with '{b}'.",
2530
+ this, '!==', left.value);
2531
+ } else if (isPoorRelation(right)) {
2532
+ warning("Use '{a}' to compare with '{b}'.",
2533
+ this, '!==', right.value);
2534
+ }
2535
+ return this;
2536
+ });
2537
+ relation('!==');
2538
+ relation('<');
2539
+ relation('>');
2540
+ relation('<=');
2541
+ relation('>=');
2542
+ bitwise('<<', 'shiftleft', 120);
2543
+ bitwise('>>', 'shiftright', 120);
2544
+ bitwise('>>>', 'shiftrightunsigned', 120);
2545
+ infix('in', 'in', 120);
2546
+ infix('instanceof', 'instanceof', 120);
2547
+ infix('+', function (left, that) {
2548
+ var right = expression(130);
2549
+ if (left && right && left.id === '(string)' && right.id === '(string)') {
2550
+ left.value += right.value;
2551
+ left.character = right.character;
2552
+ if (!option.scripturl && jx.test(left.value)) {
2553
+ warning("JavaScript URL.", left);
2554
+ }
2555
+ return left;
2556
+ }
2557
+ that.left = left;
2558
+ that.right = right;
2559
+ return that;
2560
+ }, 130);
2561
+ prefix('+', 'num');
2562
+ prefix('+++', function () {
2563
+ warning("Confusing pluses.");
2564
+ this.right = expression(150);
2565
+ this.arity = 'unary';
2566
+ return this;
2567
+ });
2568
+ infix('+++', function (left) {
2569
+ warning("Confusing pluses.");
2570
+ this.left = left;
2571
+ this.right = expression(130);
2572
+ return this;
2573
+ }, 130);
2574
+ infix('-', 'sub', 130);
2575
+ prefix('-', 'neg');
2576
+ prefix('---', function () {
2577
+ warning("Confusing minuses.");
2578
+ this.right = expression(150);
2579
+ this.arity = 'unary';
2580
+ return this;
2581
+ });
2582
+ infix('---', function (left) {
2583
+ warning("Confusing minuses.");
2584
+ this.left = left;
2585
+ this.right = expression(130);
2586
+ return this;
2587
+ }, 130);
2588
+ infix('*', 'mult', 140);
2589
+ infix('/', 'div', 140);
2590
+ infix('%', 'mod', 140);
2591
+
2592
+ suffix('++', 'postinc');
2593
+ prefix('++', 'preinc');
2594
+ syntax['++'].exps = true;
2595
+
2596
+ suffix('--', 'postdec');
2597
+ prefix('--', 'predec');
2598
+ syntax['--'].exps = true;
2599
+ prefix('delete', function () {
2600
+ var p = expression(0);
2601
+ if (!p || (p.id !== '.' && p.id !== '[')) {
2602
+ warning("Variables should not be deleted.");
2603
+ }
2604
+ this.first = p;
2605
+ return this;
2606
+ }).exps = true;
2607
+
2608
+ prefix('~', function () {
2609
+ if (option.bitwise) {
2610
+ warning("Unexpected '{a}'.", this, '~');
2611
+ }
2612
+ expression(150);
2613
+ return this;
2614
+ });
2615
+
2616
+ prefix('!', function () {
2617
+ this.right = expression(150);
2618
+ this.arity = 'unary';
2619
+ if (bang[this.right.id] === true) {
2620
+ warning("Confusing use of '{a}'.", this, '!');
2621
+ }
2622
+ return this;
2623
+ });
2624
+ prefix('typeof', 'typeof');
2625
+ prefix('new', function () {
2626
+ var c = expression(155), i;
2627
+ if (c && c.id !== 'function') {
2628
+ if (c.identifier) {
2629
+ c['new'] = true;
2630
+ switch (c.value) {
2631
+ case 'Object':
2632
+ warning("Use the object literal notation {}.", token);
2633
+ break;
2634
+ case 'Number':
2635
+ case 'String':
2636
+ case 'Boolean':
2637
+ case 'Math':
2638
+ case 'JSON':
2639
+ warning("Do not use {a} as a constructor.", token, c.value);
2640
+ break;
2641
+ case 'Function':
2642
+ if (!option.evil) {
2643
+ warning("The Function constructor is eval.");
2644
+ }
2645
+ break;
2646
+ case 'Date':
2647
+ case 'RegExp':
2648
+ break;
2649
+ default:
2650
+ if (c.id !== 'function') {
2651
+ i = c.value.substr(0, 1);
2652
+ if (option.newcap && (i < 'A' || i > 'Z')) {
2653
+ warning("A constructor name should start with an uppercase letter.", token);
2654
+ }
2655
+ }
2656
+ }
2657
+ } else {
2658
+ if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
2659
+ warning("Bad constructor.", token);
2660
+ }
2661
+ }
2662
+ } else {
2663
+ if (!option.supernew)
2664
+ warning("Weird construction. Delete 'new'.", this);
2665
+ }
2666
+ adjacent(token, nexttoken);
2667
+ if (nexttoken.id !== '(' && !option.supernew) {
2668
+ warning("Missing '()' invoking a constructor.");
2669
+ }
2670
+ this.first = c;
2671
+ return this;
2672
+ });
2673
+ syntax['new'].exps = true;
2674
+
2675
+ prefix('void').exps = true;
2676
+
2677
+ infix('.', function (left, that) {
2678
+ adjacent(prevtoken, token);
2679
+ nobreak();
2680
+ var m = identifier();
2681
+ if (typeof m === 'string') {
2682
+ countMember(m);
2683
+ }
2684
+ that.left = left;
2685
+ that.right = m;
2686
+ if (option.noarg && left && left.value === 'arguments' &&
2687
+ (m === 'callee' || m === 'caller')) {
2688
+ warning("Avoid arguments.{a}.", left, m);
2689
+ } else if (!option.evil && left && left.value === 'document' &&
2690
+ (m === 'write' || m === 'writeln')) {
2691
+ warning("document.write can be a form of eval.", left);
2692
+ }
2693
+ if (!option.evil && (m === 'eval' || m === 'execScript')) {
2694
+ warning('eval is evil.');
2695
+ }
2696
+ return that;
2697
+ }, 160, true);
2698
+
2699
+ infix('(', function (left, that) {
2700
+ if (prevtoken.id !== '}' && prevtoken.id !== ')') {
2701
+ nobreak(prevtoken, token);
2702
+ }
2703
+ nospace();
2704
+ if (option.immed && !left.immed && left.id === 'function') {
2705
+ warning("Wrap an immediate function invocation in parentheses " +
2706
+ "to assist the reader in understanding that the expression " +
2707
+ "is the result of a function, and not the function itself.");
2708
+ }
2709
+ var n = 0,
2710
+ p = [];
2711
+ if (left) {
2712
+ if (left.type === '(identifier)') {
2713
+ if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
2714
+ if (left.value !== 'Number' && left.value !== 'String' &&
2715
+ left.value !== 'Boolean' &&
2716
+ left.value !== 'Date') {
2717
+ if (left.value === 'Math') {
2718
+ warning("Math is not a function.", left);
2719
+ } else if (option.newcap) {
2720
+ warning(
2721
+ "Missing 'new' prefix when invoking a constructor.", left);
2722
+ }
2723
+ }
2724
+ }
2725
+ }
2726
+ }
2727
+ if (nexttoken.id !== ')') {
2728
+ for (;;) {
2729
+ p[p.length] = expression(10);
2730
+ n += 1;
2731
+ if (nexttoken.id !== ',') {
2732
+ break;
2733
+ }
2734
+ comma();
2735
+ }
2736
+ }
2737
+ advance(')');
2738
+ nospace(prevtoken, token);
2739
+ if (typeof left === 'object') {
2740
+ if (left.value === 'parseInt' && n === 1) {
2741
+ warning("Missing radix parameter.", left);
2742
+ }
2743
+ if (!option.evil) {
2744
+ if (left.value === 'eval' || left.value === 'Function' ||
2745
+ left.value === 'execScript') {
2746
+ warning("eval is evil.", left);
2747
+ } else if (p[0] && p[0].id === '(string)' &&
2748
+ (left.value === 'setTimeout' ||
2749
+ left.value === 'setInterval')) {
2750
+ warning(
2751
+ "Implied eval is evil. Pass a function instead of a string.", left);
2752
+ }
2753
+ }
2754
+ if (!left.identifier && left.id !== '.' && left.id !== '[' &&
2755
+ left.id !== '(' && left.id !== '&&' && left.id !== '||' &&
2756
+ left.id !== '?') {
2757
+ warning("Bad invocation.", left);
2758
+ }
2759
+ }
2760
+ that.left = left;
2761
+ return that;
2762
+ }, 155, true).exps = true;
2763
+
2764
+ prefix('(', function () {
2765
+ nospace();
2766
+ if (nexttoken.id === 'function') {
2767
+ nexttoken.immed = true;
2768
+ }
2769
+ var v = expression(0);
2770
+ advance(')', this);
2771
+ nospace(prevtoken, token);
2772
+ if (option.immed && v.id === 'function') {
2773
+ if (nexttoken.id === '(') {
2774
+ warning(
2775
+ "Move the invocation into the parens that contain the function.", nexttoken);
2776
+ } else {
2777
+ warning(
2778
+ "Do not wrap function literals in parens unless they are to be immediately invoked.",
2779
+ this);
2780
+ }
2781
+ }
2782
+ return v;
2783
+ });
2784
+
2785
+ infix('[', function (left, that) {
2786
+ nobreak(prevtoken, token);
2787
+ nospace();
2788
+ var e = expression(0), s;
2789
+ if (e && e.type === '(string)') {
2790
+ if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) {
2791
+ warning("eval is evil.", that);
2792
+ }
2793
+ countMember(e.value);
2794
+ if (!option.sub && ix.test(e.value)) {
2795
+ s = syntax[e.value];
2796
+ if (!s || !s.reserved) {
2797
+ warning("['{a}'] is better written in dot notation.",
2798
+ e, e.value);
2799
+ }
2800
+ }
2801
+ }
2802
+ advance(']', that);
2803
+ nospace(prevtoken, token);
2804
+ that.left = left;
2805
+ that.right = e;
2806
+ return that;
2807
+ }, 160, true);
2808
+
2809
+ prefix('[', function () {
2810
+ var b = token.line !== nexttoken.line;
2811
+ this.first = [];
2812
+ if (b) {
2813
+ indent += option.indent;
2814
+ if (nexttoken.from === indent + option.indent) {
2815
+ indent += option.indent;
2816
+ }
2817
+ }
2818
+ while (nexttoken.id !== '(end)') {
2819
+ while (nexttoken.id === ',') {
2820
+ warning("Extra comma.");
2821
+ advance(',');
2822
+ }
2823
+ if (nexttoken.id === ']') {
2824
+ break;
2825
+ }
2826
+ if (b && token.line !== nexttoken.line) {
2827
+ indentation();
2828
+ }
2829
+ this.first.push(expression(10));
2830
+ if (nexttoken.id === ',') {
2831
+ comma();
2832
+ if (nexttoken.id === ']' && !option.es5) {
2833
+ warning("Extra comma.", token);
2834
+ break;
2835
+ }
2836
+ } else {
2837
+ break;
2838
+ }
2839
+ }
2840
+ if (b) {
2841
+ indent -= option.indent;
2842
+ indentation();
2843
+ }
2844
+ advance(']', this);
2845
+ return this;
2846
+ }, 160);
2847
+
2848
+
2849
+ function property_name() {
2850
+ var id = optionalidentifier(true);
2851
+ if (!id) {
2852
+ if (nexttoken.id === '(string)') {
2853
+ id = nexttoken.value;
2854
+ advance();
2855
+ } else if (nexttoken.id === '(number)') {
2856
+ id = nexttoken.value.toString();
2857
+ advance();
2858
+ }
2859
+ }
2860
+ return id;
2861
+ }
2862
+
2863
+
2864
+ function functionparams() {
2865
+ var i, t = nexttoken, p = [];
2866
+ advance('(');
2867
+ nospace();
2868
+ if (nexttoken.id === ')') {
2869
+ advance(')');
2870
+ nospace(prevtoken, token);
2871
+ return;
2872
+ }
2873
+ for (;;) {
2874
+ i = identifier(true);
2875
+ p.push(i);
2876
+ addlabel(i, 'parameter');
2877
+ if (nexttoken.id === ',') {
2878
+ comma();
2879
+ } else {
2880
+ advance(')', t);
2881
+ nospace(prevtoken, token);
2882
+ return p;
2883
+ }
2884
+ }
2885
+ }
2886
+
2887
+
2888
+ function doFunction(i, statement) {
2889
+ var f,
2890
+ oldOption = option,
2891
+ oldScope = scope;
2892
+
2893
+ option = Object.create(option);
2894
+ scope = Object.create(scope);
2895
+
2896
+ funct = {
2897
+ '(name)' : i || '"' + anonname + '"',
2898
+ '(line)' : nexttoken.line,
2899
+ '(context)' : funct,
2900
+ '(breakage)' : 0,
2901
+ '(loopage)' : 0,
2902
+ '(scope)' : scope,
2903
+ '(statement)': statement
2904
+ };
2905
+ f = funct;
2906
+ token.funct = funct;
2907
+ functions.push(funct);
2908
+ if (i) {
2909
+ addlabel(i, 'function');
2910
+ }
2911
+ funct['(params)'] = functionparams();
2912
+
2913
+ block(false);
2914
+ scope = oldScope;
2915
+ option = oldOption;
2916
+ funct['(last)'] = token.line;
2917
+ funct = funct['(context)'];
2918
+ return f;
2919
+ }
2920
+
2921
+
2922
+ (function (x) {
2923
+ x.nud = function () {
2924
+ var b, f, i, j, p, seen = {}, t;
2925
+
2926
+ b = token.line !== nexttoken.line;
2927
+ if (b) {
2928
+ indent += option.indent;
2929
+ if (nexttoken.from === indent + option.indent) {
2930
+ indent += option.indent;
2931
+ }
2932
+ }
2933
+ for (;;) {
2934
+ if (nexttoken.id === '}') {
2935
+ break;
2936
+ }
2937
+ if (b) {
2938
+ indentation();
2939
+ }
2940
+ if (nexttoken.value === 'get' && peek().id !== ':') {
2941
+ advance('get');
2942
+ if (!option.es5) {
2943
+ error("get/set are ES5 features.");
2944
+ }
2945
+ i = property_name();
2946
+ if (!i) {
2947
+ error("Missing property name.");
2948
+ }
2949
+ t = nexttoken;
2950
+ adjacent(token, nexttoken);
2951
+ f = doFunction();
2952
+ if (!option.loopfunc && funct['(loopage)']) {
2953
+ warning("Don't make functions within a loop.", t);
2954
+ }
2955
+ p = f['(params)'];
2956
+ if (p) {
2957
+ warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
2958
+ }
2959
+ adjacent(token, nexttoken);
2960
+ advance(',');
2961
+ indentation();
2962
+ advance('set');
2963
+ j = property_name();
2964
+ if (i !== j) {
2965
+ error("Expected {a} and instead saw {b}.", token, i, j);
2966
+ }
2967
+ t = nexttoken;
2968
+ adjacent(token, nexttoken);
2969
+ f = doFunction();
2970
+ p = f['(params)'];
2971
+ if (!p || p.length !== 1 || p[0] !== 'value') {
2972
+ warning("Expected (value) in set {a} function.", t, i);
2973
+ }
2974
+ } else {
2975
+ i = property_name();
2976
+ if (typeof i !== 'string') {
2977
+ break;
2978
+ }
2979
+ advance(':');
2980
+ nonadjacent(token, nexttoken);
2981
+ expression(10);
2982
+ }
2983
+ if (seen[i] === true) {
2984
+ warning("Duplicate member '{a}'.", nexttoken, i);
2985
+ }
2986
+ seen[i] = true;
2987
+ countMember(i);
2988
+ if (nexttoken.id === ',') {
2989
+ comma();
2990
+ if (nexttoken.id === ',') {
2991
+ warning("Extra comma.", token);
2992
+ } else if (nexttoken.id === '}' && !option.es5) {
2993
+ warning("Extra comma.", token);
2994
+ }
2995
+ } else {
2996
+ break;
2997
+ }
2998
+ }
2999
+ if (b) {
3000
+ indent -= option.indent;
3001
+ indentation();
3002
+ }
3003
+ advance('}', this);
3004
+ return this;
3005
+ };
3006
+ x.fud = function () {
3007
+ error("Expected to see a statement and instead saw a block.", token);
3008
+ };
3009
+ }(delim('{')));
3010
+
3011
+ var varstatement = stmt('var', function (prefix) {
3012
+ // JavaScript does not have block scope. It only has function scope. So,
3013
+ // declaring a variable in a block can have unexpected consequences.
3014
+ var id, name, value;
3015
+
3016
+ if (funct['(onevar)'] && option.onevar) {
3017
+ warning("Too many var statements.");
3018
+ } else if (!funct['(global)']) {
3019
+ funct['(onevar)'] = true;
3020
+ }
3021
+ this.first = [];
3022
+ for (;;) {
3023
+ nonadjacent(token, nexttoken);
3024
+ id = identifier();
3025
+ if (funct['(global)'] && predefined[id] === false) {
3026
+ warning("Redefinition of '{a}'.", token, id);
3027
+ }
3028
+ addlabel(id, 'unused');
3029
+ if (prefix) {
3030
+ break;
3031
+ }
3032
+ name = token;
3033
+ this.first.push(token);
3034
+ if (nexttoken.id === '=') {
3035
+ nonadjacent(token, nexttoken);
3036
+ advance('=');
3037
+ nonadjacent(token, nexttoken);
3038
+ if (nexttoken.id === 'undefined') {
3039
+ warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
3040
+ }
3041
+ if (peek(0).id === '=' && nexttoken.identifier) {
3042
+ error("Variable {a} was not declared correctly.",
3043
+ nexttoken, nexttoken.value);
3044
+ }
3045
+ value = expression(0);
3046
+ name.first = value;
3047
+ }
3048
+ if (nexttoken.id !== ',') {
3049
+ break;
3050
+ }
3051
+ comma();
3052
+ }
3053
+ return this;
3054
+ });
3055
+ varstatement.exps = true;
3056
+
3057
+ blockstmt('function', function () {
3058
+ if (inblock) {
3059
+ warning(
3060
+ "Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.", token);
3061
+
3062
+ }
3063
+ var i = identifier();
3064
+ adjacent(token, nexttoken);
3065
+ addlabel(i, 'unction');
3066
+ doFunction(i, true);
3067
+ if (nexttoken.id === '(' && nexttoken.line === token.line) {
3068
+ error(
3069
+ "Function declarations are not invocable. Wrap the whole function invocation in parens.");
3070
+ }
3071
+ return this;
3072
+ });
3073
+
3074
+ prefix('function', function () {
3075
+ var i = optionalidentifier();
3076
+ if (i) {
3077
+ adjacent(token, nexttoken);
3078
+ } else {
3079
+ nonadjacent(token, nexttoken);
3080
+ }
3081
+ doFunction(i);
3082
+ if (!option.loopfunc && funct['(loopage)']) {
3083
+ warning("Don't make functions within a loop.");
3084
+ }
3085
+ return this;
3086
+ });
3087
+
3088
+ blockstmt('if', function () {
3089
+ var t = nexttoken;
3090
+ advance('(');
3091
+ nonadjacent(this, t);
3092
+ nospace();
3093
+ expression(20);
3094
+ if (nexttoken.id === '=') {
3095
+ if (!option.boss)
3096
+ warning("Expected a conditional expression and instead saw an assignment.");
3097
+ advance('=');
3098
+ expression(20);
3099
+ }
3100
+ advance(')', t);
3101
+ nospace(prevtoken, token);
3102
+ block(true, true);
3103
+ if (nexttoken.id === 'else') {
3104
+ nonadjacent(token, nexttoken);
3105
+ advance('else');
3106
+ if (nexttoken.id === 'if' || nexttoken.id === 'switch') {
3107
+ statement(true);
3108
+ } else {
3109
+ block(true, true);
3110
+ }
3111
+ }
3112
+ return this;
3113
+ });
3114
+
3115
+ blockstmt('try', function () {
3116
+ var b, e, s;
3117
+
3118
+ block(false);
3119
+ if (nexttoken.id === 'catch') {
3120
+ advance('catch');
3121
+ nonadjacent(token, nexttoken);
3122
+ advance('(');
3123
+ s = scope;
3124
+ scope = Object.create(s);
3125
+ e = nexttoken.value;
3126
+ if (nexttoken.type !== '(identifier)') {
3127
+ warning("Expected an identifier and instead saw '{a}'.",
3128
+ nexttoken, e);
3129
+ } else {
3130
+ addlabel(e, 'exception');
3131
+ }
3132
+ advance();
3133
+ advance(')');
3134
+ block(false);
3135
+ b = true;
3136
+ scope = s;
3137
+ }
3138
+ if (nexttoken.id === 'finally') {
3139
+ advance('finally');
3140
+ block(false);
3141
+ return;
3142
+ } else if (!b) {
3143
+ error("Expected '{a}' and instead saw '{b}'.",
3144
+ nexttoken, 'catch', nexttoken.value);
3145
+ }
3146
+ return this;
3147
+ });
3148
+
3149
+ blockstmt('while', function () {
3150
+ var t = nexttoken;
3151
+ funct['(breakage)'] += 1;
3152
+ funct['(loopage)'] += 1;
3153
+ advance('(');
3154
+ nonadjacent(this, t);
3155
+ nospace();
3156
+ expression(20);
3157
+ if (nexttoken.id === '=') {
3158
+ if (!option.boss)
3159
+ warning("Expected a conditional expression and instead saw an assignment.");
3160
+ advance('=');
3161
+ expression(20);
3162
+ }
3163
+ advance(')', t);
3164
+ nospace(prevtoken, token);
3165
+ block(true, true);
3166
+ funct['(breakage)'] -= 1;
3167
+ funct['(loopage)'] -= 1;
3168
+ return this;
3169
+ }).labelled = true;
3170
+
3171
+ reserve('with');
3172
+
3173
+ blockstmt('switch', function () {
3174
+ var t = nexttoken,
3175
+ g = false;
3176
+ funct['(breakage)'] += 1;
3177
+ advance('(');
3178
+ nonadjacent(this, t);
3179
+ nospace();
3180
+ this.condition = expression(20);
3181
+ advance(')', t);
3182
+ nospace(prevtoken, token);
3183
+ nonadjacent(token, nexttoken);
3184
+ t = nexttoken;
3185
+ advance('{');
3186
+ nonadjacent(token, nexttoken);
3187
+ indent += option.indent;
3188
+ this.cases = [];
3189
+ for (;;) {
3190
+ switch (nexttoken.id) {
3191
+ case 'case':
3192
+ switch (funct['(verb)']) {
3193
+ case 'break':
3194
+ case 'case':
3195
+ case 'continue':
3196
+ case 'return':
3197
+ case 'switch':
3198
+ case 'throw':
3199
+ break;
3200
+ default:
3201
+ // You can tell JSHint that you don't use break intentionally by
3202
+ // adding a comment /* falls through */ on a line just before
3203
+ // the next `case`.
3204
+ if (!ft.test(lines[nexttoken.line - 2])) {
3205
+ warning(
3206
+ "Expected a 'break' statement before 'case'.",
3207
+ token);
3208
+ }
3209
+ }
3210
+ indentation(-option.indent);
3211
+ advance('case');
3212
+ this.cases.push(expression(20));
3213
+ g = true;
3214
+ advance(':');
3215
+ funct['(verb)'] = 'case';
3216
+ break;
3217
+ case 'default':
3218
+ switch (funct['(verb)']) {
3219
+ case 'break':
3220
+ case 'continue':
3221
+ case 'return':
3222
+ case 'throw':
3223
+ break;
3224
+ default:
3225
+ if (!ft.test(lines[nexttoken.line - 2])) {
3226
+ warning(
3227
+ "Expected a 'break' statement before 'default'.",
3228
+ token);
3229
+ }
3230
+ }
3231
+ indentation(-option.indent);
3232
+ advance('default');
3233
+ g = true;
3234
+ advance(':');
3235
+ break;
3236
+ case '}':
3237
+ indent -= option.indent;
3238
+ indentation();
3239
+ advance('}', t);
3240
+ if (this.cases.length === 1 || this.condition.id === 'true' ||
3241
+ this.condition.id === 'false') {
3242
+ warning("This 'switch' should be an 'if'.", this);
3243
+ }
3244
+ funct['(breakage)'] -= 1;
3245
+ funct['(verb)'] = undefined;
3246
+ return;
3247
+ case '(end)':
3248
+ error("Missing '{a}'.", nexttoken, '}');
3249
+ return;
3250
+ default:
3251
+ if (g) {
3252
+ switch (token.id) {
3253
+ case ',':
3254
+ error("Each value should have its own case label.");
3255
+ return;
3256
+ case ':':
3257
+ statements();
3258
+ break;
3259
+ default:
3260
+ error("Missing ':' on a case clause.", token);
3261
+ }
3262
+ } else {
3263
+ error("Expected '{a}' and instead saw '{b}'.",
3264
+ nexttoken, 'case', nexttoken.value);
3265
+ }
3266
+ }
3267
+ }
3268
+ }).labelled = true;
3269
+
3270
+ stmt('debugger', function () {
3271
+ if (!option.debug) {
3272
+ warning("All 'debugger' statements should be removed.");
3273
+ }
3274
+ return this;
3275
+ }).exps = true;
3276
+
3277
+ (function () {
3278
+ var x = stmt('do', function () {
3279
+ funct['(breakage)'] += 1;
3280
+ funct['(loopage)'] += 1;
3281
+ this.first = block(true);
3282
+ advance('while');
3283
+ var t = nexttoken;
3284
+ nonadjacent(token, t);
3285
+ advance('(');
3286
+ nospace();
3287
+ expression(20);
3288
+ if (nexttoken.id === '=') {
3289
+ if (!option.boss)
3290
+ warning("Expected a conditional expression and instead saw an assignment.");
3291
+ advance('=');
3292
+ expression(20);
3293
+ }
3294
+ advance(')', t);
3295
+ nospace(prevtoken, token);
3296
+ funct['(breakage)'] -= 1;
3297
+ funct['(loopage)'] -= 1;
3298
+ return this;
3299
+ });
3300
+ x.labelled = true;
3301
+ x.exps = true;
3302
+ }());
3303
+
3304
+ blockstmt('for', function () {
3305
+ var s, t = nexttoken;
3306
+ funct['(breakage)'] += 1;
3307
+ funct['(loopage)'] += 1;
3308
+ advance('(');
3309
+ nonadjacent(this, t);
3310
+ nospace();
3311
+ if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') {
3312
+ if (nexttoken.id === 'var') {
3313
+ advance('var');
3314
+ varstatement.fud.call(varstatement, true);
3315
+ } else {
3316
+ switch (funct[nexttoken.value]) {
3317
+ case 'unused':
3318
+ funct[nexttoken.value] = 'var';
3319
+ break;
3320
+ case 'var':
3321
+ break;
3322
+ default:
3323
+ warning("Bad for in variable '{a}'.",
3324
+ nexttoken, nexttoken.value);
3325
+ }
3326
+ advance();
3327
+ }
3328
+ advance('in');
3329
+ expression(20);
3330
+ advance(')', t);
3331
+ s = block(true, true);
3332
+ if (option.forin && (s.length > 1 || typeof s[0] !== 'object' ||
3333
+ s[0].value !== 'if')) {
3334
+ warning("The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.", this);
3335
+ }
3336
+ funct['(breakage)'] -= 1;
3337
+ funct['(loopage)'] -= 1;
3338
+ return this;
3339
+ } else {
3340
+ if (nexttoken.id !== ';') {
3341
+ if (nexttoken.id === 'var') {
3342
+ advance('var');
3343
+ varstatement.fud.call(varstatement);
3344
+ } else {
3345
+ for (;;) {
3346
+ expression(0, 'for');
3347
+ if (nexttoken.id !== ',') {
3348
+ break;
3349
+ }
3350
+ comma();
3351
+ }
3352
+ }
3353
+ }
3354
+ nolinebreak(token);
3355
+ advance(';');
3356
+ if (nexttoken.id !== ';') {
3357
+ expression(20);
3358
+ if (nexttoken.id === '=') {
3359
+ if (!option.boss)
3360
+ warning("Expected a conditional expression and instead saw an assignment.");
3361
+ advance('=');
3362
+ expression(20);
3363
+ }
3364
+ }
3365
+ nolinebreak(token);
3366
+ advance(';');
3367
+ if (nexttoken.id === ';') {
3368
+ error("Expected '{a}' and instead saw '{b}'.",
3369
+ nexttoken, ')', ';');
3370
+ }
3371
+ if (nexttoken.id !== ')') {
3372
+ for (;;) {
3373
+ expression(0, 'for');
3374
+ if (nexttoken.id !== ',') {
3375
+ break;
3376
+ }
3377
+ comma();
3378
+ }
3379
+ }
3380
+ advance(')', t);
3381
+ nospace(prevtoken, token);
3382
+ block(true, true);
3383
+ funct['(breakage)'] -= 1;
3384
+ funct['(loopage)'] -= 1;
3385
+ return this;
3386
+ }
3387
+ }).labelled = true;
3388
+
3389
+
3390
+ stmt('break', function () {
3391
+ var v = nexttoken.value;
3392
+ if (funct['(breakage)'] === 0) {
3393
+ warning("Unexpected '{a}'.", nexttoken, this.value);
3394
+ }
3395
+ nolinebreak(this);
3396
+ if (nexttoken.id !== ';') {
3397
+ if (token.line === nexttoken.line) {
3398
+ if (funct[v] !== 'label') {
3399
+ warning("'{a}' is not a statement label.", nexttoken, v);
3400
+ } else if (scope[v] !== funct) {
3401
+ warning("'{a}' is out of scope.", nexttoken, v);
3402
+ }
3403
+ this.first = nexttoken;
3404
+ advance();
3405
+ }
3406
+ }
3407
+ reachable('break');
3408
+ return this;
3409
+ }).exps = true;
3410
+
3411
+
3412
+ stmt('continue', function () {
3413
+ var v = nexttoken.value;
3414
+ if (funct['(breakage)'] === 0) {
3415
+ warning("Unexpected '{a}'.", nexttoken, this.value);
3416
+ }
3417
+ nolinebreak(this);
3418
+ if (nexttoken.id !== ';') {
3419
+ if (token.line === nexttoken.line) {
3420
+ if (funct[v] !== 'label') {
3421
+ warning("'{a}' is not a statement label.", nexttoken, v);
3422
+ } else if (scope[v] !== funct) {
3423
+ warning("'{a}' is out of scope.", nexttoken, v);
3424
+ }
3425
+ this.first = nexttoken;
3426
+ advance();
3427
+ }
3428
+ } else if (!funct['(loopage)']) {
3429
+ warning("Unexpected '{a}'.", nexttoken, this.value);
3430
+ }
3431
+ reachable('continue');
3432
+ return this;
3433
+ }).exps = true;
3434
+
3435
+
3436
+ stmt('return', function () {
3437
+ nolinebreak(this);
3438
+ if (nexttoken.id === '(regexp)') {
3439
+ warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
3440
+ }
3441
+ if (nexttoken.id !== ';' && !nexttoken.reach) {
3442
+ nonadjacent(token, nexttoken);
3443
+ this.first = expression(20);
3444
+ }
3445
+ reachable('return');
3446
+ return this;
3447
+ }).exps = true;
3448
+
3449
+
3450
+ stmt('throw', function () {
3451
+ nolinebreak(this);
3452
+ nonadjacent(token, nexttoken);
3453
+ this.first = expression(20);
3454
+ reachable('throw');
3455
+ return this;
3456
+ }).exps = true;
3457
+
3458
+ // Superfluous reserved words
3459
+
3460
+ reserve('class');
3461
+ reserve('const');
3462
+ reserve('enum');
3463
+ reserve('export');
3464
+ reserve('extends');
3465
+ reserve('import');
3466
+ reserve('super');
3467
+
3468
+ reserve('let');
3469
+ reserve('yield');
3470
+ reserve('implements');
3471
+ reserve('interface');
3472
+ reserve('package');
3473
+ reserve('private');
3474
+ reserve('protected');
3475
+ reserve('public');
3476
+ reserve('static');
3477
+
3478
+
3479
+ // Parse JSON
3480
+
3481
+ function jsonValue() {
3482
+
3483
+ function jsonObject() {
3484
+ var o = {}, t = nexttoken;
3485
+ advance('{');
3486
+ if (nexttoken.id !== '}') {
3487
+ for (;;) {
3488
+ if (nexttoken.id === '(end)') {
3489
+ error("Missing '}' to match '{' from line {a}.",
3490
+ nexttoken, t.line);
3491
+ } else if (nexttoken.id === '}') {
3492
+ warning("Unexpected comma.", token);
3493
+ break;
3494
+ } else if (nexttoken.id === ',') {
3495
+ error("Unexpected comma.", nexttoken);
3496
+ } else if (nexttoken.id !== '(string)') {
3497
+ warning("Expected a string and instead saw {a}.",
3498
+ nexttoken, nexttoken.value);
3499
+ }
3500
+ if (o[nexttoken.value] === true) {
3501
+ warning("Duplicate key '{a}'.",
3502
+ nexttoken, nexttoken.value);
3503
+ } else if (nexttoken.value === '__proto__') {
3504
+ warning("Stupid key '{a}'.",
3505
+ nexttoken, nexttoken.value);
3506
+ } else {
3507
+ o[nexttoken.value] = true;
3508
+ }
3509
+ advance();
3510
+ advance(':');
3511
+ jsonValue();
3512
+ if (nexttoken.id !== ',') {
3513
+ break;
3514
+ }
3515
+ advance(',');
3516
+ }
3517
+ }
3518
+ advance('}');
3519
+ }
3520
+
3521
+ function jsonArray() {
3522
+ var t = nexttoken;
3523
+ advance('[');
3524
+ if (nexttoken.id !== ']') {
3525
+ for (;;) {
3526
+ if (nexttoken.id === '(end)') {
3527
+ error("Missing ']' to match '[' from line {a}.",
3528
+ nexttoken, t.line);
3529
+ } else if (nexttoken.id === ']') {
3530
+ warning("Unexpected comma.", token);
3531
+ break;
3532
+ } else if (nexttoken.id === ',') {
3533
+ error("Unexpected comma.", nexttoken);
3534
+ }
3535
+ jsonValue();
3536
+ if (nexttoken.id !== ',') {
3537
+ break;
3538
+ }
3539
+ advance(',');
3540
+ }
3541
+ }
3542
+ advance(']');
3543
+ }
3544
+
3545
+ switch (nexttoken.id) {
3546
+ case '{':
3547
+ jsonObject();
3548
+ break;
3549
+ case '[':
3550
+ jsonArray();
3551
+ break;
3552
+ case 'true':
3553
+ case 'false':
3554
+ case 'null':
3555
+ case '(number)':
3556
+ case '(string)':
3557
+ advance();
3558
+ break;
3559
+ case '-':
3560
+ advance('-');
3561
+ if (token.character !== nexttoken.from) {
3562
+ warning("Unexpected space after '-'.", token);
3563
+ }
3564
+ adjacent(token, nexttoken);
3565
+ advance('(number)');
3566
+ break;
3567
+ default:
3568
+ error("Expected a JSON value.", nexttoken);
3569
+ }
3570
+ }
3571
+
3572
+
3573
+ // The actual JSHINT function itself.
3574
+
3575
+ var itself = function (s, o, g) {
3576
+ var a, i, k;
3577
+ JSHINT.errors = [];
3578
+ predefined = Object.create(standard);
3579
+ combine(predefined, g || {});
3580
+ if (o) {
3581
+ a = o.predef;
3582
+ if (a) {
3583
+ if (Array.isArray(a)) {
3584
+ for (i = 0; i < a.length; i += 1) {
3585
+ predefined[a[i]] = true;
3586
+ }
3587
+ } else if (typeof a === 'object') {
3588
+ k = Object.keys(a);
3589
+ for (i = 0; i < k.length; i += 1) {
3590
+ predefined[k[i]] = !!a[k];
3591
+ }
3592
+ }
3593
+ }
3594
+ option = o;
3595
+ } else {
3596
+ option = {};
3597
+ }
3598
+ option.indent = option.indent || 4;
3599
+ option.maxerr = option.maxerr || 50;
3600
+
3601
+ tab = '';
3602
+ for (i = 0; i < option.indent; i += 1) {
3603
+ tab += ' ';
3604
+ }
3605
+ indent = 1;
3606
+ global = Object.create(predefined);
3607
+ scope = global;
3608
+ funct = {
3609
+ '(global)': true,
3610
+ '(name)': '(global)',
3611
+ '(scope)': scope,
3612
+ '(breakage)': 0,
3613
+ '(loopage)': 0
3614
+ };
3615
+ functions = [funct];
3616
+ urls = [];
3617
+ src = false;
3618
+ stack = null;
3619
+ member = {};
3620
+ membersOnly = null;
3621
+ implied = {};
3622
+ inblock = false;
3623
+ lookahead = [];
3624
+ jsonmode = false;
3625
+ warnings = 0;
3626
+ lex.init(s);
3627
+ prereg = true;
3628
+ strict_mode = false;
3629
+
3630
+ prevtoken = token = nexttoken = syntax['(begin)'];
3631
+ assume();
3632
+
3633
+ try {
3634
+ advance();
3635
+ switch (nexttoken.id) {
3636
+ case '{':
3637
+ case '[':
3638
+ option.laxbreak = true;
3639
+ jsonmode = true;
3640
+ jsonValue();
3641
+ break;
3642
+ default:
3643
+ if (nexttoken.value === 'use strict') {
3644
+ if (!option.globalstrict)
3645
+ warning("Use the function form of \"use strict\".");
3646
+ use_strict();
3647
+ }
3648
+ statements('lib');
3649
+ }
3650
+ advance('(end)');
3651
+ } catch (e) {
3652
+ if (e) {
3653
+ JSHINT.errors.push({
3654
+ reason : e.message,
3655
+ line : e.line || nexttoken.line,
3656
+ character : e.character || nexttoken.from
3657
+ }, null);
3658
+ }
3659
+ }
3660
+ return JSHINT.errors.length === 0;
3661
+ };
3662
+
3663
+
3664
+ // Data summary.
3665
+
3666
+ itself.data = function () {
3667
+
3668
+ var data = {functions: []}, fu, globals, implieds = [], f, i, j,
3669
+ members = [], n, unused = [], v;
3670
+ if (itself.errors.length) {
3671
+ data.errors = itself.errors;
3672
+ }
3673
+
3674
+ if (jsonmode) {
3675
+ data.json = true;
3676
+ }
3677
+
3678
+ for (n in implied) {
3679
+ if (is_own(implied, n)) {
3680
+ implieds.push({
3681
+ name: n,
3682
+ line: implied[n]
3683
+ });
3684
+ }
3685
+ }
3686
+ if (implieds.length > 0) {
3687
+ data.implieds = implieds;
3688
+ }
3689
+
3690
+ if (urls.length > 0) {
3691
+ data.urls = urls;
3692
+ }
3693
+
3694
+ globals = Object.keys(scope);
3695
+ if (globals.length > 0) {
3696
+ data.globals = globals;
3697
+ }
3698
+
3699
+ for (i = 1; i < functions.length; i += 1) {
3700
+ f = functions[i];
3701
+ fu = {};
3702
+ for (j = 0; j < functionicity.length; j += 1) {
3703
+ fu[functionicity[j]] = [];
3704
+ }
3705
+ for (n in f) {
3706
+ if (is_own(f, n) && n.charAt(0) !== '(') {
3707
+ v = f[n];
3708
+ if (v === 'unction') {
3709
+ v = 'unused';
3710
+ }
3711
+ if (Array.isArray(fu[v])) {
3712
+ fu[v].push(n);
3713
+ if (v === 'unused') {
3714
+ unused.push({
3715
+ name: n,
3716
+ line: f['(line)'],
3717
+ 'function': f['(name)']
3718
+ });
3719
+ }
3720
+ }
3721
+ }
3722
+ }
3723
+ for (j = 0; j < functionicity.length; j += 1) {
3724
+ if (fu[functionicity[j]].length === 0) {
3725
+ delete fu[functionicity[j]];
3726
+ }
3727
+ }
3728
+ fu.name = f['(name)'];
3729
+ fu.param = f['(params)'];
3730
+ fu.line = f['(line)'];
3731
+ fu.last = f['(last)'];
3732
+ data.functions.push(fu);
3733
+ }
3734
+
3735
+ if (unused.length > 0) {
3736
+ data.unused = unused;
3737
+ }
3738
+
3739
+ members = [];
3740
+ for (n in member) {
3741
+ if (typeof member[n] === 'number') {
3742
+ data.member = member;
3743
+ break;
3744
+ }
3745
+ }
3746
+
3747
+ return data;
3748
+ };
3749
+
3750
+ itself.report = function (option) {
3751
+ var data = itself.data();
3752
+
3753
+ var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s;
3754
+
3755
+ function detail(h, array) {
3756
+ var b, i, singularity;
3757
+ if (array) {
3758
+ o.push('<div><i>' + h + '</i> ');
3759
+ array = array.sort();
3760
+ for (i = 0; i < array.length; i += 1) {
3761
+ if (array[i] !== singularity) {
3762
+ singularity = array[i];
3763
+ o.push((b ? ', ' : '') + singularity);
3764
+ b = true;
3765
+ }
3766
+ }
3767
+ o.push('</div>');
3768
+ }
3769
+ }
3770
+
3771
+
3772
+ if (data.errors || data.implieds || data.unused) {
3773
+ err = true;
3774
+ o.push('<div id=errors><i>Error:</i>');
3775
+ if (data.errors) {
3776
+ for (i = 0; i < data.errors.length; i += 1) {
3777
+ c = data.errors[i];
3778
+ if (c) {
3779
+ e = c.evidence || '';
3780
+ o.push('<p>Problem' + (isFinite(c.line) ? ' at line ' +
3781
+ c.line + ' character ' + c.character : '') +
3782
+ ': ' + c.reason.entityify() +
3783
+ '</p><p class=evidence>' +
3784
+ (e && (e.length > 80 ? e.slice(0, 77) + '...' :
3785
+ e).entityify()) + '</p>');
3786
+ }
3787
+ }
3788
+ }
3789
+
3790
+ if (data.implieds) {
3791
+ s = [];
3792
+ for (i = 0; i < data.implieds.length; i += 1) {
3793
+ s[i] = '<code>' + data.implieds[i].name + '</code>&nbsp;<i>' +
3794
+ data.implieds[i].line + '</i>';
3795
+ }
3796
+ o.push('<p><i>Implied global:</i> ' + s.join(', ') + '</p>');
3797
+ }
3798
+
3799
+ if (data.unused) {
3800
+ s = [];
3801
+ for (i = 0; i < data.unused.length; i += 1) {
3802
+ s[i] = '<code><u>' + data.unused[i].name + '</u></code>&nbsp;<i>' +
3803
+ data.unused[i].line + '</i> <code>' +
3804
+ data.unused[i]['function'] + '</code>';
3805
+ }
3806
+ o.push('<p><i>Unused variable:</i> ' + s.join(', ') + '</p>');
3807
+ }
3808
+ if (data.json) {
3809
+ o.push('<p>JSON: bad.</p>');
3810
+ }
3811
+ o.push('</div>');
3812
+ }
3813
+
3814
+ if (!option) {
3815
+
3816
+ o.push('<br><div id=functions>');
3817
+
3818
+ if (data.urls) {
3819
+ detail("URLs<br>", data.urls, '<br>');
3820
+ }
3821
+
3822
+ if (data.json && !err) {
3823
+ o.push('<p>JSON: good.</p>');
3824
+ } else if (data.globals) {
3825
+ o.push('<div><i>Global</i> ' +
3826
+ data.globals.sort().join(', ') + '</div>');
3827
+ } else {
3828
+ o.push('<div><i>No new global variables introduced.</i></div>');
3829
+ }
3830
+
3831
+ for (i = 0; i < data.functions.length; i += 1) {
3832
+ f = data.functions[i];
3833
+
3834
+ o.push('<br><div class=function><i>' + f.line + '-' +
3835
+ f.last + '</i> ' + (f.name || '') + '(' +
3836
+ (f.param ? f.param.join(', ') : '') + ')</div>');
3837
+ detail('<big><b>Unused</b></big>', f.unused);
3838
+ detail('Closure', f.closure);
3839
+ detail('Variable', f['var']);
3840
+ detail('Exception', f.exception);
3841
+ detail('Outer', f.outer);
3842
+ detail('Global', f.global);
3843
+ detail('Label', f.label);
3844
+ }
3845
+
3846
+ if (data.member) {
3847
+ a = Object.keys(data.member);
3848
+ if (a.length) {
3849
+ a = a.sort();
3850
+ m = '<br><pre id=members>/*members ';
3851
+ l = 10;
3852
+ for (i = 0; i < a.length; i += 1) {
3853
+ k = a[i];
3854
+ n = k.name();
3855
+ if (l + n.length > 72) {
3856
+ o.push(m + '<br>');
3857
+ m = ' ';
3858
+ l = 1;
3859
+ }
3860
+ l += n.length + 2;
3861
+ if (data.member[k] === 1) {
3862
+ n = '<i>' + n + '</i>';
3863
+ }
3864
+ if (i < a.length - 1) {
3865
+ n += ', ';
3866
+ }
3867
+ m += n;
3868
+ }
3869
+ o.push(m + '<br>*/</pre>');
3870
+ }
3871
+ o.push('</div>');
3872
+ }
3873
+ }
3874
+ return o.join('');
3875
+ };
3876
+ itself.jshint = itself;
3877
+
3878
+ itself.edition = '2011-04-16';
3879
+
3880
+ return itself;
3881
+
3882
+ }());
3883
+
3884
+ // Make JSHINT a Node module, if possible.
3885
+ if (typeof exports == 'object' && exports)
3886
+ exports.JSHINT = JSHINT;