imported the whole jquery-ui package, refreshed with 1.10.2
[myslice.git] / third-party / jquery-ui-1.10.2 / external / jshint.js
1 /*!
2  * JSHint, by JSHint Community.
3  *
4  * This file (and this file only) is licensed under the same slightly modified
5  * MIT license that JSLint is. 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  */
32
33 /*
34  JSHINT is a global function. It takes two parameters.
35
36      var myResult = JSHINT(source, option);
37
38  The first parameter is either a string or an array of strings. If it is a
39  string, it will be split on '\n' or '\r'. If it is an array of strings, it
40  is assumed that each string represents one line. The source can be a
41  JavaScript text or a JSON text.
42
43  The second parameter is an optional object of options which control the
44  operation of JSHINT. Most of the options are booleans: They are all
45  optional and have a default value of false. One of the options, predef,
46  can be an array of names, which will be used to declare global variables,
47  or an object whose keys are used as global names, with a boolean value
48  that determines if they are assignable.
49
50  If it checks out, JSHINT returns true. Otherwise, it returns false.
51
52  If false, you can inspect JSHINT.errors to find out the problems.
53  JSHINT.errors is an array of objects containing these members:
54
55  {
56      line      : The line (relative to 1) at which the lint was found
57      character : The character (relative to 1) at which the lint was found
58      reason    : The problem
59      evidence  : The text line in which the problem occurred
60      raw       : The raw message before the details were inserted
61      a         : The first detail
62      b         : The second detail
63      c         : The third detail
64      d         : The fourth detail
65  }
66
67  If a fatal error was found, a null will be the last element of the
68  JSHINT.errors array.
69
70  You can request a data structure which contains JSHint's results.
71
72      var myData = JSHINT.data();
73
74  It returns a structure with this form:
75
76  {
77      errors: [
78          {
79              line: NUMBER,
80              character: NUMBER,
81              reason: STRING,
82              evidence: STRING
83          }
84      ],
85      functions: [
86          name: STRING,
87          line: NUMBER,
88          character: NUMBER,
89          last: NUMBER,
90          lastcharacter: NUMBER,
91          param: [
92              STRING
93          ],
94          closure: [
95              STRING
96          ],
97          var: [
98              STRING
99          ],
100          exception: [
101              STRING
102          ],
103          outer: [
104              STRING
105          ],
106          unused: [
107              STRING
108          ],
109          global: [
110              STRING
111          ],
112          label: [
113              STRING
114          ]
115      ],
116      globals: [
117          STRING
118      ],
119      member: {
120          STRING: NUMBER
121      },
122      unused: [
123          {
124              name: STRING,
125              line: NUMBER
126          }
127      ],
128      implieds: [
129          {
130              name: STRING,
131              line: NUMBER
132          }
133      ],
134      urls: [
135          STRING
136      ],
137      json: BOOLEAN
138  }
139
140  Empty arrays will not be included.
141
142 */
143
144 /*jshint
145  evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true,
146  undef: true, maxlen: 100, indent: 4, quotmark: double, unused: true
147 */
148
149 /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)",
150  "(breakage)", "(character)", "(context)", "(error)", "(explicitNewcap)", "(global)",
151  "(identifier)", "(last)", "(lastcharacter)", "(line)", "(loopage)", "(metrics)",
152  "(name)", "(onevar)", "(params)", "(scope)", "(statement)", "(verb)", "(tokens)", "(catch)",
153  "*", "+", "++", "-", "--", "\/", "<", "<=", "==",
154  "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax,
155  __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio,
156  Autocompleter, Asset, Boolean, Builder, Buffer, Browser, Blob, COM, CScript, Canvas,
157  CustomAnimation, Class, Control, ComplexityCount, Chain, Color, Cookie, Core, DataView, Date,
158  Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMEvent, DOMReady, DOMParser,
159  Drag, E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event,
160  Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form,
161  FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey,
162  HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement,
163  HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement,
164  HTMLDivElement, HTMLDListElement, HTMLFieldSetElement,
165  HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement,
166  HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement,
167  HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement,
168  HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement,
169  HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement,
170  HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement,
171  HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement,
172  HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement,
173  HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement,
174  HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement,
175  HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement,
176  Iframe, IframeShim, Image, importScripts, Int16Array, Int32Array, Int8Array,
177  Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E,
178  MAX_VALUE, MIN_VALUE, Map, Mask, Math, MenuItem, MessageChannel, MessageEvent, MessagePort,
179  MoveAnimation, MooTools, MutationObserver, NaN, Native, NEGATIVE_INFINITY, Node, NodeFilter,
180  Number, Object, ObjectRange,
181  Option, Options, OverText, PI, POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype,
182  RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, Set,
183  SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion,
184  ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller,
185  Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables,
186  SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template,
187  Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL,
188  VBArray, WeakMap, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XMLSerializer,
189  XPathEvaluator, XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult,
190  "\\", a, abs, addEventListener, address, alert, apply, applicationCache, arguments, arity,
191  asi, atob, b, basic, basicToken, bitwise, blacklist, block, blur, boolOptions, boss,
192  browser, btoa, c, call, callee, caller, camelcase, cases, charAt, charCodeAt, character,
193  clearInterval, clearTimeout, close, closed, closure, comment, complexityCount, condition,
194  confirm, console, constructor, content, couch, create, css, curly, d, data, datalist, dd, debug,
195  decodeURI, decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document,
196  dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent, elem,
197  eqeq, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil,
198  ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus, forEach,
199  forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions,
200  g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict,
201  hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include,
202  indent, indexOf, init, ins, internals, instanceOf, isAlpha, isApplicationRunning, isArray,
203  isDigit, isFinite, isNaN, iterator, java, join, jshint,
204  JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastcharacter, lastsemic, laxbreak,
205  laxcomma, latedef, lbp, led, left, length, line, load, loadClass, localStorage, location,
206  log, loopfunc, m, match, max, maxcomplexity, maxdepth, maxerr, maxlen, maxstatements, maxparams,
207  member, message, meta, module, moveBy, moveTo, mootools, multistr, name, navigator, new, newcap,
208  nestedBlockDepth, noarg, node, noempty, nomen, nonew, nonstandard, nud, onbeforeunload, onblur,
209  onerror, onevar, onecase, onfocus, onload, onresize, onunload, open, openDatabase, openURL,
210  opener, opera, options, outer, param, parent, parseFloat, parseInt, passfail, plusplus,
211  postMessage, pop, predef, print, process, prompt, proto, prototype, prototypejs, provides, push,
212  quit, quotmark, range, raw, reach, reason, regexp, readFile, readUrl, regexdash,
213  removeEventListener, replace, report, require, reserved, resizeBy, resizeTo, resolvePath,
214  resumeUpdates, respond, rhino, right, runCommand, scroll, scope, screen, scripturl, scrollBy,
215  scrollTo, scrollbar, search, seal, self, send, serialize, sessionStorage, setInterval, setTimeout,
216  setter, setterToken, shift, slice, smarttabs, sort, spawn, split, statement, statementCount, stack,
217  status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync, test, toLowerCase,
218  toString, toUpperCase, toint32, token, tokens, top, trailing, type, typeOf, Uint16Array,
219  Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, value, valueOf, var, vars,
220  version, verifyMaxParametersPerFunction, verifyMaxStatementsPerFunction,
221  verifyMaxComplexityPerFunction, verifyMaxNestedBlockDepthPerFunction, WebSocket, withstmt, white,
222  window, windows, Worker, worker, wsh, yui, YUI, Y, YUI_config*/
223
224 /*global exports: false */
225
226 // We build the application inside a function so that we produce only a single
227 // global variable. That function will be invoked immediately, and its return
228 // value is the JSHINT function itself.
229
230 var JSHINT = (function () {
231     "use strict";
232
233     var anonname,       // The guessed name for anonymous functions.
234
235 // These are operators that should not be used with the ! operator.
236
237         bang = {
238             "<"  : true,
239             "<=" : true,
240             "==" : true,
241             "===": true,
242             "!==": true,
243             "!=" : true,
244             ">"  : true,
245             ">=" : true,
246             "+"  : true,
247             "-"  : true,
248             "*"  : true,
249             "/"  : true,
250             "%"  : true
251         },
252
253         // These are the JSHint boolean options.
254         boolOptions = {
255             asi         : true, // if automatic semicolon insertion should be tolerated
256             bitwise     : true, // if bitwise operators should not be allowed
257             boss        : true, // if advanced usage of assignments should be allowed
258             browser     : true, // if the standard browser globals should be predefined
259             camelcase   : true, // if identifiers should be required in camel case
260             couch       : true, // if CouchDB globals should be predefined
261             curly       : true, // if curly braces around all blocks should be required
262             debug       : true, // if debugger statements should be allowed
263             devel       : true, // if logging globals should be predefined (console,
264                                 // alert, etc.)
265             dojo        : true, // if Dojo Toolkit globals should be predefined
266             eqeqeq      : true, // if === should be required
267             eqnull      : true, // if == null comparisons should be tolerated
268             es5         : true, // if ES5 syntax should be allowed
269             esnext      : true, // if es.next specific syntax should be allowed
270             evil        : true, // if eval should be allowed
271             expr        : true, // if ExpressionStatement should be allowed as Programs
272             forin       : true, // if for in statements must filter
273             funcscope   : true, // if only function scope should be used for scope tests
274             globalstrict: true, // if global "use strict"; should be allowed (also
275                                 // enables 'strict')
276             immed       : true, // if immediate invocations must be wrapped in parens
277             iterator    : true, // if the `__iterator__` property should be allowed
278             jquery      : true, // if jQuery globals should be predefined
279             lastsemic   : true, // if semicolons may be ommitted for the trailing
280                                 // statements inside of a one-line blocks.
281             latedef     : true, // if the use before definition should not be tolerated
282             laxbreak    : true, // if line breaks should not be checked
283             laxcomma    : true, // if line breaks should not be checked around commas
284             loopfunc    : true, // if functions should be allowed to be defined within
285                                 // loops
286             mootools    : true, // if MooTools globals should be predefined
287             multistr    : true, // allow multiline strings
288             newcap      : true, // if constructor names must be capitalized
289             noarg       : true, // if arguments.caller and arguments.callee should be
290                                 // disallowed
291             node        : true, // if the Node.js environment globals should be
292                                 // predefined
293             noempty     : true, // if empty blocks should be disallowed
294             nonew       : true, // if using `new` for side-effects should be disallowed
295             nonstandard : true, // if non-standard (but widely adopted) globals should
296                                 // be predefined
297             nomen       : true, // if names should be checked
298             onevar      : true, // if only one var statement per function should be
299                                 // allowed
300             onecase     : true, // if one case switch statements should be allowed
301             passfail    : true, // if the scan should stop on first error
302             plusplus    : true, // if increment/decrement should not be allowed
303             proto       : true, // if the `__proto__` property should be allowed
304             prototypejs : true, // if Prototype and Scriptaculous globals should be
305                                 // predefined
306             regexdash   : true, // if unescaped first/last dash (-) inside brackets
307                                 // should be tolerated
308             regexp      : true, // if the . should not be allowed in regexp literals
309             rhino       : true, // if the Rhino environment globals should be predefined
310             undef       : true, // if variables should be declared before used
311             unused      : true, // if variables should be always used
312             scripturl   : true, // if script-targeted URLs should be tolerated
313             shadow      : true, // if variable shadowing should be tolerated
314             smarttabs   : true, // if smarttabs should be tolerated
315                                 // (http://www.emacswiki.org/emacs/SmartTabs)
316             strict      : true, // require the "use strict"; pragma
317             sub         : true, // if all forms of subscript notation are tolerated
318             supernew    : true, // if `new function () { ... };` and `new Object;`
319                                 // should be tolerated
320             trailing    : true, // if trailing whitespace rules apply
321             validthis   : true, // if 'this' inside a non-constructor function is valid.
322                                 // This is a function scoped option only.
323             withstmt    : true, // if with statements should be allowed
324             white       : true, // if strict whitespace rules apply
325             worker      : true, // if Web Worker script symbols should be allowed
326             wsh         : true, // if the Windows Scripting Host environment globals
327                                 // should be predefined
328             yui         : true  // YUI variables should be predefined
329         },
330
331         // These are the JSHint options that can take any value
332         // (we use this object to detect invalid options)
333         valOptions = {
334             maxlen       : false,
335             indent       : false,
336             maxerr       : false,
337             predef       : false,
338             quotmark     : false, //'single'|'double'|true
339             scope        : false,
340             maxstatements: false, // {int} max statements per function
341             maxdepth     : false, // {int} max nested block depth per function
342             maxparams    : false, // {int} max params per function
343             maxcomplexity: false  // {int} max cyclomatic complexity per function
344         },
345
346         // These are JSHint boolean options which are shared with JSLint
347         // where the definition in JSHint is opposite JSLint
348         invertedOptions = {
349             bitwise     : true,
350             forin       : true,
351             newcap      : true,
352             nomen       : true,
353             plusplus    : true,
354             regexp      : true,
355             undef       : true,
356             white       : true,
357
358             // Inverted and renamed, use JSHint name here
359             eqeqeq      : true,
360             onevar      : true
361         },
362
363         // These are JSHint boolean options which are shared with JSLint
364         // where the name has been changed but the effect is unchanged
365         renamedOptions = {
366             eqeq        : "eqeqeq",
367             vars        : "onevar",
368             windows     : "wsh"
369         },
370
371
372         // browser contains a set of global names which are commonly provided by a
373         // web browser environment.
374         browser = {
375             ArrayBuffer              :  false,
376             ArrayBufferView          :  false,
377             Audio                    :  false,
378             Blob                     :  false,
379             addEventListener         :  false,
380             applicationCache         :  false,
381             atob                     :  false,
382             blur                     :  false,
383             btoa                     :  false,
384             clearInterval            :  false,
385             clearTimeout             :  false,
386             close                    :  false,
387             closed                   :  false,
388             DataView                 :  false,
389             DOMParser                :  false,
390             defaultStatus            :  false,
391             document                 :  false,
392             event                    :  false,
393             FileReader               :  false,
394             Float32Array             :  false,
395             Float64Array             :  false,
396             FormData                 :  false,
397             focus                    :  false,
398             frames                   :  false,
399             getComputedStyle         :  false,
400             HTMLElement              :  false,
401             HTMLAnchorElement        :  false,
402             HTMLBaseElement          :  false,
403             HTMLBlockquoteElement    :  false,
404             HTMLBodyElement          :  false,
405             HTMLBRElement            :  false,
406             HTMLButtonElement        :  false,
407             HTMLCanvasElement        :  false,
408             HTMLDirectoryElement     :  false,
409             HTMLDivElement           :  false,
410             HTMLDListElement         :  false,
411             HTMLFieldSetElement      :  false,
412             HTMLFontElement          :  false,
413             HTMLFormElement          :  false,
414             HTMLFrameElement         :  false,
415             HTMLFrameSetElement      :  false,
416             HTMLHeadElement          :  false,
417             HTMLHeadingElement       :  false,
418             HTMLHRElement            :  false,
419             HTMLHtmlElement          :  false,
420             HTMLIFrameElement        :  false,
421             HTMLImageElement         :  false,
422             HTMLInputElement         :  false,
423             HTMLIsIndexElement       :  false,
424             HTMLLabelElement         :  false,
425             HTMLLayerElement         :  false,
426             HTMLLegendElement        :  false,
427             HTMLLIElement            :  false,
428             HTMLLinkElement          :  false,
429             HTMLMapElement           :  false,
430             HTMLMenuElement          :  false,
431             HTMLMetaElement          :  false,
432             HTMLModElement           :  false,
433             HTMLObjectElement        :  false,
434             HTMLOListElement         :  false,
435             HTMLOptGroupElement      :  false,
436             HTMLOptionElement        :  false,
437             HTMLParagraphElement     :  false,
438             HTMLParamElement         :  false,
439             HTMLPreElement           :  false,
440             HTMLQuoteElement         :  false,
441             HTMLScriptElement        :  false,
442             HTMLSelectElement        :  false,
443             HTMLStyleElement         :  false,
444             HTMLTableCaptionElement  :  false,
445             HTMLTableCellElement     :  false,
446             HTMLTableColElement      :  false,
447             HTMLTableElement         :  false,
448             HTMLTableRowElement      :  false,
449             HTMLTableSectionElement  :  false,
450             HTMLTextAreaElement      :  false,
451             HTMLTitleElement         :  false,
452             HTMLUListElement         :  false,
453             HTMLVideoElement         :  false,
454             history                  :  false,
455             Int16Array               :  false,
456             Int32Array               :  false,
457             Int8Array                :  false,
458             Image                    :  false,
459             length                   :  false,
460             localStorage             :  false,
461             location                 :  false,
462             MessageChannel           :  false,
463             MessageEvent             :  false,
464             MessagePort              :  false,
465             moveBy                   :  false,
466             moveTo                   :  false,
467             MutationObserver         :  false,
468             name                     :  false,
469             Node                     :  false,
470             NodeFilter               :  false,
471             navigator                :  false,
472             onbeforeunload           :  true,
473             onblur                   :  true,
474             onerror                  :  true,
475             onfocus                  :  true,
476             onload                   :  true,
477             onresize                 :  true,
478             onunload                 :  true,
479             open                     :  false,
480             openDatabase             :  false,
481             opener                   :  false,
482             Option                   :  false,
483             parent                   :  false,
484             print                    :  false,
485             removeEventListener      :  false,
486             resizeBy                 :  false,
487             resizeTo                 :  false,
488             screen                   :  false,
489             scroll                   :  false,
490             scrollBy                 :  false,
491             scrollTo                 :  false,
492             sessionStorage           :  false,
493             setInterval              :  false,
494             setTimeout               :  false,
495             SharedWorker             :  false,
496             status                   :  false,
497             top                      :  false,
498             Uint16Array              :  false,
499             Uint32Array              :  false,
500             Uint8Array               :  false,
501             WebSocket                :  false,
502             window                   :  false,
503             Worker                   :  false,
504             XMLHttpRequest           :  false,
505             XMLSerializer            :  false,
506             XPathEvaluator           :  false,
507             XPathException           :  false,
508             XPathExpression          :  false,
509             XPathNamespace           :  false,
510             XPathNSResolver          :  false,
511             XPathResult              :  false
512         },
513
514         couch = {
515             "require" : false,
516             respond   : false,
517             getRow    : false,
518             emit      : false,
519             send      : false,
520             start     : false,
521             sum       : false,
522             log       : false,
523             exports   : false,
524             module    : false,
525             provides  : false
526         },
527
528         declared, // Globals that were declared using /*global ... */ syntax.
529
530         devel = {
531             alert   : false,
532             confirm : false,
533             console : false,
534             Debug   : false,
535             opera   : false,
536             prompt  : false
537         },
538
539         dojo = {
540             dojo      : false,
541             dijit     : false,
542             dojox     : false,
543             define    : false,
544             "require" : false
545         },
546
547         funct,          // The current function
548
549         functionicity = [
550             "closure", "exception", "global", "label",
551             "outer", "unused", "var"
552         ],
553
554         functions,      // All of the functions
555
556         global,         // The global scope
557         implied,        // Implied globals
558         inblock,
559         indent,
560         jsonmode,
561
562         jquery = {
563             "$"    : false,
564             jQuery : false
565         },
566
567         lines,
568         lookahead,
569         member,
570         membersOnly,
571
572         mootools = {
573             "$"             : false,
574             "$$"            : false,
575             Asset           : false,
576             Browser         : false,
577             Chain           : false,
578             Class           : false,
579             Color           : false,
580             Cookie          : false,
581             Core            : false,
582             Document        : false,
583             DomReady        : false,
584             DOMEvent        : false,
585             DOMReady        : false,
586             Drag            : false,
587             Element         : false,
588             Elements        : false,
589             Event           : false,
590             Events          : false,
591             Fx              : false,
592             Group           : false,
593             Hash            : false,
594             HtmlTable       : false,
595             Iframe          : false,
596             IframeShim      : false,
597             InputValidator  : false,
598             instanceOf      : false,
599             Keyboard        : false,
600             Locale          : false,
601             Mask            : false,
602             MooTools        : false,
603             Native          : false,
604             Options         : false,
605             OverText        : false,
606             Request         : false,
607             Scroller        : false,
608             Slick           : false,
609             Slider          : false,
610             Sortables       : false,
611             Spinner         : false,
612             Swiff           : false,
613             Tips            : false,
614             Type            : false,
615             typeOf          : false,
616             URI             : false,
617             Window          : false
618         },
619
620         nexttoken,
621
622         node = {
623             __filename    : false,
624             __dirname     : false,
625             Buffer        : false,
626             console       : false,
627             exports       : true,  // In Node it is ok to exports = module.exports = foo();
628             GLOBAL        : false,
629             global        : false,
630             module        : false,
631             process       : false,
632             require       : false,
633             setTimeout    : false,
634             clearTimeout  : false,
635             setInterval   : false,
636             clearInterval : false
637         },
638
639         noreach,
640         option,
641         predefined,     // Global variables defined by option
642         prereg,
643         prevtoken,
644
645         prototypejs = {
646             "$"               : false,
647             "$$"              : false,
648             "$A"              : false,
649             "$F"              : false,
650             "$H"              : false,
651             "$R"              : false,
652             "$break"          : false,
653             "$continue"       : false,
654             "$w"              : false,
655             Abstract          : false,
656             Ajax              : false,
657             Class             : false,
658             Enumerable        : false,
659             Element           : false,
660             Event             : false,
661             Field             : false,
662             Form              : false,
663             Hash              : false,
664             Insertion         : false,
665             ObjectRange       : false,
666             PeriodicalExecuter: false,
667             Position          : false,
668             Prototype         : false,
669             Selector          : false,
670             Template          : false,
671             Toggle            : false,
672             Try               : false,
673             Autocompleter     : false,
674             Builder           : false,
675             Control           : false,
676             Draggable         : false,
677             Draggables        : false,
678             Droppables        : false,
679             Effect            : false,
680             Sortable          : false,
681             SortableObserver  : false,
682             Sound             : false,
683             Scriptaculous     : false
684         },
685
686         quotmark,
687
688         rhino = {
689             defineClass  : false,
690             deserialize  : false,
691             gc           : false,
692             help         : false,
693             importPackage: false,
694             "java"       : false,
695             load         : false,
696             loadClass    : false,
697             print        : false,
698             quit         : false,
699             readFile     : false,
700             readUrl      : false,
701             runCommand   : false,
702             seal         : false,
703             serialize    : false,
704             spawn        : false,
705             sync         : false,
706             toint32      : false,
707             version      : false
708         },
709
710         scope,      // The current scope
711         stack,
712
713         // standard contains the global names that are provided by the
714         // ECMAScript standard.
715         standard = {
716             Array               : false,
717             Boolean             : false,
718             Date                : false,
719             decodeURI           : false,
720             decodeURIComponent  : false,
721             encodeURI           : false,
722             encodeURIComponent  : false,
723             Error               : false,
724             "eval"              : false,
725             EvalError           : false,
726             Function            : false,
727             hasOwnProperty      : false,
728             isFinite            : false,
729             isNaN               : false,
730             JSON                : false,
731             Map                 : false,
732             Math                : false,
733             NaN                 : false,
734             Number              : false,
735             Object              : false,
736             parseInt            : false,
737             parseFloat          : false,
738             RangeError          : false,
739             ReferenceError      : false,
740             RegExp              : false,
741             Set                 : false,
742             String              : false,
743             SyntaxError         : false,
744             TypeError           : false,
745             URIError            : false,
746             WeakMap             : false
747         },
748
749         // widely adopted global names that are not part of ECMAScript standard
750         nonstandard = {
751             escape              : false,
752             unescape            : false
753         },
754
755         directive,
756         syntax = {},
757         tab,
758         token,
759         unuseds,
760         urls,
761         useESNextSyntax,
762         warnings,
763
764         worker = {
765             importScripts       : true,
766             postMessage         : true,
767             self                : true
768         },
769
770         wsh = {
771             ActiveXObject             : true,
772             Enumerator                : true,
773             GetObject                 : true,
774             ScriptEngine              : true,
775             ScriptEngineBuildVersion  : true,
776             ScriptEngineMajorVersion  : true,
777             ScriptEngineMinorVersion  : true,
778             VBArray                   : true,
779             WSH                       : true,
780             WScript                   : true,
781             XDomainRequest            : true
782         },
783
784         yui = {
785             YUI             : false,
786             Y               : false,
787             YUI_config      : false
788         };
789     // Regular expressions. Some of these are stupidly long.
790     var ax, cx, tx, nx, nxg, lx, ix, jx, ft;
791     (function () {
792         /*jshint maxlen:300 */
793
794         // unsafe comment or string
795         ax = /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
796
797         // unsafe characters that are silently deleted by one or more browsers
798         cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
799
800         // token
801         tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/;
802
803         // characters in strings that need escapement
804         nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
805         nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
806
807         // star slash
808         lx = /\*\//;
809
810         // identifier
811         ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
812
813         // javascript url
814         jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
815
816         // catches /* falls through */ comments
817         ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
818     }());
819
820     function F() {}     // Used by Object.create
821
822     function is_own(object, name) {
823         // The object.hasOwnProperty method fails when the property under consideration
824         // is named 'hasOwnProperty'. So we have to use this more convoluted form.
825         return Object.prototype.hasOwnProperty.call(object, name);
826     }
827
828     function checkOption(name, t) {
829         if (valOptions[name] === undefined && boolOptions[name] === undefined) {
830             warning("Bad option: '" + name + "'.", t);
831         }
832     }
833
834     function isString(obj) {
835         return Object.prototype.toString.call(obj) === "[object String]";
836     }
837
838     // Provide critical ES5 functions to ES3.
839
840     if (typeof Array.isArray !== "function") {
841         Array.isArray = function (o) {
842             return Object.prototype.toString.apply(o) === "[object Array]";
843         };
844     }
845
846     if (!Array.prototype.forEach) {
847         Array.prototype.forEach = function (fn, scope) {
848             var len = this.length;
849
850             for (var i = 0; i < len; i++) {
851                 fn.call(scope || this, this[i], i, this);
852             }
853         };
854     }
855
856     if (!Array.prototype.indexOf) {
857         Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
858             if (this === null || this === undefined) {
859                 throw new TypeError();
860             }
861
862             var t = new Object(this);
863             var len = t.length >>> 0;
864
865             if (len === 0) {
866                 return -1;
867             }
868
869             var n = 0;
870             if (arguments.length > 0) {
871                 n = Number(arguments[1]);
872                 if (n != n) { // shortcut for verifying if it's NaN
873                     n = 0;
874                 } else if (n !== 0 && n != Infinity && n != -Infinity) {
875                     n = (n > 0 || -1) * Math.floor(Math.abs(n));
876                 }
877             }
878
879             if (n >= len) {
880                 return -1;
881             }
882
883             var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
884             for (; k < len; k++) {
885                 if (k in t && t[k] === searchElement) {
886                     return k;
887                 }
888             }
889
890             return -1;
891         };
892     }
893
894     if (typeof Object.create !== "function") {
895         Object.create = function (o) {
896             F.prototype = o;
897             return new F();
898         };
899     }
900
901     if (typeof Object.keys !== "function") {
902         Object.keys = function (o) {
903             var a = [], k;
904             for (k in o) {
905                 if (is_own(o, k)) {
906                     a.push(k);
907                 }
908             }
909             return a;
910         };
911     }
912
913     // Non standard methods
914
915     function isAlpha(str) {
916         return (str >= "a" && str <= "z\uffff") ||
917             (str >= "A" && str <= "Z\uffff");
918     }
919
920     function isDigit(str) {
921         return (str >= "0" && str <= "9");
922     }
923
924     function isIdentifier(token, value) {
925         if (!token)
926             return false;
927
928         if (!token.identifier || token.value !== value)
929             return false;
930
931         return true;
932     }
933
934     function supplant(str, data) {
935         return str.replace(/\{([^{}]*)\}/g, function (a, b) {
936             var r = data[b];
937             return typeof r === "string" || typeof r === "number" ? r : a;
938         });
939     }
940
941     function combine(t, o) {
942         var n;
943         for (n in o) {
944             if (is_own(o, n) && !is_own(JSHINT.blacklist, n)) {
945                 t[n] = o[n];
946             }
947         }
948     }
949
950     function updatePredefined() {
951         Object.keys(JSHINT.blacklist).forEach(function (key) {
952             delete predefined[key];
953         });
954     }
955
956     function assume() {
957         if (option.couch) {
958             combine(predefined, couch);
959         }
960
961         if (option.rhino) {
962             combine(predefined, rhino);
963         }
964
965         if (option.prototypejs) {
966             combine(predefined, prototypejs);
967         }
968
969         if (option.node) {
970             combine(predefined, node);
971             option.globalstrict = true;
972         }
973
974         if (option.devel) {
975             combine(predefined, devel);
976         }
977
978         if (option.dojo) {
979             combine(predefined, dojo);
980         }
981
982         if (option.browser) {
983             combine(predefined, browser);
984         }
985
986         if (option.nonstandard) {
987             combine(predefined, nonstandard);
988         }
989
990         if (option.jquery) {
991             combine(predefined, jquery);
992         }
993
994         if (option.mootools) {
995             combine(predefined, mootools);
996         }
997
998         if (option.worker) {
999             combine(predefined, worker);
1000         }
1001
1002         if (option.wsh) {
1003             combine(predefined, wsh);
1004         }
1005
1006         if (option.esnext) {
1007             useESNextSyntax();
1008         }
1009
1010         if (option.globalstrict && option.strict !== false) {
1011             option.strict = true;
1012         }
1013
1014         if (option.yui) {
1015             combine(predefined, yui);
1016         }
1017     }
1018
1019
1020     // Produce an error warning.
1021     function quit(message, line, chr) {
1022         var percentage = Math.floor((line / lines.length) * 100);
1023
1024         throw {
1025             name: "JSHintError",
1026             line: line,
1027             character: chr,
1028             message: message + " (" + percentage + "% scanned).",
1029             raw: message
1030         };
1031     }
1032
1033     function isundef(scope, m, t, a) {
1034         return JSHINT.undefs.push([scope, m, t, a]);
1035     }
1036
1037     function warning(m, t, a, b, c, d) {
1038         var ch, l, w;
1039         t = t || nexttoken;
1040         if (t.id === "(end)") {  // `~
1041             t = token;
1042         }
1043         l = t.line || 0;
1044         ch = t.from || 0;
1045         w = {
1046             id: "(error)",
1047             raw: m,
1048             evidence: lines[l - 1] || "",
1049             line: l,
1050             character: ch,
1051             scope: JSHINT.scope,
1052             a: a,
1053             b: b,
1054             c: c,
1055             d: d
1056         };
1057         w.reason = supplant(m, w);
1058         JSHINT.errors.push(w);
1059         if (option.passfail) {
1060             quit("Stopping. ", l, ch);
1061         }
1062         warnings += 1;
1063         if (warnings >= option.maxerr) {
1064             quit("Too many errors.", l, ch);
1065         }
1066         return w;
1067     }
1068
1069     function warningAt(m, l, ch, a, b, c, d) {
1070         return warning(m, {
1071             line: l,
1072             from: ch
1073         }, a, b, c, d);
1074     }
1075
1076     function error(m, t, a, b, c, d) {
1077         warning(m, t, a, b, c, d);
1078     }
1079
1080     function errorAt(m, l, ch, a, b, c, d) {
1081         return error(m, {
1082             line: l,
1083             from: ch
1084         }, a, b, c, d);
1085     }
1086
1087     // Tracking of "internal" scripts, like eval containing a static string
1088     function addInternalSrc(elem, src) {
1089         var i;
1090         i = {
1091             id: "(internal)",
1092             elem: elem,
1093             value: src
1094         };
1095         JSHINT.internals.push(i);
1096         return i;
1097     }
1098
1099
1100 // lexical analysis and token construction
1101
1102     var lex = (function lex() {
1103         var character, from, line, s;
1104
1105 // Private lex methods
1106
1107         function nextLine() {
1108             var at,
1109                 match,
1110                 tw; // trailing whitespace check
1111
1112             if (line >= lines.length)
1113                 return false;
1114
1115             character = 1;
1116             s = lines[line];
1117             line += 1;
1118
1119             // If smarttabs option is used check for spaces followed by tabs only.
1120             // Otherwise check for any occurence of mixed tabs and spaces.
1121             // Tabs and one space followed by block comment is allowed.
1122             if (option.smarttabs) {
1123                 // negative look-behind for "//"
1124                 match = s.match(/(\/\/)? \t/);
1125                 at = match && !match[1] ? 0 : -1;
1126             } else {
1127                 at = s.search(/ \t|\t [^\*]/);
1128             }
1129
1130             if (at >= 0)
1131                 warningAt("Mixed spaces and tabs.", line, at + 1);
1132
1133             s = s.replace(/\t/g, tab);
1134             at = s.search(cx);
1135
1136             if (at >= 0)
1137                 warningAt("Unsafe character.", line, at);
1138
1139             if (option.maxlen && option.maxlen < s.length)
1140                 warningAt("Line too long.", line, s.length);
1141
1142             // Check for trailing whitespaces
1143             tw = option.trailing && s.match(/^(.*?)\s+$/);
1144             if (tw && !/^\s+$/.test(s)) {
1145                 warningAt("Trailing whitespace.", line, tw[1].length + 1);
1146             }
1147             return true;
1148         }
1149
1150 // Produce a token object.  The token inherits from a syntax symbol.
1151
1152         function it(type, value) {
1153             var i, t;
1154
1155             function checkName(name) {
1156                 if (!option.proto && name === "__proto__") {
1157                     warningAt("The '{a}' property is deprecated.", line, from, name);
1158                     return;
1159                 }
1160
1161                 if (!option.iterator && name === "__iterator__") {
1162                     warningAt("'{a}' is only available in JavaScript 1.7.", line, from, name);
1163                     return;
1164                 }
1165
1166                 // Check for dangling underscores unless we're in Node
1167                 // environment and this identifier represents built-in
1168                 // Node globals with underscores.
1169
1170                 var hasDangling = /^(_+.*|.*_+)$/.test(name);
1171
1172                 if (option.nomen && hasDangling && name !== "_") {
1173                     if (option.node && token.id !== "." && /^(__dirname|__filename)$/.test(name))
1174                         return;
1175
1176                     warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", name);
1177                     return;
1178                 }
1179
1180                 // Check for non-camelcase names. Names like MY_VAR and
1181                 // _myVar are okay though.
1182
1183                 if (option.camelcase) {
1184                     if (name.replace(/^_+/, "").indexOf("_") > -1 && !name.match(/^[A-Z0-9_]*$/)) {
1185                         warningAt("Identifier '{a}' is not in camel case.", line, from, value);
1186                     }
1187                 }
1188             }
1189
1190             if (type === "(color)" || type === "(range)") {
1191                 t = {type: type};
1192             } else if (type === "(punctuator)" ||
1193                     (type === "(identifier)" && is_own(syntax, value))) {
1194                 t = syntax[value] || syntax["(error)"];
1195             } else {
1196                 t = syntax[type];
1197             }
1198
1199             t = Object.create(t);
1200
1201             if (type === "(string)" || type === "(range)") {
1202                 if (!option.scripturl && jx.test(value)) {
1203                     warningAt("Script URL.", line, from);
1204                 }
1205             }
1206
1207             if (type === "(identifier)") {
1208                 t.identifier = true;
1209                 checkName(value);
1210             }
1211
1212             t.value = value;
1213             t.line = line;
1214             t.character = character;
1215             t.from = from;
1216             i = t.id;
1217             if (i !== "(endline)") {
1218                 prereg = i &&
1219                     (("(,=:[!&|?{};".indexOf(i.charAt(i.length - 1)) >= 0) ||
1220                     i === "return" ||
1221                     i === "case");
1222             }
1223             return t;
1224         }
1225
1226         // Public lex methods
1227         return {
1228             init: function (source) {
1229                 if (typeof source === "string") {
1230                     lines = source
1231                         .replace(/\r\n/g, "\n")
1232                         .replace(/\r/g, "\n")
1233                         .split("\n");
1234                 } else {
1235                     lines = source;
1236                 }
1237
1238                 // If the first line is a shebang (#!), make it a blank and move on.
1239                 // Shebangs are used by Node scripts.
1240                 if (lines[0] && lines[0].substr(0, 2) === "#!")
1241                     lines[0] = "";
1242
1243                 line = 0;
1244                 nextLine();
1245                 from = 1;
1246             },
1247
1248             range: function (begin, end) {
1249                 var c, value = "";
1250                 from = character;
1251                 if (s.charAt(0) !== begin) {
1252                     errorAt("Expected '{a}' and instead saw '{b}'.",
1253                             line, character, begin, s.charAt(0));
1254                 }
1255                 for (;;) {
1256                     s = s.slice(1);
1257                     character += 1;
1258                     c = s.charAt(0);
1259                     switch (c) {
1260                     case "":
1261                         errorAt("Missing '{a}'.", line, character, c);
1262                         break;
1263                     case end:
1264                         s = s.slice(1);
1265                         character += 1;
1266                         return it("(range)", value);
1267                     case "\\":
1268                         warningAt("Unexpected '{a}'.", line, character, c);
1269                     }
1270                     value += c;
1271                 }
1272
1273             },
1274
1275
1276             // token -- this is called by advance to get the next token
1277             token: function () {
1278                 var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange, n;
1279
1280                 function match(x) {
1281                     var r = x.exec(s), r1;
1282
1283                     if (r) {
1284                         l = r[0].length;
1285                         r1 = r[1];
1286                         c = r1.charAt(0);
1287                         s = s.substr(l);
1288                         from = character + l - r1.length;
1289                         character += l;
1290                         return r1;
1291                     }
1292                 }
1293
1294                 function string(x) {
1295                     var c, j, r = "", allowNewLine = false;
1296
1297                     if (jsonmode && x !== "\"") {
1298                         warningAt("Strings must use doublequote.",
1299                                 line, character);
1300                     }
1301
1302                     if (option.quotmark) {
1303                         if (option.quotmark === "single" && x !== "'") {
1304                             warningAt("Strings must use singlequote.",
1305                                     line, character);
1306                         } else if (option.quotmark === "double" && x !== "\"") {
1307                             warningAt("Strings must use doublequote.",
1308                                     line, character);
1309                         } else if (option.quotmark === true) {
1310                             quotmark = quotmark || x;
1311                             if (quotmark !== x) {
1312                                 warningAt("Mixed double and single quotes.",
1313                                         line, character);
1314                             }
1315                         }
1316                     }
1317
1318                     function esc(n) {
1319                         var i = parseInt(s.substr(j + 1, n), 16);
1320                         j += n;
1321                         if (i >= 32 && i <= 126 &&
1322                                 i !== 34 && i !== 92 && i !== 39) {
1323                             warningAt("Unnecessary escapement.", line, character);
1324                         }
1325                         character += n;
1326                         c = String.fromCharCode(i);
1327                     }
1328
1329                     j = 0;
1330
1331 unclosedString:
1332                     for (;;) {
1333                         while (j >= s.length) {
1334                             j = 0;
1335
1336                             var cl = line, cf = from;
1337                             if (!nextLine()) {
1338                                 errorAt("Unclosed string.", cl, cf);
1339                                 break unclosedString;
1340                             }
1341
1342                             if (allowNewLine) {
1343                                 allowNewLine = false;
1344                             } else {
1345                                 warningAt("Unclosed string.", cl, cf);
1346                             }
1347                         }
1348
1349                         c = s.charAt(j);
1350                         if (c === x) {
1351                             character += 1;
1352                             s = s.substr(j + 1);
1353                             return it("(string)", r, x);
1354                         }
1355
1356                         if (c < " ") {
1357                             if (c === "\n" || c === "\r") {
1358                                 break;
1359                             }
1360                             warningAt("Control character in string: {a}.",
1361                                     line, character + j, s.slice(0, j));
1362                         } else if (c === "\\") {
1363                             j += 1;
1364                             character += 1;
1365                             c = s.charAt(j);
1366                             n = s.charAt(j + 1);
1367                             switch (c) {
1368                             case "\\":
1369                             case "\"":
1370                             case "/":
1371                                 break;
1372                             case "\'":
1373                                 if (jsonmode) {
1374                                     warningAt("Avoid \\'.", line, character);
1375                                 }
1376                                 break;
1377                             case "b":
1378                                 c = "\b";
1379                                 break;
1380                             case "f":
1381                                 c = "\f";
1382                                 break;
1383                             case "n":
1384                                 c = "\n";
1385                                 break;
1386                             case "r":
1387                                 c = "\r";
1388                                 break;
1389                             case "t":
1390                                 c = "\t";
1391                                 break;
1392                             case "0":
1393                                 c = "\0";
1394                                 // Octal literals fail in strict mode
1395                                 // check if the number is between 00 and 07
1396                                 // where 'n' is the token next to 'c'
1397                                 if (n >= 0 && n <= 7 && directive["use strict"]) {
1398                                     warningAt(
1399                                     "Octal literals are not allowed in strict mode.",
1400                                     line, character);
1401                                 }
1402                                 break;
1403                             case "u":
1404                                 esc(4);
1405                                 break;
1406                             case "v":
1407                                 if (jsonmode) {
1408                                     warningAt("Avoid \\v.", line, character);
1409                                 }
1410                                 c = "\v";
1411                                 break;
1412                             case "x":
1413                                 if (jsonmode) {
1414                                     warningAt("Avoid \\x-.", line, character);
1415                                 }
1416                                 esc(2);
1417                                 break;
1418                             case "":
1419                                 // last character is escape character
1420                                 // always allow new line if escaped, but show
1421                                 // warning if option is not set
1422                                 allowNewLine = true;
1423                                 if (option.multistr) {
1424                                     if (jsonmode) {
1425                                         warningAt("Avoid EOL escapement.", line, character);
1426                                     }
1427                                     c = "";
1428                                     character -= 1;
1429                                     break;
1430                                 }
1431                                 warningAt("Bad escapement of EOL. Use option multistr if needed.",
1432                                     line, character);
1433                                 break;
1434                             case "!":
1435                                 if (s.charAt(j - 2) === "<")
1436                                     break;
1437                                 /*falls through*/
1438                             default:
1439                                 warningAt("Bad escapement.", line, character);
1440                             }
1441                         }
1442                         r += c;
1443                         character += 1;
1444                         j += 1;
1445                     }
1446                 }
1447
1448                 for (;;) {
1449                     if (!s) {
1450                         return it(nextLine() ? "(endline)" : "(end)", "");
1451                     }
1452
1453                     t = match(tx);
1454
1455                     if (!t) {
1456                         t = "";
1457                         c = "";
1458                         while (s && s < "!") {
1459                             s = s.substr(1);
1460                         }
1461                         if (s) {
1462                             errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1));
1463                             s = "";
1464                         }
1465                     } else {
1466
1467     //      identifier
1468
1469                         if (isAlpha(c) || c === "_" || c === "$") {
1470                             return it("(identifier)", t);
1471                         }
1472
1473     //      number
1474
1475                         if (isDigit(c)) {
1476                             if (!isFinite(Number(t))) {
1477                                 warningAt("Bad number '{a}'.",
1478                                     line, character, t);
1479                             }
1480                             if (isAlpha(s.substr(0, 1))) {
1481                                 warningAt("Missing space after '{a}'.",
1482                                         line, character, t);
1483                             }
1484                             if (c === "0") {
1485                                 d = t.substr(1, 1);
1486                                 if (isDigit(d)) {
1487                                     if (token.id !== ".") {
1488                                         warningAt("Don't use extra leading zeros '{a}'.",
1489                                             line, character, t);
1490                                     }
1491                                 } else if (jsonmode && (d === "x" || d === "X")) {
1492                                     warningAt("Avoid 0x-. '{a}'.",
1493                                             line, character, t);
1494                                 }
1495                             }
1496                             if (t.substr(t.length - 1) === ".") {
1497                                 warningAt(
1498 "A trailing decimal point can be confused with a dot '{a}'.", line, character, t);
1499                             }
1500                             return it("(number)", t);
1501                         }
1502                         switch (t) {
1503
1504     //      string
1505
1506                         case "\"":
1507                         case "'":
1508                             return string(t);
1509
1510     //      // comment
1511
1512                         case "//":
1513                             s = "";
1514                             token.comment = true;
1515                             break;
1516
1517     //      /* comment
1518
1519                         case "/*":
1520                             for (;;) {
1521                                 i = s.search(lx);
1522                                 if (i >= 0) {
1523                                     break;
1524                                 }
1525                                 if (!nextLine()) {
1526                                     errorAt("Unclosed comment.", line, character);
1527                                 }
1528                             }
1529                             s = s.substr(i + 2);
1530                             token.comment = true;
1531                             break;
1532
1533     //      /*members /*jshint /*global
1534
1535                         case "/*members":
1536                         case "/*member":
1537                         case "/*jshint":
1538                         case "/*jslint":
1539                         case "/*global":
1540                         case "*/":
1541                             return {
1542                                 value: t,
1543                                 type: "special",
1544                                 line: line,
1545                                 character: character,
1546                                 from: from
1547                             };
1548
1549                         case "":
1550                             break;
1551     //      /
1552                         case "/":
1553                             if (s.charAt(0) === "=") {
1554                                 errorAt("A regular expression literal can be confused with '/='.",
1555                                     line, from);
1556                             }
1557
1558                             if (prereg) {
1559                                 depth = 0;
1560                                 captures = 0;
1561                                 l = 0;
1562                                 for (;;) {
1563                                     b = true;
1564                                     c = s.charAt(l);
1565                                     l += 1;
1566                                     switch (c) {
1567                                     case "":
1568                                         errorAt("Unclosed regular expression.", line, from);
1569                                         return quit("Stopping.", line, from);
1570                                     case "/":
1571                                         if (depth > 0) {
1572                                             warningAt("{a} unterminated regular expression " +
1573                                                 "group(s).", line, from + l, depth);
1574                                         }
1575                                         c = s.substr(0, l - 1);
1576                                         q = {
1577                                             g: true,
1578                                             i: true,
1579                                             m: true
1580                                         };
1581                                         while (q[s.charAt(l)] === true) {
1582                                             q[s.charAt(l)] = false;
1583                                             l += 1;
1584                                         }
1585                                         character += l;
1586                                         s = s.substr(l);
1587                                         q = s.charAt(0);
1588                                         if (q === "/" || q === "*") {
1589                                             errorAt("Confusing regular expression.",
1590                                                     line, from);
1591                                         }
1592                                         return it("(regexp)", c);
1593                                     case "\\":
1594                                         c = s.charAt(l);
1595                                         if (c < " ") {
1596                                             warningAt(
1597 "Unexpected control character in regular expression.", line, from + l);
1598                                         } else if (c === "<") {
1599                                             warningAt(
1600 "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1601                                         }
1602                                         l += 1;
1603                                         break;
1604                                     case "(":
1605                                         depth += 1;
1606                                         b = false;
1607                                         if (s.charAt(l) === "?") {
1608                                             l += 1;
1609                                             switch (s.charAt(l)) {
1610                                             case ":":
1611                                             case "=":
1612                                             case "!":
1613                                                 l += 1;
1614                                                 break;
1615                                             default:
1616                                                 warningAt(
1617 "Expected '{a}' and instead saw '{b}'.", line, from + l, ":", s.charAt(l));
1618                                             }
1619                                         } else {
1620                                             captures += 1;
1621                                         }
1622                                         break;
1623                                     case "|":
1624                                         b = false;
1625                                         break;
1626                                     case ")":
1627                                         if (depth === 0) {
1628                                             warningAt("Unescaped '{a}'.",
1629                                                     line, from + l, ")");
1630                                         } else {
1631                                             depth -= 1;
1632                                         }
1633                                         break;
1634                                     case " ":
1635                                         q = 1;
1636                                         while (s.charAt(l) === " ") {
1637                                             l += 1;
1638                                             q += 1;
1639                                         }
1640                                         if (q > 1) {
1641                                             warningAt(
1642 "Spaces are hard to count. Use {{a}}.", line, from + l, q);
1643                                         }
1644                                         break;
1645                                     case "[":
1646                                         c = s.charAt(l);
1647                                         if (c === "^") {
1648                                             l += 1;
1649                                             if (s.charAt(l) === "]") {
1650                                                 errorAt("Unescaped '{a}'.",
1651                                                     line, from + l, "^");
1652                                             }
1653                                         }
1654                                         if (c === "]") {
1655                                             warningAt("Empty class.", line,
1656                                                     from + l - 1);
1657                                         }
1658                                         isLiteral = false;
1659                                         isInRange = false;
1660 klass:
1661                                         do {
1662                                             c = s.charAt(l);
1663                                             l += 1;
1664                                             switch (c) {
1665                                             case "[":
1666                                             case "^":
1667                                                 warningAt("Unescaped '{a}'.",
1668                                                         line, from + l, c);
1669                                                 if (isInRange) {
1670                                                     isInRange = false;
1671                                                 } else {
1672                                                     isLiteral = true;
1673                                                 }
1674                                                 break;
1675                                             case "-":
1676                                                 if (isLiteral && !isInRange) {
1677                                                     isLiteral = false;
1678                                                     isInRange = true;
1679                                                 } else if (isInRange) {
1680                                                     isInRange = false;
1681                                                 } else if (s.charAt(l) === "]") {
1682                                                     isInRange = true;
1683                                                 } else {
1684                                                     if (option.regexdash !== (l === 2 || (l === 3 &&
1685                                                         s.charAt(1) === "^"))) {
1686                                                         warningAt("Unescaped '{a}'.",
1687                                                             line, from + l - 1, "-");
1688                                                     }
1689                                                     isLiteral = true;
1690                                                 }
1691                                                 break;
1692                                             case "]":
1693                                                 if (isInRange && !option.regexdash) {
1694                                                     warningAt("Unescaped '{a}'.",
1695                                                             line, from + l - 1, "-");
1696                                                 }
1697                                                 break klass;
1698                                             case "\\":
1699                                                 c = s.charAt(l);
1700                                                 if (c < " ") {
1701                                                     warningAt(
1702 "Unexpected control character in regular expression.", line, from + l);
1703                                                 } else if (c === "<") {
1704                                                     warningAt(
1705 "Unexpected escaped character '{a}' in regular expression.", line, from + l, c);
1706                                                 }
1707                                                 l += 1;
1708
1709                                                 // \w, \s and \d are never part of a character range
1710                                                 if (/[wsd]/i.test(c)) {
1711                                                     if (isInRange) {
1712                                                         warningAt("Unescaped '{a}'.",
1713                                                             line, from + l, "-");
1714                                                         isInRange = false;
1715                                                     }
1716                                                     isLiteral = false;
1717                                                 } else if (isInRange) {
1718                                                     isInRange = false;
1719                                                 } else {
1720                                                     isLiteral = true;
1721                                                 }
1722                                                 break;
1723                                             case "/":
1724                                                 warningAt("Unescaped '{a}'.",
1725                                                         line, from + l - 1, "/");
1726
1727                                                 if (isInRange) {
1728                                                     isInRange = false;
1729                                                 } else {
1730                                                     isLiteral = true;
1731                                                 }
1732                                                 break;
1733                                             case "<":
1734                                                 if (isInRange) {
1735                                                     isInRange = false;
1736                                                 } else {
1737                                                     isLiteral = true;
1738                                                 }
1739                                                 break;
1740                                             default:
1741                                                 if (isInRange) {
1742                                                     isInRange = false;
1743                                                 } else {
1744                                                     isLiteral = true;
1745                                                 }
1746                                             }
1747                                         } while (c);
1748                                         break;
1749                                     case ".":
1750                                         if (option.regexp) {
1751                                             warningAt("Insecure '{a}'.", line,
1752                                                     from + l, c);
1753                                         }
1754                                         break;
1755                                     case "]":
1756                                     case "?":
1757                                     case "{":
1758                                     case "}":
1759                                     case "+":
1760                                     case "*":
1761                                         warningAt("Unescaped '{a}'.", line,
1762                                                 from + l, c);
1763                                     }
1764                                     if (b) {
1765                                         switch (s.charAt(l)) {
1766                                         case "?":
1767                                         case "+":
1768                                         case "*":
1769                                             l += 1;
1770                                             if (s.charAt(l) === "?") {
1771                                                 l += 1;
1772                                             }
1773                                             break;
1774                                         case "{":
1775                                             l += 1;
1776                                             c = s.charAt(l);
1777                                             if (c < "0" || c > "9") {
1778                                                 warningAt(
1779 "Expected a number and instead saw '{a}'.", line, from + l, c);
1780                                                 break; // No reason to continue checking numbers.
1781                                             }
1782                                             l += 1;
1783                                             low = +c;
1784                                             for (;;) {
1785                                                 c = s.charAt(l);
1786                                                 if (c < "0" || c > "9") {
1787                                                     break;
1788                                                 }
1789                                                 l += 1;
1790                                                 low = +c + (low * 10);
1791                                             }
1792                                             high = low;
1793                                             if (c === ",") {
1794                                                 l += 1;
1795                                                 high = Infinity;
1796                                                 c = s.charAt(l);
1797                                                 if (c >= "0" && c <= "9") {
1798                                                     l += 1;
1799                                                     high = +c;
1800                                                     for (;;) {
1801                                                         c = s.charAt(l);
1802                                                         if (c < "0" || c > "9") {
1803                                                             break;
1804                                                         }
1805                                                         l += 1;
1806                                                         high = +c + (high * 10);
1807                                                     }
1808                                                 }
1809                                             }
1810                                             if (s.charAt(l) !== "}") {
1811                                                 warningAt(
1812 "Expected '{a}' and instead saw '{b}'.", line, from + l, "}", c);
1813                                             } else {
1814                                                 l += 1;
1815                                             }
1816                                             if (s.charAt(l) === "?") {
1817                                                 l += 1;
1818                                             }
1819                                             if (low > high) {
1820                                                 warningAt(
1821 "'{a}' should not be greater than '{b}'.", line, from + l, low, high);
1822                                             }
1823                                         }
1824                                     }
1825                                 }
1826                                 c = s.substr(0, l - 1);
1827                                 character += l;
1828                                 s = s.substr(l);
1829                                 return it("(regexp)", c);
1830                             }
1831                             return it("(punctuator)", t);
1832
1833     //      punctuator
1834
1835                         case "#":
1836                             return it("(punctuator)", t);
1837                         default:
1838                             return it("(punctuator)", t);
1839                         }
1840                     }
1841                 }
1842             }
1843         };
1844     }());
1845
1846
1847     function addlabel(t, type, token) {
1848         if (t === "hasOwnProperty") {
1849             warning("'hasOwnProperty' is a really bad name.");
1850         }
1851
1852         // Define t in the current function in the current scope.
1853         if (type === "exception") {
1854             if (is_own(funct["(context)"], t)) {
1855                 if (funct[t] !== true && !option.node) {
1856                     warning("Value of '{a}' may be overwritten in IE.", nexttoken, t);
1857                 }
1858             }
1859         }
1860
1861         if (is_own(funct, t) && !funct["(global)"]) {
1862             if (funct[t] === true) {
1863                 if (option.latedef)
1864                     warning("'{a}' was used before it was defined.", nexttoken, t);
1865             } else {
1866                 if (!option.shadow && type !== "exception") {
1867                     warning("'{a}' is already defined.", nexttoken, t);
1868                 }
1869             }
1870         }
1871
1872         funct[t] = type;
1873
1874         if (token) {
1875             funct["(tokens)"][t] = token;
1876         }
1877
1878         if (funct["(global)"]) {
1879             global[t] = funct;
1880             if (is_own(implied, t)) {
1881                 if (option.latedef)
1882                     warning("'{a}' was used before it was defined.", nexttoken, t);
1883                 delete implied[t];
1884             }
1885         } else {
1886             scope[t] = funct;
1887         }
1888     }
1889
1890
1891     function doOption() {
1892         var nt = nexttoken;
1893         var o  = nt.value;
1894         var quotmarkValue = option.quotmark;
1895         var predef = {};
1896         var b, obj, filter, t, tn, v, minus;
1897
1898         switch (o) {
1899         case "*/":
1900             error("Unbegun comment.");
1901             break;
1902         case "/*members":
1903         case "/*member":
1904             o = "/*members";
1905             if (!membersOnly) {
1906                 membersOnly = {};
1907             }
1908             obj = membersOnly;
1909             option.quotmark = false;
1910             break;
1911         case "/*jshint":
1912         case "/*jslint":
1913             obj = option;
1914             filter = boolOptions;
1915             break;
1916         case "/*global":
1917             obj = predef;
1918             break;
1919         default:
1920             error("What?");
1921         }
1922
1923         t = lex.token();
1924
1925 loop:
1926         for (;;) {
1927             minus = false;
1928             for (;;) {
1929                 if (t.type === "special" && t.value === "*/") {
1930                     break loop;
1931                 }
1932                 if (t.id !== "(endline)" && t.id !== ",") {
1933                     break;
1934                 }
1935                 t = lex.token();
1936             }
1937
1938             if (o === "/*global" && t.value === "-") {
1939                 minus = true;
1940                 t = lex.token();
1941             }
1942
1943             if (t.type !== "(string)" && t.type !== "(identifier)" && o !== "/*members") {
1944                 error("Bad option.", t);
1945             }
1946
1947             v = lex.token();
1948             if (v.id === ":") {
1949                 v = lex.token();
1950
1951                 if (obj === membersOnly) {
1952                     error("Expected '{a}' and instead saw '{b}'.", t, "*/", ":");
1953                 }
1954
1955                 if (o === "/*jshint") {
1956                     checkOption(t.value, t);
1957                 }
1958
1959                 var numericVals = [
1960                     "maxstatements",
1961                     "maxparams",
1962                     "maxdepth",
1963                     "maxcomplexity",
1964                     "maxerr",
1965                     "maxlen",
1966                     "indent"
1967                 ];
1968
1969                 if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) {
1970                     b = +v.value;
1971
1972                     if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) {
1973                         error("Expected a small integer and instead saw '{a}'.", v, v.value);
1974                     }
1975
1976                     if (t.value === "indent")
1977                         obj.white = true;
1978
1979                     obj[t.value] = b;
1980                 } else if (t.value === "validthis") {
1981                     if (funct["(global)"]) {
1982                         error("Option 'validthis' can't be used in a global scope.");
1983                     } else {
1984                         if (v.value === "true" || v.value === "false")
1985                             obj[t.value] = v.value === "true";
1986                         else
1987                             error("Bad option value.", v);
1988                     }
1989                 } else if (t.value === "quotmark" && (o === "/*jshint")) {
1990                     switch (v.value) {
1991                     case "true":
1992                         obj.quotmark = true;
1993                         break;
1994                     case "false":
1995                         obj.quotmark = false;
1996                         break;
1997                     case "double":
1998                     case "single":
1999                         obj.quotmark = v.value;
2000                         break;
2001                     default:
2002                         error("Bad option value.", v);
2003                     }
2004                 } else if (v.value === "true" || v.value === "false") {
2005                     if (o === "/*jslint") {
2006                         tn = renamedOptions[t.value] || t.value;
2007                         obj[tn] = v.value === "true";
2008                         if (invertedOptions[tn] !== undefined) {
2009                             obj[tn] = !obj[tn];
2010                         }
2011                     } else {
2012                         obj[t.value] = v.value === "true";
2013                     }
2014
2015                     if (t.value === "newcap")
2016                         obj["(explicitNewcap)"] = true;
2017                 } else {
2018                     error("Bad option value.", v);
2019                 }
2020                 t = lex.token();
2021             } else {
2022                 if (o === "/*jshint" || o === "/*jslint") {
2023                     error("Missing option value.", t);
2024                 }
2025
2026                 obj[t.value] = false;
2027
2028                 if (o === "/*global" && minus === true) {
2029                     JSHINT.blacklist[t.value] = t.value;
2030                     updatePredefined();
2031                 }
2032
2033                 t = v;
2034             }
2035         }
2036
2037         if (o === "/*members") {
2038             option.quotmark = quotmarkValue;
2039         }
2040
2041         combine(predefined, predef);
2042
2043         for (var key in predef) {
2044             if (is_own(predef, key)) {
2045                 declared[key] = nt;
2046             }
2047         }
2048
2049         if (filter) {
2050             assume();
2051         }
2052     }
2053
2054
2055 // We need a peek function. If it has an argument, it peeks that much farther
2056 // ahead. It is used to distinguish
2057 //     for ( var i in ...
2058 // from
2059 //     for ( var i = ...
2060
2061     function peek(p) {
2062         var i = p || 0, j = 0, t;
2063
2064         while (j <= i) {
2065             t = lookahead[j];
2066             if (!t) {
2067                 t = lookahead[j] = lex.token();
2068             }
2069             j += 1;
2070         }
2071         return t;
2072     }
2073
2074
2075
2076 // Produce the next token. It looks for programming errors.
2077
2078     function advance(id, t) {
2079         switch (token.id) {
2080         case "(number)":
2081             if (nexttoken.id === ".") {
2082                 warning("A dot following a number can be confused with a decimal point.", token);
2083             }
2084             break;
2085         case "-":
2086             if (nexttoken.id === "-" || nexttoken.id === "--") {
2087                 warning("Confusing minusses.");
2088             }
2089             break;
2090         case "+":
2091             if (nexttoken.id === "+" || nexttoken.id === "++") {
2092                 warning("Confusing plusses.");
2093             }
2094             break;
2095         }
2096
2097         if (token.type === "(string)" || token.identifier) {
2098             anonname = token.value;
2099         }
2100
2101         if (id && nexttoken.id !== id) {
2102             if (t) {
2103                 if (nexttoken.id === "(end)") {
2104                     warning("Unmatched '{a}'.", t, t.id);
2105                 } else {
2106                     warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
2107                             nexttoken, id, t.id, t.line, nexttoken.value);
2108                 }
2109             } else if (nexttoken.type !== "(identifier)" ||
2110                             nexttoken.value !== id) {
2111                 warning("Expected '{a}' and instead saw '{b}'.",
2112                         nexttoken, id, nexttoken.value);
2113             }
2114         }
2115
2116         prevtoken = token;
2117         token = nexttoken;
2118         for (;;) {
2119             nexttoken = lookahead.shift() || lex.token();
2120             if (nexttoken.id === "(end)" || nexttoken.id === "(error)") {
2121                 return;
2122             }
2123             if (nexttoken.type === "special") {
2124                 doOption();
2125             } else {
2126                 if (nexttoken.id !== "(endline)") {
2127                     break;
2128                 }
2129             }
2130         }
2131     }
2132
2133
2134 // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it
2135 // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is
2136 // like .nud except that it is only used on the first token of a statement.
2137 // Having .fud makes it much easier to define statement-oriented languages like
2138 // JavaScript. I retained Pratt's nomenclature.
2139
2140 // .nud     Null denotation
2141 // .fud     First null denotation
2142 // .led     Left denotation
2143 //  lbp     Left binding power
2144 //  rbp     Right binding power
2145
2146 // They are elements of the parsing method called Top Down Operator Precedence.
2147
2148     function expression(rbp, initial) {
2149         var left, isArray = false, isObject = false;
2150
2151         if (nexttoken.id === "(end)")
2152             error("Unexpected early end of program.", token);
2153
2154         advance();
2155         if (initial) {
2156             anonname = "anonymous";
2157             funct["(verb)"] = token.value;
2158         }
2159         if (initial === true && token.fud) {
2160             left = token.fud();
2161         } else {
2162             if (token.nud) {
2163                 left = token.nud();
2164             } else {
2165                 if (nexttoken.type === "(number)" && token.id === ".") {
2166                     warning("A leading decimal point can be confused with a dot: '.{a}'.",
2167                             token, nexttoken.value);
2168                     advance();
2169                     return token;
2170                 } else {
2171                     error("Expected an identifier and instead saw '{a}'.",
2172                             token, token.id);
2173                 }
2174             }
2175             while (rbp < nexttoken.lbp) {
2176                 isArray = token.value === "Array";
2177                 isObject = token.value === "Object";
2178
2179                 // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object()
2180                 // Line breaks in IfStatement heads exist to satisfy the checkJSHint
2181                 // "Line too long." error.
2182                 if (left && (left.value || (left.first && left.first.value))) {
2183                     // If the left.value is not "new", or the left.first.value is a "."
2184                     // then safely assume that this is not "new Array()" and possibly
2185                     // not "new Object()"...
2186                     if (left.value !== "new" ||
2187                       (left.first && left.first.value && left.first.value === ".")) {
2188                         isArray = false;
2189                         // ...In the case of Object, if the left.value and token.value
2190                         // are not equal, then safely assume that this not "new Object()"
2191                         if (left.value !== token.value) {
2192                             isObject = false;
2193                         }
2194                     }
2195                 }
2196
2197                 advance();
2198                 if (isArray && token.id === "(" && nexttoken.id === ")")
2199                     warning("Use the array literal notation [].", token);
2200                 if (isObject && token.id === "(" && nexttoken.id === ")")
2201                     warning("Use the object literal notation {}.", token);
2202                 if (token.led) {
2203                     left = token.led(left);
2204                 } else {
2205                     error("Expected an operator and instead saw '{a}'.",
2206                         token, token.id);
2207                 }
2208             }
2209         }
2210         return left;
2211     }
2212
2213
2214 // Functions for conformance of style.
2215
2216     function adjacent(left, right) {
2217         left = left || token;
2218         right = right || nexttoken;
2219         if (option.white) {
2220             if (left.character !== right.from && left.line === right.line) {
2221                 left.from += (left.character - left.from);
2222                 warning("Unexpected space after '{a}'.", left, left.value);
2223             }
2224         }
2225     }
2226
2227     function nobreak(left, right) {
2228         left = left || token;
2229         right = right || nexttoken;
2230         if (option.white && (left.character !== right.from || left.line !== right.line)) {
2231             warning("Unexpected space before '{a}'.", right, right.value);
2232         }
2233     }
2234
2235     function nospace(left, right) {
2236         left = left || token;
2237         right = right || nexttoken;
2238         if (option.white && !left.comment) {
2239             if (left.line === right.line) {
2240                 adjacent(left, right);
2241             }
2242         }
2243     }
2244
2245     function nonadjacent(left, right) {
2246         if (option.white) {
2247             left = left || token;
2248             right = right || nexttoken;
2249             if (left.value === ";" && right.value === ";") {
2250                 return;
2251             }
2252             if (left.line === right.line && left.character === right.from) {
2253                 left.from += (left.character - left.from);
2254                 warning("Missing space after '{a}'.",
2255                         left, left.value);
2256             }
2257         }
2258     }
2259
2260     function nobreaknonadjacent(left, right) {
2261         left = left || token;
2262         right = right || nexttoken;
2263         if (!option.laxbreak && left.line !== right.line) {
2264             warning("Bad line breaking before '{a}'.", right, right.id);
2265         } else if (option.white) {
2266             left = left || token;
2267             right = right || nexttoken;
2268             if (left.character === right.from) {
2269                 left.from += (left.character - left.from);
2270                 warning("Missing space after '{a}'.",
2271                         left, left.value);
2272             }
2273         }
2274     }
2275
2276     function indentation(bias) {
2277         var i;
2278         if (option.white && nexttoken.id !== "(end)") {
2279             i = indent + (bias || 0);
2280             if (nexttoken.from !== i) {
2281                 warning(
2282 "Expected '{a}' to have an indentation at {b} instead at {c}.",
2283                         nexttoken, nexttoken.value, i, nexttoken.from);
2284             }
2285         }
2286     }
2287
2288     function nolinebreak(t) {
2289         t = t || token;
2290         if (t.line !== nexttoken.line) {
2291             warning("Line breaking error '{a}'.", t, t.value);
2292         }
2293     }
2294
2295
2296     function comma() {
2297         if (token.line !== nexttoken.line) {
2298             if (!option.laxcomma) {
2299                 if (comma.first) {
2300                     warning("Comma warnings can be turned off with 'laxcomma'");
2301                     comma.first = false;
2302                 }
2303                 warning("Bad line breaking before '{a}'.", token, nexttoken.id);
2304             }
2305         } else if (!token.comment && token.character !== nexttoken.from && option.white) {
2306             token.from += (token.character - token.from);
2307             warning("Unexpected space after '{a}'.", token, token.value);
2308         }
2309         advance(",");
2310         nonadjacent(token, nexttoken);
2311     }
2312
2313
2314 // Functional constructors for making the symbols that will be inherited by
2315 // tokens.
2316
2317     function symbol(s, p) {
2318         var x = syntax[s];
2319         if (!x || typeof x !== "object") {
2320             syntax[s] = x = {
2321                 id: s,
2322                 lbp: p,
2323                 value: s
2324             };
2325         }
2326         return x;
2327     }
2328
2329
2330     function delim(s) {
2331         return symbol(s, 0);
2332     }
2333
2334
2335     function stmt(s, f) {
2336         var x = delim(s);
2337         x.identifier = x.reserved = true;
2338         x.fud = f;
2339         return x;
2340     }
2341
2342
2343     function blockstmt(s, f) {
2344         var x = stmt(s, f);
2345         x.block = true;
2346         return x;
2347     }
2348
2349
2350     function reserveName(x) {
2351         var c = x.id.charAt(0);
2352         if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
2353             x.identifier = x.reserved = true;
2354         }
2355         return x;
2356     }
2357
2358
2359     function prefix(s, f) {
2360         var x = symbol(s, 150);
2361         reserveName(x);
2362         x.nud = (typeof f === "function") ? f : function () {
2363             this.right = expression(150);
2364             this.arity = "unary";
2365             if (this.id === "++" || this.id === "--") {
2366                 if (option.plusplus) {
2367                     warning("Unexpected use of '{a}'.", this, this.id);
2368                 } else if ((!this.right.identifier || this.right.reserved) &&
2369                         this.right.id !== "." && this.right.id !== "[") {
2370                     warning("Bad operand.", this);
2371                 }
2372             }
2373             return this;
2374         };
2375         return x;
2376     }
2377
2378
2379     function type(s, f) {
2380         var x = delim(s);
2381         x.type = s;
2382         x.nud = f;
2383         return x;
2384     }
2385
2386
2387     function reserve(s, f) {
2388         var x = type(s, f);
2389         x.identifier = x.reserved = true;
2390         return x;
2391     }
2392
2393
2394     function reservevar(s, v) {
2395         return reserve(s, function () {
2396             if (typeof v === "function") {
2397                 v(this);
2398             }
2399             return this;
2400         });
2401     }
2402
2403
2404     function infix(s, f, p, w) {
2405         var x = symbol(s, p);
2406         reserveName(x);
2407         x.led = function (left) {
2408             if (!w) {
2409                 nobreaknonadjacent(prevtoken, token);
2410                 nonadjacent(token, nexttoken);
2411             }
2412             if (s === "in" && left.id === "!") {
2413                 warning("Confusing use of '{a}'.", left, "!");
2414             }
2415             if (typeof f === "function") {
2416                 return f(left, this);
2417             } else {
2418                 this.left = left;
2419                 this.right = expression(p);
2420                 return this;
2421             }
2422         };
2423         return x;
2424     }
2425
2426
2427     function relation(s, f) {
2428         var x = symbol(s, 100);
2429         x.led = function (left) {
2430             nobreaknonadjacent(prevtoken, token);
2431             nonadjacent(token, nexttoken);
2432             var right = expression(100);
2433
2434             if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
2435                 warning("Use the isNaN function to compare with NaN.", this);
2436             } else if (f) {
2437                 f.apply(this, [left, right]);
2438             }
2439             if (left.id === "!") {
2440                 warning("Confusing use of '{a}'.", left, "!");
2441             }
2442             if (right.id === "!") {
2443                 warning("Confusing use of '{a}'.", right, "!");
2444             }
2445             this.left = left;
2446             this.right = right;
2447             return this;
2448         };
2449         return x;
2450     }
2451
2452
2453     function isPoorRelation(node) {
2454         return node &&
2455               ((node.type === "(number)" && +node.value === 0) ||
2456                (node.type === "(string)" && node.value === "") ||
2457                (node.type === "null" && !option.eqnull) ||
2458                 node.type === "true" ||
2459                 node.type === "false" ||
2460                 node.type === "undefined");
2461     }
2462
2463
2464     function assignop(s) {
2465         symbol(s, 20).exps = true;
2466
2467         return infix(s, function (left, that) {
2468             that.left = left;
2469
2470             if (predefined[left.value] === false &&
2471                     scope[left.value]["(global)"] === true) {
2472                 warning("Read only.", left);
2473             } else if (left["function"]) {
2474                 warning("'{a}' is a function.", left, left.value);
2475             }
2476
2477             if (left) {
2478                 if (option.esnext && funct[left.value] === "const") {
2479                     warning("Attempting to override '{a}' which is a constant", left, left.value);
2480                 }
2481
2482                 if (left.id === "." || left.id === "[") {
2483                     if (!left.left || left.left.value === "arguments") {
2484                         warning("Bad assignment.", that);
2485                     }
2486                     that.right = expression(19);
2487                     return that;
2488                 } else if (left.identifier && !left.reserved) {
2489                     if (funct[left.value] === "exception") {
2490                         warning("Do not assign to the exception parameter.", left);
2491                     }
2492                     that.right = expression(19);
2493                     return that;
2494                 }
2495
2496                 if (left === syntax["function"]) {
2497                     warning(
2498 "Expected an identifier in an assignment and instead saw a function invocation.",
2499                                 token);
2500                 }
2501             }
2502
2503             error("Bad assignment.", that);
2504         }, 20);
2505     }
2506
2507
2508     function bitwise(s, f, p) {
2509         var x = symbol(s, p);
2510         reserveName(x);
2511         x.led = (typeof f === "function") ? f : function (left) {
2512             if (option.bitwise) {
2513                 warning("Unexpected use of '{a}'.", this, this.id);
2514             }
2515             this.left = left;
2516             this.right = expression(p);
2517             return this;
2518         };
2519         return x;
2520     }
2521
2522
2523     function bitwiseassignop(s) {
2524         symbol(s, 20).exps = true;
2525         return infix(s, function (left, that) {
2526             if (option.bitwise) {
2527                 warning("Unexpected use of '{a}'.", that, that.id);
2528             }
2529             nonadjacent(prevtoken, token);
2530             nonadjacent(token, nexttoken);
2531             if (left) {
2532                 if (left.id === "." || left.id === "[" ||
2533                         (left.identifier && !left.reserved)) {
2534                     expression(19);
2535                     return that;
2536                 }
2537                 if (left === syntax["function"]) {
2538                     warning(
2539 "Expected an identifier in an assignment, and instead saw a function invocation.",
2540                                 token);
2541                 }
2542                 return that;
2543             }
2544             error("Bad assignment.", that);
2545         }, 20);
2546     }
2547
2548
2549     function suffix(s) {
2550         var x = symbol(s, 150);
2551         x.led = function (left) {
2552             if (option.plusplus) {
2553                 warning("Unexpected use of '{a}'.", this, this.id);
2554             } else if ((!left.identifier || left.reserved) &&
2555                     left.id !== "." && left.id !== "[") {
2556                 warning("Bad operand.", this);
2557             }
2558             this.left = left;
2559             return this;
2560         };
2561         return x;
2562     }
2563
2564
2565     // fnparam means that this identifier is being defined as a function
2566     // argument (see identifier())
2567     function optionalidentifier(fnparam) {
2568         if (nexttoken.identifier) {
2569             advance();
2570             if (token.reserved && !option.es5) {
2571                 // `undefined` as a function param is a common pattern to protect
2572                 // against the case when somebody does `undefined = true` and
2573                 // help with minification. More info: https://gist.github.com/315916
2574                 if (!fnparam || token.value !== "undefined") {
2575                     warning("Expected an identifier and instead saw '{a}' (a reserved word).",
2576                             token, token.id);
2577                 }
2578             }
2579             return token.value;
2580         }
2581     }
2582
2583     // fnparam means that this identifier is being defined as a function
2584     // argument
2585     function identifier(fnparam) {
2586         var i = optionalidentifier(fnparam);
2587         if (i) {
2588             return i;
2589         }
2590         if (token.id === "function" && nexttoken.id === "(") {
2591             warning("Missing name in function declaration.");
2592         } else {
2593             error("Expected an identifier and instead saw '{a}'.",
2594                     nexttoken, nexttoken.value);
2595         }
2596     }
2597
2598
2599     function reachable(s) {
2600         var i = 0, t;
2601         if (nexttoken.id !== ";" || noreach) {
2602             return;
2603         }
2604         for (;;) {
2605             t = peek(i);
2606             if (t.reach) {
2607                 return;
2608             }
2609             if (t.id !== "(endline)") {
2610                 if (t.id === "function") {
2611                     if (!option.latedef) {
2612                         break;
2613                     }
2614                     warning(
2615 "Inner functions should be listed at the top of the outer function.", t);
2616                     break;
2617                 }
2618                 warning("Unreachable '{a}' after '{b}'.", t, t.value, s);
2619                 break;
2620             }
2621             i += 1;
2622         }
2623     }
2624
2625
2626     function statement(noindent) {
2627         var i = indent, r, s = scope, t = nexttoken;
2628
2629         if (t.id === ";") {
2630             advance(";");
2631             return;
2632         }
2633
2634         // Is this a labelled statement?
2635
2636         if (t.identifier && !t.reserved && peek().id === ":") {
2637             advance();
2638             advance(":");
2639             scope = Object.create(s);
2640             addlabel(t.value, "label");
2641
2642             if (!nexttoken.labelled && nexttoken.value !== "{") {
2643                 warning("Label '{a}' on {b} statement.", nexttoken, t.value, nexttoken.value);
2644             }
2645
2646             if (jx.test(t.value + ":")) {
2647                 warning("Label '{a}' looks like a javascript url.", t, t.value);
2648             }
2649
2650             nexttoken.label = t.value;
2651             t = nexttoken;
2652         }
2653
2654         // Is it a lonely block?
2655
2656         if (t.id === "{") {
2657             block(true, true);
2658             return;
2659         }
2660
2661         // Parse the statement.
2662
2663         if (!noindent) {
2664             indentation();
2665         }
2666         r = expression(0, true);
2667
2668         // Look for the final semicolon.
2669
2670         if (!t.block) {
2671             if (!option.expr && (!r || !r.exps)) {
2672                 warning("Expected an assignment or function call and instead saw an expression.",
2673                     token);
2674             } else if (option.nonew && r.id === "(" && r.left.id === "new") {
2675                 warning("Do not use 'new' for side effects.", t);
2676             }
2677
2678             if (nexttoken.id === ",") {
2679                 return comma();
2680             }
2681
2682             if (nexttoken.id !== ";") {
2683                 if (!option.asi) {
2684                     // If this is the last statement in a block that ends on
2685                     // the same line *and* option lastsemic is on, ignore the warning.
2686                     // Otherwise, complain about missing semicolon.
2687                     if (!option.lastsemic || nexttoken.id !== "}" ||
2688                             nexttoken.line !== token.line) {
2689                         warningAt("Missing semicolon.", token.line, token.character);
2690                     }
2691                 }
2692             } else {
2693                 adjacent(token, nexttoken);
2694                 advance(";");
2695                 nonadjacent(token, nexttoken);
2696             }
2697         }
2698
2699 // Restore the indentation.
2700
2701         indent = i;
2702         scope = s;
2703         return r;
2704     }
2705
2706
2707     function statements(startLine) {
2708         var a = [], p;
2709
2710         while (!nexttoken.reach && nexttoken.id !== "(end)") {
2711             if (nexttoken.id === ";") {
2712                 p = peek();
2713                 if (!p || p.id !== "(") {
2714                     warning("Unnecessary semicolon.");
2715                 }
2716                 advance(";");
2717             } else {
2718                 a.push(statement(startLine === nexttoken.line));
2719             }
2720         }
2721         return a;
2722     }
2723
2724
2725     /*
2726      * read all directives
2727      * recognizes a simple form of asi, but always
2728      * warns, if it is used
2729      */
2730     function directives() {
2731         var i, p, pn;
2732
2733         for (;;) {
2734             if (nexttoken.id === "(string)") {
2735                 p = peek(0);
2736                 if (p.id === "(endline)") {
2737                     i = 1;
2738                     do {
2739                         pn = peek(i);
2740                         i = i + 1;
2741                     } while (pn.id === "(endline)");
2742
2743                     if (pn.id !== ";") {
2744                         if (pn.id !== "(string)" && pn.id !== "(number)" &&
2745                             pn.id !== "(regexp)" && pn.identifier !== true &&
2746                             pn.id !== "}") {
2747                             break;
2748                         }
2749                         warning("Missing semicolon.", nexttoken);
2750                     } else {
2751                         p = pn;
2752                     }
2753                 } else if (p.id === "}") {
2754                     // directive with no other statements, warn about missing semicolon
2755                     warning("Missing semicolon.", p);
2756                 } else if (p.id !== ";") {
2757                     break;
2758                 }
2759
2760                 indentation();
2761                 advance();
2762                 if (directive[token.value]) {
2763                     warning("Unnecessary directive \"{a}\".", token, token.value);
2764                 }
2765
2766                 if (token.value === "use strict") {
2767                     if (!option["(explicitNewcap)"])
2768                         option.newcap = true;
2769                     option.undef = true;
2770                 }
2771
2772                 // there's no directive negation, so always set to true
2773                 directive[token.value] = true;
2774
2775                 if (p.id === ";") {
2776                     advance(";");
2777                 }
2778                 continue;
2779             }
2780             break;
2781         }
2782     }
2783
2784
2785     /*
2786      * Parses a single block. A block is a sequence of statements wrapped in
2787      * braces.
2788      *
2789      * ordinary - true for everything but function bodies and try blocks.
2790      * stmt     - true if block can be a single statement (e.g. in if/for/while).
2791      * isfunc   - true if block is a function body
2792      */
2793     function block(ordinary, stmt, isfunc) {
2794         var a,
2795             b = inblock,
2796             old_indent = indent,
2797             m,
2798             s = scope,
2799             t,
2800             line,
2801             d;
2802
2803         inblock = ordinary;
2804
2805         if (!ordinary || !option.funcscope)
2806             scope = Object.create(scope);
2807
2808         nonadjacent(token, nexttoken);
2809         t = nexttoken;
2810
2811         var metrics = funct["(metrics)"];
2812         metrics.nestedBlockDepth += 1;
2813         metrics.verifyMaxNestedBlockDepthPerFunction();
2814
2815         if (nexttoken.id === "{") {
2816             advance("{");
2817             line = token.line;
2818             if (nexttoken.id !== "}") {
2819                 indent += option.indent;
2820                 while (!ordinary && nexttoken.from > indent) {
2821                     indent += option.indent;
2822                 }
2823
2824                 if (isfunc) {
2825                     m = {};
2826                     for (d in directive) {
2827                         if (is_own(directive, d)) {
2828                             m[d] = directive[d];
2829                         }
2830                     }
2831                     directives();
2832
2833                     if (option.strict && funct["(context)"]["(global)"]) {
2834                         if (!m["use strict"] && !directive["use strict"]) {
2835                             warning("Missing \"use strict\" statement.");
2836                         }
2837                     }
2838                 }
2839
2840                 a = statements(line);
2841
2842                 metrics.statementCount += a.length;
2843
2844                 if (isfunc) {
2845                     directive = m;
2846                 }
2847
2848                 indent -= option.indent;
2849                 if (line !== nexttoken.line) {
2850                     indentation();
2851                 }
2852             } else if (line !== nexttoken.line) {
2853                 indentation();
2854             }
2855             advance("}", t);
2856             indent = old_indent;
2857         } else if (!ordinary) {
2858             error("Expected '{a}' and instead saw '{b}'.",
2859                   nexttoken, "{", nexttoken.value);
2860         } else {
2861             if (!stmt || option.curly)
2862                 warning("Expected '{a}' and instead saw '{b}'.",
2863                         nexttoken, "{", nexttoken.value);
2864
2865             noreach = true;
2866             indent += option.indent;
2867             // test indentation only if statement is in new line
2868             a = [statement(nexttoken.line === token.line)];
2869             indent -= option.indent;
2870             noreach = false;
2871         }
2872         funct["(verb)"] = null;
2873         if (!ordinary || !option.funcscope) scope = s;
2874         inblock = b;
2875         if (ordinary && option.noempty && (!a || a.length === 0)) {
2876             warning("Empty block.");
2877         }
2878         metrics.nestedBlockDepth -= 1;
2879         return a;
2880     }
2881
2882
2883     function countMember(m) {
2884         if (membersOnly && typeof membersOnly[m] !== "boolean") {
2885             warning("Unexpected /*member '{a}'.", token, m);
2886         }
2887         if (typeof member[m] === "number") {
2888             member[m] += 1;
2889         } else {
2890             member[m] = 1;
2891         }
2892     }
2893
2894
2895     function note_implied(token) {
2896         var name = token.value, line = token.line, a = implied[name];
2897         if (typeof a === "function") {
2898             a = false;
2899         }
2900
2901         if (!a) {
2902             a = [line];
2903             implied[name] = a;
2904         } else if (a[a.length - 1] !== line) {
2905             a.push(line);
2906         }
2907     }
2908
2909
2910     // Build the syntax table by declaring the syntactic elements of the language.
2911
2912     type("(number)", function () {
2913         return this;
2914     });
2915
2916     type("(string)", function () {
2917         return this;
2918     });
2919
2920     syntax["(identifier)"] = {
2921         type: "(identifier)",
2922         lbp: 0,
2923         identifier: true,
2924         nud: function () {
2925             var v = this.value,
2926                 s = scope[v],
2927                 f;
2928
2929             if (typeof s === "function") {
2930                 // Protection against accidental inheritance.
2931                 s = undefined;
2932             } else if (typeof s === "boolean") {
2933                 f = funct;
2934                 funct = functions[0];
2935                 addlabel(v, "var");
2936                 s = funct;
2937                 funct = f;
2938             }
2939
2940             // The name is in scope and defined in the current function.
2941             if (funct === s) {
2942                 // Change 'unused' to 'var', and reject labels.
2943                 switch (funct[v]) {
2944                 case "unused":
2945                     funct[v] = "var";
2946                     break;
2947                 case "unction":
2948                     funct[v] = "function";
2949                     this["function"] = true;
2950                     break;
2951                 case "function":
2952                     this["function"] = true;
2953                     break;
2954                 case "label":
2955                     warning("'{a}' is a statement label.", token, v);
2956                     break;
2957                 }
2958             } else if (funct["(global)"]) {
2959                 // The name is not defined in the function.  If we are in the global
2960                 // scope, then we have an undefined variable.
2961                 //
2962                 // Operators typeof and delete do not raise runtime errors even if
2963                 // the base object of a reference is null so no need to display warning
2964                 // if we're inside of typeof or delete.
2965
2966                 if (option.undef && typeof predefined[v] !== "boolean") {
2967                     // Attempting to subscript a null reference will throw an
2968                     // error, even within the typeof and delete operators
2969                     if (!(anonname === "typeof" || anonname === "delete") ||
2970                         (nexttoken && (nexttoken.value === "." || nexttoken.value === "["))) {
2971
2972                         isundef(funct, "'{a}' is not defined.", token, v);
2973                     }
2974                 }
2975
2976                 note_implied(token);
2977             } else {
2978                 // If the name is already defined in the current
2979                 // function, but not as outer, then there is a scope error.
2980
2981                 switch (funct[v]) {
2982                 case "closure":
2983                 case "function":
2984                 case "var":
2985                 case "unused":
2986                     warning("'{a}' used out of scope.", token, v);
2987                     break;
2988                 case "label":
2989                     warning("'{a}' is a statement label.", token, v);
2990                     break;
2991                 case "outer":
2992                 case "global":
2993                     break;
2994                 default:
2995                     // If the name is defined in an outer function, make an outer entry,
2996                     // and if it was unused, make it var.
2997                     if (s === true) {
2998                         funct[v] = true;
2999                     } else if (s === null) {
3000                         warning("'{a}' is not allowed.", token, v);
3001                         note_implied(token);
3002                     } else if (typeof s !== "object") {
3003                         // Operators typeof and delete do not raise runtime errors even
3004                         // if the base object of a reference is null so no need to
3005                         // display warning if we're inside of typeof or delete.
3006                         if (option.undef) {
3007                             // Attempting to subscript a null reference will throw an
3008                             // error, even within the typeof and delete operators
3009                             if (!(anonname === "typeof" || anonname === "delete") ||
3010                                 (nexttoken &&
3011                                     (nexttoken.value === "." || nexttoken.value === "["))) {
3012
3013                                 isundef(funct, "'{a}' is not defined.", token, v);
3014                             }
3015                         }
3016                         funct[v] = true;
3017                         note_implied(token);
3018                     } else {
3019                         switch (s[v]) {
3020                         case "function":
3021                         case "unction":
3022                             this["function"] = true;
3023                             s[v] = "closure";
3024                             funct[v] = s["(global)"] ? "global" : "outer";
3025                             break;
3026                         case "var":
3027                         case "unused":
3028                             s[v] = "closure";
3029                             funct[v] = s["(global)"] ? "global" : "outer";
3030                             break;
3031                         case "closure":
3032                             funct[v] = s["(global)"] ? "global" : "outer";
3033                             break;
3034                         case "label":
3035                             warning("'{a}' is a statement label.", token, v);
3036                         }
3037                     }
3038                 }
3039             }
3040             return this;
3041         },
3042         led: function () {
3043             error("Expected an operator and instead saw '{a}'.",
3044                 nexttoken, nexttoken.value);
3045         }
3046     };
3047
3048     type("(regexp)", function () {
3049         return this;
3050     });
3051
3052
3053 // ECMAScript parser
3054
3055     delim("(endline)");
3056     delim("(begin)");
3057     delim("(end)").reach = true;
3058     delim("</").reach = true;
3059     delim("<!");
3060     delim("<!--");
3061     delim("-->");
3062     delim("(error)").reach = true;
3063     delim("}").reach = true;
3064     delim(")");
3065     delim("]");
3066     delim("\"").reach = true;
3067     delim("'").reach = true;
3068     delim(";");
3069     delim(":").reach = true;
3070     delim(",");
3071     delim("#");
3072     delim("@");
3073     reserve("else");
3074     reserve("case").reach = true;
3075     reserve("catch");
3076     reserve("default").reach = true;
3077     reserve("finally");
3078     reservevar("arguments", function (x) {
3079         if (directive["use strict"] && funct["(global)"]) {
3080             warning("Strict violation.", x);
3081         }
3082     });
3083     reservevar("eval");
3084     reservevar("false");
3085     reservevar("Infinity");
3086     reservevar("null");
3087     reservevar("this", function (x) {
3088         if (directive["use strict"] && !option.validthis && ((funct["(statement)"] &&
3089                 funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
3090             warning("Possible strict violation.", x);
3091         }
3092     });
3093     reservevar("true");
3094     reservevar("undefined");
3095     assignop("=", "assign", 20);
3096     assignop("+=", "assignadd", 20);
3097     assignop("-=", "assignsub", 20);
3098     assignop("*=", "assignmult", 20);
3099     assignop("/=", "assigndiv", 20).nud = function () {
3100         error("A regular expression literal can be confused with '/='.");
3101     };
3102     assignop("%=", "assignmod", 20);
3103     bitwiseassignop("&=", "assignbitand", 20);
3104     bitwiseassignop("|=", "assignbitor", 20);
3105     bitwiseassignop("^=", "assignbitxor", 20);
3106     bitwiseassignop("<<=", "assignshiftleft", 20);
3107     bitwiseassignop(">>=", "assignshiftright", 20);
3108     bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
3109     infix("?", function (left, that) {
3110         that.left = left;
3111         that.right = expression(10);
3112         advance(":");
3113         that["else"] = expression(10);
3114         return that;
3115     }, 30);
3116
3117     infix("||", "or", 40);
3118     infix("&&", "and", 50);
3119     bitwise("|", "bitor", 70);
3120     bitwise("^", "bitxor", 80);
3121     bitwise("&", "bitand", 90);
3122     relation("==", function (left, right) {
3123         var eqnull = option.eqnull && (left.value === "null" || right.value === "null");
3124
3125         if (!eqnull && option.eqeqeq)
3126             warning("Expected '{a}' and instead saw '{b}'.", this, "===", "==");
3127         else if (isPoorRelation(left))
3128             warning("Use '{a}' to compare with '{b}'.", this, "===", left.value);
3129         else if (isPoorRelation(right))
3130             warning("Use '{a}' to compare with '{b}'.", this, "===", right.value);
3131
3132         return this;
3133     });
3134     relation("===");
3135     relation("!=", function (left, right) {
3136         var eqnull = option.eqnull &&
3137                 (left.value === "null" || right.value === "null");
3138
3139         if (!eqnull && option.eqeqeq) {
3140             warning("Expected '{a}' and instead saw '{b}'.",
3141                     this, "!==", "!=");
3142         } else if (isPoorRelation(left)) {
3143             warning("Use '{a}' to compare with '{b}'.",
3144                     this, "!==", left.value);
3145         } else if (isPoorRelation(right)) {
3146             warning("Use '{a}' to compare with '{b}'.",
3147                     this, "!==", right.value);
3148         }
3149         return this;
3150     });
3151     relation("!==");
3152     relation("<");
3153     relation(">");
3154     relation("<=");
3155     relation(">=");
3156     bitwise("<<", "shiftleft", 120);
3157     bitwise(">>", "shiftright", 120);
3158     bitwise(">>>", "shiftrightunsigned", 120);
3159     infix("in", "in", 120);
3160     infix("instanceof", "instanceof", 120);
3161     infix("+", function (left, that) {
3162         var right = expression(130);
3163         if (left && right && left.id === "(string)" && right.id === "(string)") {
3164             left.value += right.value;
3165             left.character = right.character;
3166             if (!option.scripturl && jx.test(left.value)) {
3167                 warning("JavaScript URL.", left);
3168             }
3169             return left;
3170         }
3171         that.left = left;
3172         that.right = right;
3173         return that;
3174     }, 130);
3175     prefix("+", "num");
3176     prefix("+++", function () {
3177         warning("Confusing pluses.");
3178         this.right = expression(150);
3179         this.arity = "unary";
3180         return this;
3181     });
3182     infix("+++", function (left) {
3183         warning("Confusing pluses.");
3184         this.left = left;
3185         this.right = expression(130);
3186         return this;
3187     }, 130);
3188     infix("-", "sub", 130);
3189     prefix("-", "neg");
3190     prefix("---", function () {
3191         warning("Confusing minuses.");
3192         this.right = expression(150);
3193         this.arity = "unary";
3194         return this;
3195     });
3196     infix("---", function (left) {
3197         warning("Confusing minuses.");
3198         this.left = left;
3199         this.right = expression(130);
3200         return this;
3201     }, 130);
3202     infix("*", "mult", 140);
3203     infix("/", "div", 140);
3204     infix("%", "mod", 140);
3205
3206     suffix("++", "postinc");
3207     prefix("++", "preinc");
3208     syntax["++"].exps = true;
3209
3210     suffix("--", "postdec");
3211     prefix("--", "predec");
3212     syntax["--"].exps = true;
3213     prefix("delete", function () {
3214         var p = expression(0);
3215         if (!p || (p.id !== "." && p.id !== "[")) {
3216             warning("Variables should not be deleted.");
3217         }
3218         this.first = p;
3219         return this;
3220     }).exps = true;
3221
3222     prefix("~", function () {
3223         if (option.bitwise) {
3224             warning("Unexpected '{a}'.", this, "~");
3225         }
3226         expression(150);
3227         return this;
3228     });
3229
3230     prefix("!", function () {
3231         this.right = expression(150);
3232         this.arity = "unary";
3233         if (bang[this.right.id] === true) {
3234             warning("Confusing use of '{a}'.", this, "!");
3235         }
3236         return this;
3237     });
3238     prefix("typeof", "typeof");
3239     prefix("new", function () {
3240         var c = expression(155), i;
3241         if (c && c.id !== "function") {
3242             if (c.identifier) {
3243                 c["new"] = true;
3244                 switch (c.value) {
3245                 case "Number":
3246                 case "String":
3247                 case "Boolean":
3248                 case "Math":
3249                 case "JSON":
3250                     warning("Do not use {a} as a constructor.", prevtoken, c.value);
3251                     break;
3252                 case "Function":
3253                     if (!option.evil) {
3254                         warning("The Function constructor is eval.");
3255                     }
3256                     break;
3257                 case "Date":
3258                 case "RegExp":
3259                     break;
3260                 default:
3261                     if (c.id !== "function") {
3262                         i = c.value.substr(0, 1);
3263                         if (option.newcap && (i < "A" || i > "Z") && !is_own(global, c.value)) {
3264                             warning("A constructor name should start with an uppercase letter.",
3265                                 token);
3266                         }
3267                     }
3268                 }
3269             } else {
3270                 if (c.id !== "." && c.id !== "[" && c.id !== "(") {
3271                     warning("Bad constructor.", token);
3272                 }
3273             }
3274         } else {
3275             if (!option.supernew)
3276                 warning("Weird construction. Delete 'new'.", this);
3277         }
3278         adjacent(token, nexttoken);
3279         if (nexttoken.id !== "(" && !option.supernew) {
3280             warning("Missing '()' invoking a constructor.",
3281                 token, token.value);
3282         }
3283         this.first = c;
3284         return this;
3285     });
3286     syntax["new"].exps = true;
3287
3288     prefix("void").exps = true;
3289
3290     infix(".", function (left, that) {
3291         adjacent(prevtoken, token);
3292         nobreak();
3293         var m = identifier();
3294         if (typeof m === "string") {
3295             countMember(m);
3296         }
3297         that.left = left;
3298         that.right = m;
3299         if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
3300             if (option.noarg)
3301                 warning("Avoid arguments.{a}.", left, m);
3302             else if (directive["use strict"])
3303                 error("Strict violation.");
3304         } else if (!option.evil && left && left.value === "document" &&
3305                 (m === "write" || m === "writeln")) {
3306             warning("document.write can be a form of eval.", left);
3307         }
3308         if (!option.evil && (m === "eval" || m === "execScript")) {
3309             warning("eval is evil.");
3310         }
3311         return that;
3312     }, 160, true);
3313
3314     infix("(", function (left, that) {
3315         if (prevtoken.id !== "}" && prevtoken.id !== ")") {
3316             nobreak(prevtoken, token);
3317         }
3318         nospace();
3319         if (option.immed && !left.immed && left.id === "function") {
3320             warning("Wrap an immediate function invocation in parentheses " +
3321                 "to assist the reader in understanding that the expression " +
3322                 "is the result of a function, and not the function itself.");
3323         }
3324         var n = 0,
3325             p = [];
3326         if (left) {
3327             if (left.type === "(identifier)") {
3328                 if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
3329                     if ("Number String Boolean Date Object".indexOf(left.value) === -1) {
3330                         if (left.value === "Math") {
3331                             warning("Math is not a function.", left);
3332                         } else if (option.newcap) {
3333                             warning("Missing 'new' prefix when invoking a constructor.", left);
3334                         }
3335                     }
3336                 }
3337             }
3338         }
3339         if (nexttoken.id !== ")") {
3340             for (;;) {
3341                 p[p.length] = expression(10);
3342                 n += 1;
3343                 if (nexttoken.id !== ",") {
3344                     break;
3345                 }
3346                 comma();
3347             }
3348         }
3349         advance(")");
3350         nospace(prevtoken, token);
3351         if (typeof left === "object") {
3352             if (left.value === "parseInt" && n === 1) {
3353                 warning("Missing radix parameter.", token);
3354             }
3355             if (!option.evil) {
3356                 if (left.value === "eval" || left.value === "Function" ||
3357                         left.value === "execScript") {
3358                     warning("eval is evil.", left);
3359
3360                     if (p[0] && [0].id === "(string)") {
3361                         addInternalSrc(left, p[0].value);
3362                     }
3363                 } else if (p[0] && p[0].id === "(string)" &&
3364                        (left.value === "setTimeout" ||
3365                         left.value === "setInterval")) {
3366                     warning(
3367     "Implied eval is evil. Pass a function instead of a string.", left);
3368                     addInternalSrc(left, p[0].value);
3369
3370                 // window.setTimeout/setInterval
3371                 } else if (p[0] && p[0].id === "(string)" &&
3372                        left.value === "." &&
3373                        left.left.value === "window" &&
3374                        (left.right === "setTimeout" ||
3375                         left.right === "setInterval")) {
3376                     warning(
3377     "Implied eval is evil. Pass a function instead of a string.", left);
3378                     addInternalSrc(left, p[0].value);
3379                 }
3380             }
3381             if (!left.identifier && left.id !== "." && left.id !== "[" &&
3382                     left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
3383                     left.id !== "?") {
3384                 warning("Bad invocation.", left);
3385             }
3386         }
3387         that.left = left;
3388         return that;
3389     }, 155, true).exps = true;
3390
3391     prefix("(", function () {
3392         nospace();
3393         if (nexttoken.id === "function") {
3394             nexttoken.immed = true;
3395         }
3396         var v = expression(0);
3397         advance(")", this);
3398         nospace(prevtoken, token);
3399         if (option.immed && v.id === "function") {
3400             if (nexttoken.id !== "(" &&
3401               (nexttoken.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
3402                 warning(
3403 "Do not wrap function literals in parens unless they are to be immediately invoked.",
3404                         this);
3405             }
3406         }
3407
3408         return v;
3409     });
3410
3411     infix("[", function (left, that) {
3412         nobreak(prevtoken, token);
3413         nospace();
3414         var e = expression(0), s;
3415         if (e && e.type === "(string)") {
3416             if (!option.evil && (e.value === "eval" || e.value === "execScript")) {
3417                 warning("eval is evil.", that);
3418             }
3419             countMember(e.value);
3420             if (!option.sub && ix.test(e.value)) {
3421                 s = syntax[e.value];
3422                 if (!s || !s.reserved) {
3423                     warning("['{a}'] is better written in dot notation.",
3424                             prevtoken, e.value);
3425                 }
3426             }
3427         }
3428         advance("]", that);
3429         nospace(prevtoken, token);
3430         that.left = left;
3431         that.right = e;
3432         return that;
3433     }, 160, true);
3434
3435     prefix("[", function () {
3436         var b = token.line !== nexttoken.line;
3437         this.first = [];
3438         if (b) {
3439             indent += option.indent;
3440             if (nexttoken.from === indent + option.indent) {
3441                 indent += option.indent;
3442             }
3443         }
3444         while (nexttoken.id !== "(end)") {
3445             while (nexttoken.id === ",") {
3446                 if (!option.es5)
3447                     warning("Extra comma.");
3448                 advance(",");
3449             }
3450             if (nexttoken.id === "]") {
3451                 break;
3452             }
3453             if (b && token.line !== nexttoken.line) {
3454                 indentation();
3455             }
3456             this.first.push(expression(10));
3457             if (nexttoken.id === ",") {
3458                 comma();
3459                 if (nexttoken.id === "]" && !option.es5) {
3460                     warning("Extra comma.", token);
3461                     break;
3462                 }
3463             } else {
3464                 break;
3465             }
3466         }
3467         if (b) {
3468             indent -= option.indent;
3469             indentation();
3470         }
3471         advance("]", this);
3472         return this;
3473     }, 160);
3474
3475
3476     function property_name() {
3477         var id = optionalidentifier(true);
3478         if (!id) {
3479             if (nexttoken.id === "(string)") {
3480                 id = nexttoken.value;
3481                 advance();
3482             } else if (nexttoken.id === "(number)") {
3483                 id = nexttoken.value.toString();
3484                 advance();
3485             }
3486         }
3487         return id;
3488     }
3489
3490
3491     function functionparams() {
3492         var next   = nexttoken;
3493         var params = [];
3494         var ident;
3495
3496         advance("(");
3497         nospace();
3498
3499         if (nexttoken.id === ")") {
3500             advance(")");
3501             return;
3502         }
3503
3504         for (;;) {
3505             ident = identifier(true);
3506             params.push(ident);
3507             addlabel(ident, "unused", token);
3508             if (nexttoken.id === ",") {
3509                 comma();
3510             } else {
3511                 advance(")", next);
3512                 nospace(prevtoken, token);
3513                 return params;
3514             }
3515         }
3516     }
3517
3518
3519     function doFunction(name, statement) {
3520         var f;
3521         var oldOption = option;
3522         var oldScope  = scope;
3523
3524         option = Object.create(option);
3525         scope  = Object.create(scope);
3526
3527         funct = {
3528             "(name)"     : name || "\"" + anonname + "\"",
3529             "(line)"     : nexttoken.line,
3530             "(character)": nexttoken.character,
3531             "(context)"  : funct,
3532             "(breakage)" : 0,
3533             "(loopage)"  : 0,
3534             "(metrics)"  : createMetrics(nexttoken),
3535             "(scope)"    : scope,
3536             "(statement)": statement,
3537             "(tokens)"   : {}
3538         };
3539
3540         f = funct;
3541         token.funct = funct;
3542
3543         functions.push(funct);
3544
3545         if (name) {
3546             addlabel(name, "function");
3547         }
3548
3549         funct["(params)"] = functionparams();
3550         funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
3551
3552         block(false, false, true);
3553
3554         funct["(metrics)"].verifyMaxStatementsPerFunction();
3555         funct["(metrics)"].verifyMaxComplexityPerFunction();
3556
3557         scope = oldScope;
3558         option = oldOption;
3559         funct["(last)"] = token.line;
3560         funct["(lastcharacter)"] = token.character;
3561         funct = funct["(context)"];
3562
3563         return f;
3564     }
3565
3566     function createMetrics(functionStartToken) {
3567         return {
3568             statementCount: 0,
3569             nestedBlockDepth: -1,
3570             ComplexityCount: 1,
3571             verifyMaxStatementsPerFunction: function () {
3572                 if (option.maxstatements &&
3573                     this.statementCount > option.maxstatements) {
3574                     var message = "Too many statements per function (" + this.statementCount + ").";
3575                     warning(message, functionStartToken);
3576                 }
3577             },
3578
3579             verifyMaxParametersPerFunction: function (params) {
3580                 params = params || [];
3581
3582                 if (option.maxparams && params.length > option.maxparams) {
3583                     var message = "Too many parameters per function (" + params.length + ").";
3584                     warning(message, functionStartToken);
3585                 }
3586             },
3587
3588             verifyMaxNestedBlockDepthPerFunction: function () {
3589                 if (option.maxdepth &&
3590                     this.nestedBlockDepth > 0 &&
3591                     this.nestedBlockDepth === option.maxdepth + 1) {
3592                     var message = "Blocks are nested too deeply (" + this.nestedBlockDepth + ").";
3593                     warning(message);
3594                 }
3595             },
3596
3597             verifyMaxComplexityPerFunction: function () {
3598                 var max = option.maxcomplexity;
3599                 var cc = this.ComplexityCount;
3600                 if (max && cc > max) {
3601                     var message = "Cyclomatic complexity is too high per function (" + cc + ").";
3602                     warning(message, functionStartToken);
3603                 }
3604             }
3605         };
3606     }
3607
3608     function increaseComplexityCount() {
3609         funct["(metrics)"].ComplexityCount += 1;
3610     }
3611
3612
3613     (function (x) {
3614         x.nud = function () {
3615             var b, f, i, p, t;
3616             var props = {}; // All properties, including accessors
3617
3618             function saveProperty(name, token) {
3619                 if (props[name] && is_own(props, name))
3620                     warning("Duplicate member '{a}'.", nexttoken, i);
3621                 else
3622                     props[name] = {};
3623
3624                 props[name].basic = true;
3625                 props[name].basicToken = token;
3626             }
3627
3628             function saveSetter(name, token) {
3629                 if (props[name] && is_own(props, name)) {
3630                     if (props[name].basic || props[name].setter)
3631                         warning("Duplicate member '{a}'.", nexttoken, i);
3632                 } else {
3633                     props[name] = {};
3634                 }
3635
3636                 props[name].setter = true;
3637                 props[name].setterToken = token;
3638             }
3639
3640             function saveGetter(name) {
3641                 if (props[name] && is_own(props, name)) {
3642                     if (props[name].basic || props[name].getter)
3643                         warning("Duplicate member '{a}'.", nexttoken, i);
3644                 } else {
3645                     props[name] = {};
3646                 }
3647
3648                 props[name].getter = true;
3649                 props[name].getterToken = token;
3650             }
3651
3652             b = token.line !== nexttoken.line;
3653             if (b) {
3654                 indent += option.indent;
3655                 if (nexttoken.from === indent + option.indent) {
3656                     indent += option.indent;
3657                 }
3658             }
3659             for (;;) {
3660                 if (nexttoken.id === "}") {
3661                     break;
3662                 }
3663                 if (b) {
3664                     indentation();
3665                 }
3666                 if (nexttoken.value === "get" && peek().id !== ":") {
3667                     advance("get");
3668                     if (!option.es5) {
3669                         error("get/set are ES5 features.");
3670                     }
3671                     i = property_name();
3672                     if (!i) {
3673                         error("Missing property name.");
3674                     }
3675                     saveGetter(i);
3676                     t = nexttoken;
3677                     adjacent(token, nexttoken);
3678                     f = doFunction();
3679                     p = f["(params)"];
3680                     if (p) {
3681                         warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i);
3682                     }
3683                     adjacent(token, nexttoken);
3684                 } else if (nexttoken.value === "set" && peek().id !== ":") {
3685                     advance("set");
3686                     if (!option.es5) {
3687                         error("get/set are ES5 features.");
3688                     }
3689                     i = property_name();
3690                     if (!i) {
3691                         error("Missing property name.");
3692                     }
3693                     saveSetter(i, nexttoken);
3694                     t = nexttoken;
3695                     adjacent(token, nexttoken);
3696                     f = doFunction();
3697                     p = f["(params)"];
3698                     if (!p || p.length !== 1) {
3699                         warning("Expected a single parameter in set {a} function.", t, i);
3700                     }
3701                 } else {
3702                     i = property_name();
3703                     saveProperty(i, nexttoken);
3704                     if (typeof i !== "string") {
3705                         break;
3706                     }
3707                     advance(":");
3708                     nonadjacent(token, nexttoken);
3709                     expression(10);
3710                 }
3711
3712                 countMember(i);
3713                 if (nexttoken.id === ",") {
3714                     comma();
3715                     if (nexttoken.id === ",") {
3716                         warning("Extra comma.", token);
3717                     } else if (nexttoken.id === "}" && !option.es5) {
3718                         warning("Extra comma.", token);
3719                     }
3720                 } else {
3721                     break;
3722                 }
3723             }
3724             if (b) {
3725                 indent -= option.indent;
3726                 indentation();
3727             }
3728             advance("}", this);
3729
3730             // Check for lonely setters if in the ES5 mode.
3731             if (option.es5) {
3732                 for (var name in props) {
3733                     if (is_own(props, name) && props[name].setter && !props[name].getter) {
3734                         warning("Setter is defined without getter.", props[name].setterToken);
3735                     }
3736                 }
3737             }
3738             return this;
3739         };
3740         x.fud = function () {
3741             error("Expected to see a statement and instead saw a block.", token);
3742         };
3743     }(delim("{")));
3744
3745 // This Function is called when esnext option is set to true
3746 // it adds the `const` statement to JSHINT
3747
3748     useESNextSyntax = function () {
3749         var conststatement = stmt("const", function (prefix) {
3750             var id, name, value;
3751
3752             this.first = [];
3753             for (;;) {
3754                 nonadjacent(token, nexttoken);
3755                 id = identifier();
3756                 if (funct[id] === "const") {
3757                     warning("const '" + id + "' has already been declared");
3758                 }
3759                 if (funct["(global)"] && predefined[id] === false) {
3760                     warning("Redefinition of '{a}'.", token, id);
3761                 }
3762                 addlabel(id, "const");
3763                 if (prefix) {
3764                     break;
3765                 }
3766                 name = token;
3767                 this.first.push(token);
3768
3769                 if (nexttoken.id !== "=") {
3770                     warning("const " +
3771                       "'{a}' is initialized to 'undefined'.", token, id);
3772                 }
3773
3774                 if (nexttoken.id === "=") {
3775                     nonadjacent(token, nexttoken);
3776                     advance("=");
3777                     nonadjacent(token, nexttoken);
3778                     if (nexttoken.id === "undefined") {
3779                         warning("It is not necessary to initialize " +
3780                           "'{a}' to 'undefined'.", token, id);
3781                     }
3782                     if (peek(0).id === "=" && nexttoken.identifier) {
3783                         error("Constant {a} was not declared correctly.",
3784                                 nexttoken, nexttoken.value);
3785                     }
3786                     value = expression(0);
3787                     name.first = value;
3788                 }
3789
3790                 if (nexttoken.id !== ",") {
3791                     break;
3792                 }
3793                 comma();
3794             }
3795             return this;
3796         });
3797         conststatement.exps = true;
3798     };
3799
3800     var varstatement = stmt("var", function (prefix) {
3801         // JavaScript does not have block scope. It only has function scope. So,
3802         // declaring a variable in a block can have unexpected consequences.
3803         var id, name, value;
3804
3805         if (funct["(onevar)"] && option.onevar) {
3806             warning("Too many var statements.");
3807         } else if (!funct["(global)"]) {
3808             funct["(onevar)"] = true;
3809         }
3810
3811         this.first = [];
3812
3813         for (;;) {
3814             nonadjacent(token, nexttoken);
3815             id = identifier();
3816
3817             if (option.esnext && funct[id] === "const") {
3818                 warning("const '" + id + "' has already been declared");
3819             }
3820
3821             if (funct["(global)"] && predefined[id] === false) {
3822                 warning("Redefinition of '{a}'.", token, id);
3823             }
3824
3825             addlabel(id, "unused", token);
3826
3827             if (prefix) {
3828                 break;
3829             }
3830
3831             name = token;
3832             this.first.push(token);
3833
3834             if (nexttoken.id === "=") {
3835                 nonadjacent(token, nexttoken);
3836                 advance("=");
3837                 nonadjacent(token, nexttoken);
3838                 if (nexttoken.id === "undefined") {
3839                     warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id);
3840                 }
3841                 if (peek(0).id === "=" && nexttoken.identifier) {
3842                     error("Variable {a} was not declared correctly.",
3843                             nexttoken, nexttoken.value);
3844                 }
3845                 value = expression(0);
3846                 name.first = value;
3847             }
3848             if (nexttoken.id !== ",") {
3849                 break;
3850             }
3851             comma();
3852         }
3853         return this;
3854     });
3855     varstatement.exps = true;
3856
3857     blockstmt("function", function () {
3858         if (inblock) {
3859             warning("Function declarations should not be placed in blocks. " +
3860                 "Use a function expression or move the statement to the top of " +
3861                 "the outer function.", token);
3862
3863         }
3864         var i = identifier();
3865         if (option.esnext && funct[i] === "const") {
3866             warning("const '" + i + "' has already been declared");
3867         }
3868         adjacent(token, nexttoken);
3869         addlabel(i, "unction", token);
3870
3871         doFunction(i, { statement: true });
3872         if (nexttoken.id === "(" && nexttoken.line === token.line) {
3873             error(
3874 "Function declarations are not invocable. Wrap the whole function invocation in parens.");
3875         }
3876         return this;
3877     });
3878
3879     prefix("function", function () {
3880         var i = optionalidentifier();
3881         if (i) {
3882             adjacent(token, nexttoken);
3883         } else {
3884             nonadjacent(token, nexttoken);
3885         }
3886         doFunction(i);
3887         if (!option.loopfunc && funct["(loopage)"]) {
3888             warning("Don't make functions within a loop.");
3889         }
3890         return this;
3891     });
3892
3893     blockstmt("if", function () {
3894         var t = nexttoken;
3895         increaseComplexityCount();
3896         advance("(");
3897         nonadjacent(this, t);
3898         nospace();
3899         expression(20);
3900         if (nexttoken.id === "=") {
3901             if (!option.boss)
3902                 warning("Expected a conditional expression and instead saw an assignment.");
3903             advance("=");
3904             expression(20);
3905         }
3906         advance(")", t);
3907         nospace(prevtoken, token);
3908         block(true, true);
3909         if (nexttoken.id === "else") {
3910             nonadjacent(token, nexttoken);
3911             advance("else");
3912             if (nexttoken.id === "if" || nexttoken.id === "switch") {
3913                 statement(true);
3914             } else {
3915                 block(true, true);
3916             }
3917         }
3918         return this;
3919     });
3920
3921     blockstmt("try", function () {
3922         var b;
3923
3924         function doCatch() {
3925             var oldScope = scope;
3926             var e;
3927
3928             advance("catch");
3929             nonadjacent(token, nexttoken);
3930             advance("(");
3931
3932             scope = Object.create(oldScope);
3933
3934             e = nexttoken.value;
3935             if (nexttoken.type !== "(identifier)") {
3936                 e = null;
3937                 warning("Expected an identifier and instead saw '{a}'.", nexttoken, e);
3938             }
3939
3940             advance();
3941             advance(")");
3942
3943             funct = {
3944                 "(name)"     : "(catch)",
3945                 "(line)"     : nexttoken.line,
3946                 "(character)": nexttoken.character,
3947                 "(context)"  : funct,
3948                 "(breakage)" : funct["(breakage)"],
3949                 "(loopage)"  : funct["(loopage)"],
3950                 "(scope)"    : scope,
3951                 "(statement)": false,
3952                 "(metrics)"  : createMetrics(nexttoken),
3953                 "(catch)"    : true,
3954                 "(tokens)"   : {}
3955             };
3956
3957             if (e) {
3958                 addlabel(e, "exception");
3959             }
3960
3961             token.funct = funct;
3962             functions.push(funct);
3963
3964             block(false);
3965
3966             scope = oldScope;
3967
3968             funct["(last)"] = token.line;
3969             funct["(lastcharacter)"] = token.character;
3970             funct = funct["(context)"];
3971         }
3972
3973         block(false);
3974
3975         if (nexttoken.id === "catch") {
3976             increaseComplexityCount();
3977             doCatch();
3978             b = true;
3979         }
3980
3981         if (nexttoken.id === "finally") {
3982             advance("finally");
3983             block(false);
3984             return;
3985         } else if (!b) {
3986             error("Expected '{a}' and instead saw '{b}'.",
3987                     nexttoken, "catch", nexttoken.value);
3988         }
3989
3990         return this;
3991     });
3992
3993     blockstmt("while", function () {
3994         var t = nexttoken;
3995         funct["(breakage)"] += 1;
3996         funct["(loopage)"] += 1;
3997         increaseComplexityCount();
3998         advance("(");
3999         nonadjacent(this, t);
4000         nospace();
4001         expression(20);
4002         if (nexttoken.id === "=") {
4003             if (!option.boss)
4004                 warning("Expected a conditional expression and instead saw an assignment.");
4005             advance("=");
4006             expression(20);
4007         }
4008         advance(")", t);
4009         nospace(prevtoken, token);
4010         block(true, true);
4011         funct["(breakage)"] -= 1;
4012         funct["(loopage)"] -= 1;
4013         return this;
4014     }).labelled = true;
4015
4016     blockstmt("with", function () {
4017         var t = nexttoken;
4018         if (directive["use strict"]) {
4019             error("'with' is not allowed in strict mode.", token);
4020         } else if (!option.withstmt) {
4021             warning("Don't use 'with'.", token);
4022         }
4023
4024         advance("(");
4025         nonadjacent(this, t);
4026         nospace();
4027         expression(0);
4028         advance(")", t);
4029         nospace(prevtoken, token);
4030         block(true, true);
4031
4032         return this;
4033     });
4034
4035     blockstmt("switch", function () {
4036         var t = nexttoken,
4037             g = false;
4038         funct["(breakage)"] += 1;
4039         advance("(");
4040         nonadjacent(this, t);
4041         nospace();
4042         this.condition = expression(20);
4043         advance(")", t);
4044         nospace(prevtoken, token);
4045         nonadjacent(token, nexttoken);
4046         t = nexttoken;
4047         advance("{");
4048         nonadjacent(token, nexttoken);
4049         indent += option.indent;
4050         this.cases = [];
4051         for (;;) {
4052             switch (nexttoken.id) {
4053             case "case":
4054                 switch (funct["(verb)"]) {
4055                 case "break":
4056                 case "case":
4057                 case "continue":
4058                 case "return":
4059                 case "switch":
4060                 case "throw":
4061                     break;
4062                 default:
4063                     // You can tell JSHint that you don't use break intentionally by
4064                     // adding a comment /* falls through */ on a line just before
4065                     // the next `case`.
4066                     if (!ft.test(lines[nexttoken.line - 2])) {
4067                         warning(
4068                             "Expected a 'break' statement before 'case'.",
4069                             token);
4070                     }
4071                 }
4072                 indentation(-option.indent);
4073                 advance("case");
4074                 this.cases.push(expression(20));
4075                 increaseComplexityCount();
4076                 g = true;
4077                 advance(":");
4078                 funct["(verb)"] = "case";
4079                 break;
4080             case "default":
4081                 switch (funct["(verb)"]) {
4082                 case "break":
4083                 case "continue":
4084                 case "return":
4085                 case "throw":
4086                     break;
4087                 default:
4088                     if (!ft.test(lines[nexttoken.line - 2])) {
4089                         warning(
4090                             "Expected a 'break' statement before 'default'.",
4091                             token);
4092                     }
4093                 }
4094                 indentation(-option.indent);
4095                 advance("default");
4096                 g = true;
4097                 advance(":");
4098                 break;
4099             case "}":
4100                 indent -= option.indent;
4101                 indentation();
4102                 advance("}", t);
4103                 if (this.cases.length === 1 || this.condition.id === "true" ||
4104                         this.condition.id === "false") {
4105                     if (!option.onecase)
4106                         warning("This 'switch' should be an 'if'.", this);
4107                 }
4108                 funct["(breakage)"] -= 1;
4109                 funct["(verb)"] = undefined;
4110                 return;
4111             case "(end)":
4112                 error("Missing '{a}'.", nexttoken, "}");
4113                 return;
4114             default:
4115                 if (g) {
4116                     switch (token.id) {
4117                     case ",":
4118                         error("Each value should have its own case label.");
4119                         return;
4120                     case ":":
4121                         g = false;
4122                         statements();
4123                         break;
4124                     default:
4125                         error("Missing ':' on a case clause.", token);
4126                         return;
4127                     }
4128                 } else {
4129                     if (token.id === ":") {
4130                         advance(":");
4131                         error("Unexpected '{a}'.", token, ":");
4132                         statements();
4133                     } else {
4134                         error("Expected '{a}' and instead saw '{b}'.",
4135                             nexttoken, "case", nexttoken.value);
4136                         return;
4137                     }
4138                 }
4139             }
4140         }
4141     }).labelled = true;
4142
4143     stmt("debugger", function () {
4144         if (!option.debug) {
4145             warning("All 'debugger' statements should be removed.");
4146         }
4147         return this;
4148     }).exps = true;
4149
4150     (function () {
4151         var x = stmt("do", function () {
4152             funct["(breakage)"] += 1;
4153             funct["(loopage)"] += 1;
4154             increaseComplexityCount();
4155
4156             this.first = block(true);
4157             advance("while");
4158             var t = nexttoken;
4159             nonadjacent(token, t);
4160             advance("(");
4161             nospace();
4162             expression(20);
4163             if (nexttoken.id === "=") {
4164                 if (!option.boss)
4165                     warning("Expected a conditional expression and instead saw an assignment.");
4166                 advance("=");
4167                 expression(20);
4168             }
4169             advance(")", t);
4170             nospace(prevtoken, token);
4171             funct["(breakage)"] -= 1;
4172             funct["(loopage)"] -= 1;
4173             return this;
4174         });
4175         x.labelled = true;
4176         x.exps = true;
4177     }());
4178
4179     blockstmt("for", function () {
4180         var s, t = nexttoken;
4181         funct["(breakage)"] += 1;
4182         funct["(loopage)"] += 1;
4183         increaseComplexityCount();
4184         advance("(");
4185         nonadjacent(this, t);
4186         nospace();
4187         if (peek(nexttoken.id === "var" ? 1 : 0).id === "in") {
4188             if (nexttoken.id === "var") {
4189                 advance("var");
4190                 varstatement.fud.call(varstatement, true);
4191             } else {
4192                 switch (funct[nexttoken.value]) {
4193                 case "unused":
4194                     funct[nexttoken.value] = "var";
4195                     break;
4196                 case "var":
4197                     break;
4198                 default:
4199                     warning("Bad for in variable '{a}'.",
4200                             nexttoken, nexttoken.value);
4201                 }
4202                 advance();
4203             }
4204             advance("in");
4205             expression(20);
4206             advance(")", t);
4207             s = block(true, true);
4208             if (option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
4209                     s[0].value !== "if")) {
4210                 warning("The body of a for in should be wrapped in an if statement to filter " +
4211                         "unwanted properties from the prototype.", this);
4212             }
4213             funct["(breakage)"] -= 1;
4214             funct["(loopage)"] -= 1;
4215             return this;
4216         } else {
4217             if (nexttoken.id !== ";") {
4218                 if (nexttoken.id === "var") {
4219                     advance("var");
4220                     varstatement.fud.call(varstatement);
4221                 } else {
4222                     for (;;) {
4223                         expression(0, "for");
4224                         if (nexttoken.id !== ",") {
4225                             break;
4226                         }
4227                         comma();
4228                     }
4229                 }
4230             }
4231             nolinebreak(token);
4232             advance(";");
4233             if (nexttoken.id !== ";") {
4234                 expression(20);
4235                 if (nexttoken.id === "=") {
4236                     if (!option.boss)
4237                         warning("Expected a conditional expression and instead saw an assignment.");
4238                     advance("=");
4239                     expression(20);
4240                 }
4241             }
4242             nolinebreak(token);
4243             advance(";");
4244             if (nexttoken.id === ";") {
4245                 error("Expected '{a}' and instead saw '{b}'.",
4246                         nexttoken, ")", ";");
4247             }
4248             if (nexttoken.id !== ")") {
4249                 for (;;) {
4250                     expression(0, "for");
4251                     if (nexttoken.id !== ",") {
4252                         break;
4253                     }
4254                     comma();
4255                 }
4256             }
4257             advance(")", t);
4258             nospace(prevtoken, token);
4259             block(true, true);
4260             funct["(breakage)"] -= 1;
4261             funct["(loopage)"] -= 1;
4262             return this;
4263         }
4264     }).labelled = true;
4265
4266
4267     stmt("break", function () {
4268         var v = nexttoken.value;
4269
4270         if (funct["(breakage)"] === 0)
4271             warning("Unexpected '{a}'.", nexttoken, this.value);
4272
4273         if (!option.asi)
4274             nolinebreak(this);
4275
4276         if (nexttoken.id !== ";") {
4277             if (token.line === nexttoken.line) {
4278                 if (funct[v] !== "label") {
4279                     warning("'{a}' is not a statement label.", nexttoken, v);
4280                 } else if (scope[v] !== funct) {
4281                     warning("'{a}' is out of scope.", nexttoken, v);
4282                 }
4283                 this.first = nexttoken;
4284                 advance();
4285             }
4286         }
4287         reachable("break");
4288         return this;
4289     }).exps = true;
4290
4291
4292     stmt("continue", function () {
4293         var v = nexttoken.value;
4294
4295         if (funct["(breakage)"] === 0)
4296             warning("Unexpected '{a}'.", nexttoken, this.value);
4297
4298         if (!option.asi)
4299             nolinebreak(this);
4300
4301         if (nexttoken.id !== ";") {
4302             if (token.line === nexttoken.line) {
4303                 if (funct[v] !== "label") {
4304                     warning("'{a}' is not a statement label.", nexttoken, v);
4305                 } else if (scope[v] !== funct) {
4306                     warning("'{a}' is out of scope.", nexttoken, v);
4307                 }
4308                 this.first = nexttoken;
4309                 advance();
4310             }
4311         } else if (!funct["(loopage)"]) {
4312             warning("Unexpected '{a}'.", nexttoken, this.value);
4313         }
4314         reachable("continue");
4315         return this;
4316     }).exps = true;
4317
4318
4319     stmt("return", function () {
4320         if (this.line === nexttoken.line) {
4321             if (nexttoken.id === "(regexp)")
4322                 warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator.");
4323
4324             if (nexttoken.id !== ";" && !nexttoken.reach) {
4325                 nonadjacent(token, nexttoken);
4326                 if (peek().value === "=" && !option.boss) {
4327                     warningAt("Did you mean to return a conditional instead of an assignment?",
4328                               token.line, token.character + 1);
4329                 }
4330                 this.first = expression(0);
4331             }
4332         } else if (!option.asi) {
4333             nolinebreak(this); // always warn (Line breaking error)
4334         }
4335         reachable("return");
4336         return this;
4337     }).exps = true;
4338
4339
4340     stmt("throw", function () {
4341         nolinebreak(this);
4342         nonadjacent(token, nexttoken);
4343         this.first = expression(20);
4344         reachable("throw");
4345         return this;
4346     }).exps = true;
4347
4348 //  Superfluous reserved words
4349
4350     reserve("class");
4351     reserve("const");
4352     reserve("enum");
4353     reserve("export");
4354     reserve("extends");
4355     reserve("import");
4356     reserve("super");
4357
4358     reserve("let");
4359     reserve("yield");
4360     reserve("implements");
4361     reserve("interface");
4362     reserve("package");
4363     reserve("private");
4364     reserve("protected");
4365     reserve("public");
4366     reserve("static");
4367
4368
4369 // Parse JSON
4370
4371     function jsonValue() {
4372
4373         function jsonObject() {
4374             var o = {}, t = nexttoken;
4375             advance("{");
4376             if (nexttoken.id !== "}") {
4377                 for (;;) {
4378                     if (nexttoken.id === "(end)") {
4379                         error("Missing '}' to match '{' from line {a}.",
4380                                 nexttoken, t.line);
4381                     } else if (nexttoken.id === "}") {
4382                         warning("Unexpected comma.", token);
4383                         break;
4384                     } else if (nexttoken.id === ",") {
4385                         error("Unexpected comma.", nexttoken);
4386                     } else if (nexttoken.id !== "(string)") {
4387                         warning("Expected a string and instead saw {a}.",
4388                                 nexttoken, nexttoken.value);
4389                     }
4390                     if (o[nexttoken.value] === true) {
4391                         warning("Duplicate key '{a}'.",
4392                                 nexttoken, nexttoken.value);
4393                     } else if ((nexttoken.value === "__proto__" &&
4394                         !option.proto) || (nexttoken.value === "__iterator__" &&
4395                         !option.iterator)) {
4396                         warning("The '{a}' key may produce unexpected results.",
4397                             nexttoken, nexttoken.value);
4398                     } else {
4399                         o[nexttoken.value] = true;
4400                     }
4401                     advance();
4402                     advance(":");
4403                     jsonValue();
4404                     if (nexttoken.id !== ",") {
4405                         break;
4406                     }
4407                     advance(",");
4408                 }
4409             }
4410             advance("}");
4411         }
4412
4413         function jsonArray() {
4414             var t = nexttoken;
4415             advance("[");
4416             if (nexttoken.id !== "]") {
4417                 for (;;) {
4418                     if (nexttoken.id === "(end)") {
4419                         error("Missing ']' to match '[' from line {a}.",
4420                                 nexttoken, t.line);
4421                     } else if (nexttoken.id === "]") {
4422                         warning("Unexpected comma.", token);
4423                         break;
4424                     } else if (nexttoken.id === ",") {
4425                         error("Unexpected comma.", nexttoken);
4426                     }
4427                     jsonValue();
4428                     if (nexttoken.id !== ",") {
4429                         break;
4430                     }
4431                     advance(",");
4432                 }
4433             }
4434             advance("]");
4435         }
4436
4437         switch (nexttoken.id) {
4438         case "{":
4439             jsonObject();
4440             break;
4441         case "[":
4442             jsonArray();
4443             break;
4444         case "true":
4445         case "false":
4446         case "null":
4447         case "(number)":
4448         case "(string)":
4449             advance();
4450             break;
4451         case "-":
4452             advance("-");
4453             if (token.character !== nexttoken.from) {
4454                 warning("Unexpected space after '-'.", token);
4455             }
4456             adjacent(token, nexttoken);
4457             advance("(number)");
4458             break;
4459         default:
4460             error("Expected a JSON value.", nexttoken);
4461         }
4462     }
4463
4464
4465     // The actual JSHINT function itself.
4466     var itself = function (s, o, g) {
4467         var a, i, k, x;
4468         var optionKeys;
4469         var newOptionObj = {};
4470
4471         if (o && o.scope) {
4472             JSHINT.scope = o.scope;
4473         } else {
4474             JSHINT.errors = [];
4475             JSHINT.undefs = [];
4476             JSHINT.internals = [];
4477             JSHINT.blacklist = {};
4478             JSHINT.scope = "(main)";
4479         }
4480
4481         predefined = Object.create(standard);
4482         declared = Object.create(null);
4483         combine(predefined, g || {});
4484
4485         if (o) {
4486             a = o.predef;
4487             if (a) {
4488                 if (!Array.isArray(a) && typeof a === "object") {
4489                     a = Object.keys(a);
4490                 }
4491                 a.forEach(function (item) {
4492                     var slice;
4493                     if (item[0] === "-") {
4494                         slice = item.slice(1);
4495                         JSHINT.blacklist[slice] = slice;
4496                     } else {
4497                         predefined[item] = true;
4498                     }
4499                 });
4500             }
4501
4502             optionKeys = Object.keys(o);
4503             for (x = 0; x < optionKeys.length; x++) {
4504                 newOptionObj[optionKeys[x]] = o[optionKeys[x]];
4505
4506                 if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
4507                     newOptionObj["(explicitNewcap)"] = true;
4508
4509                 if (optionKeys[x] === "indent")
4510                     newOptionObj.white = true;
4511             }
4512         }
4513
4514         option = newOptionObj;
4515
4516         option.indent = option.indent || 4;
4517         option.maxerr = option.maxerr || 50;
4518
4519         tab = "";
4520         for (i = 0; i < option.indent; i += 1) {
4521             tab += " ";
4522         }
4523         indent = 1;
4524         global = Object.create(predefined);
4525         scope = global;
4526         funct = {
4527             "(global)":   true,
4528             "(name)":     "(global)",
4529             "(scope)":    scope,
4530             "(breakage)": 0,
4531             "(loopage)":  0,
4532             "(tokens)":   {},
4533             "(metrics)":   createMetrics(nexttoken)
4534         };
4535         functions = [funct];
4536         urls = [];
4537         stack = null;
4538         member = {};
4539         membersOnly = null;
4540         implied = {};
4541         inblock = false;
4542         lookahead = [];
4543         jsonmode = false;
4544         warnings = 0;
4545         lines = [];
4546         unuseds = [];
4547
4548         if (!isString(s) && !Array.isArray(s)) {
4549             errorAt("Input is neither a string nor an array of strings.", 0);
4550             return false;
4551         }
4552
4553         if (isString(s) && /^\s*$/g.test(s)) {
4554             errorAt("Input is an empty string.", 0);
4555             return false;
4556         }
4557
4558         if (s.length === 0) {
4559             errorAt("Input is an empty array.", 0);
4560             return false;
4561         }
4562
4563         lex.init(s);
4564
4565         prereg = true;
4566         directive = {};
4567
4568         prevtoken = token = nexttoken = syntax["(begin)"];
4569
4570         // Check options
4571         for (var name in o) {
4572             if (is_own(o, name)) {
4573                 checkOption(name, token);
4574             }
4575         }
4576
4577         assume();
4578
4579         // combine the passed globals after we've assumed all our options
4580         combine(predefined, g || {});
4581
4582         //reset values
4583         comma.first = true;
4584         quotmark = undefined;
4585
4586         try {
4587             advance();
4588             switch (nexttoken.id) {
4589             case "{":
4590             case "[":
4591                 option.laxbreak = true;
4592                 jsonmode = true;
4593                 jsonValue();
4594                 break;
4595             default:
4596                 directives();
4597                 if (directive["use strict"] && !option.globalstrict) {
4598                     warning("Use the function form of \"use strict\".", prevtoken);
4599                 }
4600
4601                 statements();
4602             }
4603             advance((nexttoken && nexttoken.value !== ".")  ? "(end)" : undefined);
4604
4605             var markDefined = function (name, context) {
4606                 do {
4607                     if (typeof context[name] === "string") {
4608                         // JSHINT marks unused variables as 'unused' and
4609                         // unused function declaration as 'unction'. This
4610                         // code changes such instances back 'var' and
4611                         // 'closure' so that the code in JSHINT.data()
4612                         // doesn't think they're unused.
4613
4614                         if (context[name] === "unused")
4615                             context[name] = "var";
4616                         else if (context[name] === "unction")
4617                             context[name] = "closure";
4618
4619                         return true;
4620                     }
4621
4622                     context = context["(context)"];
4623                 } while (context);
4624
4625                 return false;
4626             };
4627
4628             var clearImplied = function (name, line) {
4629                 if (!implied[name])
4630                     return;
4631
4632                 var newImplied = [];
4633                 for (var i = 0; i < implied[name].length; i += 1) {
4634                     if (implied[name][i] !== line)
4635                         newImplied.push(implied[name][i]);
4636                 }
4637
4638                 if (newImplied.length === 0)
4639                     delete implied[name];
4640                 else
4641                     implied[name] = newImplied;
4642             };
4643
4644             var warnUnused = function (name, token) {
4645                 var line = token.line;
4646                 var chr  = token.character;
4647
4648                 if (option.unused)
4649                     warningAt("'{a}' is defined but never used.", line, chr, name);
4650
4651                 unuseds.push({
4652                     name: name,
4653                     line: line,
4654                     character: chr
4655                 });
4656             };
4657
4658             var checkUnused = function (func, key) {
4659                 var type = func[key];
4660                 var token = func["(tokens)"][key];
4661
4662                 if (key.charAt(0) === "(")
4663                     return;
4664
4665                 if (type !== "unused" && type !== "unction")
4666                     return;
4667
4668                 // Params are checked separately from other variables.
4669                 if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
4670                     return;
4671
4672                 warnUnused(key, token);
4673             };
4674
4675             // Check queued 'x is not defined' instances to see if they're still undefined.
4676             for (i = 0; i < JSHINT.undefs.length; i += 1) {
4677                 k = JSHINT.undefs[i].slice(0);
4678
4679                 if (markDefined(k[2].value, k[0])) {
4680                     clearImplied(k[2].value, k[2].line);
4681                 } else {
4682                     warning.apply(warning, k.slice(1));
4683                 }
4684             }
4685
4686             functions.forEach(function (func) {
4687                 for (var key in func) {
4688                     if (is_own(func, key)) {
4689                         checkUnused(func, key);
4690                     }
4691                 }
4692
4693                 if (!func["(params)"])
4694                     return;
4695
4696                 var params = func["(params)"].slice();
4697                 var param  = params.pop();
4698                 var type;
4699
4700                 while (param) {
4701                     type = func[param];
4702
4703                     // 'undefined' is a special case for (function (window, undefined) { ... })();
4704                     // patterns.
4705
4706                     if (param === "undefined")
4707                         return;
4708
4709                     if (type !== "unused" && type !== "unction")
4710                         return;
4711
4712                     warnUnused(param, func["(tokens)"][param]);
4713                     param = params.pop();
4714                 }
4715             });
4716
4717             for (var key in declared) {
4718                 if (is_own(declared, key) && !is_own(global, key)) {
4719                     warnUnused(key, declared[key]);
4720                 }
4721             }
4722         } catch (e) {
4723             if (e) {
4724                 var nt = nexttoken || {};
4725                 JSHINT.errors.push({
4726                     raw       : e.raw,
4727                     reason    : e.message,
4728                     line      : e.line || nt.line,
4729                     character : e.character || nt.from
4730                 }, null);
4731             }
4732         }
4733
4734         // Loop over the listed "internals", and check them as well.
4735
4736         if (JSHINT.scope === "(main)") {
4737             o = o || {};
4738
4739             for (i = 0; i < JSHINT.internals.length; i += 1) {
4740                 k = JSHINT.internals[i];
4741                 o.scope = k.elem;
4742                 itself(k.value, o, g);
4743             }
4744         }
4745
4746         return JSHINT.errors.length === 0;
4747     };
4748
4749     // Data summary.
4750     itself.data = function () {
4751         var data = {
4752             functions: [],
4753             options: option
4754         };
4755         var implieds = [];
4756         var members = [];
4757         var fu, f, i, j, n, globals;
4758
4759         if (itself.errors.length) {
4760             data.errors = itself.errors;
4761         }
4762
4763         if (jsonmode) {
4764             data.json = true;
4765         }
4766
4767         for (n in implied) {
4768             if (is_own(implied, n)) {
4769                 implieds.push({
4770                     name: n,
4771                     line: implied[n]
4772                 });
4773             }
4774         }
4775
4776         if (implieds.length > 0) {
4777             data.implieds = implieds;
4778         }
4779
4780         if (urls.length > 0) {
4781             data.urls = urls;
4782         }
4783
4784         globals = Object.keys(scope);
4785         if (globals.length > 0) {
4786             data.globals = globals;
4787         }
4788
4789         for (i = 1; i < functions.length; i += 1) {
4790             f = functions[i];
4791             fu = {};
4792
4793             for (j = 0; j < functionicity.length; j += 1) {
4794                 fu[functionicity[j]] = [];
4795             }
4796
4797             for (j = 0; j < functionicity.length; j += 1) {
4798                 if (fu[functionicity[j]].length === 0) {
4799                     delete fu[functionicity[j]];
4800                 }
4801             }
4802
4803             fu.name = f["(name)"];
4804             fu.param = f["(params)"];
4805             fu.line = f["(line)"];
4806             fu.character = f["(character)"];
4807             fu.last = f["(last)"];
4808             fu.lastcharacter = f["(lastcharacter)"];
4809             data.functions.push(fu);
4810         }
4811
4812         if (unuseds.length > 0) {
4813             data.unused = unuseds;
4814         }
4815
4816         members = [];
4817         for (n in member) {
4818             if (typeof member[n] === "number") {
4819                 data.member = member;
4820                 break;
4821             }
4822         }
4823
4824         return data;
4825     };
4826
4827     itself.jshint = itself;
4828
4829     return itself;
4830 }());
4831
4832 // Make JSHINT a Node module, if possible.
4833 if (typeof exports === "object" && exports) {
4834     exports.JSHINT = JSHINT;
4835 }