diff --git a/tools/lint/eslint.yml b/tools/lint/eslint.yml index 569423990b8c..627cd1a658a6 100644 --- a/tools/lint/eslint.yml +++ b/tools/lint/eslint.yml @@ -4,7 +4,7 @@ eslint: # ESLint infra handles its own path filtering, so just include cwd include: ['.'] exclude: [] - extensions: ['js', 'jsm', 'jsx', 'xml', 'xul', 'html', 'xhtml'] + extensions: ['js', 'jsm', 'jsx', 'xul', 'html', 'xhtml'] support-files: - '**/.eslintrc.js' - '.eslintignore' diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index 787ac8352e52..0eecf34b9308 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -50,14 +50,6 @@ module.exports = { }, overrides: [ - { - // Turn off use-services for xml files. XBL bindings are going away, and - // working out the valid globals for those is difficult. - files: "**/*.xml", - rules: { - "mozilla/use-services": "off", - }, - }, { // We don't have the general browser environment for jsm files, but we do // have our own special environments for them. diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js index 265713a6562f..9d297db9b693 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js @@ -28,7 +28,6 @@ module.exports = { privileged: require("../lib/environments/privileged.js"), }, processors: { - ".xml": require("../lib/processors/xbl-bindings"), ".xul": require("../lib/processors/xul"), }, rules: { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xbl-bindings.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xbl-bindings.js deleted file mode 100644 index 8d1fd2e11ae9..000000000000 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xbl-bindings.js +++ /dev/null @@ -1,301 +0,0 @@ -/** - * @fileoverview Converts functions and handlers from XBL bindings into JS - * functions - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -"use strict"; - -const NS_XBL = "http://www.mozilla.org/xbl"; - -let XMLParser = require("./processor-helpers").XMLParser; - -// ----------------------------------------------------------------------------- -// Processor Definition -// ----------------------------------------------------------------------------- - -// Stores any XML parse error -let xmlParseError = null; - -// Stores the lines of JS code generated from the XBL -let scriptLines = []; -// Stores a map from the synthetic line number to the real line number -// and column offset. -let lineMap = []; - -function addSyntheticLine(line, linePos, addDisableLine) { - lineMap[scriptLines.length] = { line: linePos, offset: null }; - scriptLines.push(line + (addDisableLine ? "" : " // eslint-disable-line")); -} - -/** - * Adds generated lines from an XBL node to the script to be passed back to - * eslint. - */ -function addNodeLines(node, reindent) { - let lines = node.textContent.split("\n"); - let startLine = node.textLine; - let startColumn = node.textColumn; - - // The case where there are no whitespace lines before the first text is - // treated differently for indentation - let indentFirst = false; - - // Strip off any preceding whitespace only lines. These are often used to - // format the XML and CDATA blocks. - while (lines.length && lines[0].trim() == "") { - indentFirst = true; - startLine++; - lines.shift(); - } - - // Remember the indent of the last blank line, which is the closing part of - // the CDATA block. - let lastIndent = 0; - if (lines.length && lines[lines.length - 1].trim() == "") { - lastIndent = lines[lines.length - 1].length; - } - - // If the second to last line is also blank and has a higher indent than the - // last one, then the CDATA block doesn't close with the closing tag. - if ( - lines.length > 2 && - lines[lines.length - 2].trim() == "" && - lines[lines.length - 2].length > lastIndent - ) { - lastIndent = lines[lines.length - 2].length; - } - - // Strip off any whitespace lines at the end. These are often used to line - // up the closing tags - while (lines.length && lines[lines.length - 1].trim() == "") { - lines.pop(); - } - - if (!indentFirst) { - let firstLine = lines.shift(); - // ESLint counts columns starting at 1 rather than 0 - lineMap[scriptLines.length] = { line: startLine, offset: startColumn - 1 }; - scriptLines.push(firstLine); - startLine++; - } - - // Find the preceding whitespace for all lines that aren't entirely - // whitespace. - let indents = lines - .filter(s => s.trim().length > 0) - .map(s => s.length - s.trimLeft().length); - // Find the smallest indent level in use - let minIndent = Math.min.apply(null, indents); - let indent = Math.max(2, minIndent - lastIndent); - - for (let line of lines) { - if (line.trim().length == 0) { - // Don't offset lines that are only whitespace, the only possible JS error - // is trailing whitespace and we want it to point at the right place - lineMap[scriptLines.length] = { line: startLine, offset: 0 }; - } else { - line = " ".repeat(indent) + line.substring(minIndent); - lineMap[scriptLines.length] = { - line: startLine, - offset: 1 + indent - minIndent, - }; - } - - scriptLines.push(line); - startLine++; - } -} - -module.exports = { - preprocess(text, filename) { - xmlParseError = null; - scriptLines = []; - lineMap = []; - - let xp = new XMLParser(text); - if (xp.lastError) { - xmlParseError = xp.lastError; - } - - // Sanity checks to make sure we're dealing with an XBL document - let document = xp.document; - if (document.children.length != 1) { - return []; - } - - let bindings = document.children[0]; - if (bindings.local != "bindings" || bindings.namespace != NS_XBL) { - return []; - } - - for (let comment of document.comments) { - addSyntheticLine(`/*`, 0, true); - for (let line of comment.split("\n")) { - addSyntheticLine(`${line.trim()}`, 0, true); - } - addSyntheticLine(`*/`, 0, true); - } - - addSyntheticLine(`this.bindings = {`, bindings.textLine); - - for (let binding of bindings.children) { - if (binding.local != "binding" || binding.namespace != NS_XBL) { - continue; - } - - addSyntheticLine(`"${binding.attributes.id}": {`, binding.textLine); - - for (let part of binding.children) { - if (part.namespace != NS_XBL) { - continue; - } - - if (part.local == "implementation") { - addSyntheticLine(`implementation: {`, part.textLine); - } else if (part.local == "handlers") { - addSyntheticLine(`handlers: [`, part.textLine); - } else { - continue; - } - - for (let item of part.children) { - if (item.namespace != NS_XBL) { - continue; - } - - switch (item.local) { - case "field": { - // Fields are something like lazy getter functions - - // Ignore empty fields - if (item.textContent.trim().length == 0) { - continue; - } - - addSyntheticLine( - `get ${item.attributes.name}() {`, - item.textLine - ); - addSyntheticLine(`return (`, item.textLine); - - // Remove trailing semicolons, as we are adding our own - item.textContent = item.textContent.replace(/;(?=\s*$)/, ""); - addNodeLines(item, 5); - - addSyntheticLine(`);`, item.textLine); - addSyntheticLine(`},`, item.textEndLine); - break; - } - case "constructor": - case "destructor": { - // Constructors and destructors become function declarations - addSyntheticLine(`${item.local}() {`, item.textLine); - addNodeLines(item, 4); - addSyntheticLine(`},`, item.textEndLine); - break; - } - case "method": { - // Methods become function declarations with the appropriate - // params. - - let params = item.children - .filter(n => { - return n.local == "parameter" && n.namespace == NS_XBL; - }) - .map(n => n.attributes.name) - .join(", "); - let body = item.children.filter(n => { - return n.local == "body" && n.namespace == NS_XBL; - })[0]; - - addSyntheticLine( - `${item.attributes.name}(${params}) {`, - item.textLine - ); - addNodeLines(body, 4); - addSyntheticLine(`},`, item.textEndLine); - break; - } - case "property": { - // Properties become one or two function declarations - for (let propdef of item.children) { - if (propdef.namespace != NS_XBL) { - continue; - } - - if (propdef.local == "setter") { - addSyntheticLine( - `set ${item.attributes.name}(val) {`, - propdef.textLine - ); - } else if (propdef.local == "getter") { - addSyntheticLine( - `get ${item.attributes.name}() {`, - propdef.textLine - ); - } else { - continue; - } - addNodeLines(propdef, 4); - addSyntheticLine(`},`, propdef.textEndLine); - } - break; - } - case "handler": { - // Handlers become a function declaration with an `event` - // parameter. - addSyntheticLine(`function(event) {`, item.textLine); - addNodeLines(item, 4); - addSyntheticLine(`},`, item.textEndLine); - break; - } - default: - continue; - } - } - - addSyntheticLine( - part.local == "implementation" ? `},` : `],`, - part.textEndLine - ); - } - addSyntheticLine(`},`, binding.textEndLine); - } - addSyntheticLine(`};`, bindings.textEndLine); - - let script = scriptLines.join("\n") + "\n"; - return [script]; - }, - - postprocess(messages, filename) { - // If there was an XML parse error then just return that - if (xmlParseError) { - return [xmlParseError]; - } - - // For every message from every script block update the line to point to the - // correct place. - let errors = []; - for (let i = 0; i < messages.length; i++) { - for (let message of messages[i]) { - // ESLint indexes lines starting at 1 but our arrays start at 0 - let mapped = lineMap[message.line - 1]; - - message.line = mapped.line + 1; - if (mapped.offset) { - message.column -= mapped.offset; - } else { - message.column = NaN; - } - - errors.push(message); - } - } - - return errors; - }, -}; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xul.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xul.js index f6adf90cf238..c486b38e0669 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xul.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/processors/xul.js @@ -17,7 +17,7 @@ let XMLParser = require("./processor-helpers").XMLParser; // Stores any XML parse error let xmlParseError = null; -// Stores the lines of JS code generated from the XBL +// Stores the lines of JS code generated from the XUL. let scriptLines = []; // Stores a map from the synthetic line number to the real line number // and column offset. diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json index a7d0abf8fcc4..ea6206483bab 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "2.2.0", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index fd1f35edf788..31f80b81af36 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "2.2.0", + "version": "2.3.0", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint",