X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=jslint.js;fp=jslint.js;h=0000000000000000000000000000000000000000;hb=f1626066e26b36586c5da4e6f04b2dcdf6889a90;hp=a1291ba47054953c332a191c70d3d1bc0db0150e;hpb=914267a94d253c23c16cb2b64a6dc246b2f6a311;p=pve-jslint.git diff --git a/jslint.js b/jslint.js deleted file mode 100644 index a1291ba..0000000 --- a/jslint.js +++ /dev/null @@ -1,6904 +0,0 @@ -// jslint.js -// 2011-07-04 - -// Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. - -// The Software shall be used for Good, not Evil. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// WARNING: JSLint will hurt your feelings. - -// JSLINT is a global function. It takes two parameters. - -// var myResult = JSLINT(source, option); - -// The first parameter is either a string or an array of strings. If it is a -// string, it will be split on '\n' or '\r'. If it is an array of strings, it -// is assumed that each string represents one line. The source can be a -// JavaScript text, or HTML text, or a JSON text, or a CSS text. - -// The second parameter is an optional object of options that control the -// operation of JSLINT. Most of the options are booleans: They are all -// optional and have a default value of false. One of the options, predef, -// can be an array of names, which will be used to declare global variables, -// or an object whose keys are used as global names, with a boolean value -// that determines if they are assignable. - -// If it checks out, JSLINT returns true. Otherwise, it returns false. - -// If false, you can inspect JSLINT.errors to find out the problems. -// JSLINT.errors is an array of objects containing these properties: - -// { -// line : The line (relative to 0) at which the lint was found -// character : The character (relative to 0) at which the lint was found -// reason : The problem -// evidence : The text line in which the problem occurred -// raw : The raw message before the details were inserted -// a : The first detail -// b : The second detail -// c : The third detail -// d : The fourth detail -// } - -// If a stopping error was found, a null will be the last element of the -// JSLINT.errors array. A stopping error means that JSLint was not confident -// enough to continue. It does not necessarily mean that the error was -// especially heinous. - -// You can request a Function Report, which shows all of the functions -// and the parameters and vars that they use. This can be used to find -// implied global variables and other problems. The report is in HTML and -// can be inserted in an HTML . - -// var myReport = JSLINT.report(errors_only); - -// If errors_only is true, then the report will be limited to only errors. - -// You can request a data structure that contains JSLint's results. - -// var myData = JSLINT.data(); - -// It returns a structure with this form: - -// { -// errors: [ -// { -// line: NUMBER, -// character: NUMBER, -// reason: STRING, -// evidence: STRING -// } -// ], -// functions: [ -// { -// name: STRING, -// line: NUMBER, -// last: NUMBER, -// params: [ -// { -// string: STRING -// } -// ], -// closure: [ -// STRING -// ], -// var: [ -// STRING -// ], -// exception: [ -// STRING -// ], -// outer: [ -// STRING -// ], -// unused: [ -// STRING -// ], -// undef: [ -// STRING -// ], -// global: [ -// STRING -// ], -// label: [ -// STRING -// ] -// } -// ], -// globals: [ -// STRING -// ], -// member: { -// STRING: NUMBER -// }, -// urls: [ -// STRING -// ], -// json: BOOLEAN -// } - -// Empty arrays will not be included. - -// You can obtain the parse tree that JSLint constructed while parsing. The -// latest tree is kept in JSLINT.tree. A nice stringication can be produced -// with - -// JSON.stringify(JSLINT.tree, [ -// 'string', 'arity', 'name', 'first', -// 'second', 'third', 'block', 'else' -// ], 4)); - -// JSLint provides three directives. They look like slashstar comments, and -// allow for setting options, declaring global variables, and establishing a -// set of allowed property names. - -// These directives respect function scope. - -// The jslint directive is a special comment that can set one or more options. -// The current option set is - -// adsafe true, if ADsafe rules should be enforced -// bitwise true, if bitwise operators should be allowed -// browser true, if the standard browser globals should be predefined -// cap true, if upper case HTML should be allowed -// confusion true, if types can be used inconsistently -// 'continue' true, if the continuation statement should be tolerated -// css true, if CSS workarounds should be tolerated -// debug true, if debugger statements should be allowed -// devel true, if logging should be allowed (console, alert, etc.) -// eqeq true, if == should be allowed -// es5 true, if ES5 syntax should be allowed -// evil true, if eval should be allowed -// forin true, if for in statements need not filter -// fragment true, if HTML fragments should be allowed -// indent the indentation factor -// maxerr the maximum number of errors to allow -// maxlen the maximum length of a source line -// newcap true, if constructor names capitalization is ignored -// node true, if Node.js globals should be predefined -// nomen true, if names may have dangling _ -// on true, if HTML event handlers should be allowed -// passfail true, if the scan should stop on first error -// plusplus true, if increment/decrement should be allowed -// properties true, if all property names must be declared with /*properties*/ -// regexp true, if the . should be allowed in regexp literals -// rhino true, if the Rhino environment globals should be predefined -// undef true, if variables can be declared out of order -// unparam true, if unused parameters should be tolerated -// safe true, if use of some browser features should be restricted -// sloppy true, if the 'use strict'; pragma is optional -// sub true, if all forms of subscript notation are tolerated -// vars true, if multiple var statements per function should be allowed -// white true, if sloppy whitespace is tolerated -// widget true if the Yahoo Widgets globals should be predefined -// windows true, if MS Windows-specific globals should be predefined - -// For example: - -/*jslint - evil: true, nomen: true, regexp: true -*/ - -// The properties directive declares an exclusive list of property names. -// Any properties named in the program that are not in the list will -// produce a warning. - -// For example: - -/*properties - '\b': string, '\t': string, '\n': string, '\f': string, '\r': string, - '!=': boolean, '!==': boolean, '"': string, '%': boolean, '\'': string, - '(begin)', '(breakage)': number, '(complexity)', - '(confusion)': boolean, '(context)': object, - '(error)', '(identifier)', '(line)': number, '(loopage)': number, '(name)', - '(old_property_type)', '(params)', '(return_type)', '(scope)': object, - '(statement)', '(token)', '(vars)', '(verb)', '*': boolean, '+': boolean, - '-': boolean, '/': *, '<': boolean, '<=': boolean, '==': boolean, - '===': boolean, '>': boolean, '>=': boolean, ADSAFE: boolean, Array, - Date, E: string, Function, LN10: string, LN2: string, LOG10E: string, - LOG2E: string, MAX_VALUE: string, MIN_VALUE: string, - NEGATIVE_INFINITY: string, Object, PI: string, POSITIVE_INFINITY: string, - SQRT1_2: string, SQRT2: string, '\\': string, a: object, a_label: string, - a_not_allowed: string, a_not_defined: string, a_scope: string, - abbr: object, acronym: object, address: object, adsafe, adsafe_a: string, - adsafe_autocomplete: string, adsafe_bad_id: string, adsafe_div: string, - adsafe_fragment: string, adsafe_go: string, adsafe_html: string, - adsafe_id: string, adsafe_id_go: string, adsafe_lib: string, - adsafe_lib_second: string, adsafe_missing_id: string, - adsafe_name_a: string, adsafe_placement: string, adsafe_prefix_a: string, - adsafe_script: string, adsafe_source: string, adsafe_subscript_a: string, - adsafe_tag: string, all: boolean, already_defined: string, and: string, - applet: object, apply: string, approved: array, area: object, - arity: string, article: object, aside: object, assign: boolean, - assign_exception: string, assignment_function_expression: string, - at: number, attribute_case_a: string, audio: object, autocomplete: string, - avoid_a: string, b: *, background: array, 'background-attachment': array, - 'background-color': array, 'background-image': array, - 'background-position': array, 'background-repeat': array, - bad_assignment: string, bad_color_a: string, bad_constructor: string, - bad_entity: string, bad_html: string, bad_id_a: string, bad_in_a: string, - bad_invocation: string, bad_name_a: string, bad_new: string, - bad_number: string, bad_operand: string, bad_type: string, bad_url: string, - bad_wrap: string, base: object, bdo: object, big: object, bind: string, - bitwise: boolean, block: array, blockquote: object, body: object, - border: array, 'border-bottom': array, 'border-bottom-color', - 'border-bottom-style': array, 'border-bottom-width', - 'border-collapse': array, 'border-color': array, 'border-left': array, - 'border-left-color', 'border-left-style': array, 'border-left-width', - 'border-right': array, 'border-right-color', 'border-right-style': array, - 'border-right-width', 'border-spacing': array, 'border-style': array, - 'border-top': array, 'border-top-color', 'border-top-style': array, - 'border-top-width', 'border-width': array, bottom: array, br: object, - braille: boolean, browser: boolean, button: object, c, call: string, - canvas: object, cap, caption: object, 'caption-side': array, ceil: string, - center: object, charAt: *, charCodeAt: *, character, cite: object, - clear: array, clip: array, closure, cm: boolean, code: object, col: object, - colgroup: object, color, combine_var: string, command: object, comment, - comments: array, concat: string, conditional_assignment: string, - confusing_a: string, confusing_regexp: string, confusion: boolean, - constructor: string, constructor_name_a: string, content: array, continue, - control_a: string, 'counter-increment': array, 'counter-reset': array, - create: *, css: string, cursor: array, d, dangerous_comment: string, - dangling_a: string, data: function object, datalist: object, dd: object, - debug, defineProperties: string, defineProperty: string, del: object, - deleted: string, details: object, devel: boolean, dfn: object, - dialog: object, dir: object, direction: array, display: array, - disrupt: boolean, div: object, dl: object, dt: object, duplicate_a: string, - edge: string, edition: string, else, em: *, embed: object, - embossed: boolean, empty: boolean, 'empty-cells': array, - empty_block: string, empty_case: string, empty_class: string, - entityify: function, eqeq, errors: array, es5: string, eval, every: string, - evidence, evil: string, ex: boolean, exception, exec: *, - expected_a: string, expected_a_at_b_c: string, expected_a_b: string, - expected_a_b_from_c_d: string, expected_at_a: string, - expected_attribute_a: string, expected_attribute_value_a: string, - expected_class_a: string, expected_fraction_a: string, - expected_id_a: string, expected_identifier_a: string, - expected_identifier_a_reserved: string, expected_lang_a: string, - expected_linear_a: string, expected_media_a: string, - expected_name_a: string, expected_nonstandard_style_attribute: string, - expected_number_a: string, expected_operator_a: string, - expected_percent_a: string, expected_positive_a: string, - expected_pseudo_a: string, expected_selector_a: string, - expected_small_a: string, expected_space_a_b: string, - expected_string_a: string, expected_style_attribute: string, - expected_style_pattern: string, expected_tagname_a: string, - expected_type_a: string, f: string, fieldset: object, figure: object, - filter: *, first: *, float: array, floor: *, font: *, 'font-family', - 'font-size': array, 'font-size-adjust': array, 'font-stretch': array, - 'font-style': array, 'font-variant': array, 'font-weight': array, - footer: object, forEach: *, for_if: string, forin, form: object, fragment, - frame: object, frameset: object, freeze: string, from: number, - fromCharCode: function, fud: function, funct: object, function, - function_block: string, function_eval: string, function_loop: string, - function_statement: string, function_strict: string, functions: array, - getDate: string, getDay: string, getFullYear: string, getHours: string, - getMilliseconds: string, getMinutes: string, getMonth: string, - getOwnPropertyDescriptor: string, getOwnPropertyNames: string, - getPrototypeOf: string, getSeconds: string, getTime: string, - getTimezoneOffset: string, getUTCDate: string, getUTCDay: string, - getUTCFullYear: string, getUTCHours: string, getUTCMilliseconds: string, - getUTCMinutes: string, getUTCMonth: string, getUTCSeconds: string, - getYear: string, global, globals, h1: object, h2: object, h3: object, - h4: object, h5: object, h6: object, handheld: boolean, hasOwnProperty: *, - head: object, header: object, height: array, hgroup: object, hr: object, - 'hta:application': object, html: *, html_confusion_a: string, - html_handlers: string, i: object, id: string, identifier: boolean, - identifier_function: string, iframe: object, img: object, immed: boolean, - implied_evil: string, in: boolean, indent: number, indexOf: *, - infix_in: string, init: function, input: object, ins: object, - insecure_a: string, isAlpha: function, isArray: function boolean, - isDigit: function, isExtensible: string, isFrozen: string, isNaN: string, - isPrototypeOf: string, isSealed: string, join: *, jslint: function boolean, - json: boolean, kbd: object, keygen: object, keys: *, label: object, - label_a_b: string, labeled: boolean, lang: string, lastIndex: string, - lastIndexOf: *, lbp: number, leading_decimal_a: string, led: function, - left: array, legend: object, length: *, 'letter-spacing': array, - li: object, lib: boolean, line: number, 'line-height': array, link: object, - 'list-style': array, 'list-style-image': array, - 'list-style-position': array, 'list-style-type': array, map: *, - margin: array, 'margin-bottom', 'margin-left', 'margin-right', - 'margin-top', mark: object, 'marker-offset': array, match: function, - 'max-height': array, 'max-width': array, maxerr: number, maxlen: number, - member: object, menu: object, message, meta: object, meter: object, - 'min-height': function, 'min-width': function, missing_a: string, - missing_a_after_b: string, missing_option: string, - missing_property: string, missing_space_a_b: string, missing_url: string, - missing_use_strict: string, mixed: string, mm: boolean, mode: string, - move_invocation: string, move_var: string, n: string, name: string, - name_function: string, nav: object, nested_comment: string, - newcap: boolean, next, node: boolean, noframes: object, nomen, - noscript: object, not: string, not_a_constructor: string, - not_a_defined: string, not_a_function: string, not_a_label: string, - not_a_scope: string, not_greater: string, now: string, nud: function, - number: number, object: object, ol: object, on, opacity, open: boolean, - optgroup: object, option: object, outer: regexp, outline: array, - 'outline-color': array, 'outline-style': array, 'outline-width', - output: object, overflow: array, 'overflow-x': array, 'overflow-y': array, - p: object, padding: array, 'padding-bottom': function, - 'padding-left': function, 'padding-right': function, - 'padding-top': function, 'page-break-after': array, - 'page-break-before': array, param: object, parameter_a_get_b: string, - parameter_set_a: string, params: array, paren: boolean, parent: string, - parse: string, passfail, pc: boolean, plusplus, pop: *, position: array, - postscript: boolean, pre: object, predef, prev, preventExtensions: string, - print: boolean, progress: object, projection: boolean, properties: boolean, - propertyIsEnumerable: string, prototype: string, pt: boolean, push: *, - px: boolean, q: object, quote, quotes: array, r: string, radix: string, - range: function, raw, read_only: string, reason, redefinition_a: string, - reduce: string, reduceRight: string, regexp, replace: function, - report: function, reserved: boolean, reserved_a: string, reverse: string, - rhino: boolean, right: array, rp: object, rt: object, ruby: object, - safe: boolean, samp: object, scanned_a_b: string, screen: boolean, - script: object, seal: string, search: function, second: *, section: object, - select: object, setDate: string, setDay: string, setFullYear: string, - setHours: string, setMilliseconds: string, setMinutes: string, - setMonth: string, setSeconds: string, setTime: string, - setTimezoneOffset: string, setUTCDate: string, setUTCDay: string, - setUTCFullYear: string, setUTCHours: string, setUTCMilliseconds: string, - setUTCMinutes: string, setUTCMonth: string, setUTCSeconds: string, - setYear: string, shift: *, slash_equal: string, slice: string, sloppy, - small: object, some: string, sort: *, source: object, span: object, - speech: boolean, splice: string, split: function, src, - statement_block: string, stopping: string, strange_loop: string, - strict: string, string: string, stringify: string, strong: object, style: *, - styleproperty: regexp, sub: object, subscript: string, substr: *, - substring: string, sup: object, supplant: function, t: string, - table: object, 'table-layout': array, tag_a_in_b: string, tbody: object, - td: object, test: *, 'text-align': array, 'text-decoration': array, - 'text-indent': function, 'text-shadow': array, 'text-transform': array, - textarea: object, tfoot: object, th: object, thead: object, third: array, - thru: number, time: object, title: object, toDateString: string, - toExponential: string, toFixed: string, toISOString: string, - toJSON: string, toLocaleDateString: string, toLocaleLowerCase: string, - toLocaleString: string, toLocaleTimeString: string, - toLocaleUpperCase: string, toLowerCase: *, toPrecision: string, - toString: function, toTimeString: string, toUTCString: string, - toUpperCase: *, token: function, too_long: string, too_many: string, - top: array, tr: object, trailing_decimal_a: string, tree: string, - trim: string, tt: object, tty: boolean, tv: boolean, type: string, - type_confusion_a_b: string, u: object, ul: object, unclosed: string, - unclosed_comment: string, unclosed_regexp: string, undef: boolean, - undefined, unescaped_a: string, unexpected_a: string, - unexpected_char_a_b: string, unexpected_comment: string, - unexpected_property_a: string, unexpected_space_a_b: string, - 'unicode-bidi': array, unnecessary_initialize: string, - unnecessary_use: string, unparam, unreachable_a_b: string, - unrecognized_style_attribute_a: string, unrecognized_tag_a: string, - unsafe: string, unshift: string, unused: array, url: string, urls: array, - use_array: string, use_braces: string, use_charAt: string, - use_object: string, use_or: string, use_param: string, - used_before_a: string, valueOf: string, var: object, - var_a_not: string, vars, 'vertical-align': array, video: object, - visibility: array, was: object, weird_assignment: string, - weird_condition: string, weird_new: string, weird_program: string, - weird_relation: string, weird_ternary: string, white: boolean, - 'white-space': array, widget: boolean, width: array, windows: boolean, - 'word-spacing': array, 'word-wrap': array, wrap: boolean, - wrap_immediate: string, wrap_regexp: string, write_is_wrong: string, - writeable: boolean, 'z-index': array -*/ - -// The global directive is used to declare global variables that can -// be accessed by the program. If a declaration is true, then the variable -// is writeable. Otherwise, it is read-only. - -// We build the application inside a function so that we produce only a single -// global variable. That function will be invoked immediately, and its return -// value is the JSLINT function itself. That function is also an object that -// can contain data and other functions. - -var JSLINT = (function () { - 'use strict'; - - function array_to_object(array, value) { - var i, object = {}; - for (i = 0; i < array.length; i += 1) { - object[array[i]] = value; - } - return object; - } - - - var adsafe_id, // The widget's ADsafe id. - adsafe_may, // The widget may load approved scripts. - adsafe_top, // At the top of the widget script. - adsafe_went, // ADSAFE.go has been called. - anonname, // The guessed name for anonymous functions. - approved, // ADsafe approved urls. - -// These are operators that should not be used with the ! operator. - - bang = { - '<' : true, - '<=' : true, - '==' : true, - '===': true, - '!==': true, - '!=' : true, - '>' : true, - '>=' : true, - '+' : true, - '-' : true, - '*' : true, - '/' : true, - '%' : true - }, - -// These are property names that should not be permitted in the safe subset. - - banned = array_to_object([ - 'arguments', 'callee', 'caller', 'constructor', 'eval', 'prototype', - 'stack', 'unwatch', 'valueOf', 'watch' - ], true), - begin, // The root token - -// browser contains a set of global names that are commonly provided by a -// web browser environment. - - browser = array_to_object([ - 'clearInterval', 'clearTimeout', 'document', 'event', 'frames', - 'history', 'Image', 'localStorage', 'location', 'name', 'navigator', - 'Option', 'parent', 'screen', 'sessionStorage', 'setInterval', - 'setTimeout', 'Storage', 'window', 'XMLHttpRequest' - ], false), - -// bundle contains the text messages. - - bundle = { - a_label: "'{a}' is a statement label.", - a_not_allowed: "'{a}' is not allowed.", - a_not_defined: "'{a}' is not defined.", - a_scope: "'{a}' used out of scope.", - adsafe_a: "ADsafe violation: '{a}'.", - adsafe_autocomplete: "ADsafe autocomplete violation.", - adsafe_bad_id: "ADSAFE violation: bad id.", - adsafe_div: "ADsafe violation: Wrap the widget in a div.", - adsafe_fragment: "ADSAFE: Use the fragment option.", - adsafe_go: "ADsafe violation: Misformed ADSAFE.go.", - adsafe_html: "Currently, ADsafe does not operate on whole HTML " + - "documents. It operates on
fragments and .js files.", - adsafe_id: "ADsafe violation: id does not match.", - adsafe_id_go: "ADsafe violation: Missing ADSAFE.id or ADSAFE.go.", - adsafe_lib: "ADsafe lib violation.", - adsafe_lib_second: "ADsafe: The second argument to lib must be a function.", - adsafe_missing_id: "ADSAFE violation: missing ID_.", - adsafe_name_a: "ADsafe name violation: '{a}'.", - adsafe_placement: "ADsafe script placement violation.", - adsafe_prefix_a: "ADsafe violation: An id must have a '{a}' prefix", - adsafe_script: "ADsafe script violation.", - adsafe_source: "ADsafe unapproved script source.", - adsafe_subscript_a: "ADsafe subscript '{a}'.", - adsafe_tag: "ADsafe violation: Disallowed tag '{a}'.", - already_defined: "'{a}' is already defined.", - and: "The '&&' subexpression should be wrapped in parens.", - assign_exception: "Do not assign to the exception parameter.", - assignment_function_expression: "Expected an assignment or " + - "function call and instead saw an expression.", - attribute_case_a: "Attribute '{a}' not all lower case.", - avoid_a: "Avoid '{a}'.", - bad_assignment: "Bad assignment.", - bad_color_a: "Bad hex color '{a}'.", - bad_constructor: "Bad constructor.", - bad_entity: "Bad entity.", - bad_html: "Bad HTML string", - bad_id_a: "Bad id: '{a}'.", - bad_in_a: "Bad for in variable '{a}'.", - bad_invocation: "Bad invocation.", - bad_name_a: "Bad name: '{a}'.", - bad_new: "Do not use 'new' for side effects.", - bad_number: "Bad number '{a}'.", - bad_operand: "Bad operand.", - bad_type: "Bad type.", - bad_url: "Bad url string.", - bad_wrap: "Do not wrap function literals in parens unless they " + - "are to be immediately invoked.", - combine_var: "Combine this with the previous 'var' statement.", - conditional_assignment: "Expected a conditional expression and " + - "instead saw an assignment.", - confusing_a: "Confusing use of '{a}'.", - confusing_regexp: "Confusing regular expression.", - constructor_name_a: "A constructor name '{a}' should start with " + - "an uppercase letter.", - control_a: "Unexpected control character '{a}'.", - css: "A css file should begin with @charset 'UTF-8';", - dangling_a: "Unexpected dangling '_' in '{a}'.", - dangerous_comment: "Dangerous comment.", - deleted: "Only properties should be deleted.", - duplicate_a: "Duplicate '{a}'.", - empty_block: "Empty block.", - empty_case: "Empty case.", - empty_class: "Empty class.", - es5: "This is an ES5 feature.", - evil: "eval is evil.", - expected_a: "Expected '{a}'.", - expected_a_b: "Expected '{a}' and instead saw '{b}'.", - expected_a_b_from_c_d: "Expected '{a}' to match '{b}' from line " + - "{c} and instead saw '{d}'.", - expected_at_a: "Expected an at-rule, and instead saw @{a}.", - expected_a_at_b_c: "Expected '{a}' at column {b}, not column {c}.", - expected_attribute_a: "Expected an attribute, and instead saw [{a}].", - expected_attribute_value_a: "Expected an attribute value and " + - "instead saw '{a}'.", - expected_class_a: "Expected a class, and instead saw .{a}.", - expected_fraction_a: "Expected a number between 0 and 1 and " + - "instead saw '{a}'", - expected_id_a: "Expected an id, and instead saw #{a}.", - expected_identifier_a: "Expected an identifier and instead saw '{a}'.", - expected_identifier_a_reserved: "Expected an identifier and " + - "instead saw '{a}' (a reserved word).", - expected_linear_a: "Expected a linear unit and instead saw '{a}'.", - expected_lang_a: "Expected a lang code, and instead saw :{a}.", - expected_media_a: "Expected a CSS media type, and instead saw '{a}'.", - expected_name_a: "Expected a name and instead saw '{a}'.", - expected_nonstandard_style_attribute: "Expected a non-standard " + - "style attribute and instead saw '{a}'.", - expected_number_a: "Expected a number and instead saw '{a}'.", - expected_operator_a: "Expected an operator and instead saw '{a}'.", - expected_percent_a: "Expected a percentage and instead saw '{a}'", - expected_positive_a: "Expected a positive number and instead saw '{a}'", - expected_pseudo_a: "Expected a pseudo, and instead saw :{a}.", - expected_selector_a: "Expected a CSS selector, and instead saw {a}.", - expected_small_a: "Expected a small number and instead saw '{a}'", - expected_space_a_b: "Expected exactly one space between '{a}' and '{b}'.", - expected_string_a: "Expected a string and instead saw {a}.", - expected_style_attribute: "Excepted a style attribute, and instead saw '{a}'.", - expected_style_pattern: "Expected a style pattern, and instead saw '{a}'.", - expected_tagname_a: "Expected a tagName, and instead saw {a}.", - expected_type_a: "Expected a type, and instead saw {a}.", - for_if: "The body of a for in should be wrapped in an if " + - "statement to filter unwanted properties from the prototype.", - function_block: "Function statements should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", - function_eval: "The Function constructor is eval.", - function_loop: "Don't make functions within a loop.", - function_statement: "Function statements are not invocable. " + - "Wrap the whole function invocation in parens.", - function_strict: "Use the function form of 'use strict'.", - html_confusion_a: "HTML confusion in regular expression '<{a}'.", - html_handlers: "Avoid HTML event handlers.", - identifier_function: "Expected an identifier in an assignment " + - "and instead saw a function invocation.", - implied_evil: "Implied eval is evil. Pass a function instead of a string.", - infix_in: "Unexpected 'in'. Compare with undefined, or use the " + - "hasOwnProperty method instead.", - insecure_a: "Insecure '{a}'.", - isNaN: "Use the isNaN function to compare with NaN.", - label_a_b: "Label '{a}' on '{b}' statement.", - lang: "lang is deprecated.", - leading_decimal_a: "A leading decimal point can be confused with a dot: '.{a}'.", - missing_a: "Missing '{a}'.", - missing_a_after_b: "Missing '{a}' after '{b}'.", - missing_option: "Missing option value.", - missing_property: "Missing property name.", - missing_space_a_b: "Missing space between '{a}' and '{b}'.", - missing_url: "Missing url.", - missing_use_strict: "Missing 'use strict' statement.", - mixed: "Mixed spaces and tabs.", - move_invocation: "Move the invocation into the parens that " + - "contain the function.", - move_var: "Move 'var' declarations to the top of the function.", - name_function: "Missing name in function statement.", - nested_comment: "Nested comment.", - not: "Nested not.", - not_a_constructor: "Do not use {a} as a constructor.", - not_a_defined: "'{a}' has not been fully defined yet.", - not_a_function: "'{a}' is not a function.", - not_a_label: "'{a}' is not a label.", - not_a_scope: "'{a}' is out of scope.", - not_greater: "'{a}' should not be greater than '{b}'.", - parameter_a_get_b: "Unexpected parameter '{a}' in get {b} function.", - parameter_set_a: "Expected parameter (value) in set {a} function.", - radix: "Missing radix parameter.", - read_only: "Read only.", - redefinition_a: "Redefinition of '{a}'.", - reserved_a: "Reserved name '{a}'.", - scanned_a_b: "{a} ({b}% scanned).", - slash_equal: "A regular expression literal can be confused with '/='.", - statement_block: "Expected to see a statement and instead saw a block.", - stopping: "Stopping. ", - strange_loop: "Strange loop.", - strict: "Strict violation.", - subscript: "['{a}'] is better written in dot notation.", - tag_a_in_b: "A '<{a}>' must be within '<{b}>'.", - too_long: "Line too long.", - too_many: "Too many errors.", - trailing_decimal_a: "A trailing decimal point can be confused " + - "with a dot: '.{a}'.", - type: "type is unnecessary.", - type_confusion_a_b: "Type confusion: {a} and {b}.", - unclosed: "Unclosed string.", - unclosed_comment: "Unclosed comment.", - unclosed_regexp: "Unclosed regular expression.", - unescaped_a: "Unescaped '{a}'.", - unexpected_a: "Unexpected '{a}'.", - unexpected_char_a_b: "Unexpected character '{a}' in {b}.", - unexpected_comment: "Unexpected comment.", - unexpected_property_a: "Unexpected /*property*/ '{a}'.", - unexpected_space_a_b: "Unexpected space between '{a}' and '{b}'.", - unnecessary_initialize: "It is not necessary to initialize '{a}' " + - "to 'undefined'.", - unnecessary_use: "Unnecessary 'use strict'.", - unreachable_a_b: "Unreachable '{a}' after '{b}'.", - unrecognized_style_attribute_a: "Unrecognized style attribute '{a}'.", - unrecognized_tag_a: "Unrecognized tag '<{a}>'.", - unsafe: "Unsafe character.", - url: "JavaScript URL.", - use_array: "Use the array literal notation [].", - use_braces: "Spaces are hard to count. Use {{a}}.", - use_charAt: "Use the charAt method.", - use_object: "Use the object literal notation {}.", - use_or: "Use the || operator.", - use_param: "Use a named parameter.", - used_before_a: "'{a}' was used before it was defined.", - var_a_not: "Variable {a} was not declared correctly.", - weird_assignment: "Weird assignment.", - weird_condition: "Weird condition.", - weird_new: "Weird construction. Delete 'new'.", - weird_program: "Weird program.", - weird_relation: "Weird relation.", - weird_ternary: "Weird ternary.", - wrap_immediate: "Wrap an immediate function invocation in parentheses " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself.", - wrap_regexp: "Wrap the /regexp/ literal in parens to " + - "disambiguate the slash operator.", - write_is_wrong: "document.write can be a form of eval." - }, - comments_off, - css_attribute_data, - css_any, - - css_colorData = array_to_object([ - "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", - "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", - "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", - "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", - "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkkhaki", - "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", - "darkred", "darksalmon", "darkseagreen", "darkslateblue", - "darkslategray", "darkturquoise", "darkviolet", "deeppink", - "deepskyblue", "dimgray", "dodgerblue", "firebrick", "floralwhite", - "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", - "goldenrod", "gray", "green", "greenyellow", "honeydew", "hotpink", - "indianred", "indigo", "ivory", "khaki", "lavender", - "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", - "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgreen", - "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", - "lightslategray", "lightsteelblue", "lightyellow", "lime", - "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", - "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", - "mediumslateblue", "mediumspringgreen", "mediumturquoise", - "mediumvioletred", "midnightblue", "mintcream", "mistyrose", - "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", - "orange", "orangered", "orchid", "palegoldenrod", "palegreen", - "paleturquoise", "palevioletred", "papayawhip", "peachpuff", - "peru", "pink", "plum", "powderblue", "purple", "red", "rosybrown", - "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", - "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", - "snow", "springgreen", "steelblue", "tan", "teal", "thistle", - "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", - "yellow", "yellowgreen", - - "activeborder", "activecaption", "appworkspace", "background", - "buttonface", "buttonhighlight", "buttonshadow", "buttontext", - "captiontext", "graytext", "highlight", "highlighttext", - "inactiveborder", "inactivecaption", "inactivecaptiontext", - "infobackground", "infotext", "menu", "menutext", "scrollbar", - "threeddarkshadow", "threedface", "threedhighlight", - "threedlightshadow", "threedshadow", "window", "windowframe", - "windowtext" - ], true), - - css_border_style, - css_break, - - css_lengthData = { - '%': true, - 'cm': true, - 'em': true, - 'ex': true, - 'in': true, - 'mm': true, - 'pc': true, - 'pt': true, - 'px': true - }, - - css_media, - css_overflow, - - descapes = { - 'b': '\b', - 't': '\t', - 'n': '\n', - 'f': '\f', - 'r': '\r', - '"': '"', - '/': '/', - '\\': '\\' - }, - - devel = array_to_object([ - 'alert', 'confirm', 'console', 'Debug', 'opera', 'prompt' - ], false), - - escapes = { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\'': '\\\'', - '"' : '\\"', - '/' : '\\/', - '\\': '\\\\' - }, - - funct, // The current function, including the labels used - // in the function, as well as (verb), (context), - // (statement), (name), (params), (complexity), - // (loopage), (breakage), (vars) - - functionicity = [ - 'closure', 'exception', 'global', 'label', 'outer', 'undef', - 'unused', 'var' - ], - - functions, // All of the functions - global_funct, // The global body - global_scope, // The global scope - html_tag = { - a: {}, - abbr: {}, - acronym: {}, - address: {}, - applet: {}, - area: {empty: true, parent: ' map '}, - article: {}, - aside: {}, - audio: {}, - b: {}, - base: {empty: true, parent: ' head '}, - bdo: {}, - big: {}, - blockquote: {}, - body: {parent: ' html noframes '}, - br: {empty: true}, - button: {}, - canvas: {parent: ' body p div th td '}, - caption: {parent: ' table '}, - center: {}, - cite: {}, - code: {}, - col: {empty: true, parent: ' table colgroup '}, - colgroup: {parent: ' table '}, - command: {parent: ' menu '}, - datalist: {}, - dd: {parent: ' dl '}, - del: {}, - details: {}, - dialog: {}, - dfn: {}, - dir: {}, - div: {}, - dl: {}, - dt: {parent: ' dl '}, - em: {}, - embed: {}, - fieldset: {}, - figure: {}, - font: {}, - footer: {}, - form: {}, - frame: {empty: true, parent: ' frameset '}, - frameset: {parent: ' html frameset '}, - h1: {}, - h2: {}, - h3: {}, - h4: {}, - h5: {}, - h6: {}, - head: {parent: ' html '}, - header: {}, - hgroup: {}, - hr: {empty: true}, - 'hta:application': - {empty: true, parent: ' head '}, - html: {parent: '*'}, - i: {}, - iframe: {}, - img: {empty: true}, - input: {empty: true}, - ins: {}, - kbd: {}, - keygen: {}, - label: {}, - legend: {parent: ' details fieldset figure '}, - li: {parent: ' dir menu ol ul '}, - link: {empty: true, parent: ' head '}, - map: {}, - mark: {}, - menu: {}, - meta: {empty: true, parent: ' head noframes noscript '}, - meter: {}, - nav: {}, - noframes: {parent: ' html body '}, - noscript: {parent: ' body head noframes '}, - object: {}, - ol: {}, - optgroup: {parent: ' select '}, - option: {parent: ' optgroup select '}, - output: {}, - p: {}, - param: {empty: true, parent: ' applet object '}, - pre: {}, - progress: {}, - q: {}, - rp: {}, - rt: {}, - ruby: {}, - samp: {}, - script: {empty: true, parent: ' body div frame head iframe p pre span '}, - section: {}, - select: {}, - small: {}, - span: {}, - source: {}, - strong: {}, - style: {parent: ' head ', empty: true}, - sub: {}, - sup: {}, - table: {}, - tbody: {parent: ' table '}, - td: {parent: ' tr '}, - textarea: {}, - tfoot: {parent: ' table '}, - th: {parent: ' tr '}, - thead: {parent: ' table '}, - time: {}, - title: {parent: ' head '}, - tr: {parent: ' table tbody thead tfoot '}, - tt: {}, - u: {}, - ul: {}, - 'var': {}, - video: {} - }, - - ids, // HTML ids - in_block, - indent, - is_type = array_to_object([ - '*', 'array', 'boolean', 'function', 'number', 'object', - 'regexp', 'string' - ], true), - itself, // JSLint itself - json_mode, - lex, // the tokenizer - lines, - lookahead, - member, - node = array_to_object([ - 'Buffer', 'clearInterval', 'clearTimeout', 'console', 'exports', - 'global', 'module', 'process', 'querystring', 'require', - 'setInterval', 'setTimeout', '__dirname', '__filename' - ], false), - node_js, - numbery = array_to_object(['indexOf', 'lastIndexOf', 'search'], true), - next_token, - older_token, - option, - predefined, // Global variables defined by option - prereg, - prev_token, - property_type, - regexp_flag = array_to_object(['g', 'i', 'm'], true), - rhino = array_to_object([ - 'defineClass', 'deserialize', 'gc', 'help', 'load', 'loadClass', - 'print', 'quit', 'readFile', 'readUrl', 'runCommand', 'seal', - 'serialize', 'spawn', 'sync', 'toint32', 'version' - ], false), - - scope, // An object containing an object for each variable in scope - semicolon_coda = array_to_object([';', '"', '\'', ')'], true), - src, - stack, - -// standard contains the global names that are provided by the -// ECMAScript standard. - - standard = array_to_object([ - 'Array', 'Boolean', 'Date', 'decodeURI', 'decodeURIComponent', - 'encodeURI', 'encodeURIComponent', 'Error', 'eval', 'EvalError', - 'Function', 'isFinite', 'isNaN', 'JSON', 'Math', 'Number', 'Object', - 'parseInt', 'parseFloat', 'RangeError', 'ReferenceError', 'RegExp', - 'String', 'SyntaxError', 'TypeError', 'URIError' - ], false), - - standard_property_type = { - E : 'number', - LN2 : 'number', - LN10 : 'number', - LOG2E : 'number', - LOG10E : 'number', - MAX_VALUE : 'number', - MIN_VALUE : 'number', - NEGATIVE_INFINITY : 'number', - PI : 'number', - POSITIVE_INFINITY : 'number', - SQRT1_2 : 'number', - SQRT2 : 'number', - apply : 'function', - bind : 'function function', - call : 'function', - ceil : 'function number', - charAt : 'function string', - concat : 'function', - constructor : 'function object', - create : 'function object', - defineProperty : 'function object', - defineProperties : 'function object', - every : 'function boolean', - exec : 'function array', - filter : 'function array', - floor : 'function number', - forEach : 'function', - freeze : 'function object', - getDate : 'function number', - getDay : 'function number', - getFullYear : 'function number', - getHours : 'function number', - getMilliseconds : 'function number', - getMinutes : 'function number', - getMonth : 'function number', - getOwnPropertyDescriptor - : 'function object', - getOwnPropertyNames : 'function array', - getPrototypeOf : 'function object', - getSeconds : 'function number', - getTime : 'function number', - getTimezoneOffset : 'function number', - getUTCDate : 'function number', - getUTCDay : 'function number', - getUTCFullYear : 'function number', - getUTCHours : 'function number', - getUTCMilliseconds : 'function number', - getUTCMinutes : 'function number', - getUTCMonth : 'function number', - getUTCSeconds : 'function number', - getYear : 'function number', - hasOwnProperty : 'function boolean', - indexOf : 'function number', - isExtensible : 'function boolean', - isFrozen : 'function boolean', - isPrototypeOf : 'function boolean', - isSealed : 'function boolean', - join : 'function string', - keys : 'function array', - lastIndexOf : 'function number', - lastIndex : 'number', - length : 'number', - map : 'function array', - now : 'function number', - parse : 'function', - pop : 'function', - preventExtensions : 'function object', - propertyIsEnumerable: 'function boolean', - prototype : 'object', - push : 'function number', - reduce : 'function', - reduceRight : 'function', - reverse : 'function', - seal : 'function object', - setDate : 'function', - setDay : 'function', - setFullYear : 'function', - setHours : 'function', - setMilliseconds : 'function', - setMinutes : 'function', - setMonth : 'function', - setSeconds : 'function', - setTime : 'function', - setTimezoneOffset : 'function', - setUTCDate : 'function', - setUTCDay : 'function', - setUTCFullYear : 'function', - setUTCHours : 'function', - setUTCMilliseconds : 'function', - setUTCMinutes : 'function', - setUTCMonth : 'function', - setUTCSeconds : 'function', - setYear : 'function', - shift : 'function', - slice : 'function', - some : 'function boolean', - sort : 'function', - splice : 'function', - stringify : 'function string', - substr : 'function string', - substring : 'function string', - test : 'function boolean', - toDateString : 'function string', - toExponential : 'function string', - toFixed : 'function string', - toJSON : 'function', - toISOString : 'function string', - toLocaleDateString : 'function string', - toLocaleLowerCase : 'function string', - toLocaleUpperCase : 'function string', - toLocaleString : 'function string', - toLocaleTimeString : 'function string', - toLowerCase : 'function string', - toPrecision : 'function string', - toTimeString : 'function string', - toUpperCase : 'function string', - toUTCString : 'function string', - trim : 'function string', - unshift : 'function number', - valueOf : 'function' - }, - - strict_mode, - syntax = {}, - tab, - token, - urls, - var_mode, - warnings, - -// widget contains the global names which are provided to a Yahoo -// (fna Konfabulator) widget. - - widget = array_to_object([ - 'alert', 'animator', 'appleScript', 'beep', 'bytesToUIString', - 'Canvas', 'chooseColor', 'chooseFile', 'chooseFolder', - 'closeWidget', 'COM', 'convertPathToHFS', 'convertPathToPlatform', - 'CustomAnimation', 'escape', 'FadeAnimation', 'filesystem', 'Flash', - 'focusWidget', 'form', 'FormField', 'Frame', 'HotKey', 'Image', - 'include', 'isApplicationRunning', 'iTunes', 'konfabulatorVersion', - 'log', 'md5', 'MenuItem', 'MoveAnimation', 'openURL', 'play', - 'Point', 'popupMenu', 'preferenceGroups', 'preferences', 'print', - 'prompt', 'random', 'Rectangle', 'reloadWidget', 'ResizeAnimation', - 'resolvePath', 'resumeUpdates', 'RotateAnimation', 'runCommand', - 'runCommandInBg', 'saveAs', 'savePreferences', 'screen', - 'ScrollBar', 'showWidgetPreferences', 'sleep', 'speak', 'Style', - 'suppressUpdates', 'system', 'tellWidget', 'Text', 'TextArea', - 'Timer', 'unescape', 'updateNow', 'URL', 'Web', 'widget', 'Window', - 'XMLDOM', 'XMLHttpRequest', 'yahooCheckLogin', 'yahooLogin', - 'yahooLogout' - ], true), - - windows = array_to_object([ - 'ActiveXObject', 'CScript', 'Debug', 'Enumerator', 'System', - 'VBArray', 'WScript' - ], false), - -// xmode is used to adapt to the exceptions in html parsing. -// It can have these states: -// '' .js script file -// 'html' -// 'outer' -// 'script' -// 'style' -// 'scriptstring' -// 'styleproperty' - - xmode, - xquote, - -// Regular expressions. Some of these are stupidly long. - -// unsafe comment or string - ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i, -// carriage return, or carriage return linefeed - crx = /\r/g, - crlfx = /\r\n/g, -// unsafe characters that are silently deleted by one or more browsers - cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/, -// query characters for ids - dx = /[\[\]\/\\"'*<>.&:(){}+=#]/, -// html token - hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/, -// identifier - ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/, -// javascript url - jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i, -// star slash - lx = /\*\/|\/\*/, -// characters in strings that need escapement - nx = /[\u0000-\u001f'\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, -// outer html token - ox = /[>&]|<[\/!]?|--/, -// attributes characters - qx = /[^a-zA-Z0-9+\-_\/ ]/, -// style - sx = /^\s*([{:#%.=,>+\[\]@()"';]|\*=?|\$=|\|=|\^=|~=|[a-zA-Z_][a-zA-Z0-9_\-]*|[0-9]+|<\/|\/\*)/, - ssx = /^\s*([@#!"'};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/, -// token - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|properties|property|members?|globals?)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/, -// url badness - ux = /&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i, - - rx = { - outer: hx, - html: hx, - style: sx, - styleproperty: ssx - }; - - - function return_this() { - return this; - } - - function F() {} // Used by Object.create - -// Provide critical ES5 functions to ES3. - - if (typeof Array.prototype.filter !== 'function') { - Array.prototype.filter = function (f) { - var i, length = this.length, result = [], value; - for (i = 0; i < length; i += 1) { - try { - value = this[i]; - if (f(value)) { - result.push(value); - } - } catch (ignore) { - } - } - return result; - }; - } - - if (typeof Array.prototype.forEach !== 'function') { - Array.prototype.forEach = function (f) { - var i, length = this.length; - for (i = 0; i < length; i += 1) { - try { - f(this[i]); - } catch (ignore) { - } - } - }; - } - - if (typeof Array.isArray !== 'function') { - Array.isArray = function (o) { - return Object.prototype.toString.apply(o) === '[object Array]'; - }; - } - - if (!Object.prototype.hasOwnProperty.call(Object, 'create')) { - Object.create = function (o) { - F.prototype = o; - return new F(); - }; - } - - if (typeof Object.keys !== 'function') { - Object.keys = function (o) { - var array = [], key; - for (key in o) { - if (Object.prototype.hasOwnProperty.call(o, key)) { - array.push(key); - } - } - return array; - }; - } - - if (typeof String.prototype.entityify !== 'function') { - String.prototype.entityify = function () { - return this - .replace(/&/g, '&') - .replace(//g, '>'); - }; - } - - if (typeof String.prototype.isAlpha !== 'function') { - String.prototype.isAlpha = function () { - return (this >= 'a' && this <= 'z\uffff') || - (this >= 'A' && this <= 'Z\uffff'); - }; - } - - if (typeof String.prototype.isDigit !== 'function') { - String.prototype.isDigit = function () { - return (this >= '0' && this <= '9'); - }; - } - - if (typeof String.prototype.supplant !== 'function') { - String.prototype.supplant = function (o) { - return this.replace(/\{([^{}]*)\}/g, function (a, b) { - var replacement = o[b]; - return typeof replacement === 'string' || - typeof replacement === 'number' ? replacement : a; - }); - }; - } - - - function sanitize(a) { - -// Escapify a troublesome character. - - return escapes[a] || - '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); - } - - - function add_to_predefined(group) { - Object.keys(group).forEach(function (name) { - predefined[name] = group[name]; - }); - } - - - function assume() { - if (!option.safe) { - if (option.rhino) { - add_to_predefined(rhino); - option.rhino = false; - } - if (option.devel) { - add_to_predefined(devel); - option.devel = false; - } - if (option.browser) { - add_to_predefined(browser); - option.browser = false; - } - if (option.windows) { - add_to_predefined(windows); - option.windows = false; - } - if (option.node) { - add_to_predefined(node); - option.node = false; - node_js = true; - } - if (option.widget) { - add_to_predefined(widget); - option.widget = false; - } - } - if (option.type) { - option.confusion = true; - } - } - - -// Produce an error warning. - - function quit(message, line, character) { - throw { - name: 'JSLintError', - line: line, - character: character, - message: bundle.scanned_a_b.supplant({ - a: message, - b: Math.floor((line / lines.length) * 100) - }) - }; - } - - function warn(message, offender, a, b, c, d) { - var character, line, warning; - offender = offender || next_token; // `~ - line = offender.line || 0; - character = offender.from || 0; - warning = { - id: '(error)', - raw: bundle[message] || message, - evidence: lines[line - 1] || '', - line: line, - character: character, - a: a || (offender.id === '(number)' ? - String(offender.number) : offender.string), - b: b, - c: c, - d: d - }; - warning.reason = warning.raw.supplant(warning); - JSLINT.errors.push(warning); - if (option.passfail) { - quit(bundle.stopping, line, character); - } - warnings += 1; - if (warnings >= option.maxerr) { - quit(bundle.too_many, line, character); - } - return warning; - } - - function warn_at(message, line, character, a, b, c, d) { - return warn(message, { - line: line, - from: character - }, a, b, c, d); - } - - function stop(message, offender, a, b, c, d) { - var warning = warn(message, offender, a, b, c, d); - quit(bundle.stopping, warning.line, warning.character); - } - - function stop_at(message, line, character, a, b, c, d) { - return stop(message, { - line: line, - from: character - }, a, b, c, d); - } - - function expected_at(at) { - if (!option.white && next_token.from !== at) { - warn('expected_a_at_b_c', next_token, '', at, - next_token.from); - } - } - - function aint(it, name, expected) { - if (it[name] !== expected) { - warn('expected_a_b', it, expected, it[name]); - return true; - } else { - return false; - } - } - - -// lexical analysis and token construction - - lex = (function lex() { - var character, c, from, length, line, pos, source_row; - -// Private lex methods - - function collect_comment(comment, quote, line, at) { - var comment_object = { - comment: comment, - quote: quote, - at: at, - line: line - }; - if (comments_off || src || (xmode && xmode !== 'script' && - xmode !== 'style' && xmode !== 'styleproperty')) { - warn_at('unexpected_comment', line, character); - } else if (xmode === 'script' && /<\//i.test(source_row)) { - warn_at('unexpected_a', line, character, '<\/'); - } else if (option.safe && ax.test(comment)) { - warn_at('dangerous_comment', line, at); - } - if (older_token.comments) { - older_token.comments.push(comment_object); - } else { - older_token.comments = [comment_object]; - } - JSLINT.comments.push(comment_object); - } - - function next_line() { - var at; - if (line >= lines.length) { - return false; - } - character = 1; - source_row = lines[line]; - line += 1; - at = source_row.search(/ \t/); - if (at >= 0) { - warn_at('mixed', line, at + 1); - } - source_row = source_row.replace(/\t/g, tab); - at = source_row.search(cx); - if (at >= 0) { - warn_at('unsafe', line, at); - } - if (option.maxlen && option.maxlen < source_row.length) { - warn_at('too_long', line, source_row.length); - } - return true; - } - -// Produce a token object. The token inherits from a syntax symbol. - - function it(type, value, quote) { - var id, the_token; - if (type === '(string)' || type === '(range)') { - if (jx.test(value)) { - warn_at('url', line, from); - } - } - the_token = Object.create(syntax[( - type === '(punctuator)' || - (type === '(identifier)' && - Object.prototype.hasOwnProperty.call(syntax, value)) ? - value : - type - )] || syntax['(error)']); - if (type === '(identifier)') { - the_token.identifier = true; - if (value === '__iterator__' || value === '__proto__') { - stop_at('reserved_a', line, from, value); - } else if (!option.nomen && - (value.charAt(0) === '_' || - value.charAt(value.length - 1) === '_')) { - warn_at('dangling_a', line, from, value); - } - } - if (type === '(number)') { - the_token.number = +value; - } else if (value !== undefined) { - the_token.string = String(value); - } - if (quote) { - the_token.quote = quote; - } - the_token.line = line; - the_token.from = from; - the_token.thru = character; - the_token.prev = older_token; - id = the_token.id; - prereg = id && ( - ('(,=:[!&|?{};'.indexOf(id.charAt(id.length - 1)) >= 0) || - id === 'return' - ); - older_token.next = the_token; - older_token = the_token; - return the_token; - } - - function match(x) { - var exec = x.exec(source_row), first; - if (exec) { - length = exec[0].length; - first = exec[1]; - c = first.charAt(0); - source_row = source_row.slice(length); - from = character + length - first.length; - character += length; - return first; - } - } - - function string(x) { - var c, pos = 0, r = ''; - - function hex(n) { - var i = parseInt(source_row.substr(pos + 1, n), 16); - pos += n; - if (i >= 32 && i <= 126 && - i !== 34 && i !== 92 && i !== 39) { - warn_at('unexpected_a', line, character, '\\'); - } - character += n; - c = String.fromCharCode(i); - } - - if (json_mode && x !== '"') { - warn_at('expected_a', line, character, '"'); - } - - if (xquote === x || (xmode === 'scriptstring' && !xquote)) { - return it('(punctuator)', x); - } - - for (;;) { - while (pos >= source_row.length) { - pos = 0; - if (xmode !== 'html' || !next_line()) { - stop_at('unclosed', line, from); - } - } - c = source_row.charAt(pos); - if (c === x) { - character += 1; - source_row = source_row.slice(pos + 1); - return it('(string)', r, x); - } - if (c < ' ') { - if (c === '\n' || c === '\r') { - break; - } - warn_at('control_a', - line, character + pos, source_row.slice(0, pos)); - } else if (c === xquote) { - warn_at('bad_html', line, character + pos); - } else if (c === '<') { - if (option.safe && xmode === 'html') { - warn_at('adsafe_a', line, character + pos, c); - } else if (source_row.charAt(pos + 1) === '/' && (xmode || option.safe)) { - warn_at('expected_a_b', line, character, - '<\\/', ' 0) { - warn_at('unescaped_a', - line, from + length, '/'); - } - c = source_row.slice(0, length - 1); - flag = Object.create(regexp_flag); - while (flag[source_row.charAt(length)] === true) { - flag[source_row.charAt(length)] = false; - length += 1; - } - if (source_row.charAt(length).isAlpha()) { - stop_at('unexpected_a', - line, from, source_row.charAt(length)); - } - character += length; - source_row = source_row.slice(length); - quote = source_row.charAt(0); - if (quote === '/' || quote === '*') { - stop_at('confusing_regexp', - line, from); - } - return it('(regexp)', c); - case '\\': - c = source_row.charAt(length); - if (c < ' ') { - warn_at('control_a', - line, from + length, String(c)); - } else if (c === '<') { - warn_at( - bundle.unexpected_a, - line, - from + length, - '\\' - ); - } - length += 1; - break; - case '(': - depth += 1; - b = false; - if (source_row.charAt(length) === '?') { - length += 1; - switch (source_row.charAt(length)) { - case ':': - case '=': - case '!': - length += 1; - break; - default: - warn_at( - bundle.expected_a_b, - line, - from + length, - ':', - source_row.charAt(length) - ); - } - } else { - captures += 1; - } - break; - case '|': - b = false; - break; - case ')': - if (depth === 0) { - warn_at('unescaped_a', - line, from + length, ')'); - } else { - depth -= 1; - } - break; - case ' ': - pos = 1; - while (source_row.charAt(length) === ' ') { - length += 1; - pos += 1; - } - if (pos > 1) { - warn_at('use_braces', - line, from + length, pos); - } - break; - case '[': - c = source_row.charAt(length); - if (c === '^') { - length += 1; - if (!option.regexp) { - warn_at('insecure_a', - line, from + length, c); - } else if (source_row.charAt(length) === ']') { - stop_at('unescaped_a', - line, from + length, '^'); - } - } - bit = false; - if (c === ']') { - warn_at('empty_class', line, - from + length - 1); - bit = true; - } -klass: do { - c = source_row.charAt(length); - length += 1; - switch (c) { - case '[': - case '^': - warn_at('unescaped_a', - line, from + length, c); - bit = true; - break; - case '-': - if (bit) { - bit = false; - } else { - warn_at('unescaped_a', - line, from + length, '-'); - bit = true; - } - break; - case ']': - if (!bit) { - warn_at('unescaped_a', - line, from + length - 1, '-'); - } - break klass; - case '\\': - c = source_row.charAt(length); - if (c < ' ') { - warn_at( - bundle.control_a, - line, - from + length, - String(c) - ); - } else if (c === '<') { - warn_at( - bundle.unexpected_a, - line, - from + length, - '\\' - ); - } - length += 1; - bit = true; - break; - case '/': - warn_at('unescaped_a', - line, from + length - 1, '/'); - bit = true; - break; - case '<': - if (xmode === 'script') { - c = source_row.charAt(length); - if (c === '!' || c === '/') { - warn_at( - bundle.html_confusion_a, - line, - from + length, - c - ); - } - } - bit = true; - break; - default: - bit = true; - } - } while (c); - break; - case '.': - if (!option.regexp) { - warn_at('insecure_a', line, - from + length, c); - } - break; - case ']': - case '?': - case '{': - case '}': - case '+': - case '*': - warn_at('unescaped_a', line, - from + length, c); - break; - case '<': - if (xmode === 'script') { - c = source_row.charAt(length); - if (c === '!' || c === '/') { - warn_at( - bundle.html_confusion_a, - line, - from + length, - c - ); - } - } - break; - } - if (b) { - switch (source_row.charAt(length)) { - case '?': - case '+': - case '*': - length += 1; - if (source_row.charAt(length) === '?') { - length += 1; - } - break; - case '{': - length += 1; - c = source_row.charAt(length); - if (c < '0' || c > '9') { - warn_at( - bundle.expected_number_a, - line, - from + length, - c - ); - } - length += 1; - low = +c; - for (;;) { - c = source_row.charAt(length); - if (c < '0' || c > '9') { - break; - } - length += 1; - low = +c + (low * 10); - } - high = low; - if (c === ',') { - length += 1; - high = Infinity; - c = source_row.charAt(length); - if (c >= '0' && c <= '9') { - length += 1; - high = +c; - for (;;) { - c = source_row.charAt(length); - if (c < '0' || c > '9') { - break; - } - length += 1; - high = +c + (high * 10); - } - } - } - if (source_row.charAt(length) !== '}') { - warn_at( - bundle.expected_a_b, - line, - from + length, - '}', - c - ); - } else { - length += 1; - } - if (source_row.charAt(length) === '?') { - length += 1; - } - if (low > high) { - warn_at( - bundle.not_greater, - line, - from + length, - low, - high - ); - } - break; - } - } - } - c = source_row.slice(0, length - 1); - character += length; - source_row = source_row.slice(length); - return it('(regexp)', c); - } - -// Public lex methods - - return { - init: function (source) { - if (typeof source === 'string') { - lines = source - .replace(crlfx, '\n') - .replace(crx, '\n') - .split('\n'); - } else { - lines = source; - } - line = 0; - next_line(); - from = 1; - }, - - range: function (begin, end) { - var c, value = ''; - from = character; - if (source_row.charAt(0) !== begin) { - stop_at('expected_a_b', line, character, begin, - source_row.charAt(0)); - } - for (;;) { - source_row = source_row.slice(1); - character += 1; - c = source_row.charAt(0); - switch (c) { - case '': - stop_at('missing_a', line, character, c); - break; - case end: - source_row = source_row.slice(1); - character += 1; - return it('(range)', value); - case xquote: - case '\\': - warn_at('unexpected_a', line, character, c); - break; - } - value += c; - } - }, - -// token -- this is called by advance to get the next token. - - token: function () { - var c, i, quote, snippet; - - for (;;) { - while (!source_row) { - if (!next_line()) { - return it('(end)'); - } - } - while (xmode === 'outer') { - i = source_row.search(ox); - if (i === 0) { - break; - } else if (i > 0) { - character += 1; - source_row = source_row.slice(i); - break; - } else { - if (!next_line()) { - return it('(end)', ''); - } - } - } - snippet = match(rx[xmode] || tx); - if (!snippet) { - snippet = ''; - c = ''; - while (source_row && source_row < '!') { - source_row = source_row.slice(1); - } - if (source_row) { - if (xmode === 'html') { - return it('(error)', source_row.charAt(0)); - } else { - stop_at('unexpected_a', - line, character, source_row.charAt(0)); - } - } - } else { - -// identifier - - c = snippet.charAt(0); - if (c.isAlpha() || c === '_' || c === '$') { - return it('(identifier)', snippet); - } - -// number - - if (c.isDigit()) { - return number(snippet); - } - switch (snippet) { - -// string - - case '"': - case "'": - return string(snippet); - -// // comment - - case '//': - collect_comment(source_row, '//', line, character); - source_row = ''; - break; - -// /* comment - - case '/*': - quote = '/*'; - for (;;) { - i = source_row.search(lx); - if (i >= 0) { - break; - } - collect_comment(source_row, quote, line, character); - quote = ''; - if (!next_line()) { - stop_at('unclosed_comment', line, character); - } - } - collect_comment(source_row.slice(0, i), quote, character, line); - character += i + 2; - if (source_row.charAt(i) === '/') { - stop_at('nested_comment', line, character); - } - source_row = source_row.slice(i + 2); - break; - - case '': - break; -// / - case '/': - if (token.id === '/=') { - stop_at( - bundle.slash_equal, - line, - from - ); - } - return prereg ? regexp() : it('(punctuator)', snippet); - -// punctuator - - case ''); - } - character += 3; - source_row = source_row.slice(i + 3); - break; - case '#': - if (xmode === 'html' || xmode === 'styleproperty') { - for (;;) { - c = source_row.charAt(0); - if ((c < '0' || c > '9') && - (c < 'a' || c > 'f') && - (c < 'A' || c > 'F')) { - break; - } - character += 1; - source_row = source_row.slice(1); - snippet += c; - } - if (snippet.length !== 4 && snippet.length !== 7) { - warn_at('bad_color_a', line, - from + length, snippet); - } - return it('(color)', snippet); - } - return it('(punctuator)', snippet); - - default: - if (xmode === 'outer' && c === '&') { - character += 1; - source_row = source_row.slice(1); - for (;;) { - c = source_row.charAt(0); - character += 1; - source_row = source_row.slice(1); - if (c === ';') { - break; - } - if (!((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - c === '#')) { - stop_at('bad_entity', line, from + length, - character); - } - } - break; - } - return it('(punctuator)', snippet); - } - } - } - } - }; - }()); - - - function add_label(token, kind, name) { - -// Define the symbol in the current function in the current scope. - - name = name || token.string; - -// Global variables cannot be created in the safe subset. If a global variable -// already exists, do nothing. If it is predefined, define it. - - if (funct === global_funct) { - if (option.safe) { - warn('adsafe_a', token, name); - } - if (typeof global_funct[name] !== 'string') { - token.writeable = typeof predefined[name] === 'boolean' ? - predefined[name] : true; - token.funct = funct; - global_scope[name] = token; - } - if (kind === 'becoming') { - kind = 'var'; - } - -// Ordinary variables. - - } else { - -// Warn if the variable already exists. - - if (typeof funct[name] === 'string') { - if (funct[name] === 'undef') { - if (!option.undef) { - warn('used_before_a', token, name); - } - kind = 'var'; - } else { - warn('already_defined', token, name); - } - } else { - -// Add the symbol to the current function. - - token.funct = funct; - token.writeable = true; - scope[name] = token; - } - } - funct[name] = kind; - } - - - function peek(distance) { - -// Peek ahead to a future token. The distance is how far ahead to look. The -// default is the next token. - - var found, slot = 0; - - distance = distance || 0; - while (slot <= distance) { - found = lookahead[slot]; - if (!found) { - found = lookahead[slot] = lex.token(); - } - slot += 1; - } - return found; - } - - - function discard(it) { - -// The token will not be included in the parse tree, so move the comments -// that are attached to the token to tokens that are in the tree. - - it = it || token; - if (it.comments) { - var prev = it.prev; - while (prev.comments === null) { - prev = prev.prev; - } - if (prev.comments) { - prev.comments = prev.comments.concat(it.comments); - } else { - prev.comments = it.comments; - } - } - it.comments = null; - } - - - function advance(id, match) { - -// Produce the next token, also looking for programming errors. - - if (indent) { - -// In indentation checking was requested, then inspect all of the line breakings. -// The var statement is tricky because the names might be aligned or not. We -// look at the first line break after the var to determine the programmer's -// intention. - - if (var_mode && next_token.line !== token.line) { - if ((var_mode !== indent || !next_token.edge) && - next_token.from === indent.at - - (next_token.edge ? option.indent : 0)) { - var dent = indent; - for (;;) { - dent.at -= option.indent; - if (dent === var_mode) { - break; - } - dent = dent.was; - } - dent.open = false; - } - var_mode = null; - } - if (indent.open) { - -// If the token is an edge. - - if (next_token.edge) { - if (next_token.edge === 'label') { - expected_at(1); - } else if (next_token.edge === 'case') { - expected_at(indent.at - option.indent); - } else if (indent.mode !== 'array' || next_token.line !== token.line) { - expected_at(indent.at); - } - -// If the token is not an edge, but is the first token on the line. - - } else if (next_token.line !== token.line) { - if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); - } - indent.wrap = true; - } - } else if (next_token.line !== token.line) { - if (next_token.edge) { - expected_at(indent.at); - } else { - indent.wrap = true; - if (indent.mode === 'statement' || indent.mode === 'var') { - expected_at(indent.at + option.indent); - } else if (next_token.from < indent.at + (indent.mode === - 'expression' ? 0 : option.indent)) { - expected_at(indent.at + option.indent); - } - } - } - } - - switch (token.id) { - case '(number)': - if (next_token.id === '.') { - warn('trailing_decimal_a'); - } - break; - case '-': - if (next_token.id === '-' || next_token.id === '--') { - warn('confusing_a'); - } - break; - case '+': - if (next_token.id === '+' || next_token.id === '++') { - warn('confusing_a'); - } - break; - } - if (token.id === '(string)' || token.identifier) { - anonname = token.string; - } - - if (id && next_token.id !== id) { - if (match) { - warn('expected_a_b_from_c_d', next_token, id, - match.id, match.line, next_token.string); - } else if (!next_token.identifier || next_token.string !== id) { - warn('expected_a_b', next_token, id, next_token.string); - } - } - prev_token = token; - token = next_token; - next_token = lookahead.shift() || lex.token(); - if (token.id === '(end)') { - discard(); - } - } - - - function do_safe() { - if (option.adsafe) { - option.safe = true; - } - if (option.safe) { - option.browser = - option['continue'] = - option.css = - option.debug = - option.devel = - option.evil = - option.forin = - option.newcap = - option.nomen = - option.on = - option.rhino = - option.sloppy = - option.sub = - option.undef = - option.widget = - option.windows = false; - - - delete predefined.Array; - delete predefined.Date; - delete predefined.Function; - delete predefined.Object; - delete predefined['eval']; - - add_to_predefined({ - ADSAFE: false, - lib: false - }); - } - } - - - function do_globals() { - var name, writeable; - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - advance(); - writeable = false; - if (next_token.id === ':') { - advance(':'); - switch (next_token.id) { - case 'true': - writeable = predefined[name] !== false; - advance('true'); - break; - case 'false': - advance('false'); - break; - default: - stop('unexpected_a'); - } - } - predefined[name] = writeable; - if (next_token.id !== ',') { - return; - } - advance(','); - } - } - - - function do_jslint() { - var name, value; - while (next_token.id === '(string)' || next_token.identifier) { - name = next_token.string; - advance(); - if (next_token.id !== ':') { - stop('expected_a_b', next_token, ':', next_token.string); - } - advance(':'); - switch (name) { - case 'indent': - value = next_token.number; - if (!isFinite(value) || value < 0 || Math.floor(value) !== value) { - stop('expected_small_a'); - } - option.indent = value; - break; - case 'maxerr': - value = +next_token.string; - value = next_token.number; - if (!isFinite(value) || value <= 0 || Math.floor(value) !== value) { - stop('expected_small_a'); - } - option.maxerr = value; - break; - case 'maxlen': - value = next_token.number; - if (!isFinite(value) || value <= 0 || Math.floor(value) !== value) { - stop('expected_small_a'); - } - option.maxlen = value; - break; - default: - if (next_token.id === 'true') { - option[name] = true; - } else if (next_token.id === 'false') { - option[name] = false; - } else { - stop('unexpected_a'); - } - switch (name) { - case 'adsafe': - option.adsafe = option.safe = true; - do_safe(); - break; - case 'safe': - do_safe(); - break; - } - } - advance(); - if (next_token.id === ',') { - advance(','); - } - } - assume(); - } - - - function do_properties() { - var name, type; - option.properties = true; - if (!funct['(old_property_type)']) { - funct['(old_property_type)'] = property_type; - property_type = Object.create(property_type); - } - for (;;) { - if (next_token.id !== '(string)' && !next_token.identifier) { - return; - } - name = next_token.string; - type = ''; - advance(); - if (next_token.id === ':') { - advance(':'); - if (next_token.id === 'function') { - advance('function'); - if (is_type[next_token.string] === true) { - type = 'function ' + next_token.string; - advance(); - } else { - type = 'function'; - } - } else { - type = next_token.string; - if (is_type[type] !== true) { - warn('expected_type_a', next_token); - type = ''; - } - advance(); - } - } - property_type[name] = type; - if (next_token.id !== ',') { - return; - } - advance(','); - } - } - - - function directive() { - var command = this.id, - old_comments_off = comments_off, - old_indent = indent; - comments_off = true; - indent = null; - if (next_token.line === token.line && next_token.from === token.thru) { - warn('missing_space_a_b', next_token, token.string, next_token.string); - } - if (lookahead.length > 0 || next_token.comments) { - warn('unexpected_a', this); - } - switch (command) { - case '/*properties': - case '/*property': - case '/*members': - case '/*member': - do_properties(); - break; - case '/*jslint': - if (option.safe) { - warn('adsafe_a', this); - } - do_jslint(); - break; - case '/*globals': - case '/*global': - if (option.safe) { - warn('adsafe_a', this); - } - do_globals(); - break; - default: - stop('unexpected_a', this); - } - comments_off = old_comments_off; - advance('*/'); - indent = old_indent; - } - - -// Indentation intention - - function edge(mode) { - next_token.edge = indent ? indent.open && (mode || 'edge') : ''; - } - - - function step_in(mode) { - var open, was; - if (typeof mode === 'number') { - indent = { - at: +mode, - open: true, - was: was - }; - } else if (!indent) { - indent = { - at: 1, - mode: 'statement', - open: true - }; - } else { - was = indent; - open = mode === 'var' || - (next_token.line !== token.line && mode !== 'statement'); - indent = { - at: (open || mode === 'control' ? - was.at + option.indent : was.at) + - (was.wrap ? option.indent : 0), - mode: mode, - open: open, - was: was - }; - if (mode === 'var' && open) { - var_mode = indent; - } - } - } - - function step_out(id, symbol) { - if (id) { - if (indent && indent.open) { - indent.at -= option.indent; - edge(); - } - advance(id, symbol); - } - if (indent) { - indent = indent.was; - } - } - -// Functions for conformance of whitespace. - - function one_space(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && !option.white && - (token.line !== right.line || - token.thru + 1 !== right.from)) { - warn('expected_space_a_b', right, token.string, right.string); - } - } - - function one_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru + 1 !== right.from))) { - warn('expected_space_a_b', right, left.string, right.string); - } - } - - function no_space(left, right) { - left = left || token; - right = right || next_token; - if ((!option.white || xmode === 'styleproperty' || xmode === 'style') && - left.thru !== right.from && left.line === right.line) { - warn('unexpected_space_a_b', right, left.string, right.string); - } - } - - function no_space_only(left, right) { - left = left || token; - right = right || next_token; - if (right.id !== '(end)' && (left.line !== right.line || - (!option.white && left.thru !== right.from))) { - warn('unexpected_space_a_b', right, left.string, right.string); - } - } - - function spaces(left, right) { - if (!option.white) { - left = left || token; - right = right || next_token; - if (left.thru === right.from && left.line === right.line) { - warn('missing_space_a_b', right, left.string, right.string); - } - } - } - - function comma() { - if (next_token.id !== ',') { - warn_at('expected_a_b', token.line, token.thru, ',', next_token.string); - } else { - if (!option.white) { - no_space_only(); - } - advance(','); - discard(); - spaces(); - } - } - - - function semicolon() { - if (next_token.id !== ';') { - warn_at('expected_a_b', token.line, token.thru, ';', next_token.string); - } else { - if (!option.white) { - no_space_only(); - } - advance(';'); - discard(); - if (semicolon_coda[next_token.id] !== true) { - spaces(); - } - } - } - - function use_strict() { - if (next_token.string === 'use strict') { - if (strict_mode) { - warn('unnecessary_use'); - } - edge(); - advance(); - semicolon(); - strict_mode = true; - option.newcap = false; - option.undef = false; - return true; - } else { - return false; - } - } - - - function are_similar(a, b) { - if (a === b) { - return true; - } - if (Array.isArray(a)) { - if (Array.isArray(b) && a.length === b.length) { - var i; - for (i = 0; i < a.length; i += 1) { - if (!are_similar(a[i], b[i])) { - return false; - } - } - return true; - } - return false; - } - if (Array.isArray(b)) { - return false; - } - if (a.id === '(number)' && b.id === '(number)') { - return a.number === b.number; - } - if (a.arity === b.arity && a.string === b.string) { - switch (a.arity) { - case 'prefix': - case 'suffix': - case undefined: - return a.id === b.id && are_similar(a.first, b.first); - case 'infix': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second); - case 'ternary': - return are_similar(a.first, b.first) && - are_similar(a.second, b.second) && - are_similar(a.third, b.third); - case 'function': - case 'regexp': - return false; - default: - return true; - } - } else { - if (a.id === '.' && b.id === '[' && b.arity === 'infix') { - return a.second.string === b.second.string && b.second.id === '(string)'; - } else if (a.id === '[' && a.arity === 'infix' && b.id === '.') { - return a.second.string === b.second.string && a.second.id === '(string)'; - } - } - return false; - } - - -// This is the heart of JSLINT, the Pratt parser. In addition to parsing, it -// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is -// like .nud except that it is only used on the first token of a statement. -// Having .fud makes it much easier to define statement-oriented languages like -// JavaScript. I retained Pratt's nomenclature. - -// .nud Null denotation -// .fud First null denotation -// .led Left denotation -// lbp Left binding power -// rbp Right binding power - -// They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - -// rbp is the right binding power. -// initial indicates that this is the first expression of a statement. - - var left; - if (next_token.id === '(end)') { - stop('unexpected_a', token, next_token.id); - } - advance(); - if (option.safe && scope[token.string] && - scope[token.string] === global_scope[token.string] && - (next_token.id !== '(' && next_token.id !== '.')) { - warn('adsafe_a', token); - } - if (initial) { - anonname = 'anonymous'; - funct['(verb)'] = token.string; - } - if (initial === true && token.fud) { - left = token.fud(); - } else { - if (token.nud) { - left = token.nud(); - } else { - if (next_token.id === '(number)' && token.id === '.') { - warn('leading_decimal_a', token, - next_token.string); - advance(); - return token; - } else { - stop('expected_identifier_a', token, token.id); - } - } - while (rbp < next_token.lbp) { - advance(); - if (token.led) { - left = token.led(left); - } else { - stop('expected_operator_a', token, token.id); - } - } - } - return left; - } - - -// Functional constructors for making the symbols that will be inherited by -// tokens. - - function symbol(s, p) { - var x = syntax[s]; - if (!x || typeof x !== 'object') { - syntax[s] = x = { - id: s, - lbp: p, - string: s - }; - } - return x; - } - - - function delim(s) { - return symbol(s, 0); - } - - - function postscript(x) { - x.postscript = true; - return x; - } - - function ultimate(s) { - var x = symbol(s, 0); - x.from = 1; - x.thru = 1; - x.line = 0; - x.edge = 'edge'; - s.string = s; - return postscript(x); - } - - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - function labeled_stmt(s, f) { - var x = stmt(s, f); - x.labeled = true; - } - - function disrupt_stmt(s, f) { - var x = stmt(s, f); - x.disrupt = true; - } - - - function reserve_name(x) { - var c = x.id.charAt(0); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - x.identifier = x.reserved = true; - } - return x; - } - - - function prefix(s, f, type) { - var x = symbol(s, 150); - reserve_name(x); - x.nud = (typeof f === 'function') ? f : function () { - if (s === 'typeof') { - one_space(); - } else { - no_space_only(); - } - this.first = expression(150); - this.arity = 'prefix'; - if (this.id === '++' || this.id === '--') { - if (!option.plusplus) { - warn('unexpected_a', this); - } else if ((!this.first.identifier || this.first.reserved) && - this.first.id !== '.' && this.first.id !== '[') { - warn('bad_operand', this); - } - } - this.type = type; - return this; - }; - return x; - } - - - function type(s, t, nud) { - var x = delim(s); - x.arity = x.type = t; - if (nud) { - x.nud = nud; - } - return x; - } - - - function get_type(one) { - var type; - if (typeof one !== 'object') { - return one; - } if (one.id === '.') { - type = property_type[one.second.string]; - return typeof type === 'string' ? type : ''; - } else { - return ((one.identifier && scope[one.string]) || one).type; - } - } - - - function set_type(one, type) { - if (type && typeof one === 'object') { - if (one.id === '.') { - property_type[one.second.string] = type; - } else { - ((one.identifier && scope[one.string]) || one).type = type; - } - } - return type; - } - - - function conform_type(one, two) { - -// This takes a type string or a token, or two tokens. - - var one_type = get_type(one), - two_type = get_type(two), - one_string, - two_string; - if (one_type) { - if (two_type) { - if (one_type === two_type || one_type === '*') { - return two_type !== '*' ? two_type : ''; - } else if (one_type === 'function' && - two_type.slice(0, 8) === 'function') { - return set_type(one, two_type); - } else if (two_type === 'function' && - one_type.slice(0, 8) === 'function') { - return set_type(two, one_type); - } else { - if (two_type !== '*' && !option.confusion) { - if (typeof one === 'string') { - one_string = one_type; - } else if (one.id === '.') { - one_string = '.' + one.second.string + ': ' + one_type; - } else { - one_string = '\'' + (one.number || one.string) + '\': ' + one_type; - } - if (two.id === '.') { - two_string = '.' + two.second.string + ': ' + two_type; - } else { - two_string = '\'' + (two.number || two.string) + '\': ' + two_type; - } - warn('type_confusion_a_b', two, one_string, two_string); - } - return one_type; - } - } else if (one_type !== '*') { - return set_type(two, one_type); - } - } else if (two_type && two_type !== '*') { - return set_type(one, two_type); - } - } - - - function reserve(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - if (typeof f === 'function') { - x.nud = f; - } - return x; - } - - - function constant(name, type) { - var x = reserve(name); - x.type = type; - x.string = name; - x.nud = return_this; - return x; - } - - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === 'function') { - v(this); - } - return this; - }); - } - - - function infix(s, p, f, type, w) { - var x = symbol(s, p); - reserve_name(x); - x.led = function (left) { - this.arity = 'infix'; - if (!w) { - spaces(prev_token, token); - spaces(); - } - if (!option.bitwise && this.bitwise) { - warn('unexpected_a', this); - } - if (typeof f === 'function') { - return f(left, this); - } else { - this.first = left; - this.second = expression(p); - return this; - } - }; - if (type) { - x.type = type; - } - return x; - } - - function expected_relation(node, message) { - if (node.assign) { - warn(message || bundle.conditional_assignment, node); - } - return node; - } - - function expected_condition(node, message) { - switch (node.id) { - case '[': - case '-': - if (node.arity !== 'infix') { - warn(message || bundle.weird_condition, node); - } - break; - case 'false': - case 'function': - case 'Infinity': - case 'NaN': - case 'null': - case 'true': - case 'undefined': - case 'void': - case '(number)': - case '(regexp)': - case '(string)': - case '{': - warn(message || bundle.weird_condition, node); - break; - case '(': - if (node.first.id === '.' && numbery[node.first.second.string] === true) { - warn(message || bundle.weird_condition, node); - } - break; - } - return node; - } - - function check_relation(node) { - switch (node.arity) { - case 'prefix': - switch (node.id) { - case '{': - case '[': - warn('unexpected_a', node); - break; - case '!': - warn('confusing_a', node); - break; - } - break; - case 'function': - case 'regexp': - warn('unexpected_a', node); - break; - default: - if (node.id === 'NaN') { - warn('isnan', node); - } - } - return node; - } - - - function relation(s, eqeq) { - return infix(s, 100, function (left, that) { - check_relation(left); - if (eqeq && !option.eqeq) { - warn('expected_a_b', that, eqeq, that.id); - } - var right = expression(100); - if (are_similar(left, right) || - ((left.id === '(string)' || left.id === '(number)') && - (right.id === '(string)' || right.id === '(number)'))) { - warn('weird_relation', that); - } - that.first = left; - that.second = check_relation(right); - conform_type(left, that.second, that); - return that; - }, 'boolean'); - } - - - function assignop(s, op) { - var x = infix(s, 20, function (left, that) { - var l; - that.first = left; - if (left.identifier) { - if (scope[left.string]) { - if (scope[left.string].writeable === false) { - warn('read_only', left); - } - } else { - stop('read_only'); - } - } else if (option.safe) { - l = left; - do { - if (typeof predefined[l.string] === 'boolean') { - warn('adsafe_a', l); - } - l = l.first; - } while (l); - } - if (left === syntax['function']) { - warn('identifier_function', token); - } - if (left.id === '.' || left.id === '[') { - if (!left.first || left.first.string === 'arguments') { - warn('bad_assignment', that); - } - } else if (left.identifier && !left.reserved) { - if (funct[left.string] === 'exception') { - warn('assign_exception', left); - } - } - that.second = expression(19); - if (that.id === '=' && are_similar(that.first, that.second)) { - warn('weird_assignment', that); - } - if (that.type) { - conform_type(left, that); - conform_type(that, that.second); - } else { - conform_type(left, that.second); - } - return that; - }); - x.assign = true; - if (op) { - if (syntax[op].type) { - x.type = syntax[op].type; - } - if (syntax[op].bitwise) { - x.bitwise = true; - } - } - return x; - } - - - function bitwise(s, p) { - var x = infix(s, p, 'number'); - x.bitwise = true; - return x; - } - - - function suffix(s) { - var x = symbol(s, 150); - x.led = function (left) { - no_space_only(prev_token, token); - if (!option.plusplus) { - warn('unexpected_a', this); - } else if ((!left.identifier || left.reserved) && - left.id !== '.' && left.id !== '[') { - warn('bad_operand', this); - } - this.first = left; - this.arity = 'suffix'; - return this; - }; - return x; - } - - - function optional_identifier() { - if (next_token.identifier) { - advance(); - if (option.safe && banned[token.string]) { - warn('adsafe_a', token); - } else if (token.reserved && !option.es5) { - warn('expected_identifier_a_reserved', token); - } - return token.string; - } - } - - - function identifier() { - var i = optional_identifier(); - if (!i) { - stop(token.id === 'function' && next_token.id === '(' ? - 'name_function' : 'expected_identifier_a'); - } - return i; - } - - - function statement() { - - var label, old_scope = scope, the_statement; - -// We don't like the empty statement. - - if (next_token.id === ';') { - warn('unexpected_a'); - semicolon(); - return; - } - -// Is this a labeled statement? - - if (next_token.identifier && !next_token.reserved && peek().id === ':') { - edge('label'); - label = next_token; - advance(); - discard(); - advance(':'); - discard(); - scope = Object.create(old_scope); - add_label(label, 'label'); - if (next_token.labeled !== true) { - warn('label_a_b', next_token, label.string, next_token.string); - } else if (jx.test(label.string + ':')) { - warn('url', label); - } else if (funct === global_funct) { - stop('unexpected_a', token); - } - next_token.label = label; - } - -// Parse the statement. - - edge(); - step_in('statement'); - the_statement = expression(0, true); - if (the_statement) { - -// Look for the final semicolon. - - if (the_statement.arity === 'statement') { - if (the_statement.id === 'switch' || - (the_statement.block && the_statement.id !== 'do')) { - spaces(); - } else { - semicolon(); - } - } else { - -// If this is an expression statement, determine if it is acceptable. -// We do not like -// new Blah(); -// statments. If it is to be used at all, new should only be used to make -// objects, not side effects. The expression statements we do like do -// assignment or invocation or delete. - - if (the_statement.id === '(') { - if (the_statement.first.id === 'new') { - warn('bad_new'); - } - } else if (!the_statement.assign && - the_statement.id !== 'delete' && - the_statement.id !== '++' && - the_statement.id !== '--') { - warn('assignment_function_expression', token); - } - semicolon(); - } - } - step_out(); - scope = old_scope; - return the_statement; - } - - - function statements() { - var array = [], disruptor, the_statement; - -// A disrupt statement may not be followed by any other statement. -// If the last statement is disrupt, then the sequence is disrupt. - - while (next_token.postscript !== true) { - if (next_token.id === ';') { - warn('unexpected_a', next_token); - semicolon(); - } else { - if (next_token.string === 'use strict') { - if (!node_js || funct !== global_funct || array.length > 0) { - warn('function_strict'); - } - use_strict(); - } - if (disruptor) { - warn('unreachable_a_b', next_token, next_token.string, - disruptor.string); - disruptor = null; - } - the_statement = statement(); - if (the_statement) { - array.push(the_statement); - if (the_statement.disrupt) { - disruptor = the_statement; - array.disrupt = true; - } - } - } - } - return array; - } - - - function block(ordinary) { - -// array block is array sequence of statements wrapped in braces. -// ordinary is false for function bodies and try blocks. -// ordinary is true for if statements, while, etc. - - var array, - curly = next_token, - old_inblock = in_block, - old_scope = scope, - old_strict_mode = strict_mode; - - in_block = ordinary; - scope = Object.create(scope); - spaces(); - if (next_token.id === '{') { - advance('{'); - step_in(); - if (!ordinary && !use_strict() && !old_strict_mode && - !option.sloppy && funct['(context)'] === global_funct) { - warn('missing_use_strict'); - } - array = statements(); - strict_mode = old_strict_mode; - step_out('}', curly); - discard(); - } else if (!ordinary) { - stop('expected_a_b', next_token, '{', next_token.string); - } else { - warn('expected_a_b', next_token, '{', next_token.string); - array = [statement()]; - array.disrupt = array[0].disrupt; - } - funct['(verb)'] = null; - scope = old_scope; - in_block = old_inblock; - if (ordinary && array.length === 0) { - warn('empty_block'); - } - return array; - } - - - function tally_property(name) { - if (option.properties && typeof property_type[name] !== 'string') { - warn('unexpected_property_a', token, name); - } - if (typeof member[name] === 'number') { - member[name] += 1; - } else { - member[name] = 1; - } - } - - -// ECMAScript parser - - syntax['(identifier)'] = { - lbp: 0, - identifier: true, - nud: function () { - var name = this.string, - variable = scope[name], - site, - writeable; - -// If the variable is not in scope, then we may have an undeclared variable. -// Check the predefined list. If it was predefined, create the global -// variable. - - if (typeof variable !== 'object') { - writeable = predefined[name]; - if (typeof writeable === 'boolean') { - global_scope[name] = variable = { - string: name, - writeable: writeable, - funct: global_funct - }; - global_funct[name] = 'var'; - -// But if the variable is not in scope, and is not predefined, and if we are not -// in the global scope, then we have an undefined variable error. - - } else { - if (!option.undef) { - warn('used_before_a', token); - } - scope[name] = variable = { - string: name, - writeable: true, - funct: funct - }; - funct[name] = 'undef'; - } - - } - site = variable.funct; - -// The name is in scope and defined in the current function. - - if (funct === site) { - -// Change 'unused' to 'var', and reject labels. - - switch (funct[name]) { - case 'becoming': - warn('unexpected_a', token); - funct[name] = 'var'; - break; - case 'unused': - funct[name] = 'var'; - break; - case 'unparam': - funct[name] = 'parameter'; - break; - case 'unction': - funct[name] = 'function'; - break; - case 'label': - warn('a_label', token, name); - break; - } - -// If the name is already defined in the current -// function, but not as outer, then there is a scope error. - - } else { - switch (funct[name]) { - case 'closure': - case 'function': - case 'var': - case 'unused': - warn('a_scope', token, name); - break; - case 'label': - warn('a_label', token, name); - break; - case 'outer': - case 'global': - break; - default: - -// If the name is defined in an outer function, make an outer entry, and if -// it was unused, make it var. - - switch (site[name]) { - case 'becoming': - case 'function': - case 'unction': - case 'var': - case 'unused': - case 'closure': - case 'parameter': - site[name] = 'closure'; - funct[name] = site === global_funct ? 'global' : 'outer'; - break; - case 'unparam': - site[name] = 'parameter'; - funct[name] = 'outer'; - break; - case 'undef': - funct[name] = 'undef'; - break; - case 'label': - warn('a_label', token, name); - break; - } - } - } - return this; - }, - led: function () { - stop('expected_operator_a'); - } - }; - -// Build the syntax table by declaring the syntactic elements. - - type('(array)', 'array'); - type('(color)', 'color'); - type('(function)', 'function'); - type('(number)', 'number', return_this); - type('(object)', 'object'); - type('(string)', 'string', return_this); - type('(boolean)', 'boolean', return_this); - type('(range)', 'range'); - type('(regexp)', 'regexp', return_this); - - ultimate('(begin)'); - ultimate('(end)'); - ultimate('(error)'); - postscript(delim(''); - postscript(delim('}')); - delim(')'); - delim(']'); - postscript(delim('"')); - postscript(delim('\'')); - delim(';'); - delim(':'); - delim(','); - delim('#'); - delim('@'); - delim('*/'); - postscript(reserve('case')); - reserve('catch'); - postscript(reserve('default')); - reserve('else'); - reserve('finally'); - - reservevar('arguments', function (x) { - if (strict_mode && funct === global_funct) { - warn('strict', x); - } else if (option.safe) { - warn('adsafe_a', x); - } - }); - reservevar('eval', function (x) { - if (option.safe) { - warn('adsafe_a', x); - } - }); - constant('false', 'boolean'); - constant('Infinity', 'number'); - constant('NaN', 'number'); - constant('null', ''); - reservevar('this', function (x) { - if (strict_mode && ((funct['(statement)'] && - funct['(name)'].charAt(0) > 'Z') || funct === global_funct)) { - warn('strict', x); - } else if (option.safe) { - warn('adsafe_a', x); - } - }); - constant('true', 'boolean'); - constant('undefined', ''); - - infix('?', 30, function (left, that) { - that.first = expected_condition(expected_relation(left)); - that.second = expression(0); - spaces(); - var colon = next_token; - advance(':'); - discard(); - spaces(); - that.third = expression(10); - that.arity = 'ternary'; - set_type(that, conform_type(that.second, that.third)); - if (are_similar(that.second, that.third)) { - warn('weird_ternary', colon); - } else if (are_similar(that.first, that.second)) { - warn('use_or', that); - } - return that; - }); - - infix('||', 40, function (left, that) { - function paren_check(that) { - if (that.id === '&&' && !that.paren) { - warn('and', that); - } - return that; - } - - that.first = paren_check(expected_condition(expected_relation(left))); - that.second = paren_check(expected_relation(expression(40))); - if (are_similar(that.first, that.second)) { - warn('weird_condition', that); - } - return that; - }); - - infix('&&', 50, function (left, that) { - that.first = expected_condition(expected_relation(left)); - that.second = expected_relation(expression(50)); - if (are_similar(that.first, that.second)) { - warn('weird_condition', that); - } - return that; - }); - - prefix('void', function () { - this.first = expression(0); - this.arity = 'prefix'; - if (this.first.id !== '(number)' || this.first.string) { - warn('unexpected_a', this); - return this; - } - this.type = 'undefined'; - return this; - }); - - bitwise('|', 70); - bitwise('^', 80); - bitwise('&', 90); - - relation('==', '==='); - relation('==='); - relation('!=', '!=='); - relation('!=='); - relation('<'); - relation('>'); - relation('<='); - relation('>='); - - bitwise('<<', 120); - bitwise('>>', 120); - bitwise('>>>', 120); - - infix('in', 120, function (left, that) { - warn('infix_in', that); - that.left = left; - that.right = expression(130); - return that; - }, 'boolean'); - infix('instanceof', 120, null, 'boolean'); - infix('+', 130, function (left, that) { - if (left.id === '(number)') { - if (left.number === 0) { - warn('unexpected_a', left, '0'); - } - } else if (left.id === '(string)') { - if (left.string === '') { - warn('expected_a_b', left, 'String', '\'\''); - } - } - var right = expression(130); - if (right.id === '(number)') { - if (right.number === 0) { - warn('unexpected_a', right, '0'); - } - } else if (right.id === '(string)') { - if (right.string === '') { - warn('expected_a_b', right, 'String', '\'\''); - } - } - if (left.id === right.id) { - if (left.id === '(string)' || left.id === '(number)') { - if (left.id === '(string)') { - left.string += right.string; - if (jx.test(left.string)) { - warn('url', left); - } - } else { - left.number += right.number; - } - left.thru = right.thru; - discard(right); - discard(that); - return left; - } - } - that.first = left; - that.second = right; - set_type(that, conform_type(left, right)); - return that; - }); - prefix('+', 'num'); - prefix('+++', function () { - warn('confusing_a', token); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('+++', 130, function (left) { - warn('confusing_a', token); - this.first = left; - this.second = expression(130); - return this; - }); - infix('-', 130, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(130); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - warn('unexpected_a', left); - } - if (left.id === right.id && left.id === '(number)') { - left.number -= right.number; - left.thru = right.thru; - discard(right); - discard(that); - return left; - } - that.first = left; - that.second = right; - return that; - }, 'number'); - prefix('-'); - prefix('---', function () { - warn('confusing_a', token); - this.first = expression(150); - this.arity = 'prefix'; - return this; - }); - infix('---', 130, function (left) { - warn('confusing_a', token); - this.first = left; - this.second = expression(130); - return this; - }); - infix('*', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number *= right.number; - left.thru = right.thru; - discard(right); - discard(that); - return left; - } - that.first = left; - that.second = right; - return that; - }, 'number'); - infix('/', 140, function (left, that) { - if ((left.id === '(number)' && left.number === 0) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && (right.number === 0 || right.number === 1)) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number /= right.number; - left.thru = right.thru; - discard(right); - discard(that); - return left; - } - that.first = left; - that.second = right; - return that; - }, 'number'); - infix('%', 140, function (left, that) { - if ((left.id === '(number)' && (left.number === 0 || left.number === 1)) || left.id === '(string)') { - warn('unexpected_a', left); - } - var right = expression(140); - if ((right.id === '(number)' && right.number === 0) || right.id === '(string)') { - warn('unexpected_a', right); - } - if (left.id === right.id && left.id === '(number)') { - left.number %= right.number; - left.thru = right.thru; - discard(right); - discard(that); - return left; - } - that.first = left; - that.second = right; - return that; - }, 'number'); - - suffix('++'); - prefix('++'); - - suffix('--'); - prefix('--'); - prefix('delete', function () { - one_space(); - var p = expression(0); - if (!p || (p.id !== '.' && p.id !== '[')) { - warn('deleted'); - } - this.first = p; - return this; - }); - - - prefix('~', function () { - no_space_only(); - if (!option.bitwise) { - warn('unexpected_a', this); - } - expression(150); - return this; - }, 'number'); - prefix('!', function () { - no_space_only(); - this.first = expected_condition(expression(150)); - this.arity = 'prefix'; - if (bang[this.first.id] === true) { - warn('confusing_a', this); - } - return this; - }, 'boolean'); - prefix('typeof', null, 'string'); - prefix('new', function () { - one_space(); - var c = expression(160), n, p, v; - this.first = c; - if (c.id !== 'function') { - if (c.identifier) { - switch (c.string) { - case 'Object': - warn('use_object', token); - break; - case 'Array': - if (next_token.id === '(') { - p = next_token; - p.first = this; - advance('('); - if (next_token.id !== ')') { - n = expression(0); - p.second = [n]; - if (get_type(n) !== 'number' || next_token.id === ',') { - warn('use_array', p); - } - while (next_token.id === ',') { - advance(','); - p.second.push(expression(0)); - } - } else { - warn('use_array', token); - } - advance(')', p); - discard(); - return p; - } - warn('use_array', token); - break; - case 'Number': - case 'String': - case 'Boolean': - case 'Math': - case 'JSON': - warn('not_a_constructor', c); - break; - case 'Function': - if (!option.evil) { - warn('function_eval'); - } - break; - case 'Date': - case 'RegExp': - break; - default: - if (c.id !== 'function') { - v = c.string.charAt(0); - if (!option.newcap && (v < 'A' || v > 'Z')) { - warn('constructor_name_a', token); - } - } - } - } else { - if (c.id !== '.' && c.id !== '[' && c.id !== '(') { - warn('bad_constructor', token); - } - } - } else { - warn('weird_new', this); - } - if (next_token.id !== '(') { - warn('missing_a', next_token, '()'); - } - return this; - }); - - infix('(', 160, function (left, that) { - var p; - if (indent && indent.mode === 'expression') { - no_space(prev_token, token); - } else { - no_space_only(prev_token, token); - } - if (!left.immed && left.id === 'function') { - warn('wrap_immediate'); - } - p = []; - if (left.identifier) { - if (left.string === 'String') { - conform_type('string', that); - } else if (left.string === 'Number') { - conform_type('number', that); - } else if (left.string === 'Boolean') { - conform_type('boolean', that); - } else { - set_type(that, conform_type('function', left).slice(9)); - } - } else if (left.id === '.') { - switch (left.second.string) { - case 'apply': - case 'call': - set_type(that, conform_type('function', left.first).slice(9)); - break; - case 'concat': - case 'slice': - conform_type(that, left.first); - break; - case 'parse': - case 'toJSON': - conform_type('function', left); - break; - default: - set_type(that, conform_type('function', left).slice(9)); - } - } else { - set_type(that, conform_type('function', left).slice(9)); - } - if (left.identifier) { - if (left.string.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if (left.string !== 'Number' && left.string !== 'String' && - left.string !== 'Boolean' && left.string !== 'Date') { - if (left.string === 'Math' || left.string === 'JSON') { - warn('not_a_function', left); - } else if (left.string === 'Object') { - warn('use_object', token); - } else if (left.string === 'Array' || !option.newcap) { - warn('missing_a', left, 'new'); - } - } - } - } else if (left.id === '.') { - if (option.safe && left.first.string === 'Math' && - left.second === 'random') { - warn('adsafe_a', left); - } else if (left.second.string === 'split' && - left.first.id === '(string)') { - warn('use_array', left.second); - } - } - step_in(); - if (next_token.id !== ')') { - no_space(); - for (;;) { - edge(); - p.push(expression(10)); - if (next_token.id !== ',') { - break; - } - comma(); - } - } - no_space(); - step_out(')', that); - if (typeof left === 'object') { - if (left.string === 'parseInt' && p.length === 1) { - warn('radix', left); - } - if (!option.evil) { - if (left.string === 'eval' || left.string === 'Function' || - left.string === 'execScript') { - warn('evil', left); - } else if (p[0] && p[0].id === '(string)' && - (left.string === 'setTimeout' || - left.string === 'setInterval')) { - warn('implied_evil', left); - } - } - if (!left.identifier && left.id !== '.' && left.id !== '[' && - left.id !== '(' && left.id !== '&&' && left.id !== '||' && - left.id !== '?') { - warn('bad_invocation', left); - } - } - that.first = left; - that.second = p; - return that; - }, '', true); - - prefix('(', function () { - step_in('expression'); - discard(); - no_space(); - edge(); - if (next_token.id === 'function') { - next_token.immed = true; - } - var value = expression(0); - value.paren = true; - no_space(); - step_out(')', this); - discard(); - if (value.id === 'function') { - if (next_token.id === '(') { - warn('move_invocation'); - } else { - warn('bad_wrap', this); - } - } - return value; - }); - - infix('.', 170, function (left, that) { - no_space(prev_token, token); - no_space(); - var name = identifier(), type; - if (typeof name === 'string') { - tally_property(name); - } - that.first = left; - that.second = token; - if (left && left.string === 'arguments' && - (name === 'callee' || name === 'caller')) { - warn('avoid_a', left, 'arguments.' + name); - } else if (!option.evil && left && left.string === 'document' && - (name === 'write' || name === 'writeln')) { - warn('write_is_wrong', left); - } else if (option.adsafe) { - if (!adsafe_top && left.string === 'ADSAFE') { - if (name === 'id' || name === 'lib') { - warn('adsafe_a', that); - } else if (name === 'go') { - if (xmode !== 'script') { - warn('adsafe_a', that); - } else if (adsafe_went || next_token.id !== '(' || - peek(0).id !== '(string)' || - peek(0).string !== adsafe_id || - peek(1).id !== ',') { - stop('adsafe_a', that, 'go'); - } - adsafe_went = true; - adsafe_may = false; - } - } - adsafe_top = false; - } - if (!option.evil && (name === 'eval' || name === 'execScript')) { - warn('evil'); - } else if (option.safe) { - for (;;) { - if (banned[name] === true) { - warn('adsafe_a', token, name); - } - if (typeof predefined[left.string] !== 'boolean' || //// check for writeable - next_token.id === '(') { - break; - } - if (next_token.id !== '.') { - warn('adsafe_a', that); - break; - } - advance('.'); - token.first = that; - token.second = name; - that = token; - name = identifier(); - if (typeof name === 'string') { - tally_property(name); - } - } - } - type = property_type[name]; - if (type && typeof type === 'string' && type !== '*') { - that.type = type; - } - return that; - }, '', true); - - infix('[', 170, function (left, that) { - var e, s; - no_space_only(prev_token, token); - no_space(); - step_in(); - edge(); - e = expression(0); - switch (get_type(e)) { - case 'number': - if (e.id === '(number)' && left.id === 'arguments') { - warn('use_param', left); - } - conform_type('array', left); - break; - case 'string': - if (e.id === '(string)') { - if (option.safe && (banned[e.string] || - e.string.charAt(0) === '_' || e.string.slice(-1) === '_')) { - warn('adsafe_subscript_a', e); - } else if (!option.evil && - (e.string === 'eval' || e.string === 'execScript')) { - warn('evil', e); - } else if (!option.sub && ix.test(e.string)) { - s = syntax[e.string]; - if (!s || !s.reserved) { - warn('subscript', e); - } - } - tally_property(e.string); - } else if (option.safe && e.id !== 'typeof') { - warn('adsafe_subscript_a', e); - } - conform_type('object', left); - break; - case undefined: - switch (get_type(left)) { - case 'array': - conform_type('number', e); - break; - case 'object': - conform_type('string', e); - break; - case 'string': - if (!option.confusion) { - warn('use_charAt', that); - } - set_type(that, 'string'); - break; - } - if (option.safe) { - warn('adsafe_subscript_a', e); - } - break; - default: - if (option.safe) { - warn('adsafe_subscript_a', e); - } - } - step_out(']', that); - discard(); - no_space(prev_token, token); - that.first = left; - that.second = e; - return that; - }, '', true); - - prefix('[', function () { - this.arity = 'prefix'; - this.first = []; - set_type(this, 'array'); - step_in('array'); - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - advance(','); - discard(); - } - if (next_token.id === ']') { - break; - } - indent.wrap = false; - edge(); - this.first.push(expression(10)); - if (next_token.id === ',') { - comma(); - if (next_token.id === ']' && !option.es5) { - warn('unexpected_a', token); - break; - } - } else { - break; - } - } - step_out(']', this); - discard(); - return this; - }, 170); - - - function property_name() { - var id = optional_identifier(true); - if (!id) { - if (next_token.id === '(string)') { - id = next_token.string; - if (option.safe) { - if (banned[id]) { - warn('adsafe_a'); - } else if (id.charAt(0) === '_' || - id.charAt(id.length - 1) === '_') { - warn('dangling_a'); - } - } - advance(); - } else if (next_token.id === '(number)') { - id = next_token.number.toString(); - advance(); - } - } - return id; - } - - - function function_params() { - var id, paren = next_token, params = []; - advance('('); - step_in(); - discard(); - no_space(); - if (next_token.id === ')') { - no_space(); - step_out(')', paren); - discard(); - return; - } - for (;;) { - edge(); - id = identifier(); - params.push(token); - add_label(token, option.unparam ? 'parameter' : 'unparam'); - if (next_token.id === ',') { - comma(); - } else { - no_space(); - step_out(')', paren); - discard(); - return params; - } - } - } - - - function complexity(exp) { - var score = 0; - if (exp) { - if (Array.isArray(exp)) { - exp.forEach(function (tok) { - score += complexity(tok); - }); - } else { - switch (exp.arity) { - case 'statement': - switch (exp.id) { - case 'if': - score += complexity(exp.first) + complexity(exp.block) + - complexity(exp['else']) + 1; - break; - case 'while': - case 'do': - if (exp.first.id !== 'true' && exp.first.number !== 1) { - score += 1; - } - score += complexity(exp.first) + complexity(exp.block); - break; - case 'for': - if (exp.second !== undefined && - exp.second.id !== 'true' && - exp.second.number !== 1) { - score += 1; - } - score += complexity(exp.first) + complexity(exp.second) + - complexity(exp.third) + complexity(exp.block); - break; - case 'switch': - score += complexity(exp.first) + - complexity(exp.second) + exp.second.length; - if (exp.second[exp.second.length - 1].id === 'default') { - score -= 1; - } - break; - case 'try': - if (exp.second) { - score += 1; - } - if (exp.third) { - score += 1; - } - score += complexity(exp.first) + complexity(exp.second) + - complexity(exp.third) + complexity(exp.block); - break; - } - break; - case 'prefix': - score += complexity(exp.first); - break; - case 'case': - case 'infix': - score += complexity(exp.first) + complexity(exp.second); - if (exp.id === '&&' || exp.id === '||') { - score += 1; - } - break; - case 'ternary': - score += complexity(exp.first) + complexity(exp.second) + complexity(exp.third); - break; - } - } - } - return score; - } - - - function do_function(func, name) { - var old_funct = funct, - old_option = option, - old_scope = scope; - funct = { - '(name)' : name || '\'' + (anonname || '').replace(nx, sanitize) + '\'', - '(line)' : next_token.line, - '(context)' : old_funct, - '(breakage)' : 0, - '(loopage)' : 0, - '(scope)' : scope, - '(token)' : func - }; - option = Object.create(old_option); - scope = Object.create(old_scope); - functions.push(funct); - func.name = name; - if (name) { - add_label(func, 'function', name); - } - func.writeable = false; - func.first = funct['(params)'] = function_params(); - one_space(); - func.block = block(false); - set_type(func, funct['(return_type)'] ? - 'function ' + funct['(return_type)'] : - 'function'); - if (funct['(old_property_type)']) { - property_type = funct['(old_property_type)']; - delete funct['(old_property_type)']; - } - funct['(complexity)'] = complexity(func.block) + 1; - if (option.confusion) { - funct['(confusion)'] = true; - } - funct = old_funct; - option = old_option; - scope = old_scope; - } - - - assignop('='); - assignop('+=', '+'); - assignop('-=', '-'); - assignop('*=', '*'); - assignop('/=', '/').nud = function () { - stop('slash_equal'); - }; - assignop('%=', '%'); - assignop('&=', '&'); - assignop('|=', '|'); - assignop('^=', '^'); - assignop('<<=', '<<'); - assignop('>>=', '>>'); - assignop('>>>=', '>>>'); - - - prefix('{', function () { - var get, i, j, name, p, set, seen = {}, type; - this.arity = 'prefix'; - this.first = []; - set_type(this, 'object'); - step_in(); - while (next_token.id !== '}') { - indent.wrap = false; - -// JSLint recognizes the ES5 extension for get/set in object literals, -// but requires that they be used in pairs. - - edge(); - if (next_token.string === 'get' && peek().id !== ':') { - if (!option.es5) { - warn('es5'); - } - get = next_token; - advance('get'); - one_space_only(); - name = next_token; - i = property_name(); - if (!i) { - stop('missing_property'); - } - get.string = ''; - do_function(get); - if (funct['(loopage)']) { - warn('function_loop', get); - } - p = get.first; - if (p) { - warn('parameter_a_get_b', p[0], p[0].string, i); - } - comma(); - set = next_token; - set.string = ''; - spaces(); - edge(); - advance('set'); - one_space_only(); - j = property_name(); - if (i !== j) { - stop('expected_a_b', token, i, j || next_token.string); - } - do_function(set); - p = set.first; - if (!p || p.length !== 1) { - stop('parameter_set_a', set, 'value'); - } else if (p[0].string !== 'value') { - stop('expected_a_b', p[0], 'value', p[0].string); - } - name.first = [get, set]; - } else { - name = next_token; - i = property_name(); - if (typeof i !== 'string') { - stop('missing_property'); - } - advance(':'); - discard(); - spaces(); - name.first = expression(10); - type = property_type[i]; - if (type) { - name.type = conform_type(type, name.first); - } else { - type = get_type(name.first); - if (type && type !== '*') { - property_type[i] = name.type = type; - } - } - } - this.first.push(name); - if (seen[i] === true) { - warn('duplicate_a', next_token, i); - } - seen[i] = true; - tally_property(i); - if (next_token.id !== ',') { - break; - } - for (;;) { - comma(); - if (next_token.id !== ',') { - break; - } - warn('unexpected_a', next_token); - } - if (next_token.id === '}' && !option.es5) { - warn('unexpected_a', token); - } - } - step_out('}', this); - discard(); - return this; - }); - - stmt('{', function () { - discard(); - warn('statement_block'); - this.arity = 'statement'; - this.block = statements(); - this.disrupt = this.block.disrupt; - advance('}', this); - discard(); - return this; - }); - - stmt('/*global', directive); - stmt('/*globals', directive); - stmt('/*jslint', directive); - stmt('/*member', directive); - stmt('/*members', directive); - stmt('/*property', directive); - stmt('/*properties', directive); - - stmt('var', function () { - -// JavaScript does not have block scope. It only has function scope. So, -// declaring a variable in a block can have unexpected consequences. - -// var.first will contain an array, the array containing name tokens -// and assignment tokens. - - var assign, id, name; - - if (funct['(vars)'] && !option.vars) { - warn('combine_var'); - } else if (funct !== global_funct) { - funct['(vars)'] = true; - } - this.arity = 'statement'; - this.first = []; - step_in('var'); - for (;;) { - name = next_token; - id = identifier(); - add_label(name, 'becoming'); - - if (next_token.id === '=') { - assign = next_token; - assign.first = name; - spaces(); - advance('='); - spaces(); - if (next_token.id === 'undefined') { - warn('unnecessary_initialize', token, id); - } - if (peek(0).id === '=' && next_token.identifier) { - stop('var_a_not'); - } - assign.second = expression(0); - assign.arity = 'infix'; - this.first.push(assign); - conform_type(name, assign.second); - } else { - this.first.push(name); - } - if (funct[id] === 'becoming') { - funct[id] = 'unused'; - } - if (next_token.id !== ',') { - break; - } - comma(); - indent.wrap = false; - if (var_mode && next_token.line === token.line && - this.first.length === 1) { - var_mode = null; - indent.open = false; - indent.at -= option.indent; - } - spaces(); - edge(); - } - var_mode = null; - step_out(); - return this; - }); - - stmt('function', function () { - one_space(); - if (in_block) { - warn('function_block', token); - } - var name = next_token, id = identifier(); - add_label(name, 'unction'); - no_space(); - do_function(this, id); - if (next_token.id === '(' && next_token.line === token.line) { - stop('function_statement'); - } - this.arity = 'statement'; - return this; - }); - - prefix('function', function () { - one_space(); - var id = optional_identifier(); - if (id) { - no_space(); - } else { - id = ''; - } - do_function(this, id); - if (funct['(loopage)']) { - warn('function_loop'); - } - this.arity = 'function'; - return this; - }); - - stmt('if', function () { - var paren = next_token; - one_space(); - advance('('); - step_in('control'); - discard(); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', paren); - discard(); - one_space(); - this.block = block(true); - if (next_token.id === 'else') { - one_space(); - advance('else'); - discard(); - one_space(); - this['else'] = next_token.id === 'if' || next_token.id === 'switch' ? - statement(true) : block(true); - if (this['else'].disrupt && this.block.disrupt) { - this.disrupt = true; - } - } - return this; - }); - - stmt('try', function () { - -// try.first The catch variable -// try.second The catch clause -// try.third The finally clause -// try.block The try block - - var exception_variable, old_scope, paren; - if (option.adsafe) { - warn('adsafe_a', this); - } - one_space(); - this.arity = 'statement'; - this.block = block(false); - if (next_token.id === 'catch') { - one_space(); - advance('catch'); - discard(); - one_space(); - paren = next_token; - advance('('); - step_in('control'); - discard(); - no_space(); - edge(); - old_scope = scope; - scope = Object.create(old_scope); - exception_variable = next_token.string; - this.first = exception_variable; - if (!next_token.identifier) { - warn('expected_identifier_a', next_token); - } else { - add_label(next_token, 'exception'); - } - advance(); - no_space(); - step_out(')', paren); - discard(); - one_space(); - this.second = block(false); - scope = old_scope; - } - if (next_token.id === 'finally') { - discard(); - one_space(); - advance('finally'); - discard(); - one_space(); - this.third = block(false); - } else if (!this.second) { - stop('expected_a_b', next_token, 'catch', next_token.string); - } - return this; - }); - - labeled_stmt('while', function () { - one_space(); - var paren = next_token; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - step_in('control'); - discard(); - no_space(); - edge(); - this.arity = 'statement'; - this.first = expected_relation(expression(0)); - if (this.first.id !== 'true') { - expected_condition(this.first, bundle.unexpected_a); - } - no_space(); - step_out(')', paren); - discard(); - one_space(); - this.block = block(true); - if (this.block.disrupt) { - warn('strange_loop', prev_token); - } - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - reserve('with'); - - labeled_stmt('switch', function () { - -// switch.first the switch expression -// switch.second the array of cases. A case is 'case' or 'default' token: -// case.first the array of case expressions -// case.second the array of statements -// If all of the arrays of statements are disrupt, then the switch is disrupt. - - var cases = [], - particular, - the_case = next_token, - unbroken = true; - - function find_duplicate_case(value) { - if (are_similar(particular, value)) { - warn('duplicate_a', value); - } - } - - funct['(breakage)'] += 1; - one_space(); - advance('('); - discard(); - no_space(); - step_in(); - this.arity = 'statement'; - this.first = expected_condition(expected_relation(expression(0))); - no_space(); - step_out(')', the_case); - discard(); - one_space(); - advance('{'); - step_in(); - this.second = []; - while (next_token.id === 'case') { - the_case = next_token; - cases.forEach(find_duplicate_case); - the_case.first = []; - the_case.arity = 'case'; - spaces(); - edge('case'); - advance('case'); - for (;;) { - one_space(); - particular = expression(0); - cases.forEach(find_duplicate_case); - cases.push(particular); - the_case.first.push(particular); - if (particular.id === 'NaN') { - warn('unexpected_a', particular); - } - no_space_only(); - advance(':'); - discard(); - if (next_token.id !== 'case') { - break; - } - spaces(); - edge('case'); - advance('case'); - discard(); - } - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - particular = the_case.second[the_case.second.length - 1]; - if (particular.disrupt) { - if (particular.id === 'break') { - unbroken = false; - } - } else { - warn('missing_a_after_b', next_token, 'break', 'case'); - } - } else { - warn('empty_case'); - } - this.second.push(the_case); - } - if (this.second.length === 0) { - warn('missing_a', next_token, 'case'); - } - if (next_token.id === 'default') { - spaces(); - the_case = next_token; - the_case.arity = 'case'; - edge('case'); - advance('default'); - discard(); - no_space_only(); - advance(':'); - discard(); - spaces(); - the_case.second = statements(); - if (the_case.second && the_case.second.length > 0) { - particular = the_case.second[the_case.second.length - 1]; - if (unbroken && particular.disrupt && particular.id !== 'break') { - this.disrupt = true; - } - } - this.second.push(the_case); - } - funct['(breakage)'] -= 1; - spaces(); - step_out('}', this); - return this; - }); - - stmt('debugger', function () { - if (!option.debug) { - warn('unexpected_a', this); - } - this.arity = 'statement'; - return this; - }); - - labeled_stmt('do', function () { - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - one_space(); - this.arity = 'statement'; - this.block = block(true); - if (this.block.disrupt) { - warn('strange_loop', prev_token); - } - one_space(); - advance('while'); - discard(); - var paren = next_token; - one_space(); - advance('('); - step_in(); - discard(); - no_space(); - edge(); - this.first = expected_condition(expected_relation(expression(0)), bundle.unexpected_a); - no_space(); - step_out(')', paren); - discard(); - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - labeled_stmt('for', function () { - - var blok, filter, ok = false, paren = next_token, the_in, value; - this.arity = 'statement'; - funct['(breakage)'] += 1; - funct['(loopage)'] += 1; - advance('('); - step_in('control'); - discard(); - spaces(this, paren); - no_space(); - if (next_token.id === 'var') { - stop('move_var'); - } - edge(); - if (peek(0).id === 'in') { - value = next_token; - switch (funct[value.string]) { - case 'unused': - funct[value.string] = 'var'; - break; - case 'closure': - case 'var': - break; - default: - warn('bad_in_a', value); - } - conform_type('string', value); - advance(); - the_in = next_token; - advance('in'); - the_in.first = value; - the_in.second = expression(20); - conform_type('object', the_in.second); - step_out(')', paren); - discard(); - this.first = the_in; - blok = block(true); - if (!option.forin) { - if (blok.length === 1 && typeof blok[0] === 'object' && - blok[0].string === 'if' && !blok[0]['else']) { - filter = blok[0].first; - while (filter.id === '&&') { - filter = filter.first; - } - switch (filter.id) { - case '===': - case '!==': - ok = filter.first.id === '[' ? ( - filter.first.first.string === the_in.second.string && - filter.first.second.string === the_in.first.string - ) : ( - filter.first.id === 'typeof' && - filter.first.first.id === '[' && - filter.first.first.first.string === the_in.second.string && - filter.first.first.second.string === the_in.first.string - ); - break; - case '(': - ok = filter.first.id === '.' && (( - filter.first.first.string === the_in.second.string && - filter.first.second.string === 'hasOwnProperty' && - filter.second[0].string === the_in.first.string - ) || ( - filter.first.first.string === 'ADSAFE' && - filter.first.second.string === 'has' && - filter.second[0].string === the_in.second.string && - filter.second[1].string === the_in.first.string - ) || ( - filter.first.first.id === '.' && - filter.first.first.first.id === '.' && - filter.first.first.first.first.string === 'Object' && - filter.first.first.first.second.string === 'prototype' && - filter.first.first.second.string === 'hasOwnProperty' && - filter.first.second.string === 'call' && - filter.second[0].string === the_in.second.string && - filter.second[1].string === the_in.first.string - )); - break; - } - } - if (!ok) { - warn('for_if', this); - } - } - } else { - if (next_token.id !== ';') { - edge(); - this.first = []; - for (;;) { - this.first.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - } - semicolon(); - if (next_token.id !== ';') { - edge(); - this.second = expected_relation(expression(0)); - if (this.second.id !== 'true') { - expected_condition(this.second, bundle.unexpected_a); - } - } - semicolon(token); - if (next_token.id === ';') { - stop('expected_a_b', next_token, ')', ';'); - } - if (next_token.id !== ')') { - this.third = []; - edge(); - for (;;) { - this.third.push(expression(0, 'for')); - if (next_token.id !== ',') { - break; - } - comma(); - } - } - no_space(); - step_out(')', paren); - discard(); - one_space(); - blok = block(true); - } - if (blok.disrupt) { - warn('strange_loop', prev_token); - } - this.block = blok; - funct['(breakage)'] -= 1; - funct['(loopage)'] -= 1; - return this; - }); - - disrupt_stmt('break', function () { - var label = next_token.string; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warn('unexpected_a', this); - } - if (next_token.identifier && token.line === next_token.line) { - one_space_only(); - if (funct[label] !== 'label') { - warn('not_a_label', next_token); - } else if (scope[label].funct !== funct) { - warn('not_a_scope', next_token); - } - this.first = next_token; - advance(); - } - return this; - }); - - disrupt_stmt('continue', function () { - if (!option['continue']) { - warn('unexpected_a', this); - } - var label = next_token.string; - this.arity = 'statement'; - if (funct['(breakage)'] === 0) { - warn('unexpected_a', this); - } - if (next_token.identifier && token.line === next_token.line) { - one_space_only(); - if (funct[label] !== 'label') { - warn('not_a_label', next_token); - } else if (scope[label].funct !== funct) { - warn('not_a_scope', next_token); - } - this.first = next_token; - advance(); - } - return this; - }); - - disrupt_stmt('return', function () { - if (funct === global_funct) { - warn('unexpected_a', this); - } - this.arity = 'statement'; - if (next_token.id !== ';' && next_token.line === token.line) { - one_space_only(); - if (next_token.id === '/' || next_token.id === '(regexp)') { - warn('wrap_regexp'); - } - this.first = expression(20); - funct['(return_type)'] = conform_type(funct['(return_type)'], this.first); - } - return this; - }); - - disrupt_stmt('throw', function () { - this.arity = 'statement'; - one_space_only(); - this.first = expression(20); - return this; - }); - - -// Superfluous reserved words - - reserve('class'); - reserve('const'); - reserve('enum'); - reserve('export'); - reserve('extends'); - reserve('import'); - reserve('super'); - -// Harmony reserved words - - reserve('let'); - reserve('yield'); - reserve('implements'); - reserve('interface'); - reserve('package'); - reserve('private'); - reserve('protected'); - reserve('public'); - reserve('static'); - - -// Parse JSON - - function json_value() { - - function json_object() { - var brace = next_token, object = {}; - advance('{'); - if (next_token.id !== '}') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - comma(); - } - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - if (object[next_token.string] === true) { - warn('duplicate_a'); - } else if (next_token.string === '__proto__') { - warn('dangling_a'); - } else { - object[next_token.string] = true; - } - advance(); - advance(':'); - json_value(); - if (next_token.id !== ',') { - break; - } - comma(); - if (next_token.id === '}') { - warn('unexpected_a', token); - break; - } - } - } - advance('}', brace); - } - - function json_array() { - var bracket = next_token; - advance('['); - if (next_token.id !== ']') { - while (next_token.id !== '(end)') { - while (next_token.id === ',') { - warn('unexpected_a', next_token); - comma(); - } - json_value(); - if (next_token.id !== ',') { - break; - } - comma(); - if (next_token.id === ']') { - warn('unexpected_a', token); - break; - } - } - } - advance(']', bracket); - } - - switch (next_token.id) { - case '{': - json_object(); - break; - case '[': - json_array(); - break; - case 'true': - case 'false': - case 'null': - case '(number)': - case '(string)': - advance(); - break; - case '-': - advance('-'); - no_space_only(); - advance('(number)'); - break; - default: - stop('unexpected_a'); - } - } - - -// CSS parsing. - - function css_name() { - if (next_token.identifier) { - advance(); - return true; - } - } - - - function css_number() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance('(number)'); - return true; - } - } - - - function css_string() { - if (next_token.id === '(string)') { - advance(); - return true; - } - } - - function css_color() { - var i, number, paren, value; - if (next_token.identifier) { - value = next_token.string; - if (value === 'rgb' || value === 'rgba') { - advance(); - paren = next_token; - advance('('); - for (i = 0; i < 3; i += 1) { - if (i) { - comma(); - } - number = next_token.number; - if (next_token.id !== '(string)' || number < 0) { - warn('expected_positive_a', next_token); - advance(); - } else { - advance(); - if (next_token.id === '%') { - advance('%'); - if (number > 100) { - warn('expected_percent_a', token, number); - } - } else { - if (number > 255) { - warn('expected_small_a', token, number); - } - } - } - } - if (value === 'rgba') { - comma(); - number = next_token.number; - if (next_token.id !== '(string)' || number < 0 || number > 1) { - warn('expected_fraction_a', next_token); - } - advance(); - if (next_token.id === '%') { - warn('unexpected_a'); - advance('%'); - } - } - advance(')', paren); - return true; - } else if (css_colorData[next_token.string] === true) { - advance(); - return true; - } - } else if (next_token.id === '(color)') { - advance(); - return true; - } - return false; - } - - - function css_length() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance(); - if (next_token.id !== '(string)' && - css_lengthData[next_token.string] === true) { - no_space_only(); - advance(); - } else if (+token.number !== 0) { - warn('expected_linear_a'); - } - return true; - } - return false; - } - - - function css_line_height() { - if (next_token.id === '-') { - advance('-'); - no_space_only(); - } - if (next_token.id === '(number)') { - advance(); - if (next_token.id !== '(string)' && - css_lengthData[next_token.string] === true) { - no_space_only(); - advance(); - } - return true; - } - return false; - } - - - function css_width() { - if (next_token.identifier) { - switch (next_token.string) { - case 'thin': - case 'medium': - case 'thick': - advance(); - return true; - } - } else { - return css_length(); - } - } - - - function css_margin() { - if (next_token.identifier) { - if (next_token.string === 'auto') { - advance(); - return true; - } - } else { - return css_length(); - } - } - - function css_attr() { - if (next_token.identifier && next_token.string === 'attr') { - advance(); - advance('('); - if (!next_token.identifier) { - warn('expected_name_a'); - } - advance(); - advance(')'); - return true; - } - return false; - } - - - function css_comma_list() { - while (next_token.id !== ';') { - if (!css_name() && !css_string()) { - warn('expected_name_a'); - } - if (next_token.id !== ',') { - return true; - } - comma(); - } - } - - - function css_counter() { - if (next_token.identifier && next_token.string === 'counter') { - advance(); - advance('('); - advance(); - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(')'); - return true; - } - if (next_token.identifier && next_token.string === 'counters') { - advance(); - advance('('); - if (!next_token.identifier) { - warn('expected_name_a'); - } - advance(); - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - if (next_token.id === ',') { - comma(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(')'); - return true; - } - return false; - } - - - function css_shape() { - var i; - if (next_token.identifier && next_token.string === 'rect') { - advance(); - advance('('); - for (i = 0; i < 4; i += 1) { - if (!css_length()) { - warn('expected_number_a'); - break; - } - } - advance(')'); - return true; - } - return false; - } - - - function css_url() { - var c, url; - if (next_token.identifier && next_token.string === 'url') { - next_token = lex.range('(', ')'); - url = next_token.string; - c = url.charAt(0); - if (c === '"' || c === '\'') { - if (url.slice(-1) !== c) { - warn('bad_url'); - } else { - url = url.slice(1, -1); - if (url.indexOf(c) >= 0) { - warn('bad_url'); - } - } - } - if (!url) { - warn('missing_url'); - } - if (option.safe && ux.test(url)) { - stop('adsafe_a', next_token, url); - } - urls.push(url); - advance(); - return true; - } - return false; - } - - - css_any = [css_url, function () { - for (;;) { - if (next_token.identifier) { - switch (next_token.string.toLowerCase()) { - case 'url': - css_url(); - break; - case 'expression': - warn('unexpected_a'); - advance(); - break; - default: - advance(); - } - } else { - if (next_token.id === ';' || next_token.id === '!' || - next_token.id === '(end)' || next_token.id === '}') { - return true; - } - advance(); - } - } - }]; - - - css_border_style = [ - 'none', 'dashed', 'dotted', 'double', 'groove', - 'hidden', 'inset', 'outset', 'ridge', 'solid' - ]; - - css_break = [ - 'auto', 'always', 'avoid', 'left', 'right' - ]; - - css_media = { - 'all': true, - 'braille': true, - 'embossed': true, - 'handheld': true, - 'print': true, - 'projection': true, - 'screen': true, - 'speech': true, - 'tty': true, - 'tv': true - }; - - css_overflow = [ - 'auto', 'hidden', 'scroll', 'visible' - ]; - - css_attribute_data = { - background: [ - true, 'background-attachment', 'background-color', - 'background-image', 'background-position', 'background-repeat' - ], - 'background-attachment': ['scroll', 'fixed'], - 'background-color': ['transparent', css_color], - 'background-image': ['none', css_url], - 'background-position': [ - 2, [css_length, 'top', 'bottom', 'left', 'right', 'center'] - ], - 'background-repeat': [ - 'repeat', 'repeat-x', 'repeat-y', 'no-repeat' - ], - 'border': [true, 'border-color', 'border-style', 'border-width'], - 'border-bottom': [ - true, 'border-bottom-color', 'border-bottom-style', - 'border-bottom-width' - ], - 'border-bottom-color': css_color, - 'border-bottom-style': css_border_style, - 'border-bottom-width': css_width, - 'border-collapse': ['collapse', 'separate'], - 'border-color': ['transparent', 4, css_color], - 'border-left': [ - true, 'border-left-color', 'border-left-style', 'border-left-width' - ], - 'border-left-color': css_color, - 'border-left-style': css_border_style, - 'border-left-width': css_width, - 'border-right': [ - true, 'border-right-color', 'border-right-style', - 'border-right-width' - ], - 'border-right-color': css_color, - 'border-right-style': css_border_style, - 'border-right-width': css_width, - 'border-spacing': [2, css_length], - 'border-style': [4, css_border_style], - 'border-top': [ - true, 'border-top-color', 'border-top-style', 'border-top-width' - ], - 'border-top-color': css_color, - 'border-top-style': css_border_style, - 'border-top-width': css_width, - 'border-width': [4, css_width], - bottom: [css_length, 'auto'], - 'caption-side' : ['bottom', 'left', 'right', 'top'], - clear: ['both', 'left', 'none', 'right'], - clip: [css_shape, 'auto'], - color: css_color, - content: [ - 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote', - css_string, css_url, css_counter, css_attr - ], - 'counter-increment': [ - css_name, 'none' - ], - 'counter-reset': [ - css_name, 'none' - ], - cursor: [ - css_url, 'auto', 'crosshair', 'default', 'e-resize', 'help', 'move', - 'n-resize', 'ne-resize', 'nw-resize', 'pointer', 's-resize', - 'se-resize', 'sw-resize', 'w-resize', 'text', 'wait' - ], - direction: ['ltr', 'rtl'], - display: [ - 'block', 'compact', 'inline', 'inline-block', 'inline-table', - 'list-item', 'marker', 'none', 'run-in', 'table', 'table-caption', - 'table-cell', 'table-column', 'table-column-group', - 'table-footer-group', 'table-header-group', 'table-row', - 'table-row-group' - ], - 'empty-cells': ['show', 'hide'], - 'float': ['left', 'none', 'right'], - font: [ - 'caption', 'icon', 'menu', 'message-box', 'small-caption', - 'status-bar', true, 'font-size', 'font-style', 'font-weight', - 'font-family' - ], - 'font-family': css_comma_list, - 'font-size': [ - 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', - 'xx-large', 'larger', 'smaller', css_length - ], - 'font-size-adjust': ['none', css_number], - 'font-stretch': [ - 'normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded' - ], - 'font-style': [ - 'normal', 'italic', 'oblique' - ], - 'font-variant': [ - 'normal', 'small-caps' - ], - 'font-weight': [ - 'normal', 'bold', 'bolder', 'lighter', css_number - ], - height: [css_length, 'auto'], - left: [css_length, 'auto'], - 'letter-spacing': ['normal', css_length], - 'line-height': ['normal', css_line_height], - 'list-style': [ - true, 'list-style-image', 'list-style-position', 'list-style-type' - ], - 'list-style-image': ['none', css_url], - 'list-style-position': ['inside', 'outside'], - 'list-style-type': [ - 'circle', 'disc', 'square', 'decimal', 'decimal-leading-zero', - 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', - 'lower-latin', 'upper-alpha', 'upper-latin', 'hebrew', 'katakana', - 'hiragana-iroha', 'katakana-oroha', 'none' - ], - margin: [4, css_margin], - 'margin-bottom': css_margin, - 'margin-left': css_margin, - 'margin-right': css_margin, - 'margin-top': css_margin, - 'marker-offset': [css_length, 'auto'], - 'max-height': [css_length, 'none'], - 'max-width': [css_length, 'none'], - 'min-height': css_length, - 'min-width': css_length, - opacity: css_number, - outline: [true, 'outline-color', 'outline-style', 'outline-width'], - 'outline-color': ['invert', css_color], - 'outline-style': [ - 'dashed', 'dotted', 'double', 'groove', 'inset', 'none', - 'outset', 'ridge', 'solid' - ], - 'outline-width': css_width, - overflow: css_overflow, - 'overflow-x': css_overflow, - 'overflow-y': css_overflow, - padding: [4, css_length], - 'padding-bottom': css_length, - 'padding-left': css_length, - 'padding-right': css_length, - 'padding-top': css_length, - 'page-break-after': css_break, - 'page-break-before': css_break, - position: ['absolute', 'fixed', 'relative', 'static'], - quotes: [8, css_string], - right: [css_length, 'auto'], - 'table-layout': ['auto', 'fixed'], - 'text-align': ['center', 'justify', 'left', 'right'], - 'text-decoration': [ - 'none', 'underline', 'overline', 'line-through', 'blink' - ], - 'text-indent': css_length, - 'text-shadow': ['none', 4, [css_color, css_length]], - 'text-transform': ['capitalize', 'uppercase', 'lowercase', 'none'], - top: [css_length, 'auto'], - 'unicode-bidi': ['normal', 'embed', 'bidi-override'], - 'vertical-align': [ - 'baseline', 'bottom', 'sub', 'super', 'top', 'text-top', 'middle', - 'text-bottom', css_length - ], - visibility: ['visible', 'hidden', 'collapse'], - 'white-space': [ - 'normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'inherit' - ], - width: [css_length, 'auto'], - 'word-spacing': ['normal', css_length], - 'word-wrap': ['break-word', 'normal'], - 'z-index': ['auto', css_number] - }; - - function style_attribute() { - var v; - while (next_token.id === '*' || next_token.id === '#' || - next_token.string === '_') { - if (!option.css) { - warn('unexpected_a'); - } - advance(); - } - if (next_token.id === '-') { - if (!option.css) { - warn('unexpected_a'); - } - advance('-'); - if (!next_token.identifier) { - warn('expected_nonstandard_style_attribute'); - } - advance(); - return css_any; - } else { - if (!next_token.identifier) { - warn('expected_style_attribute'); - } else { - if (Object.prototype.hasOwnProperty.call(css_attribute_data, next_token.string)) { - v = css_attribute_data[next_token.string]; - } else { - v = css_any; - if (!option.css) { - warn('unrecognized_style_attribute_a'); - } - } - } - advance(); - return v; - } - } - - - function style_value(v) { - - /*jslint confusion: true */ - - var i = 0, - n, - once, - match, - round, - start = 0, - vi; - switch (typeof v) { - case 'function': - return v(); - case 'string': - if (next_token.identifier && next_token.string === v) { - advance(); - return true; - } - return false; - } - for (;;) { - if (i >= v.length) { - return false; - } - vi = v[i]; - i += 1; - if (typeof vi === 'boolean') { - break; - } else if (typeof vi === 'number') { - n = vi; - vi = v[i]; - i += 1; - } else { - n = 1; - } - match = false; - while (n > 0) { - if (style_value(vi)) { - match = true; - n -= 1; - } else { - break; - } - } - if (match) { - return true; - } - } - start = i; - once = []; - for (;;) { - round = false; - for (i = start; i < v.length; i += 1) { - if (!once[i]) { - if (style_value(css_attribute_data[v[i]])) { - match = true; - round = true; - once[i] = true; - break; - } - } - } - if (!round) { - return match; - } - } - } - - function style_child() { - if (next_token.id === '(number)') { - advance(); - if (next_token.string === 'n' && next_token.identifier) { - no_space_only(); - advance(); - if (next_token.id === '+') { - no_space_only(); - advance('+'); - no_space_only(); - advance('(number)'); - } - } - return; - } else { - if (next_token.identifier && - (next_token.string === 'odd' || next_token.string === 'even')) { - advance(); - return; - } - } - warn('unexpected_a'); - } - - function substyle() { - var v; - for (;;) { - if (next_token.id === '}' || next_token.id === '(end)' || - (xquote && next_token.id === xquote)) { - return; - } - while (next_token.id === ';') { - warn('unexpected_a'); - semicolon(); - } - v = style_attribute(); - advance(':'); - if (next_token.identifier && next_token.string === 'inherit') { - advance(); - } else { - if (!style_value(v)) { - warn('unexpected_a'); - advance(); - } - } - if (next_token.id === '!') { - advance('!'); - no_space_only(); - if (next_token.identifier && next_token.string === 'important') { - advance(); - } else { - warn('expected_a_b', - next_token, 'important', next_token.string); - } - } - if (next_token.id === '}' || next_token.id === xquote) { - warn('expected_a_b', next_token, ';', next_token.string); - } else { - semicolon(); - } - } - } - - function style_selector() { - if (next_token.identifier) { - if (!Object.prototype.hasOwnProperty.call(html_tag, option.cap ? - next_token.string.toLowerCase() : next_token.string)) { - warn('expected_tagname_a'); - } - advance(); - } else { - switch (next_token.id) { - case '>': - case '+': - advance(); - style_selector(); - break; - case ':': - advance(':'); - switch (next_token.string) { - case 'active': - case 'after': - case 'before': - case 'checked': - case 'disabled': - case 'empty': - case 'enabled': - case 'first-child': - case 'first-letter': - case 'first-line': - case 'first-of-type': - case 'focus': - case 'hover': - case 'last-child': - case 'last-of-type': - case 'link': - case 'only-of-type': - case 'root': - case 'target': - case 'visited': - advance(); - break; - case 'lang': - advance(); - advance('('); - if (!next_token.identifier) { - warn('expected_lang_a'); - } - advance(')'); - break; - case 'nth-child': - case 'nth-last-child': - case 'nth-last-of-type': - case 'nth-of-type': - advance(); - advance('('); - style_child(); - advance(')'); - break; - case 'not': - advance(); - advance('('); - if (next_token.id === ':' && peek(0).string === 'not') { - warn('not'); - } - style_selector(); - advance(')'); - break; - default: - warn('expected_pseudo_a'); - } - break; - case '#': - advance('#'); - if (!next_token.identifier) { - warn('expected_id_a'); - } - advance(); - break; - case '*': - advance('*'); - break; - case '.': - advance('.'); - if (!next_token.identifier) { - warn('expected_class_a'); - } - advance(); - break; - case '[': - advance('['); - if (!next_token.identifier) { - warn('expected_attribute_a'); - } - advance(); - if (next_token.id === '=' || next_token.string === '~=' || - next_token.string === '$=' || - next_token.string === '|=' || - next_token.id === '*=' || - next_token.id === '^=') { - advance(); - if (next_token.id !== '(string)') { - warn('expected_string_a'); - } - advance(); - } - advance(']'); - break; - default: - stop('expected_selector_a'); - } - } - } - - function style_pattern() { - if (next_token.id === '{') { - warn('expected_style_pattern'); - } - for (;;) { - style_selector(); - if (next_token.id === '= 0) { - warn('unexpected_char_a_b', token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'class' || a === 'type' || a === 'name') { - x = v.search(qx); - if (x >= 0) { - warn('unexpected_char_a_b', token, v.charAt(x), a); - } - ids[u] = true; - } else if (a === 'href' || a === 'background' || - a === 'content' || a === 'data' || - a.indexOf('src') >= 0 || a.indexOf('url') >= 0) { - if (option.safe && ux.test(v)) { - stop('bad_url', next_token, v); - } - urls.push(v); - } else if (a === 'for') { - if (option.adsafe) { - if (adsafe_id) { - if (v.slice(0, adsafe_id.length) !== adsafe_id) { - warn('adsafe_prefix_a', next_token, adsafe_id); - } else if (!/^[A-Z]+_[A-Z]+$/.test(v)) { - warn('adsafe_bad_id'); - } - } else { - warn('adsafe_bad_id'); - } - } - } else if (a === 'name') { - if (option.adsafe && v.indexOf('_') >= 0) { - warn('adsafe_name_a', next_token, v); - } - } - } - - function do_tag(name, attribute) { - var i, tag = html_tag[name], script, x; - src = false; - if (!tag) { - stop( - bundle.unrecognized_tag_a, - next_token, - name === name.toLowerCase() ? name : name + ' (capitalization error)' - ); - } - if (stack.length > 0) { - if (name === 'html') { - stop('unexpected_a', token, name); - } - x = tag.parent; - if (x) { - if (x.indexOf(' ' + stack[stack.length - 1].name + ' ') < 0) { - stop('tag_a_in_b', token, name, x); - } - } else if (!option.adsafe && !option.fragment) { - i = stack.length; - do { - if (i <= 0) { - stop('tag_a_in_b', token, name, 'body'); - } - i -= 1; - } while (stack[i].name !== 'body'); - } - } - switch (name) { - case 'div': - if (option.adsafe && stack.length === 1 && !adsafe_id) { - warn('adsafe_missing_id'); - } - break; - case 'script': - xmode = 'script'; - advance('>'); - if (attribute.lang) { - warn('lang', token); - } - if (option.adsafe && stack.length !== 1) { - warn('adsafe_placement', token); - } - if (attribute.src) { - if (option.adsafe && (!adsafe_may || !approved[attribute.src])) { - warn('adsafe_source', token); - } - if (attribute.type) { - warn('type', token); - } - } else { - step_in(next_token.from); - edge(); - use_strict(); - adsafe_top = true; - script = statements(); - -// JSLint is also the static analyzer for ADsafe. See www.ADsafe.org. - - if (option.adsafe) { - if (adsafe_went) { - stop('adsafe_script', token); - } - if (script.length !== 1 || - aint(script[0], 'id', '(') || - aint(script[0].first, 'id', '.') || - aint(script[0].first.first, 'string', 'ADSAFE') || - aint(script[0].second[0], 'string', adsafe_id)) { - stop('adsafe_id_go'); - } - switch (script[0].first.second.string) { - case 'id': - if (adsafe_may || adsafe_went || - script[0].second.length !== 1) { - stop('adsafe_id', next_token); - } - adsafe_may = true; - break; - case 'go': - if (adsafe_went) { - stop('adsafe_go'); - } - if (script[0].second.length !== 2 || - aint(script[0].second[1], 'id', 'function') || - !script[0].second[1].first || - script[0].second[1].first.length !== 2 || - aint(script[0].second[1].first[0], 'string', 'dom') || - aint(script[0].second[1].first[1], 'string', 'lib')) { - stop('adsafe_go', next_token); - } - adsafe_went = true; - break; - default: - stop('adsafe_id_go'); - } - } - indent = null; - } - xmode = 'html'; - advance(''); - styles(); - xmode = 'html'; - advance(''; - } - - function html() { - - /*jslint confusion: true */ - - var attribute, attributes, is_empty, name, old_white = option.white, - quote, tag_name, tag, wmode; - xmode = 'html'; - xquote = ''; - stack = null; - for (;;) { - switch (next_token.string) { - case '<': - xmode = 'html'; - advance('<'); - attributes = {}; - tag_name = next_token; - if (!tag_name.identifier) { - warn('bad_name_a', tag_name); - } - name = tag_name.string; - if (option.cap) { - name = name.toLowerCase(); - } - tag_name.name = name; - advance(); - if (!stack) { - stack = []; - do_begin(name); - } - tag = html_tag[name]; - if (typeof tag !== 'object') { - stop('unrecognized_tag_a', tag_name, name); - } - is_empty = tag.empty; - tag_name.type = name; - for (;;) { - if (next_token.id === '/') { - advance('/'); - if (next_token.id !== '>') { - warn('expected_a_b', next_token, '>', next_token.string); - } - break; - } - if (next_token.id && next_token.id.charAt(0) === '>') { - break; - } - if (!next_token.identifier) { - if (next_token.id === '(end)' || next_token.id === '(error)') { - warn('expected_a_b', next_token, '>', next_token.string); - } - warn('bad_name_a'); - } - option.white = false; - spaces(); - attribute = next_token.string; - option.white = old_white; - advance(); - if (!option.cap && attribute !== attribute.toLowerCase()) { - warn('attribute_case_a', token); - } - attribute = attribute.toLowerCase(); - xquote = ''; - if (Object.prototype.hasOwnProperty.call(attributes, attribute)) { - warn('duplicate_a', token, attribute); - } - if (attribute.slice(0, 2) === 'on') { - if (!option.on) { - warn('html_handlers'); - } - xmode = 'scriptstring'; - advance('='); - quote = next_token.id; - if (quote !== '"' && quote !== '\'') { - stop('expected_a_b', next_token, '"', next_token.string); - } - xquote = quote; - wmode = option.white; - option.white = true; - advance(quote); - use_strict(); - statements(); - option.white = wmode; - if (next_token.id !== quote) { - stop('expected_a_b', next_token, quote, next_token.string); - } - xmode = 'html'; - xquote = ''; - advance(quote); - tag = false; - } else if (attribute === 'style') { - xmode = 'scriptstring'; - advance('='); - quote = next_token.id; - if (quote !== '"' && quote !== '\'') { - stop('expected_a_b', next_token, '"', next_token.string); - } - xmode = 'styleproperty'; - xquote = quote; - advance(quote); - substyle(); - xmode = 'html'; - xquote = ''; - advance(quote); - tag = false; - } else { - if (next_token.id === '=') { - advance('='); - tag = next_token.string; - if (!next_token.identifier && - next_token.id !== '"' && - next_token.id !== '\'' && - next_token.id !== '(string)' && - next_token.id !== '(string)' && - next_token.id !== '(color)') { - warn('expected_attribute_value_a', token, attribute); - } - advance(); - } else { - tag = true; - } - } - attributes[attribute] = tag; - do_attribute(attribute, tag); - } - do_tag(name, attributes); - if (!is_empty) { - stack.push(tag_name); - } - xmode = 'outer'; - advance('>'); - break; - case '') { - stop('expected_a_b', next_token, '>', next_token.string); - } - xmode = 'outer'; - advance('>'); - break; - case '' || next_token.id === '(end)') { - break; - } - if (next_token.string.indexOf('--') >= 0) { - stop('unexpected_a', next_token, '--'); - } - if (next_token.string.indexOf('<') >= 0) { - stop('unexpected_a', next_token, '<'); - } - if (next_token.string.indexOf('>') >= 0) { - stop('unexpected_a', next_token, '>'); - } - } - xmode = 'outer'; - advance('>'); - break; - case '(end)': - return; - default: - if (next_token.id === '(end)') { - stop('missing_a', next_token, - ''); - } else { - advance(); - } - } - if (stack && stack.length === 0 && (option.adsafe || - !option.fragment || next_token.id === '(end)')) { - break; - } - } - if (next_token.id !== '(end)') { - stop('unexpected_a'); - } - } - - -// The actual JSLINT function itself. - - itself = function JSLint(the_source, the_option) { - - var i, predef, tree; - JSLINT.comments = []; - JSLINT.errors = []; - JSLINT.tree = ''; - begin = older_token = prev_token = token = next_token = - Object.create(syntax['(begin)']); - predefined = {}; - add_to_predefined(standard); - property_type = Object.create(standard_property_type); - if (the_option) { - option = Object.create(the_option); - predef = option.predef; - if (predef) { - if (Array.isArray(predef)) { - for (i = 0; i < predef.length; i += 1) { - predefined[predef[i]] = true; - } - } else if (typeof predef === 'object') { - add_to_predefined(predef); - } - } - do_safe(); - } else { - option = {}; - } - option.indent = +option.indent || 0; - option.maxerr = option.maxerr || 50; - adsafe_id = ''; - adsafe_may = adsafe_top = adsafe_went = false; - approved = {}; - if (option.approved) { - for (i = 0; i < option.approved.length; i += 1) { - approved[option.approved[i]] = option.approved[i]; - } - } else { - approved.test = 'test'; - } - tab = ''; - for (i = 0; i < option.indent; i += 1) { - tab += ' '; - } - global_scope = scope = {}; - global_funct = funct = { - '(scope)': scope, - '(breakage)': 0, - '(loopage)': 0 - }; - functions = [funct]; - - comments_off = false; - ids = {}; - in_block = false; - indent = null; - json_mode = false; - lookahead = []; - member = {}; - node_js = false; - prereg = true; - src = false; - stack = null; - strict_mode = false; - urls = []; - var_mode = null; - warnings = 0; - xmode = ''; - lex.init(the_source); - - assume(); - - try { - advance(); - if (next_token.id === '(number)') { - stop('unexpected_a'); - } else if (next_token.string.charAt(0) === '<') { - html(); - if (option.adsafe && !adsafe_went) { - warn('adsafe_go', this); - } - } else { - switch (next_token.id) { - case '{': - case '[': - json_mode = true; - json_value(); - break; - case '@': - case '*': - case '#': - case '.': - case ':': - xmode = 'style'; - advance(); - if (token.id !== '@' || !next_token.identifier || - next_token.string !== 'charset' || token.line !== 1 || - token.from !== 1) { - stop('css'); - } - advance(); - if (next_token.id !== '(string)' && - next_token.string !== 'UTF-8') { - stop('css'); - } - advance(); - semicolon(); - styles(); - break; - - default: - if (option.adsafe && option.fragment) { - stop('expected_a_b', - next_token, '
', next_token.string); - } - -// If the first token is predef semicolon, ignore it. This is sometimes used when -// files are intended to be appended to files that may be sloppy. predef sloppy -// file may be depending on semicolon insertion on its last line. - - step_in(1); - if (next_token.id === ';' && !node_js) { - semicolon(); - } - adsafe_top = true; - tree = statements(); - begin.first = tree; - JSLINT.tree = begin; - if (option.adsafe && (tree.length !== 1 || - aint(tree[0], 'id', '(') || - aint(tree[0].first, 'id', '.') || - aint(tree[0].first.first, 'string', 'ADSAFE') || - aint(tree[0].first.second, 'string', 'lib') || - tree[0].second.length !== 2 || - tree[0].second[0].id !== '(string)' || - aint(tree[0].second[1], 'id', 'function'))) { - stop('adsafe_lib'); - } - if (tree.disrupt) { - warn('weird_program', prev_token); - } - } - } - indent = null; - advance('(end)'); - } catch (e) { - if (e) { // `~ - JSLINT.errors.push({ - reason : e.message, - line : e.line || next_token.line, - character : e.character || next_token.from - }, null); - } - } - return JSLINT.errors.length === 0; - }; - - -// Data summary. - - itself.data = function () { - var data = {functions: []}, - function_data, - globals, - i, - j, - kind, - members = [], - name, - the_function, - undef = [], - unused = []; - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (json_mode) { - data.json = true; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(global_scope).filter(function (value) { - return value.charAt(0) !== '(' && typeof standard[value] !== 'boolean'; - }); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - the_function = functions[i]; - function_data = {}; - for (j = 0; j < functionicity.length; j += 1) { - function_data[functionicity[j]] = []; - } - for (name in the_function) { - if (Object.prototype.hasOwnProperty.call(the_function, name)) { - if (name.charAt(0) !== '(') { - kind = the_function[name]; - if (kind === 'unction' || kind === 'unparam') { - kind = 'unused'; - } - if (Array.isArray(function_data[kind])) { - function_data[kind].push(name); - if (kind === 'unused') { - unused.push({ - name: name, - line: the_function['(line)'], - 'function': the_function['(name)'] - }); - } else if (kind === 'undef') { - undef.push({ - name: name, - line: the_function['(line)'], - 'function': the_function['(name)'] - }); - } - } - } - } - } - for (j = 0; j < functionicity.length; j += 1) { - if (function_data[functionicity[j]].length === 0) { - delete function_data[functionicity[j]]; - } - } - function_data.name = the_function['(name)']; - function_data.params = the_function['(params)']; - function_data.line = the_function['(line)']; - function_data['(complexity)'] = the_function['(complexity)']; - data.functions.push(function_data); - } - - if (unused.length > 0) { - data.unused = unused; - } - if (undef.length > 0) { - data['undefined'] = undef; - } - - members = []; - for (name in member) { - if (typeof member[name] === 'number') { - data.member = member; - break; - } - } - - return data; - }; - - - itself.report = function (errors_only) { - var data = itself.data(), err, evidence, i, italics, j, key, keys, length, - mem = '', name, names, output = [], snippets, the_function, type, - warning; - - function detail(h, value) { - var comma_needed, singularity; - if (Array.isArray(value)) { - output.push('
' + h + ' '); - value.sort().forEach(function (item) { - if (item !== singularity) { - singularity = item; - output.push((comma_needed ? ', ' : '') + singularity); - comma_needed = true; - } - }); - output.push('
'); - } else if (value) { - output.push('
' + h + ' ' + value + '
'); - } - } - - if (data.errors || data.unused || data['undefined']) { - err = true; - output.push('
Error:'); - if (data.errors) { - for (i = 0; i < data.errors.length; i += 1) { - warning = data.errors[i]; - if (warning) { - evidence = warning.evidence || ''; - output.push('

Problem' + (isFinite(warning.line) ? - ' at line ' + String(warning.line) + ' character ' + - String(warning.character) : '') + - ': ' + warning.reason.entityify() + - '

' + - (evidence && (evidence.length > 80 ? evidence.slice(0, 77) + '...' : - evidence).entityify()) + '

'); - } - } - } - - if (data['undefined']) { - snippets = []; - for (i = 0; i < data['undefined'].length; i += 1) { - snippets[i] = '' + data['undefined'][i].name + ' ' + - String(data['undefined'][i].line) + ' ' + - data['undefined'][i]['function'] + ''; - } - output.push('

Undefined variable: ' + snippets.join(', ') + '

'); - } - if (data.unused) { - snippets = []; - for (i = 0; i < data.unused.length; i += 1) { - snippets[i] = '' + data.unused[i].name + ' ' + - String(data.unused[i].line) + ' ' + - data.unused[i]['function'] + ''; - } - output.push('

Unused variable: ' + snippets.join(', ') + '

'); - } - if (data.json) { - output.push('

JSON: bad.

'); - } - output.push('
'); - } - - if (!errors_only) { - - output.push('
'); - - if (data.urls) { - detail("URLs
", data.urls, '
'); - } - - if (xmode === 'style') { - output.push('

CSS.

'); - } else if (data.json && !err) { - output.push('

JSON: good.

'); - } else if (data.globals) { - output.push('
Global ' + - data.globals.sort().join(', ') + '
'); - } else { - output.push('
No new global variables introduced.
'); - } - - for (i = 0; i < data.functions.length; i += 1) { - the_function = data.functions[i]; - names = []; - if (the_function.params) { - for (j = 0; j < the_function.params.length; j += 1) { - names[j] = the_function.params[j].string; - } - } - output.push('
' + - String(the_function.line) + ' ' + - the_function.name.entityify() + - '(' + names.join(', ') + ')
'); - detail('Undefined', the_function['undefined']); - detail('Unused', the_function.unused); - detail('Closure', the_function.closure); - detail('Variable', the_function['var']); - detail('Exception', the_function.exception); - detail('Outer', the_function.outer); - detail('Global', the_function.global); - detail('Label', the_function.label); - detail('Complexity', the_function['(complexity)']); - } - - if (data.member) { - keys = Object.keys(data.member); - if (keys.length) { - keys = keys.sort(); - output.push('
/*properties
'); - mem = ' '; - italics = 0; - j = 0; - if (option.confusion) { - for (i = 0; i < keys.length; i += 1) { - key = keys[i]; - if (typeof standard_property_type[key] !== 'string') { - name = ix.test(key) ? key : - '\'' + key.entityify().replace(nx, sanitize) + '\''; - if (data.member[key] === 1) { - name = '' + name + ''; - italics += 1; - j = 1; - } - if (i < keys.length - 1) { - name += ', '; - } - if (mem.length + name.length - (italics * 7) > 80) { - output.push(mem + '
'); - mem = ' '; - italics = j; - } - mem += name; - j = 0; - } - } - } else { - for (i = 0; i < keys.length; i += 1) { - key = keys[i]; - type = property_type[key]; - if (typeof type !== 'string') { - type = ''; - } - if (standard_property_type[key] !== type) { - name = ix.test(key) ? key : - '\'' + key.entityify().replace(nx, sanitize) + '\''; - length += name.length + 2; - if (data.member[key] === 1) { - name = '' + name + ''; - italics += 1; - j = 1; - } - if (type) { - name += ': ' + type; - } - if (i < keys.length - 1) { - name += ', '; - } - if (mem.length + name.length - (italics * 7) > 80) { - output.push(mem + '
'); - mem = ' '; - italics = j; - } - mem += name; - j = 0; - } - } - } - output.push(mem + '
*/
'); - } - output.push('
'); - } - } - return output.join(''); - }; - itself.jslint = itself; - - itself.edition = '2011-07-04'; - - return itself; - -}()); \ No newline at end of file