source: ether_iasi/trunk/web/resources/js/library/jquery-ui-1.9.2.custom/development-bundle/external/jshint.js @ 786

Last change on this file since 786 was 786, checked in by cbipsl, 10 years ago

commit temp
bug libraries

File size: 167.2 KB
Line 
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
230var 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
1331unclosedString:
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;
1660klass:
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
1925loop:
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.
4833if (typeof exports === "object" && exports) {
4834    exports.JSHINT = JSHINT;
4835}
Note: See TracBrowser for help on using the repository browser.