зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1561435 - Format tools/, a=automatic-formatting
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35940 --HG-- extra : source : d214f0c82813e5a8d3987debc490a2c11f1308ff
This commit is contained in:
Родитель
336c4fb8a4
Коммит
5c7cdbd4ba
|
@ -45,7 +45,6 @@ module.exports = {
|
|||
"overrides": [{
|
||||
"files": [
|
||||
"devtools/**",
|
||||
"tools/**",
|
||||
"uriloader/**",
|
||||
"view/**",
|
||||
"widget/**",
|
||||
|
|
|
@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
|
|||
toolkit/components/telemetry/healthreport-prefs.js
|
||||
|
||||
# Ignore all top-level directories for now.
|
||||
tools/**
|
||||
uriloader/**
|
||||
view/**
|
||||
widget/**
|
||||
|
|
|
@ -10,7 +10,9 @@ var EXPORTED_SYMBOLS = ["PerTestCoverageUtils"];
|
|||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
const env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
// This is the directory where gcov is emitting the gcda files.
|
||||
const gcovPrefixPath = env.get("GCOV_PREFIX");
|
||||
// This is the directory where codecoverage.py is expecting to see the gcda files.
|
||||
|
@ -20,7 +22,9 @@ const jsvmPrefixPath = env.get("JS_CODE_COVERAGE_OUTPUT_DIR");
|
|||
// This is the directory where codecoverage.py is expecting to see the lcov files.
|
||||
const jsvmResultsPath = env.get("JSVM_RESULTS_DIR");
|
||||
|
||||
const gcovPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
const gcovPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(
|
||||
Ci.nsIFile
|
||||
);
|
||||
if (gcovPrefixPath) {
|
||||
gcovPrefixDir.initWithPath(gcovPrefixPath);
|
||||
}
|
||||
|
@ -30,7 +34,9 @@ if (gcovResultsPath) {
|
|||
gcovResultsDir.initWithPath(gcovResultsPath);
|
||||
}
|
||||
|
||||
const jsvmPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
const jsvmPrefixDir = Cc["@mozilla.org/file/local;1"].createInstance(
|
||||
Ci.nsIFile
|
||||
);
|
||||
if (jsvmPrefixPath) {
|
||||
jsvmPrefixDir.initWithPath(jsvmPrefixPath);
|
||||
}
|
||||
|
@ -44,7 +50,9 @@ function awaitPromise(promise) {
|
|||
let ret;
|
||||
let complete = false;
|
||||
let error = null;
|
||||
promise.catch(e => error = e).then(v => {
|
||||
promise
|
||||
.catch(e => (error = e))
|
||||
.then(v => {
|
||||
ret = v;
|
||||
complete = true;
|
||||
});
|
||||
|
@ -77,7 +85,9 @@ var PerTestCoverageUtils = class PerTestCoverageUtilsClass {
|
|||
}
|
||||
|
||||
// Flush the counters.
|
||||
let codeCoverageService = Cc["@mozilla.org/tools/code-coverage;1"].getService(Ci.nsICodeCoverage);
|
||||
let codeCoverageService = Cc[
|
||||
"@mozilla.org/tools/code-coverage;1"
|
||||
].getService(Ci.nsICodeCoverage);
|
||||
await codeCoverageService.flushCounters();
|
||||
|
||||
// Remove coverage files created by the flush, and those that might have been created between the end of a previous test and the beginning of the next one (e.g. some tests can create a new content process for every sub-test).
|
||||
|
@ -100,7 +110,9 @@ var PerTestCoverageUtils = class PerTestCoverageUtilsClass {
|
|||
}
|
||||
|
||||
// Flush the counters.
|
||||
let codeCoverageService = Cc["@mozilla.org/tools/code-coverage;1"].getService(Ci.nsICodeCoverage);
|
||||
let codeCoverageService = Cc[
|
||||
"@mozilla.org/tools/code-coverage;1"
|
||||
].getService(Ci.nsICodeCoverage);
|
||||
await codeCoverageService.flushCounters();
|
||||
|
||||
// Move the coverage files in GCOV_RESULTS_DIR and JSVM_RESULTS_DIR, so that the execution from now to shutdown (or next test) is not counted.
|
||||
|
|
|
@ -2,15 +2,21 @@
|
|||
* 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/. */
|
||||
|
||||
var {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
var { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
var { OS, require } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
function getFiles() {
|
||||
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
const env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
// This is the directory where gcov is emitting the gcda files.
|
||||
const jsCoveragePath = env.get("JS_CODE_COVERAGE_OUTPUT_DIR");
|
||||
|
||||
const jsCoverageDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
const jsCoverageDir = Cc["@mozilla.org/file/local;1"].createInstance(
|
||||
Ci.nsIFile
|
||||
);
|
||||
jsCoverageDir.initWithPath(jsCoveragePath);
|
||||
|
||||
let files = [];
|
||||
|
@ -47,9 +53,9 @@ function parseRecords(files) {
|
|||
|
||||
let [hits, name] = recordContent.split(",");
|
||||
currentSF.push({
|
||||
"type": "FNDA",
|
||||
"hits": hits,
|
||||
"name": name,
|
||||
type: "FNDA",
|
||||
hits,
|
||||
name,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -61,8 +67,8 @@ function parseRecords(files) {
|
|||
|
||||
let name = recordContent.split(",")[1];
|
||||
currentSF.push({
|
||||
"type": "FN",
|
||||
"name": name,
|
||||
type: "FN",
|
||||
name,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -29,19 +29,41 @@ async function run_test() {
|
|||
await codeCoverage.flushCounters();
|
||||
|
||||
const first_flush_files = getFiles();
|
||||
const first_flush_records = parseRecords(diffFiles(first_flush_files, files_orig));
|
||||
const first_flush_records = parseRecords(
|
||||
diffFiles(first_flush_files, files_orig)
|
||||
);
|
||||
|
||||
Assert.ok(first_flush_records.has("test_basic.js"));
|
||||
let fnRecords = first_flush_records.get("test_basic.js").filter(record => record.type == "FN");
|
||||
let fndaRecords = first_flush_records.get("test_basic.js").filter(record => record.type == "FNDA");
|
||||
let fnRecords = first_flush_records
|
||||
.get("test_basic.js")
|
||||
.filter(record => record.type == "FN");
|
||||
let fndaRecords = first_flush_records
|
||||
.get("test_basic.js")
|
||||
.filter(record => record.type == "FNDA");
|
||||
Assert.ok(fnRecords.some(record => record.name == "top-level"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "run_test"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func1"));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "run_test" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "run_test" && record.hits != 1));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits != 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func2"));
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func1")
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(record => record.name == "run_test" && record.hits == 1)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(record => record.name == "run_test" && record.hits != 1)
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits == 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits != 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(record => record.name == "test_code_coverage_func2")
|
||||
);
|
||||
|
||||
test_code_coverage_func2();
|
||||
|
||||
|
@ -49,19 +71,45 @@ async function run_test() {
|
|||
await codeCoverage.flushCounters();
|
||||
|
||||
const second_flush_files = getFiles();
|
||||
const second_flush_records = parseRecords(diffFiles(second_flush_files, first_flush_files));
|
||||
const second_flush_records = parseRecords(
|
||||
diffFiles(second_flush_files, first_flush_files)
|
||||
);
|
||||
|
||||
Assert.ok(second_flush_records.has("test_basic.js"));
|
||||
fnRecords = second_flush_records.get("test_basic.js").filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records.get("test_basic.js").filter(record => record.type == "FNDA");
|
||||
fnRecords = second_flush_records
|
||||
.get("test_basic.js")
|
||||
.filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records
|
||||
.get("test_basic.js")
|
||||
.filter(record => record.type == "FNDA");
|
||||
Assert.ok(fnRecords.some(record => record.name == "top-level"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "run_test"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func1"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func2"));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits == 0));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits != 0));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func2" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func2" && record.hits != 1));
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func1")
|
||||
);
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func2")
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits == 0
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits != 0
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func2" && record.hits == 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func2" && record.hits != 1
|
||||
)
|
||||
);
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ async function run_test() {
|
|||
do_load_child_test_harness();
|
||||
do_test_pending();
|
||||
|
||||
const codeCoverage = Cc["@mozilla.org/tools/code-coverage;1"].getService(Ci.nsICodeCoverage);
|
||||
const codeCoverage = Cc["@mozilla.org/tools/code-coverage;1"].getService(
|
||||
Ci.nsICodeCoverage
|
||||
);
|
||||
|
||||
const files_orig = getFiles();
|
||||
|
||||
|
@ -19,43 +21,99 @@ async function run_test() {
|
|||
await codeCoverage.flushCounters();
|
||||
|
||||
const first_flush_files = getFiles();
|
||||
const first_flush_records = parseRecords(diffFiles(first_flush_files, files_orig));
|
||||
const first_flush_records = parseRecords(
|
||||
diffFiles(first_flush_files, files_orig)
|
||||
);
|
||||
|
||||
Assert.ok(first_flush_records.has("test_basic_child_and_parent.js"));
|
||||
Assert.ok(!first_flush_records.has("support.js"));
|
||||
let fnRecords = first_flush_records.get("test_basic_child_and_parent.js").filter(record => record.type == "FN");
|
||||
let fndaRecords = first_flush_records.get("test_basic_child_and_parent.js").filter(record => record.type == "FNDA");
|
||||
let fnRecords = first_flush_records
|
||||
.get("test_basic_child_and_parent.js")
|
||||
.filter(record => record.type == "FN");
|
||||
let fndaRecords = first_flush_records
|
||||
.get("test_basic_child_and_parent.js")
|
||||
.filter(record => record.type == "FNDA");
|
||||
Assert.ok(fnRecords.some(record => record.name == "top-level"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "run_test"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func1"));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "run_test" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "run_test" && record.hits != 1));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits != 1));
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func1")
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(record => record.name == "run_test" && record.hits == 1)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(record => record.name == "run_test" && record.hits != 1)
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits == 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits != 1
|
||||
)
|
||||
);
|
||||
|
||||
sendCommand("load('support.js');", async function() {
|
||||
await codeCoverage.flushCounters();
|
||||
|
||||
const second_flush_files = getFiles();
|
||||
const second_flush_records = parseRecords(diffFiles(second_flush_files, first_flush_files));
|
||||
const second_flush_records = parseRecords(
|
||||
diffFiles(second_flush_files, first_flush_files)
|
||||
);
|
||||
|
||||
Assert.ok(second_flush_records.has("test_basic_child_and_parent.js"));
|
||||
fnRecords = second_flush_records.get("test_basic_child_and_parent.js").filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records.get("test_basic_child_and_parent.js").filter(record => record.type == "FNDA");
|
||||
fnRecords = second_flush_records
|
||||
.get("test_basic_child_and_parent.js")
|
||||
.filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records
|
||||
.get("test_basic_child_and_parent.js")
|
||||
.filter(record => record.type == "FNDA");
|
||||
Assert.ok(fnRecords.some(record => record.name == "top-level"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "run_test"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func1"));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits == 0));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func1" && record.hits != 0));
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func1")
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits == 0
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func1" && record.hits != 0
|
||||
)
|
||||
);
|
||||
Assert.ok(second_flush_records.has("support.js"));
|
||||
fnRecords = second_flush_records.get("support.js").filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records.get("support.js").filter(record => record.type == "FNDA");
|
||||
fnRecords = second_flush_records
|
||||
.get("support.js")
|
||||
.filter(record => record.type == "FN");
|
||||
fndaRecords = second_flush_records
|
||||
.get("support.js")
|
||||
.filter(record => record.type == "FNDA");
|
||||
Assert.ok(fnRecords.some(record => record.name == "top-level"));
|
||||
Assert.ok(fnRecords.some(record => record.name == "test_code_coverage_func2"));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "top-level" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "top-level" && record.hits != 1));
|
||||
Assert.ok(fndaRecords.some(record => record.name == "test_code_coverage_func2" && record.hits == 1));
|
||||
Assert.ok(!fndaRecords.some(record => record.name == "test_code_coverage_func2" && record.hits != 1));
|
||||
Assert.ok(
|
||||
fnRecords.some(record => record.name == "test_code_coverage_func2")
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(record => record.name == "top-level" && record.hits == 1)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "top-level" && record.hits != 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func2" && record.hits == 1
|
||||
)
|
||||
);
|
||||
Assert.ok(
|
||||
!fndaRecords.some(
|
||||
record => record.name == "test_code_coverage_func2" && record.hits != 1
|
||||
)
|
||||
);
|
||||
|
||||
do_test_finished();
|
||||
});
|
||||
|
|
|
@ -2,64 +2,62 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
env: {
|
||||
browser: true,
|
||||
"mozilla/browser-window": true,
|
||||
"mozilla/simpletest": true,
|
||||
// "node": true
|
||||
},
|
||||
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
globals: {
|
||||
// `$` is defined in SimpleTest.js
|
||||
"$": false,
|
||||
"Assert": false,
|
||||
"BrowserTestUtils": false,
|
||||
"ContentTask": false,
|
||||
"ContentTaskUtils": false,
|
||||
"EventUtils": false,
|
||||
"PromiseDebugging": false,
|
||||
"SpecialPowers": false,
|
||||
"TestUtils": false,
|
||||
"XPCNativeWrapper": false,
|
||||
"XULDocument": false,
|
||||
"addLoadEvent": false,
|
||||
"add_task": false,
|
||||
"content": false,
|
||||
"executeSoon": false,
|
||||
"expectUncaughtException": false,
|
||||
"export_assertions": false,
|
||||
"extractJarToTmp": false,
|
||||
"finish": false,
|
||||
"gTestPath": false,
|
||||
"getChromeDir": false,
|
||||
"getJar": false,
|
||||
"getResolvedURI": false,
|
||||
"getRootDirectory": false,
|
||||
"getTestFilePath": false,
|
||||
"ignoreAllUncaughtExceptions": false,
|
||||
"info": false,
|
||||
"is": false,
|
||||
"isnot": false,
|
||||
"ok": false,
|
||||
"privateNoteIntentionalCrash": false,
|
||||
"record": false,
|
||||
"registerCleanupFunction": false,
|
||||
"requestLongerTimeout": false,
|
||||
"setExpectedFailuresForSelfTest": false,
|
||||
"todo": false,
|
||||
"todo_is": false,
|
||||
"todo_isnot": false,
|
||||
"waitForClipboard": false,
|
||||
"waitForExplicitFinish": false,
|
||||
"waitForFocus": false,
|
||||
$: false,
|
||||
Assert: false,
|
||||
BrowserTestUtils: false,
|
||||
ContentTask: false,
|
||||
ContentTaskUtils: false,
|
||||
EventUtils: false,
|
||||
PromiseDebugging: false,
|
||||
SpecialPowers: false,
|
||||
TestUtils: false,
|
||||
XPCNativeWrapper: false,
|
||||
XULDocument: false,
|
||||
addLoadEvent: false,
|
||||
add_task: false,
|
||||
content: false,
|
||||
executeSoon: false,
|
||||
expectUncaughtException: false,
|
||||
export_assertions: false,
|
||||
extractJarToTmp: false,
|
||||
finish: false,
|
||||
gTestPath: false,
|
||||
getChromeDir: false,
|
||||
getJar: false,
|
||||
getResolvedURI: false,
|
||||
getRootDirectory: false,
|
||||
getTestFilePath: false,
|
||||
ignoreAllUncaughtExceptions: false,
|
||||
info: false,
|
||||
is: false,
|
||||
isnot: false,
|
||||
ok: false,
|
||||
privateNoteIntentionalCrash: false,
|
||||
record: false,
|
||||
registerCleanupFunction: false,
|
||||
requestLongerTimeout: false,
|
||||
setExpectedFailuresForSelfTest: false,
|
||||
todo: false,
|
||||
todo_is: false,
|
||||
todo_isnot: false,
|
||||
waitForClipboard: false,
|
||||
waitForExplicitFinish: false,
|
||||
waitForFocus: false,
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"mozilla",
|
||||
],
|
||||
plugins: ["mozilla"],
|
||||
|
||||
"rules": {
|
||||
rules: {
|
||||
"mozilla/import-content-task-globals": "error",
|
||||
"mozilla/import-headjs-globals": "error",
|
||||
"mozilla/mark-test-function-used": "error",
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
env: {
|
||||
browser: true,
|
||||
"mozilla/browser-window": true,
|
||||
},
|
||||
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
globals: {
|
||||
// SpecialPowers is injected into the window object via SimpleTest.js
|
||||
"SpecialPowers": false,
|
||||
SpecialPowers: false,
|
||||
},
|
||||
|
||||
"overrides": [{
|
||||
"env": {
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
// Ideally we wouldn't be using the simpletest env here, but our uses of
|
||||
// js files mean we pick up everything from the global scope, which could
|
||||
// be any one of a number of html files. So we just allow the basics...
|
||||
"mozilla/simpletest": true,
|
||||
},
|
||||
"files": ["*.js"],
|
||||
}],
|
||||
|
||||
"plugins": [
|
||||
"mozilla",
|
||||
files: ["*.js"],
|
||||
},
|
||||
],
|
||||
|
||||
plugins: ["mozilla"],
|
||||
|
||||
rules: {
|
||||
"mozilla/import-content-task-globals": "error",
|
||||
"mozilla/import-headjs-globals": "error",
|
||||
|
|
|
@ -2,32 +2,32 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
globals: {
|
||||
// SpecialPowers is injected into the window object via SimpleTest.js
|
||||
"SpecialPowers": false,
|
||||
"XPCNativeWrapper": false,
|
||||
SpecialPowers: false,
|
||||
XPCNativeWrapper: false,
|
||||
},
|
||||
|
||||
"overrides": [{
|
||||
"env": {
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
// Ideally we wouldn't be using the simpletest env here, but our uses of
|
||||
// js files mean we pick up everything from the global scope, which could
|
||||
// be any one of a number of html files. So we just allow the basics...
|
||||
"mozilla/simpletest": true,
|
||||
},
|
||||
"files": ["*.js"],
|
||||
}],
|
||||
|
||||
"plugins": [
|
||||
"mozilla",
|
||||
files: ["*.js"],
|
||||
},
|
||||
],
|
||||
|
||||
"rules": {
|
||||
plugins: ["mozilla"],
|
||||
|
||||
rules: {
|
||||
"mozilla/import-content-task-globals": "error",
|
||||
"mozilla/import-headjs-globals": "error",
|
||||
"mozilla/mark-test-function-used": "error",
|
||||
|
|
|
@ -8,89 +8,88 @@
|
|||
* https://eslint.org/docs/rules/
|
||||
*/
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
"mozilla/privileged": true,
|
||||
},
|
||||
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:prettier/recommended",
|
||||
],
|
||||
extends: ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
|
||||
"globals": {
|
||||
"Cc": false,
|
||||
globals: {
|
||||
Cc: false,
|
||||
// Specific to Firefox (Chrome code only).
|
||||
"ChromeUtils": false,
|
||||
"Ci": false,
|
||||
"Components": false,
|
||||
"Cr": false,
|
||||
"Cu": false,
|
||||
"Debugger": false,
|
||||
"InstallTrigger": false,
|
||||
ChromeUtils: false,
|
||||
Ci: false,
|
||||
Components: false,
|
||||
Cr: false,
|
||||
Cu: false,
|
||||
Debugger: false,
|
||||
InstallTrigger: false,
|
||||
// Specific to Firefox
|
||||
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/InternalError
|
||||
"InternalError": true,
|
||||
"Intl": false,
|
||||
"SharedArrayBuffer": false,
|
||||
"StopIteration": false,
|
||||
"dump": true,
|
||||
InternalError: true,
|
||||
Intl: false,
|
||||
SharedArrayBuffer: false,
|
||||
StopIteration: false,
|
||||
dump: true,
|
||||
// Override the "browser" env definition of "location" to allow writing as it
|
||||
// is a writeable property.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1509270#c1 for more information.
|
||||
"location": true,
|
||||
"openDialog": false,
|
||||
"saveStack": false,
|
||||
"sizeToContent": false,
|
||||
location: true,
|
||||
openDialog: false,
|
||||
saveStack: false,
|
||||
sizeToContent: false,
|
||||
// Specific to Firefox
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
|
||||
"uneval": false,
|
||||
uneval: false,
|
||||
},
|
||||
|
||||
"overrides": [{
|
||||
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": {
|
||||
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.
|
||||
"env": {
|
||||
"browser": false,
|
||||
env: {
|
||||
browser: false,
|
||||
"mozilla/jsm": true,
|
||||
},
|
||||
"files": "**/*.jsm",
|
||||
"rules": {
|
||||
files: "**/*.jsm",
|
||||
rules: {
|
||||
"mozilla/mark-exported-symbols-as-used": "error",
|
||||
// JSM modules are far easier to check for no-unused-vars on a global scope,
|
||||
// than our content files. Hence we turn that on here.
|
||||
"no-unused-vars": ["error", {
|
||||
"args": "none",
|
||||
"vars": "all",
|
||||
}],
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
args: "none",
|
||||
vars: "all",
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 9,
|
||||
parserOptions: {
|
||||
ecmaVersion: 9,
|
||||
},
|
||||
|
||||
// When adding items to this file please check for effects on sub-directories.
|
||||
"plugins": [
|
||||
"html",
|
||||
"fetch-options",
|
||||
"no-unsanitized",
|
||||
],
|
||||
plugins: ["html", "fetch-options", "no-unsanitized"],
|
||||
|
||||
// When adding items to this file please check for effects on all of toolkit
|
||||
// and browser
|
||||
"rules": {
|
||||
rules: {
|
||||
// Warn about cyclomatic complexity in functions.
|
||||
// XXX Get this down to 20?
|
||||
"complexity": ["error", 34],
|
||||
complexity: ["error", 34],
|
||||
|
||||
// Functions must always return something or nothing
|
||||
"consistent-return": "error",
|
||||
|
@ -100,7 +99,7 @@ module.exports = {
|
|||
"constructor-super": "off",
|
||||
|
||||
// Require braces around blocks that start a new line
|
||||
"curly": ["error", "all"],
|
||||
curly: ["error", "all"],
|
||||
|
||||
// Encourage the use of dot notation whenever possible.
|
||||
"dot-notation": "error",
|
||||
|
@ -164,7 +163,7 @@ module.exports = {
|
|||
"no-else-return": "error",
|
||||
|
||||
// No empty statements
|
||||
"no-empty": ["error", {"allowEmptyCatch": true}],
|
||||
"no-empty": ["error", { allowEmptyCatch: true }],
|
||||
|
||||
// Disallow eval and setInteral/setTimeout with strings
|
||||
"no-eval": "error",
|
||||
|
@ -238,10 +237,13 @@ module.exports = {
|
|||
"no-unsanitized/property": "error",
|
||||
|
||||
// No declaring variables that are never used
|
||||
"no-unused-vars": ["error", {
|
||||
"args": "none",
|
||||
"vars": "local",
|
||||
}],
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
args: "none",
|
||||
vars: "local",
|
||||
},
|
||||
],
|
||||
|
||||
// No using variables before defined
|
||||
// "no-use-before-define": ["error", "nofunc"],
|
||||
|
@ -264,7 +266,7 @@ module.exports = {
|
|||
"no-with": "error",
|
||||
|
||||
// Require object-literal shorthand with ES6 method syntax
|
||||
"object-shorthand": ["error", "always", { "avoidQuotes": true }],
|
||||
"object-shorthand": ["error", "always", { avoidQuotes: true }],
|
||||
|
||||
// XXX Bug 1487642 - decide if we want to enable this or not.
|
||||
// Require generator functions to contain yield
|
||||
|
@ -274,7 +276,7 @@ module.exports = {
|
|||
// To avoid bad interactions of the html plugin with the xml preprocessor in
|
||||
// eslint-plugin-mozilla, we turn off processing of the html plugin for .xml
|
||||
// files.
|
||||
"settings": {
|
||||
settings: {
|
||||
"html/xml-extensions": [".xhtml"],
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3,80 +3,85 @@
|
|||
|
||||
module.exports = {
|
||||
// All globals made available in the test environment.
|
||||
"globals": {
|
||||
"Assert": false,
|
||||
"PromiseDebugging": false,
|
||||
"_TEST_FILE": false,
|
||||
"add_task": false,
|
||||
"add_test": false,
|
||||
globals: {
|
||||
Assert: false,
|
||||
PromiseDebugging: false,
|
||||
_TEST_FILE: false,
|
||||
add_task: false,
|
||||
add_test: false,
|
||||
// Test-only function.
|
||||
"allocationMarker": false,
|
||||
"byteSize": false,
|
||||
"deepEqual": false,
|
||||
"do_await_remote_message": false,
|
||||
"do_check_instanceof": false,
|
||||
"do_get_cwd": false,
|
||||
"do_get_file": false,
|
||||
"do_get_idle": false,
|
||||
"do_get_profile": false,
|
||||
"do_get_tempdir": false,
|
||||
"do_load_child_test_harness": false,
|
||||
"do_load_manifest": false,
|
||||
"do_load_module": false,
|
||||
"do_note_exception": false,
|
||||
"do_parse_document": false,
|
||||
"do_report_unexpected_exception": false,
|
||||
"do_send_remote_message": false,
|
||||
"do_test_finished": false,
|
||||
"do_test_pending": false,
|
||||
"do_throw": false,
|
||||
"do_timeout": false,
|
||||
"equal": false,
|
||||
"executeSoon": false,
|
||||
"gc": false,
|
||||
allocationMarker: false,
|
||||
byteSize: false,
|
||||
deepEqual: false,
|
||||
do_await_remote_message: false,
|
||||
do_check_instanceof: false,
|
||||
do_get_cwd: false,
|
||||
do_get_file: false,
|
||||
do_get_idle: false,
|
||||
do_get_profile: false,
|
||||
do_get_tempdir: false,
|
||||
do_load_child_test_harness: false,
|
||||
do_load_manifest: false,
|
||||
do_load_module: false,
|
||||
do_note_exception: false,
|
||||
do_parse_document: false,
|
||||
do_report_unexpected_exception: false,
|
||||
do_send_remote_message: false,
|
||||
do_test_finished: false,
|
||||
do_test_pending: false,
|
||||
do_throw: false,
|
||||
do_timeout: false,
|
||||
equal: false,
|
||||
executeSoon: false,
|
||||
gc: false,
|
||||
// XPCShell specific function, see XPCShellEnvironment.cpp
|
||||
"gczeal": false,
|
||||
"greater": false,
|
||||
"greaterOrEqual": false,
|
||||
"info": false,
|
||||
"less": false,
|
||||
"lessOrEqual": false,
|
||||
"load": false,
|
||||
"mozinfo": false,
|
||||
"notDeepEqual": false,
|
||||
"notEqual": false,
|
||||
"notStrictEqual": false,
|
||||
"ok": false,
|
||||
"registerCleanupFunction": false,
|
||||
"run_next_test": false,
|
||||
"run_test": false,
|
||||
"run_test_in_child": false,
|
||||
"runningInParent": false,
|
||||
gczeal: false,
|
||||
greater: false,
|
||||
greaterOrEqual: false,
|
||||
info: false,
|
||||
less: false,
|
||||
lessOrEqual: false,
|
||||
load: false,
|
||||
mozinfo: false,
|
||||
notDeepEqual: false,
|
||||
notEqual: false,
|
||||
notStrictEqual: false,
|
||||
ok: false,
|
||||
registerCleanupFunction: false,
|
||||
run_next_test: false,
|
||||
run_test: false,
|
||||
run_test_in_child: false,
|
||||
runningInParent: false,
|
||||
// Defined in XPCShellImpl.
|
||||
"sendCommand": false,
|
||||
"strictEqual": false,
|
||||
"throws": false,
|
||||
"todo": false,
|
||||
"todo_check_false": false,
|
||||
"todo_check_true": false,
|
||||
sendCommand: false,
|
||||
strictEqual: false,
|
||||
throws: false,
|
||||
todo: false,
|
||||
todo_check_false: false,
|
||||
todo_check_true: false,
|
||||
// Firefox specific function.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
|
||||
"uneval": false,
|
||||
uneval: false,
|
||||
},
|
||||
|
||||
"overrides": [{
|
||||
overrides: [
|
||||
{
|
||||
// If it is a head file, we turn off global unused variable checks, as it
|
||||
// would require searching the other test files to know if they are used or not.
|
||||
// This would be expensive and slow, and it isn't worth it for head files.
|
||||
// We could get developers to declare as exported, but that doesn't seem worth it.
|
||||
"files": "head*.js",
|
||||
"rules": {
|
||||
"no-unused-vars": ["error", {
|
||||
"args": "none",
|
||||
"vars": "local",
|
||||
}],
|
||||
files: "head*.js",
|
||||
rules: {
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
args: "none",
|
||||
vars: "local",
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
rules: {
|
||||
"mozilla/import-headjs-globals": "error",
|
||||
|
|
|
@ -51,8 +51,7 @@ const MAPPINGS = {
|
|||
"places-tree.js": "browser/components/places/content/places-tree.js",
|
||||
};
|
||||
|
||||
const globalScriptsRegExp =
|
||||
/^\s*Services.scriptloader.loadSubScript\(\"(.*?)\", this\);$/;
|
||||
const globalScriptsRegExp = /^\s*Services.scriptloader.loadSubScript\(\"(.*?)\", this\);$/;
|
||||
|
||||
function getGlobalScriptIncludes(scriptPath) {
|
||||
let fileData;
|
||||
|
@ -71,7 +70,10 @@ function getGlobalScriptIncludes(scriptPath) {
|
|||
let match = line.match(globalScriptsRegExp);
|
||||
if (match) {
|
||||
let sourceFile = match[1]
|
||||
.replace("chrome://browser/content/search/", "browser/components/search/content/")
|
||||
.replace(
|
||||
"chrome://browser/content/search/",
|
||||
"browser/components/search/content/"
|
||||
)
|
||||
.replace("chrome://browser/content/", "browser/base/content/")
|
||||
.replace("chrome://global/content/", "toolkit/content/");
|
||||
|
||||
|
@ -110,7 +112,8 @@ function getScriptGlobals() {
|
|||
} catch (e) {
|
||||
console.error(`Could not load globals from file ${fileName}: ${e}`);
|
||||
console.error(
|
||||
`You may need to update the mappings in ${module.filename}`);
|
||||
`You may need to update the mappings in ${module.filename}`
|
||||
);
|
||||
throw new Error(`Could not load globals from file ${fileName}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +136,6 @@ function getMozillaCentralItems() {
|
|||
};
|
||||
}
|
||||
|
||||
module.exports = helpers.isMozillaCentralBased() ?
|
||||
getMozillaCentralItems() :
|
||||
helpers.getSavedEnvironmentItems("browser-window");
|
||||
module.exports = helpers.isMozillaCentralBased()
|
||||
? getMozillaCentralItems()
|
||||
: helpers.getSavedEnvironmentItems("browser-window");
|
||||
|
|
|
@ -13,9 +13,12 @@
|
|||
var globals = require("globals");
|
||||
var util = require("util");
|
||||
|
||||
var workerGlobals = util._extend({
|
||||
var workerGlobals = util._extend(
|
||||
{
|
||||
ctypes: false,
|
||||
}, globals.worker);
|
||||
},
|
||||
globals.worker
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
globals: workerGlobals,
|
||||
|
|
|
@ -9,16 +9,16 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"globals": {
|
||||
globals: {
|
||||
// These globals are hard-coded and available in .jsm scopes.
|
||||
// https://searchfox.org/mozilla-central/rev/ed212c79cfe86357e9a5740082b9364e7f6e526f/js/xpconnect/loader/mozJSComponentLoader.cpp#134-140
|
||||
"atob": false,
|
||||
"btoa": false,
|
||||
"debug": false,
|
||||
"dump": false,
|
||||
atob: false,
|
||||
btoa: false,
|
||||
debug: false,
|
||||
dump: false,
|
||||
// The WebAssembly global is available in most (if not all) contexts where
|
||||
// JS can run. It's definitely available in JSMs. So even if this is not
|
||||
// the perfect place to add it, it's not wrong, and we can move it later.
|
||||
"WebAssembly": false,
|
||||
WebAssembly: false,
|
||||
},
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -54,7 +54,7 @@ function mapGlobals(fileGlobals) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
globals: helpers.isMozillaCentralBased() ?
|
||||
mapGlobals(getScriptGlobals()) :
|
||||
helpers.getSavedEnvironmentItems("simpletest").globals,
|
||||
globals: helpers.isMozillaCentralBased()
|
||||
? mapGlobals(getScriptGlobals())
|
||||
: helpers.getSavedEnvironmentItems("simpletest").globals,
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ function parseBooleanConfig(string, comment) {
|
|||
}
|
||||
|
||||
items[name] = {
|
||||
value: (value === "true"),
|
||||
value: value === "true",
|
||||
comment,
|
||||
};
|
||||
});
|
||||
|
@ -135,7 +135,10 @@ GlobalsForNode.prototype = {
|
|||
// Note: We check the expression types here and only call the necessary
|
||||
// functions to aid performance.
|
||||
if (node.expression.type === "AssignmentExpression") {
|
||||
globals = helpers.convertThisAssignmentExpressionToGlobals(node, isGlobal);
|
||||
globals = helpers.convertThisAssignmentExpressionToGlobals(
|
||||
node,
|
||||
isGlobal
|
||||
);
|
||||
} else if (node.expression.type === "CallExpression") {
|
||||
globals = helpers.convertCallExpressionToGlobals(node, isGlobal);
|
||||
}
|
||||
|
@ -144,8 +147,11 @@ GlobalsForNode.prototype = {
|
|||
// this is a worker. It would be nice if eslint gave us a way of getting
|
||||
// the environment directly.
|
||||
if (globalScope && globalScope.set.get("importScripts")) {
|
||||
let workerDetails = helpers.convertWorkerExpressionToGlobals(node,
|
||||
isGlobal, this.dirname);
|
||||
let workerDetails = helpers.convertWorkerExpressionToGlobals(
|
||||
node,
|
||||
isGlobal,
|
||||
this.dirname
|
||||
);
|
||||
globals = globals.concat(workerDetails);
|
||||
}
|
||||
|
||||
|
@ -265,19 +271,31 @@ module.exports = {
|
|||
} else if (script.src.includes("chrome")) {
|
||||
// This is one way of referencing test files.
|
||||
script.src = script.src.replace("chrome://mochikit/content/", "/");
|
||||
scriptName = path.join(helpers.rootDir, "testing", "mochitest", script.src);
|
||||
scriptName = path.join(
|
||||
helpers.rootDir,
|
||||
"testing",
|
||||
"mochitest",
|
||||
script.src
|
||||
);
|
||||
} else if (script.src.includes("SimpleTest")) {
|
||||
// This is another way of referencing test files...
|
||||
scriptName = path.join(helpers.rootDir, "testing", "mochitest", script.src);
|
||||
scriptName = path.join(
|
||||
helpers.rootDir,
|
||||
"testing",
|
||||
"mochitest",
|
||||
script.src
|
||||
);
|
||||
} else {
|
||||
// Fallback to hoping this is a relative path.
|
||||
scriptName = path.join(dir, script.src);
|
||||
}
|
||||
if (scriptName && fs.existsSync(scriptName)) {
|
||||
globals.push(...module.exports.getGlobalsForFile(scriptName, {
|
||||
globals.push(
|
||||
...module.exports.getGlobalsForFile(scriptName, {
|
||||
ecmaVersion: helpers.getECMAVersion(),
|
||||
sourceType: script.type,
|
||||
}));
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +335,11 @@ module.exports = {
|
|||
helpers.addGlobals(extraHTMLGlobals, globalScope);
|
||||
}
|
||||
let globals = handler[type](node, context.getAncestors(), globalScope);
|
||||
helpers.addGlobals(globals, globalScope, node.type !== "Program" && node);
|
||||
helpers.addGlobals(
|
||||
globals,
|
||||
globalScope,
|
||||
node.type !== "Program" && node
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,13 @@ module.exports = {
|
|||
get modulesGlobalData() {
|
||||
if (!gModules) {
|
||||
if (this.isMozillaCentralBased()) {
|
||||
gModules = require(path.join(this.rootDir, "tools", "lint", "eslint", "modules.json"));
|
||||
gModules = require(path.join(
|
||||
this.rootDir,
|
||||
"tools",
|
||||
"lint",
|
||||
"eslint",
|
||||
"modules.json"
|
||||
));
|
||||
} else {
|
||||
gModules = require("./modules.json");
|
||||
}
|
||||
|
@ -97,10 +103,15 @@ module.exports = {
|
|||
case "MemberExpression":
|
||||
if (node.computed) {
|
||||
let filename = context && context.getFilename();
|
||||
throw new Error(`getASTSource unsupported computed MemberExpression in ${filename}`);
|
||||
throw new Error(
|
||||
`getASTSource unsupported computed MemberExpression in ${filename}`
|
||||
);
|
||||
}
|
||||
return this.getASTSource(node.object) + "." +
|
||||
this.getASTSource(node.property);
|
||||
return (
|
||||
this.getASTSource(node.object) +
|
||||
"." +
|
||||
this.getASTSource(node.property)
|
||||
);
|
||||
case "ThisExpression":
|
||||
return "this";
|
||||
case "Identifier":
|
||||
|
@ -121,10 +132,17 @@ module.exports = {
|
|||
case "ArrowFunctionExpression":
|
||||
return "() => {}";
|
||||
case "AssignmentExpression":
|
||||
return this.getASTSource(node.left) + " = " +
|
||||
this.getASTSource(node.right);
|
||||
return (
|
||||
this.getASTSource(node.left) + " = " + this.getASTSource(node.right)
|
||||
);
|
||||
case "BinaryExpression":
|
||||
return this.getASTSource(node.left) + " " + node.operator + " " + this.getASTSource(node.right);
|
||||
return (
|
||||
this.getASTSource(node.left) +
|
||||
" " +
|
||||
node.operator +
|
||||
" " +
|
||||
this.getASTSource(node.right)
|
||||
);
|
||||
default:
|
||||
throw new Error("getASTSource unsupported node type: " + node.type);
|
||||
}
|
||||
|
@ -187,10 +205,12 @@ module.exports = {
|
|||
let results = [];
|
||||
let expr = node.expression;
|
||||
|
||||
if (node.expression.type === "CallExpression" &&
|
||||
if (
|
||||
node.expression.type === "CallExpression" &&
|
||||
expr.callee &&
|
||||
expr.callee.type === "Identifier" &&
|
||||
expr.callee.name === "importScripts") {
|
||||
expr.callee.name === "importScripts"
|
||||
) {
|
||||
for (var arg of expr.arguments) {
|
||||
var match = arg.value && arg.value.match(workerImportFilenameMatch);
|
||||
if (match) {
|
||||
|
@ -201,9 +221,11 @@ module.exports = {
|
|||
results = results.concat(additionalGlobals);
|
||||
}
|
||||
} else if (match[2] in globalModules) {
|
||||
results = results.concat(globalModules[match[2]].map(name => {
|
||||
results = results.concat(
|
||||
globalModules[match[2]].map(name => {
|
||||
return { name, writable: true };
|
||||
}));
|
||||
})
|
||||
);
|
||||
} else {
|
||||
results.push({ name: match[3], writable: true, explicit: true });
|
||||
}
|
||||
|
@ -231,12 +253,14 @@ module.exports = {
|
|||
* If the global is writeable or not.
|
||||
*/
|
||||
convertThisAssignmentExpressionToGlobals(node, isGlobal) {
|
||||
if (isGlobal &&
|
||||
if (
|
||||
isGlobal &&
|
||||
node.expression.left &&
|
||||
node.expression.left.object &&
|
||||
node.expression.left.object.type === "ThisExpression" &&
|
||||
node.expression.left.property &&
|
||||
node.expression.left.property.type === "Identifier") {
|
||||
node.expression.left.property.type === "Identifier"
|
||||
) {
|
||||
return [{ name: node.expression.left.property.name, writable: true }];
|
||||
}
|
||||
return [];
|
||||
|
@ -260,14 +284,16 @@ module.exports = {
|
|||
*/
|
||||
convertCallExpressionToGlobals(node, isGlobal) {
|
||||
let express = node.expression;
|
||||
if (express.type === "CallExpression" &&
|
||||
if (
|
||||
express.type === "CallExpression" &&
|
||||
express.callee.type === "MemberExpression" &&
|
||||
express.callee.object &&
|
||||
express.callee.object.type === "Identifier" &&
|
||||
express.arguments.length === 1 &&
|
||||
express.arguments[0].type === "ArrayExpression" &&
|
||||
express.callee.property.type === "Identifier" &&
|
||||
express.callee.property.name === "importGlobalProperties") {
|
||||
express.callee.property.name === "importGlobalProperties"
|
||||
) {
|
||||
return express.arguments[0].elements.map(literal => {
|
||||
return {
|
||||
explicit: true,
|
||||
|
@ -301,7 +327,9 @@ module.exports = {
|
|||
// of them.
|
||||
let explicit = globalModules[match[1]].length == 1;
|
||||
return globalModules[match[1]].map(name => ({
|
||||
name, writable: true, explicit,
|
||||
name,
|
||||
writable: true,
|
||||
explicit,
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -322,27 +350,43 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
|
||||
if (callExpressionMultiDefinitions.some(expr => source.startsWith(expr)) &&
|
||||
node.expression.arguments[1]) {
|
||||
if (
|
||||
callExpressionMultiDefinitions.some(expr => source.startsWith(expr)) &&
|
||||
node.expression.arguments[1]
|
||||
) {
|
||||
let arg = node.expression.arguments[1];
|
||||
if (arg.type === "ObjectExpression") {
|
||||
return arg.properties
|
||||
.map(p => ({ name: p.type === "Property" && p.key.name, writable: true, explicit: true }))
|
||||
.map(p => ({
|
||||
name: p.type === "Property" && p.key.name,
|
||||
writable: true,
|
||||
explicit: true,
|
||||
}))
|
||||
.filter(g => g.name);
|
||||
}
|
||||
if (arg.type === "ArrayExpression") {
|
||||
return arg.elements
|
||||
.map(p => ({ name: p.type === "Literal" && p.value, writable: true, explicit: true }))
|
||||
.map(p => ({
|
||||
name: p.type === "Literal" && p.value,
|
||||
writable: true,
|
||||
explicit: true,
|
||||
}))
|
||||
.filter(g => typeof g.name == "string");
|
||||
}
|
||||
}
|
||||
|
||||
if (node.expression.callee.type == "MemberExpression" &&
|
||||
if (
|
||||
node.expression.callee.type == "MemberExpression" &&
|
||||
node.expression.callee.property.type == "Identifier" &&
|
||||
node.expression.callee.property.name == "defineLazyScriptGetter") {
|
||||
node.expression.callee.property.name == "defineLazyScriptGetter"
|
||||
) {
|
||||
// The case where we have a single symbol as a string has already been
|
||||
// handled by the regexp, so we have an array of symbols here.
|
||||
return node.expression.arguments[1].elements.map(n => ({ name: n.value, writable: true, explicit: true }));
|
||||
return node.expression.arguments[1].elements.map(n => ({
|
||||
name: n.value,
|
||||
writable: true,
|
||||
explicit: true,
|
||||
}));
|
||||
}
|
||||
|
||||
return [];
|
||||
|
@ -402,7 +446,9 @@ module.exports = {
|
|||
* The AST node that defined the globals.
|
||||
*/
|
||||
addGlobals(globalVars, scope, node) {
|
||||
globalVars.forEach(v => this.addVarToScope(v.name, scope, v.writable, v.explicit && node));
|
||||
globalVars.forEach(v =>
|
||||
this.addVarToScope(v.name, scope, v.writable, v.explicit && node)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -503,10 +549,13 @@ module.exports = {
|
|||
let filepath = this.cleanUpPath(scope.getFilename());
|
||||
let dir = path.dirname(filepath);
|
||||
|
||||
let names =
|
||||
fs.readdirSync(dir)
|
||||
.filter(name => (name.startsWith("head") ||
|
||||
name.startsWith("xpcshell-head")) && name.endsWith(".js"))
|
||||
let names = fs
|
||||
.readdirSync(dir)
|
||||
.filter(
|
||||
name =>
|
||||
(name.startsWith("head") || name.startsWith("xpcshell-head")) &&
|
||||
name.endsWith(".js")
|
||||
)
|
||||
.map(name => path.join(dir, name));
|
||||
return names;
|
||||
},
|
||||
|
@ -548,8 +597,7 @@ module.exports = {
|
|||
file: path.join(dir, name),
|
||||
manifest,
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
directoryManifests.set(dir, manifests);
|
||||
|
@ -673,7 +721,10 @@ module.exports = {
|
|||
return null;
|
||||
}
|
||||
|
||||
let possibleRoot = searchUpForIgnore(path.dirname(module.filename), ".eslintignore");
|
||||
let possibleRoot = searchUpForIgnore(
|
||||
path.dirname(module.filename),
|
||||
".eslintignore"
|
||||
);
|
||||
if (!possibleRoot) {
|
||||
possibleRoot = searchUpForIgnore(path.resolve(), ".eslintignore");
|
||||
}
|
||||
|
@ -736,7 +787,13 @@ module.exports = {
|
|||
get globalScriptPaths() {
|
||||
return [
|
||||
path.join(this.rootDir, "browser", "base", "content", "browser.xhtml"),
|
||||
path.join(this.rootDir, "browser", "base", "content", "global-scripts.inc"),
|
||||
path.join(
|
||||
this.rootDir,
|
||||
"browser",
|
||||
"base",
|
||||
"content",
|
||||
"global-scripts.inc"
|
||||
),
|
||||
];
|
||||
},
|
||||
|
||||
|
@ -745,7 +802,9 @@ module.exports = {
|
|||
},
|
||||
|
||||
getSavedEnvironmentItems(environment) {
|
||||
return require("./environments/saved-globals.json").environments[environment];
|
||||
return require("./environments/saved-globals.json").environments[
|
||||
environment
|
||||
];
|
||||
},
|
||||
|
||||
getSavedRuleData(rule) {
|
||||
|
|
|
@ -16,16 +16,16 @@ module.exports = {
|
|||
"browser-test": require("../lib/configs/browser-test"),
|
||||
"chrome-test": require("../lib/configs/chrome-test"),
|
||||
"mochitest-test": require("../lib/configs/mochitest-test"),
|
||||
"recommended": require("../lib/configs/recommended"),
|
||||
recommended: require("../lib/configs/recommended"),
|
||||
"xpcshell-test": require("../lib/configs/xpcshell-test"),
|
||||
},
|
||||
environments: {
|
||||
"browser-window": require("../lib/environments/browser-window.js"),
|
||||
"chrome-worker": require("../lib/environments/chrome-worker.js"),
|
||||
"frame-script": require("../lib/environments/frame-script.js"),
|
||||
"jsm": require("../lib/environments/jsm.js"),
|
||||
"simpletest": require("../lib/environments/simpletest.js"),
|
||||
"privileged": require("../lib/environments/privileged.js"),
|
||||
jsm: require("../lib/environments/jsm.js"),
|
||||
simpletest: require("../lib/environments/simpletest.js"),
|
||||
privileged: require("../lib/environments/privileged.js"),
|
||||
},
|
||||
processors: {
|
||||
".xml": require("../lib/processors/xbl-bindings"),
|
||||
|
@ -36,10 +36,8 @@ module.exports = {
|
|||
"avoid-removeChild": require("../lib/rules/avoid-removeChild"),
|
||||
"balanced-listeners": require("../lib/rules/balanced-listeners"),
|
||||
"consistent-if-bracing": require("../lib/rules/consistent-if-bracing"),
|
||||
"import-browser-window-globals":
|
||||
require("../lib/rules/import-browser-window-globals"),
|
||||
"import-content-task-globals":
|
||||
require("../lib/rules/import-content-task-globals"),
|
||||
"import-browser-window-globals": require("../lib/rules/import-browser-window-globals"),
|
||||
"import-content-task-globals": require("../lib/rules/import-content-task-globals"),
|
||||
"import-globals": require("../lib/rules/import-globals"),
|
||||
"import-headjs-globals": require("../lib/rules/import-headjs-globals"),
|
||||
"mark-exported-symbols-as-used": require("../lib/rules/mark-exported-symbols-as-used"),
|
||||
|
@ -50,19 +48,15 @@ module.exports = {
|
|||
"no-define-cc-etc": require("../lib/rules/no-define-cc-etc"),
|
||||
"no-task": require("../lib/rules/no-task"),
|
||||
"no-useless-parameters": require("../lib/rules/no-useless-parameters"),
|
||||
"no-useless-removeEventListener":
|
||||
require("../lib/rules/no-useless-removeEventListener"),
|
||||
"no-useless-run-test":
|
||||
require("../lib/rules/no-useless-run-test"),
|
||||
"reject-importGlobalProperties":
|
||||
require("../lib/rules/reject-importGlobalProperties"),
|
||||
"no-useless-removeEventListener": require("../lib/rules/no-useless-removeEventListener"),
|
||||
"no-useless-run-test": require("../lib/rules/no-useless-run-test"),
|
||||
"reject-importGlobalProperties": require("../lib/rules/reject-importGlobalProperties"),
|
||||
"reject-some-requires": require("../lib/rules/reject-some-requires"),
|
||||
"rejects-requires-await": require("../lib/rules/rejects-requires-await"),
|
||||
"use-cc-etc": require("../lib/rules/use-cc-etc"),
|
||||
"use-chromeutils-generateqi": require("../lib/rules/use-chromeutils-generateqi"),
|
||||
"use-chromeutils-import": require("../lib/rules/use-chromeutils-import"),
|
||||
"use-default-preference-values":
|
||||
require("../lib/rules/use-default-preference-values"),
|
||||
"use-default-preference-values": require("../lib/rules/use-default-preference-values"),
|
||||
"use-ownerGlobal": require("../lib/rules/use-ownerGlobal"),
|
||||
"use-includes-instead-of-indexOf": require("../lib/rules/use-includes-instead-of-indexOf"),
|
||||
"use-returnValue": require("../lib/rules/use-returnValue"),
|
||||
|
|
|
@ -61,8 +61,11 @@ function addNodeLines(node, reindent) {
|
|||
|
||||
// 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) {
|
||||
if (
|
||||
lines.length > 2 &&
|
||||
lines[lines.length - 2].trim() == "" &&
|
||||
lines[lines.length - 2].length > lastIndent
|
||||
) {
|
||||
lastIndent = lines[lines.length - 2].length;
|
||||
}
|
||||
|
||||
|
@ -82,7 +85,8 @@ function addNodeLines(node, reindent) {
|
|||
|
||||
// Find the preceding whitespace for all lines that aren't entirely
|
||||
// whitespace.
|
||||
let indents = lines.filter(s => s.trim().length > 0)
|
||||
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);
|
||||
|
@ -172,7 +176,10 @@ module.exports = {
|
|||
continue;
|
||||
}
|
||||
|
||||
addSyntheticLine(`get ${item.attributes.name}() {`, item.textLine);
|
||||
addSyntheticLine(
|
||||
`get ${item.attributes.name}() {`,
|
||||
item.textLine
|
||||
);
|
||||
addSyntheticLine(`return (`, item.textLine);
|
||||
|
||||
// Remove trailing semicolons, as we are adding our own
|
||||
|
@ -195,7 +202,8 @@ module.exports = {
|
|||
// Methods become function declarations with the appropriate
|
||||
// params.
|
||||
|
||||
let params = item.children.filter(n => {
|
||||
let params = item.children
|
||||
.filter(n => {
|
||||
return n.local == "parameter" && n.namespace == NS_XBL;
|
||||
})
|
||||
.map(n => n.attributes.name)
|
||||
|
@ -204,7 +212,10 @@ module.exports = {
|
|||
return n.local == "body" && n.namespace == NS_XBL;
|
||||
})[0];
|
||||
|
||||
addSyntheticLine(`${item.attributes.name}(${params}) {`, item.textLine);
|
||||
addSyntheticLine(
|
||||
`${item.attributes.name}(${params}) {`,
|
||||
item.textLine
|
||||
);
|
||||
addNodeLines(body, 4);
|
||||
addSyntheticLine(`},`, item.textEndLine);
|
||||
break;
|
||||
|
@ -217,9 +228,15 @@ module.exports = {
|
|||
}
|
||||
|
||||
if (propdef.local == "setter") {
|
||||
addSyntheticLine(`set ${item.attributes.name}(val) {`, propdef.textLine);
|
||||
addSyntheticLine(
|
||||
`set ${item.attributes.name}(val) {`,
|
||||
propdef.textLine
|
||||
);
|
||||
} else if (propdef.local == "getter") {
|
||||
addSyntheticLine(`get ${item.attributes.name}() {`, propdef.textLine);
|
||||
addSyntheticLine(
|
||||
`get ${item.attributes.name}() {`,
|
||||
propdef.textLine
|
||||
);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -241,7 +258,10 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
|
||||
addSyntheticLine((part.local == "implementation" ? `},` : `],`), part.textEndLine);
|
||||
addSyntheticLine(
|
||||
part.local == "implementation" ? `},` : `],`,
|
||||
part.textEndLine
|
||||
);
|
||||
}
|
||||
addSyntheticLine(`},`, binding.textEndLine);
|
||||
}
|
||||
|
|
|
@ -51,8 +51,12 @@ function dealWithIfdefs(text, filename) {
|
|||
if (!line.startsWith("#")) {
|
||||
outputLines.push(shouldSkip ? "" : line);
|
||||
} else {
|
||||
if (line.startsWith("# ") || line.startsWith("#filter") ||
|
||||
line == "#" || line.startsWith("#define")) {
|
||||
if (
|
||||
line.startsWith("# ") ||
|
||||
line.startsWith("#filter") ||
|
||||
line == "#" ||
|
||||
line.startsWith("#define")
|
||||
) {
|
||||
outputLines.push("");
|
||||
continue;
|
||||
}
|
||||
|
@ -225,15 +229,20 @@ module.exports = {
|
|||
let mapped = lineMap[message.line - 1];
|
||||
// Ensure we don't modify this by making a copy. We might need it for another failure.
|
||||
let target = mapped.line;
|
||||
let includedRange = includedRanges.find(r => (target >= r.start && target <= r.end));
|
||||
let includedRange = includedRanges.find(
|
||||
r => target >= r.start && target <= r.end
|
||||
);
|
||||
// If this came from an #included file, indicate this in the message
|
||||
if (includedRange) {
|
||||
target = includedRange.start;
|
||||
message.message += " (from included file " + path.basename(includedRange.filename) + ")";
|
||||
message.message +=
|
||||
" (from included file " +
|
||||
path.basename(includedRange.filename) +
|
||||
")";
|
||||
}
|
||||
// Compensate for line numbers shifting as a result of #include:
|
||||
let includeBallooning =
|
||||
includedRanges.filter(r => (target >= r.end))
|
||||
let includeBallooning = includedRanges
|
||||
.filter(r => target >= r.end)
|
||||
.map(r => r.end - r.start)
|
||||
.reduce((acc, next) => acc + next, 0);
|
||||
target -= includeBallooning;
|
||||
|
@ -250,4 +259,3 @@ module.exports = {
|
|||
return errors;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -27,32 +27,41 @@ module.exports = {
|
|||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type !== "MemberExpression" ||
|
||||
if (
|
||||
callee.type !== "MemberExpression" ||
|
||||
callee.object.type !== "Identifier" ||
|
||||
callee.object.name !== "Date" ||
|
||||
callee.property.type !== "Identifier" ||
|
||||
callee.property.name !== "now") {
|
||||
callee.property.name !== "now"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report(node, "use performance.now() instead of Date.now() for timing " +
|
||||
"measurements");
|
||||
context.report(
|
||||
node,
|
||||
"use performance.now() instead of Date.now() for timing " +
|
||||
"measurements"
|
||||
);
|
||||
},
|
||||
|
||||
"NewExpression": function(node) {
|
||||
NewExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type !== "Identifier" ||
|
||||
if (
|
||||
callee.type !== "Identifier" ||
|
||||
callee.name !== "Date" ||
|
||||
node.arguments.length > 0) {
|
||||
node.arguments.length > 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report(node, "use performance.now() instead of new Date() for timing " +
|
||||
"measurements");
|
||||
context.report(
|
||||
node,
|
||||
"use performance.now() instead of new Date() for timing " +
|
||||
"measurements"
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -21,31 +21,43 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type !== "MemberExpression" ||
|
||||
if (
|
||||
callee.type !== "MemberExpression" ||
|
||||
callee.property.type !== "Identifier" ||
|
||||
callee.property.name != "removeChild" ||
|
||||
node.arguments.length != 1) {
|
||||
node.arguments.length != 1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (callee.object.type == "MemberExpression" &&
|
||||
if (
|
||||
callee.object.type == "MemberExpression" &&
|
||||
callee.object.property.type == "Identifier" &&
|
||||
callee.object.property.name == "parentNode" &&
|
||||
helpers.getASTSource(callee.object.object, context) ==
|
||||
helpers.getASTSource(node.arguments[0])) {
|
||||
context.report(node, "use element.remove() instead of " +
|
||||
"element.parentNode.removeChild(element)");
|
||||
helpers.getASTSource(node.arguments[0])
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
"use element.remove() instead of " +
|
||||
"element.parentNode.removeChild(element)"
|
||||
);
|
||||
}
|
||||
|
||||
if (node.arguments[0].type == "MemberExpression" &&
|
||||
if (
|
||||
node.arguments[0].type == "MemberExpression" &&
|
||||
node.arguments[0].property.type == "Identifier" &&
|
||||
node.arguments[0].property.name == "firstChild" &&
|
||||
helpers.getASTSource(callee.object, context) ==
|
||||
helpers.getASTSource(node.arguments[0].object)) {
|
||||
context.report(node, "use element.firstChild.remove() instead of " +
|
||||
"element.removeChild(element.firstChild)");
|
||||
helpers.getASTSource(node.arguments[0].object)
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
"use element.firstChild.remove() instead of " +
|
||||
"element.removeChild(element.firstChild)"
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -22,8 +22,8 @@ module.exports = function(context) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
var DICTIONARY = {
|
||||
"addEventListener": "removeEventListener",
|
||||
"on": "off",
|
||||
addEventListener: "removeEventListener",
|
||||
on: "off",
|
||||
};
|
||||
// Invert this dictionary to make it easy later.
|
||||
var INVERTED_DICTIONARY = {};
|
||||
|
@ -40,13 +40,17 @@ module.exports = function(context) {
|
|||
let options = node.arguments[2];
|
||||
if (options) {
|
||||
if (options.type == "ObjectExpression") {
|
||||
if (options.properties.some(p => p.key.name == "once" &&
|
||||
p.value.value === true)) {
|
||||
if (
|
||||
options.properties.some(
|
||||
p => p.key.name == "once" && p.value.value === true
|
||||
)
|
||||
) {
|
||||
// No point in adding listeners using the 'once' option.
|
||||
return;
|
||||
}
|
||||
capture = options.properties.some(p => p.key.name == "capture" &&
|
||||
p.value.value === true);
|
||||
capture = options.properties.some(
|
||||
p => p.key.name == "capture" && p.value.value === true
|
||||
);
|
||||
} else {
|
||||
capture = options.value;
|
||||
}
|
||||
|
@ -64,8 +68,9 @@ module.exports = function(context) {
|
|||
let options = node.arguments[2];
|
||||
if (options) {
|
||||
if (options.type == "ObjectExpression") {
|
||||
capture = options.properties.some(p => p.key.name == "capture" &&
|
||||
p.value.value === true);
|
||||
capture = options.properties.some(
|
||||
p => p.key.name == "capture" && p.value.value === true
|
||||
);
|
||||
} else {
|
||||
capture = options.value;
|
||||
}
|
||||
|
@ -93,9 +98,11 @@ module.exports = function(context) {
|
|||
function hasRemovedListener(addedListener) {
|
||||
for (var k = 0; k < removedListeners.length; k++) {
|
||||
var listener = removedListeners[k];
|
||||
if (DICTIONARY[addedListener.functionName] === listener.functionName &&
|
||||
if (
|
||||
DICTIONARY[addedListener.functionName] === listener.functionName &&
|
||||
addedListener.type === listener.type &&
|
||||
addedListener.useCapture === listener.useCapture) {
|
||||
addedListener.useCapture === listener.useCapture
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +133,14 @@ module.exports = function(context) {
|
|||
|
||||
"Program:exit": function() {
|
||||
getUnbalancedListeners().forEach(function(listener) {
|
||||
context.report(listener.node,
|
||||
context.report(
|
||||
listener.node,
|
||||
"No corresponding '{{functionName}}({{type}})' was found.",
|
||||
{
|
||||
functionName: DICTIONARY[listener.functionName],
|
||||
type: listener.type,
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,10 +20,17 @@ module.exports = {
|
|||
IfStatement(node) {
|
||||
if (node.parent.type !== "IfStatement") {
|
||||
let types = new Set();
|
||||
for (let currentNode = node; currentNode; currentNode = currentNode.alternate) {
|
||||
for (
|
||||
let currentNode = node;
|
||||
currentNode;
|
||||
currentNode = currentNode.alternate
|
||||
) {
|
||||
let type = currentNode.consequent.type;
|
||||
types.add(type == "BlockStatement" ? "Block" : "NotBlock");
|
||||
if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") {
|
||||
if (
|
||||
currentNode.alternate &&
|
||||
currentNode.alternate.type !== "IfStatement"
|
||||
) {
|
||||
type = currentNode.alternate.type;
|
||||
types.add(type == "BlockStatement" ? "Block" : "NotBlock");
|
||||
break;
|
||||
|
|
|
@ -32,11 +32,16 @@ module.exports = function(context) {
|
|||
relativePath = relativePath.split(path.sep).join("/");
|
||||
}
|
||||
|
||||
if (browserWindowEnv.browserjsScripts &&
|
||||
browserWindowEnv.browserjsScripts.includes(relativePath)) {
|
||||
if (
|
||||
browserWindowEnv.browserjsScripts &&
|
||||
browserWindowEnv.browserjsScripts.includes(relativePath)
|
||||
) {
|
||||
for (let global in browserWindowEnv.globals) {
|
||||
helpers.addVarToScope(global, context.getScope(),
|
||||
browserWindowEnv.globals[global]);
|
||||
helpers.addVarToScope(
|
||||
global,
|
||||
context.getScope(),
|
||||
browserWindowEnv.globals[global]
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -25,10 +25,15 @@ module.exports = function(context) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"CallExpression[callee.object.name='ContentTask'][callee.property.name='spawn']": function(node) {
|
||||
"CallExpression[callee.object.name='ContentTask'][callee.property.name='spawn']": function(
|
||||
node
|
||||
) {
|
||||
for (let global in frameScriptEnv.globals) {
|
||||
helpers.addVarToScope(global, context.getScope(),
|
||||
frameScriptEnv.globals[global]);
|
||||
helpers.addVarToScope(
|
||||
global,
|
||||
context.getScope(),
|
||||
frameScriptEnv.globals[global]
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -43,11 +43,13 @@ module.exports = function(context) {
|
|||
|
||||
return {
|
||||
AssignmentExpression(node, parents) {
|
||||
if (node.operator === "=" &&
|
||||
if (
|
||||
node.operator === "=" &&
|
||||
node.left.type === "MemberExpression" &&
|
||||
node.left.object.type === "ThisExpression" &&
|
||||
node.left.property.name === "EXPORTED_SYMBOLS" &&
|
||||
isGlobalScope()) {
|
||||
isGlobalScope()
|
||||
) {
|
||||
markArrayElementsAsUsed(context, node, node.right);
|
||||
}
|
||||
},
|
||||
|
@ -58,15 +60,18 @@ module.exports = function(context) {
|
|||
}
|
||||
|
||||
for (let item of node.declarations) {
|
||||
if (item.id &&
|
||||
if (
|
||||
item.id &&
|
||||
item.id.type == "Identifier" &&
|
||||
item.id.name === "EXPORTED_SYMBOLS") {
|
||||
item.id.name === "EXPORTED_SYMBOLS"
|
||||
) {
|
||||
if (node.kind === "let") {
|
||||
// The use of 'let' isn't allowed as the lexical scope may die after
|
||||
// the script executes.
|
||||
context.report({
|
||||
node,
|
||||
message: "EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`",
|
||||
message:
|
||||
"EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`",
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@ module.exports = function(context) {
|
|||
}
|
||||
|
||||
function deHungarianize(name) {
|
||||
return name.substring(1, 2).toLowerCase() +
|
||||
name.substring(2, name.length);
|
||||
return name.substring(1, 2).toLowerCase() + name.substring(2, name.length);
|
||||
}
|
||||
|
||||
function checkFunction(node) {
|
||||
|
@ -35,10 +34,12 @@ module.exports = function(context) {
|
|||
name: param.name,
|
||||
suggestion: deHungarianize(param.name),
|
||||
};
|
||||
context.report(param,
|
||||
context.report(
|
||||
param,
|
||||
"Parameter '{{name}}' uses Hungarian Notation, " +
|
||||
"consider using '{{suggestion}}' instead.",
|
||||
errorObj);
|
||||
errorObj
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +49,8 @@ module.exports = function(context) {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"FunctionDeclaration": checkFunction,
|
||||
"ArrowFunctionExpression": checkFunction,
|
||||
"FunctionExpression": checkFunction,
|
||||
FunctionDeclaration: checkFunction,
|
||||
ArrowFunctionExpression: checkFunction,
|
||||
FunctionExpression: checkFunction,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,10 +13,7 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
var helpers = require("../helpers");
|
||||
var testTypes = new Set([
|
||||
"browser",
|
||||
"xpcshell",
|
||||
]);
|
||||
var testTypes = new Set(["browser", "xpcshell"]);
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
|
@ -33,7 +30,7 @@ module.exports = {
|
|||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
// We don't want to run this on mochitest plain as it already
|
||||
// prevents flaky setTimeout at runtime. This check is built-in
|
||||
// to the rule itself as sometimes other tests can live alongside
|
||||
|
@ -44,14 +41,15 @@ module.exports = {
|
|||
|
||||
let callee = node.callee;
|
||||
if (callee.type === "MemberExpression") {
|
||||
if (callee.property.name !== "setTimeout" ||
|
||||
if (
|
||||
callee.property.name !== "setTimeout" ||
|
||||
callee.object.name !== "window" ||
|
||||
node.arguments.length < 2) {
|
||||
node.arguments.length < 2
|
||||
) {
|
||||
return;
|
||||
}
|
||||
} else if (callee.type === "Identifier") {
|
||||
if (callee.name !== "setTimeout" ||
|
||||
node.arguments.length < 2) {
|
||||
if (callee.name !== "setTimeout" || node.arguments.length < 2) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -60,8 +58,11 @@ module.exports = {
|
|||
|
||||
let timeout = node.arguments[1];
|
||||
if (timeout.type !== "Literal" || timeout.value > 0) {
|
||||
context.report(node, "listen for events instead of setTimeout() " +
|
||||
"with arbitrary delay");
|
||||
context.report(
|
||||
node,
|
||||
"listen for events instead of setTimeout() " +
|
||||
"with arbitrary delay"
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -18,11 +18,16 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"BinaryExpression": function(node) {
|
||||
if (["==", "!="].includes(node.operator) &&
|
||||
BinaryExpression(node) {
|
||||
if (
|
||||
["==", "!="].includes(node.operator) &&
|
||||
(["true", "false"].includes(node.left.raw) ||
|
||||
["true", "false"].includes(node.right.raw))) {
|
||||
context.report(node, "Don't compare for inexact equality against boolean literals");
|
||||
["true", "false"].includes(node.right.raw))
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
"Don't compare for inexact equality against boolean literals"
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,17 +20,31 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"VariableDeclarator": function(node) {
|
||||
if (node.id.type == "Identifier" && componentsBlacklist.includes(node.id.name)) {
|
||||
context.report(node,
|
||||
`${node.id.name} is now defined in global scope, a separate definition is no longer necessary.`);
|
||||
VariableDeclarator(node) {
|
||||
if (
|
||||
node.id.type == "Identifier" &&
|
||||
componentsBlacklist.includes(node.id.name)
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
`${
|
||||
node.id.name
|
||||
} is now defined in global scope, a separate definition is no longer necessary.`
|
||||
);
|
||||
}
|
||||
|
||||
if (node.id.type == "ObjectPattern") {
|
||||
for (let property of node.id.properties) {
|
||||
if (property.type == "Property" && componentsBlacklist.includes(property.value.name)) {
|
||||
context.report(node,
|
||||
`${property.value.name} is now defined in global scope, a separate definition is no longer necessary.`);
|
||||
if (
|
||||
property.type == "Property" &&
|
||||
componentsBlacklist.includes(property.value.name)
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
`${
|
||||
property.value.name
|
||||
} is now defined in global scope, a separate definition is no longer necessary.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type === "MemberExpression" &&
|
||||
if (
|
||||
callee.type === "MemberExpression" &&
|
||||
callee.object.type === "Identifier" &&
|
||||
callee.object.name === "Task") {
|
||||
callee.object.name === "Task"
|
||||
) {
|
||||
context.report({ node, message: "Task.jsm is deprecated." });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
module.exports = function(context) {
|
||||
function getRangeAfterArgToEnd(argNumber, args) {
|
||||
let sourceCode = context.getSourceCode();
|
||||
return [sourceCode.getTokenAfter(args[argNumber]).range[0],
|
||||
args[args.length - 1].range[1]];
|
||||
return [
|
||||
sourceCode.getTokenAfter(args[argNumber]).range[0],
|
||||
args[args.length - 1].range[1],
|
||||
];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -25,22 +27,29 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type !== "MemberExpression" ||
|
||||
callee.property.type !== "Identifier") {
|
||||
if (
|
||||
callee.type !== "MemberExpression" ||
|
||||
callee.property.type !== "Identifier"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let isFalse = arg => arg.type === "Literal" && arg.value === false;
|
||||
let isFalsy = arg => arg.type === "Literal" && !arg.value;
|
||||
let isBool = arg => arg.type === "Literal" && (arg.value === false ||
|
||||
arg.value === true);
|
||||
let isBool = arg =>
|
||||
arg.type === "Literal" && (arg.value === false || arg.value === true);
|
||||
let name = callee.property.name;
|
||||
let args = node.arguments;
|
||||
|
||||
if (["addEventListener", "removeEventListener", "addObserver"]
|
||||
.includes(name) && args.length === 3 && isFalse(args[2])) {
|
||||
if (
|
||||
["addEventListener", "removeEventListener", "addObserver"].includes(
|
||||
name
|
||||
) &&
|
||||
args.length === 3 &&
|
||||
isFalse(args[2])
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
fix: fixer => {
|
||||
|
@ -80,8 +89,7 @@ module.exports = function(context) {
|
|||
});
|
||||
}
|
||||
|
||||
if (name === "notifyObservers" && args.length === 3 &&
|
||||
isFalsy(args[2])) {
|
||||
if (name === "notifyObservers" && args.length === 3 && isFalsy(args[2])) {
|
||||
context.report({
|
||||
node,
|
||||
fix: fixer => {
|
||||
|
@ -91,8 +99,11 @@ module.exports = function(context) {
|
|||
});
|
||||
}
|
||||
|
||||
if (name === "getComputedStyle" && args.length === 2 &&
|
||||
isFalsy(args[1])) {
|
||||
if (
|
||||
name === "getComputedStyle" &&
|
||||
args.length === 2 &&
|
||||
isFalsy(args[1])
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
fix: fixer => {
|
||||
|
@ -102,8 +113,11 @@ module.exports = function(context) {
|
|||
});
|
||||
}
|
||||
|
||||
if (name === "newURI" && args.length > 1 &&
|
||||
isFalsy(args[args.length - 1])) {
|
||||
if (
|
||||
name === "newURI" &&
|
||||
args.length > 1 &&
|
||||
isFalsy(args[args.length - 1])
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
fix: fixer => {
|
||||
|
@ -111,7 +125,9 @@ module.exports = function(context) {
|
|||
return fixer.removeRange(getRangeAfterArgToEnd(0, args));
|
||||
}
|
||||
|
||||
return fixer.removeRange(getRangeAfterArgToEnd(args.length - 2, args));
|
||||
return fixer.removeRange(
|
||||
getRangeAfterArgToEnd(args.length - 2, args)
|
||||
);
|
||||
},
|
||||
message: "newURI's last parameters are optional.",
|
||||
});
|
||||
|
|
|
@ -19,37 +19,45 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let callee = node.callee;
|
||||
if (callee.type !== "MemberExpression" ||
|
||||
if (
|
||||
callee.type !== "MemberExpression" ||
|
||||
callee.property.type !== "Identifier" ||
|
||||
callee.property.name !== "addEventListener" ||
|
||||
node.arguments.length == 4) {
|
||||
node.arguments.length == 4
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let listener = node.arguments[1];
|
||||
if (!listener ||
|
||||
if (
|
||||
!listener ||
|
||||
listener.type != "FunctionExpression" ||
|
||||
!listener.body ||
|
||||
listener.body.type != "BlockStatement" ||
|
||||
!listener.body.body.length ||
|
||||
listener.body.body[0].type != "ExpressionStatement" ||
|
||||
listener.body.body[0].expression.type != "CallExpression") {
|
||||
listener.body.body[0].expression.type != "CallExpression"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let call = listener.body.body[0].expression;
|
||||
if (call.callee.type == "MemberExpression" &&
|
||||
if (
|
||||
call.callee.type == "MemberExpression" &&
|
||||
call.callee.property.type == "Identifier" &&
|
||||
call.callee.property.name == "removeEventListener" &&
|
||||
((call.arguments[0].type == "Literal" &&
|
||||
call.arguments[0].value == node.arguments[0].value) ||
|
||||
(call.arguments[0].type == "Identifier" &&
|
||||
call.arguments[0].name == node.arguments[0].name))) {
|
||||
context.report(call,
|
||||
call.arguments[0].name == node.arguments[0].name))
|
||||
) {
|
||||
context.report(
|
||||
call,
|
||||
"use {once: true} instead of removeEventListener as " +
|
||||
"the first instruction of the listener");
|
||||
"the first instruction of the listener"
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -19,12 +19,14 @@ module.exports = function(context) {
|
|||
|
||||
return {
|
||||
"Program > FunctionDeclaration": function(node) {
|
||||
if (node.id.name === "run_test" &&
|
||||
if (
|
||||
node.id.name === "run_test" &&
|
||||
node.body.type === "BlockStatement" &&
|
||||
node.body.body.length === 1 &&
|
||||
node.body.body[0].type === "ExpressionStatement" &&
|
||||
node.body.body[0].expression.type === "CallExpression" &&
|
||||
node.body.body[0].expression.callee.name === "run_next_test") {
|
||||
node.body.body[0].expression.callee.name === "run_next_test"
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
fix: fixer => {
|
||||
|
@ -51,7 +53,7 @@ module.exports = function(context) {
|
|||
return fixer.removeRange([
|
||||
// If there's no startNode, we fall back to zero, i.e. start of
|
||||
// file.
|
||||
startNode ? (startNode.end + 1) : 0,
|
||||
startNode ? startNode.end + 1 : 0,
|
||||
// We know the function is a block and it'll end with }. Normally
|
||||
// there's a new line after that, so just advance past it. This
|
||||
// may be slightly not dodgy in some cases, but covers the existing
|
||||
|
@ -59,7 +61,8 @@ module.exports = function(context) {
|
|||
node.end + 1,
|
||||
]);
|
||||
},
|
||||
message: "Useless run_test function - only contains run_next_test; whole function can be removed",
|
||||
message:
|
||||
"Useless run_test function - only contains run_next_test; whole function can be removed",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const privilegedGlobals = Object.keys(require("../environments/privileged.js").globals);
|
||||
const privilegedGlobals = Object.keys(
|
||||
require("../environments/privileged.js").globals
|
||||
);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
|
@ -18,27 +20,32 @@ module.exports = {
|
|||
meta: {
|
||||
messages: {
|
||||
unexpectedCall: "Unexpected call to Cu.importGlobalProperties",
|
||||
unexpectedCallWebIdl: "Unnecessary call to Cu.importGlobalProperties (webidl names are automatically imported)",
|
||||
unexpectedCallWebIdl:
|
||||
"Unnecessary call to Cu.importGlobalProperties (webidl names are automatically imported)",
|
||||
},
|
||||
schema: [{
|
||||
schema: [
|
||||
{
|
||||
// XXX Better name?
|
||||
"enum": ["everything", "allownonwebidl"],
|
||||
}],
|
||||
enum: ["everything", "allownonwebidl"],
|
||||
},
|
||||
],
|
||||
type: "problem",
|
||||
},
|
||||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
if (node.callee.type !== "MemberExpression") {
|
||||
return;
|
||||
}
|
||||
let memexp = node.callee;
|
||||
if (memexp.object.type === "Identifier" &&
|
||||
if (
|
||||
memexp.object.type === "Identifier" &&
|
||||
// Only Cu, not Components.utils; see bug 1230369.
|
||||
memexp.object.name === "Cu" &&
|
||||
memexp.property.type === "Identifier" &&
|
||||
memexp.property.name === "importGlobalProperties") {
|
||||
memexp.property.name === "importGlobalProperties"
|
||||
) {
|
||||
if (context.options.includes("allownonwebidl")) {
|
||||
for (let element of node.arguments[0].elements) {
|
||||
if (privilegedGlobals.includes(element.value)) {
|
||||
|
|
|
@ -17,7 +17,7 @@ module.exports = function(context) {
|
|||
// Public
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
if (typeof(context.options[0]) !== "string") {
|
||||
if (typeof context.options[0] !== "string") {
|
||||
throw new Error("reject-some-requires expects a regexp");
|
||||
}
|
||||
const RX = new RegExp(context.options[0]);
|
||||
|
@ -29,17 +29,21 @@ module.exports = function(context) {
|
|||
};
|
||||
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
if (node.callee.type == "Identifier" &&
|
||||
CallExpression(node) {
|
||||
if (
|
||||
node.callee.type == "Identifier" &&
|
||||
node.callee.name == "require" &&
|
||||
node.arguments.length == 1 &&
|
||||
node.arguments[0].type == "Literal") {
|
||||
node.arguments[0].type == "Literal"
|
||||
) {
|
||||
checkPath(node, node.arguments[0].value);
|
||||
} else if (node.callee.type == "MemberExpression" &&
|
||||
} else if (
|
||||
node.callee.type == "MemberExpression" &&
|
||||
node.callee.property.type == "Identifier" &&
|
||||
node.callee.property.name == "lazyRequireGetter" &&
|
||||
node.arguments.length >= 3 &&
|
||||
node.arguments[2].type == "Literal") {
|
||||
node.arguments[2].type == "Literal"
|
||||
) {
|
||||
checkPath(node, node.arguments[2].value);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -17,13 +17,15 @@ module.exports = {
|
|||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
if (node.callee.type === "MemberExpression") {
|
||||
let memexp = node.callee;
|
||||
if (memexp.object.type === "Identifier" &&
|
||||
if (
|
||||
memexp.object.type === "Identifier" &&
|
||||
memexp.object.name === "Assert" &&
|
||||
memexp.property.type === "Identifier" &&
|
||||
memexp.property.name === "rejects") {
|
||||
memexp.property.name === "rejects"
|
||||
) {
|
||||
// We have ourselves an Assert.rejects.
|
||||
|
||||
if (node.parent.type !== "AwaitExpression") {
|
||||
|
|
|
@ -25,13 +25,19 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"MemberExpression": function(node) {
|
||||
if (node.object.type === "Identifier" &&
|
||||
MemberExpression(node) {
|
||||
if (
|
||||
node.object.type === "Identifier" &&
|
||||
node.object.name === "Components" &&
|
||||
node.property.type === "Identifier" &&
|
||||
Object.getOwnPropertyNames(componentsMap).includes(node.property.name)) {
|
||||
context.report(node,
|
||||
`Use ${componentsMap[node.property.name]} rather than Components.${node.property.name}`);
|
||||
Object.getOwnPropertyNames(componentsMap).includes(node.property.name)
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
`Use ${componentsMap[node.property.name]} rather than Components.${
|
||||
node.property.name
|
||||
}`
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -18,17 +18,19 @@ function isIdentifier(node, id) {
|
|||
}
|
||||
|
||||
function isMemberExpression(node, object, member) {
|
||||
return (node.type === "MemberExpression" &&
|
||||
return (
|
||||
node.type === "MemberExpression" &&
|
||||
isIdentifier(node.object, object) &&
|
||||
isIdentifier(node.property, member));
|
||||
isIdentifier(node.property, member)
|
||||
);
|
||||
}
|
||||
|
||||
const MSG_NO_JS_QUERY_INTERFACE = (
|
||||
const MSG_NO_JS_QUERY_INTERFACE =
|
||||
"Please use ChromeUtils.generateQI rather than manually creating " +
|
||||
"JavaScript QueryInterface functions");
|
||||
"JavaScript QueryInterface functions";
|
||||
|
||||
const MSG_NO_XPCOMUTILS_GENERATEQI = (
|
||||
"Please use ChromeUtils.generateQI instead of XPCOMUtils.generateQI");
|
||||
const MSG_NO_XPCOMUTILS_GENERATEQI =
|
||||
"Please use ChromeUtils.generateQI instead of XPCOMUtils.generateQI";
|
||||
|
||||
function funcToGenerateQI(context, node) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
|
@ -41,7 +43,8 @@ function funcToGenerateQI(context, node) {
|
|||
interfaces.push(match[1] || match[2]);
|
||||
}
|
||||
|
||||
let ifaces = interfaces.filter(iface => iface != "nsISupports")
|
||||
let ifaces = interfaces
|
||||
.filter(iface => iface != "nsISupports")
|
||||
.map(iface => JSON.stringify(iface))
|
||||
.join(", ");
|
||||
|
||||
|
@ -55,7 +58,7 @@ module.exports = {
|
|||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
let { callee } = node;
|
||||
if (isMemberExpression(callee, "XPCOMUtils", "generateQI")) {
|
||||
context.report({
|
||||
|
@ -68,7 +71,9 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
|
||||
"AssignmentExpression > MemberExpression[property.name='QueryInterface']": function(node) {
|
||||
"AssignmentExpression > MemberExpression[property.name='QueryInterface']": function(
|
||||
node
|
||||
) {
|
||||
const { right } = node.parent;
|
||||
if (right.type === "FunctionExpression") {
|
||||
context.report({
|
||||
|
@ -81,7 +86,9 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
|
||||
"Property[key.name='QueryInterface'][value.type='FunctionExpression']": function(node) {
|
||||
"Property[key.name='QueryInterface'][value.type='FunctionExpression']": function(
|
||||
node
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: MSG_NO_JS_QUERY_INTERFACE,
|
||||
|
@ -94,4 +101,3 @@ module.exports = {
|
|||
};
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -18,22 +18,24 @@ function isIdentifier(node, id) {
|
|||
}
|
||||
|
||||
function isMemberExpression(node, object, member) {
|
||||
return (node.type === "MemberExpression" &&
|
||||
return (
|
||||
node.type === "MemberExpression" &&
|
||||
isIdentifier(node.object, object) &&
|
||||
isIdentifier(node.property, member));
|
||||
isIdentifier(node.property, member)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
schema: [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allowCu": {
|
||||
"type": "boolean",
|
||||
type: "object",
|
||||
properties: {
|
||||
allowCu: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
"additionalProperties": false,
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
fixable: "code",
|
||||
|
@ -41,7 +43,7 @@ module.exports = {
|
|||
|
||||
create(context) {
|
||||
return {
|
||||
"CallExpression": function(node) {
|
||||
CallExpression(node) {
|
||||
if (node.callee.type !== "MemberExpression") {
|
||||
return;
|
||||
}
|
||||
|
@ -50,9 +52,11 @@ module.exports = {
|
|||
let { callee } = node;
|
||||
|
||||
// Is the expression starting with `Cu` or `Components.utils`?
|
||||
if (((!allowCu && isIdentifier(callee.object, "Cu")) ||
|
||||
if (
|
||||
((!allowCu && isIdentifier(callee.object, "Cu")) ||
|
||||
isMemberExpression(callee.object, "Components", "utils")) &&
|
||||
isIdentifier(callee.property, "import")) {
|
||||
isIdentifier(callee.property, "import")
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: "Please use ChromeUtils.import instead of Cu.import",
|
||||
|
@ -62,14 +66,20 @@ module.exports = {
|
|||
});
|
||||
}
|
||||
|
||||
if (isMemberExpression(callee, "XPCOMUtils", "defineLazyModuleGetter") &&
|
||||
node.arguments.length < 4) {
|
||||
if (
|
||||
isMemberExpression(callee, "XPCOMUtils", "defineLazyModuleGetter") &&
|
||||
node.arguments.length < 4
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: ("Please use ChromeUtils.defineModuleGetter instead of " +
|
||||
"XPCOMUtils.defineLazyModuleGetter"),
|
||||
message:
|
||||
"Please use ChromeUtils.defineModuleGetter instead of " +
|
||||
"XPCOMUtils.defineLazyModuleGetter",
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(callee, "ChromeUtils.defineModuleGetter");
|
||||
return fixer.replaceText(
|
||||
callee,
|
||||
"ChromeUtils.defineModuleGetter"
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,21 +19,22 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"TryStatement": function(node) {
|
||||
TryStatement(node) {
|
||||
let types = ["Bool", "Char", "Float", "Int"];
|
||||
let methods = types.map(type => "get" + type + "Pref");
|
||||
if (node.block.type != "BlockStatement" ||
|
||||
node.block.body.length != 1) {
|
||||
if (node.block.type != "BlockStatement" || node.block.body.length != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
let firstStm = node.block.body[0];
|
||||
if (firstStm.type != "ExpressionStatement" ||
|
||||
if (
|
||||
firstStm.type != "ExpressionStatement" ||
|
||||
firstStm.expression.type != "AssignmentExpression" ||
|
||||
firstStm.expression.right.type != "CallExpression" ||
|
||||
firstStm.expression.right.callee.type != "MemberExpression" ||
|
||||
firstStm.expression.right.callee.property.type != "Identifier" ||
|
||||
!methods.includes(firstStm.expression.right.callee.property.name)) {
|
||||
!methods.includes(firstStm.expression.right.callee.property.name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,22 +18,26 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"BinaryExpression": function(node) {
|
||||
if (node.left.type != "CallExpression" ||
|
||||
BinaryExpression(node) {
|
||||
if (
|
||||
node.left.type != "CallExpression" ||
|
||||
node.left.callee.type != "MemberExpression" ||
|
||||
node.left.callee.property.type != "Identifier" ||
|
||||
node.left.callee.property.name != "indexOf") {
|
||||
node.left.callee.property.name != "indexOf"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((["!=", "!==", "==", "==="].includes(node.operator) &&
|
||||
if (
|
||||
(["!=", "!==", "==", "==="].includes(node.operator) &&
|
||||
node.right.type == "UnaryExpression" &&
|
||||
node.right.operator == "-" &&
|
||||
node.right.argument.type == "Literal" &&
|
||||
node.right.argument.value == 1) ||
|
||||
([">=", "<"].includes(node.operator) &&
|
||||
node.right.type == "Literal" &&
|
||||
node.right.value == 0)) {
|
||||
node.right.value == 0)
|
||||
) {
|
||||
context.report(node, "use .includes instead of .indexOf");
|
||||
}
|
||||
},
|
||||
|
|
|
@ -18,17 +18,21 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"MemberExpression": function(node) {
|
||||
if (node.property.type != "Identifier" ||
|
||||
MemberExpression(node) {
|
||||
if (
|
||||
node.property.type != "Identifier" ||
|
||||
node.property.name != "defaultView" ||
|
||||
node.object.type != "MemberExpression" ||
|
||||
node.object.property.type != "Identifier" ||
|
||||
node.object.property.name != "ownerDocument") {
|
||||
node.object.property.name != "ownerDocument"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report(node,
|
||||
"use .ownerGlobal instead of .ownerDocument.defaultView");
|
||||
context.report(
|
||||
node,
|
||||
"use .ownerGlobal instead of .ownerDocument.defaultView"
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -18,8 +18,9 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"ExpressionStatement": function(node) {
|
||||
if (!node.expression ||
|
||||
ExpressionStatement(node) {
|
||||
if (
|
||||
!node.expression ||
|
||||
node.expression.type != "CallExpression" ||
|
||||
!node.expression.callee ||
|
||||
node.expression.callee.type != "MemberExpression" ||
|
||||
|
@ -27,12 +28,17 @@ module.exports = function(context) {
|
|||
node.expression.callee.property.type != "Identifier" ||
|
||||
(node.expression.callee.property.name != "concat" &&
|
||||
node.expression.callee.property.name != "join" &&
|
||||
node.expression.callee.property.name != "slice")) {
|
||||
node.expression.callee.property.name != "slice")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.report(node,
|
||||
`{Array/String}.${node.expression.callee.property.name} doesn't modify the instance in-place`);
|
||||
context.report(
|
||||
node,
|
||||
`{Array/String}.${
|
||||
node.expression.callee.property.name
|
||||
} doesn't modify the instance in-place`
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -22,16 +22,16 @@ var servicesASTParser = {
|
|||
identifiers: {},
|
||||
// These interfaces are difficult/not possible to get via processing.
|
||||
result: {
|
||||
"nsIPrefBranch": "prefs",
|
||||
"nsIPrefService": "prefs",
|
||||
"nsIXULRuntime": "appinfo",
|
||||
"nsIXULAppInfo": "appinfo",
|
||||
"nsIDirectoryService": "dirsvc",
|
||||
"nsIProperties": "dirsvc",
|
||||
"nsIIOService": "io",
|
||||
"nsISpeculativeConnect": "io",
|
||||
"nsICookieManager": "cookies",
|
||||
"nsIBlocklistService": "blocklist",
|
||||
nsIPrefBranch: "prefs",
|
||||
nsIPrefService: "prefs",
|
||||
nsIXULRuntime: "appinfo",
|
||||
nsIXULAppInfo: "appinfo",
|
||||
nsIDirectoryService: "dirsvc",
|
||||
nsIProperties: "dirsvc",
|
||||
nsIIOService: "io",
|
||||
nsISpeculativeConnect: "io",
|
||||
nsICookieManager: "cookies",
|
||||
nsIBlocklistService: "blocklist",
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -39,10 +39,12 @@ var servicesASTParser = {
|
|||
* with objects, and records the assumed interface definitions.
|
||||
*/
|
||||
VariableDeclaration(node, parents) {
|
||||
if (node.declarations.length === 1 &&
|
||||
if (
|
||||
node.declarations.length === 1 &&
|
||||
node.declarations[0].id &&
|
||||
helpers.getIsGlobalScope(parents) &&
|
||||
node.declarations[0].init.type === "ObjectExpression") {
|
||||
node.declarations[0].init.type === "ObjectExpression"
|
||||
) {
|
||||
let name = node.declarations[0].id.name;
|
||||
let interfaces = {};
|
||||
|
||||
|
@ -61,13 +63,16 @@ var servicesASTParser = {
|
|||
* them to the identifier tables created by the VariableDeclaration calls.
|
||||
*/
|
||||
AssignmentExpression(node, parents) {
|
||||
if (node.left.type === "MemberExpression" &&
|
||||
if (
|
||||
node.left.type === "MemberExpression" &&
|
||||
node.right.type === "ArrayExpression" &&
|
||||
helpers.getIsGlobalScope(parents)) {
|
||||
helpers.getIsGlobalScope(parents)
|
||||
) {
|
||||
let variableName = node.left.object.name;
|
||||
if (variableName in this.identifiers) {
|
||||
let servicesPropName = node.left.property.name;
|
||||
this.identifiers[variableName][servicesPropName] = node.right.elements[1].value;
|
||||
this.identifiers[variableName][servicesPropName] =
|
||||
node.right.elements[1].value;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -78,11 +83,13 @@ var servicesASTParser = {
|
|||
* Services.jsm is caching.
|
||||
*/
|
||||
CallExpression(node) {
|
||||
if (node.callee.object &&
|
||||
if (
|
||||
node.callee.object &&
|
||||
node.callee.object.name === "XPCOMUtils" &&
|
||||
node.callee.property &&
|
||||
node.callee.property.name === "defineLazyServiceGetters" &&
|
||||
node.arguments.length >= 2) {
|
||||
node.arguments.length >= 2
|
||||
) {
|
||||
// The second argument has the getters name.
|
||||
let gettersVarName = node.arguments[1].name;
|
||||
if (!(gettersVarName in this.identifiers)) {
|
||||
|
@ -97,7 +104,12 @@ var servicesASTParser = {
|
|||
};
|
||||
|
||||
function getInterfacesFromServicesFile() {
|
||||
let filePath = path.join(helpers.rootDir, "toolkit", "modules", "Services.jsm");
|
||||
let filePath = path.join(
|
||||
helpers.rootDir,
|
||||
"toolkit",
|
||||
"modules",
|
||||
"Services.jsm"
|
||||
);
|
||||
|
||||
let content = fs.readFileSync(filePath, "utf8");
|
||||
|
||||
|
@ -120,9 +132,9 @@ function getInterfacesFromServicesFile() {
|
|||
return servicesASTParser.result;
|
||||
}
|
||||
|
||||
let getServicesInterfaceMap = helpers.isMozillaCentralBased() ?
|
||||
getInterfacesFromServicesFile() :
|
||||
helpers.getSavedRuleData("use-services.js");
|
||||
let getServicesInterfaceMap = helpers.isMozillaCentralBased()
|
||||
? getInterfacesFromServicesFile()
|
||||
: helpers.getSavedRuleData("use-services.js");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
|
@ -141,7 +153,8 @@ module.exports = function(context) {
|
|||
},
|
||||
|
||||
CallExpression(node) {
|
||||
if (!node.callee ||
|
||||
if (
|
||||
!node.callee ||
|
||||
!node.callee.property ||
|
||||
node.callee.property.type != "Identifier" ||
|
||||
node.callee.property.name != "getService" ||
|
||||
|
@ -149,14 +162,18 @@ module.exports = function(context) {
|
|||
!node.arguments[0].property ||
|
||||
node.arguments[0].property.type != "Identifier" ||
|
||||
!node.arguments[0].property.name ||
|
||||
!(node.arguments[0].property.name in getServicesInterfaceMap)) {
|
||||
!(node.arguments[0].property.name in getServicesInterfaceMap)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
let serviceName = getServicesInterfaceMap[node.arguments[0].property.name];
|
||||
let serviceName =
|
||||
getServicesInterfaceMap[node.arguments[0].property.name];
|
||||
|
||||
context.report(node,
|
||||
`Use Services.${serviceName} rather than getService().`);
|
||||
context.report(
|
||||
node,
|
||||
`Use Services.${serviceName} rather than getService().`
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ module.exports = function(context) {
|
|||
// --------------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
"VariableDeclaration": function(node) {
|
||||
VariableDeclaration(node) {
|
||||
if (node.kind === "var") {
|
||||
if (helpers.getIsGlobalScope(context.getAncestors())) {
|
||||
return;
|
||||
|
|
|
@ -29,7 +29,11 @@ function MozillaFormatter(runner) {
|
|||
failures++;
|
||||
// Replace any newlines in the title.
|
||||
let title = test.title.replace(/\n/g, "|");
|
||||
console.log(`TEST-UNEXPECTED-FAIL | ${path.basename(test.file)} | ${title} | ${err.message}`);
|
||||
console.log(
|
||||
`TEST-UNEXPECTED-FAIL | ${path.basename(test.file)} | ${title} | ${
|
||||
err.message
|
||||
}`
|
||||
);
|
||||
});
|
||||
|
||||
runner.on("end", function() {
|
||||
|
|
|
@ -10,19 +10,32 @@ var fs = require("fs");
|
|||
var path = require("path");
|
||||
var helpers = require("../lib/helpers");
|
||||
|
||||
const eslintDir = path.join(helpers.rootDir,
|
||||
"tools", "lint", "eslint");
|
||||
const eslintDir = path.join(helpers.rootDir, "tools", "lint", "eslint");
|
||||
|
||||
const globalsFile = path.join(eslintDir, "eslint-plugin-mozilla",
|
||||
"lib", "environments", "saved-globals.json");
|
||||
const rulesFile = path.join(eslintDir, "eslint-plugin-mozilla",
|
||||
"lib", "rules", "saved-rules-data.json");
|
||||
const globalsFile = path.join(
|
||||
eslintDir,
|
||||
"eslint-plugin-mozilla",
|
||||
"lib",
|
||||
"environments",
|
||||
"saved-globals.json"
|
||||
);
|
||||
const rulesFile = path.join(
|
||||
eslintDir,
|
||||
"eslint-plugin-mozilla",
|
||||
"lib",
|
||||
"rules",
|
||||
"saved-rules-data.json"
|
||||
);
|
||||
|
||||
console.log("Copying modules.json");
|
||||
|
||||
const modulesFile = path.join(eslintDir, "modules.json");
|
||||
const shipModulesFile = path.join(eslintDir, "eslint-plugin-mozilla", "lib",
|
||||
"modules.json");
|
||||
const shipModulesFile = path.join(
|
||||
eslintDir,
|
||||
"eslint-plugin-mozilla",
|
||||
"lib",
|
||||
"modules.json"
|
||||
);
|
||||
|
||||
fs.writeFileSync(shipModulesFile, fs.readFileSync(modulesFile));
|
||||
|
||||
|
@ -31,7 +44,10 @@ console.log("Generating globals file");
|
|||
// Export the environments.
|
||||
let environmentGlobals = require("../lib/index.js").environments;
|
||||
|
||||
return fs.writeFile(globalsFile, JSON.stringify({environments: environmentGlobals}), err => {
|
||||
return fs.writeFile(
|
||||
globalsFile,
|
||||
JSON.stringify({ environments: environmentGlobals }),
|
||||
err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
|
@ -53,4 +69,5 @@ return fs.writeFile(globalsFile, JSON.stringify({environments: environmentGlobal
|
|||
|
||||
console.log("Globals file generation complete");
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -28,12 +28,15 @@ ruleTester.run("avoid-Date-timing", rule, {
|
|||
"Date.UTC(2017, 7);",
|
||||
],
|
||||
invalid: [
|
||||
invalidCode("Date.now();", "CallExpression",
|
||||
"use performance.now() instead of Date.now() " +
|
||||
"for timing measurements"),
|
||||
invalidCode("new Date();", "NewExpression",
|
||||
"use performance.now() instead of new Date() " +
|
||||
"for timing measurements"),
|
||||
invalidCode(
|
||||
"Date.now();",
|
||||
"CallExpression",
|
||||
"use performance.now() instead of Date.now() " + "for timing measurements"
|
||||
),
|
||||
invalidCode(
|
||||
"new Date();",
|
||||
"NewExpression",
|
||||
"use performance.now() instead of new Date() " + "for timing measurements"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
|
|||
|
||||
function invalidCode(code, message) {
|
||||
if (!message) {
|
||||
message = "use element.remove() instead of " +
|
||||
message =
|
||||
"use element.remove() instead of " +
|
||||
"element.parentNode.removeChild(element)";
|
||||
}
|
||||
return { code, errors: [{ message, type: "CallExpression" }] };
|
||||
|
@ -36,8 +37,10 @@ ruleTester.run("avoid-removeChild", rule, {
|
|||
invalidCode("elt.parentNode.parentNode.removeChild(elt.parentNode);"),
|
||||
invalidCode("$(e).parentNode.removeChild($(e));"),
|
||||
invalidCode("$('e').parentNode.removeChild($('e'));"),
|
||||
invalidCode("elt.removeChild(elt.firstChild);",
|
||||
invalidCode(
|
||||
"elt.removeChild(elt.firstChild);",
|
||||
"use element.firstChild.remove() instead of " +
|
||||
"element.removeChild(element.firstChild)"),
|
||||
"element.removeChild(element.firstChild)"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -57,23 +57,33 @@ ruleTester.run("balanced-listeners", rule, {
|
|||
"elt.addEventListener('event', handler, {once: true, capture: true});",
|
||||
],
|
||||
invalid: [
|
||||
error("elt.addEventListener('click', handler, false);",
|
||||
"No corresponding 'removeEventListener(click)' was found."),
|
||||
error(
|
||||
"elt.addEventListener('click', handler, false);",
|
||||
"No corresponding 'removeEventListener(click)' was found."
|
||||
),
|
||||
|
||||
error("elt.addEventListener('click', handler, false);" +
|
||||
error(
|
||||
"elt.addEventListener('click', handler, false);" +
|
||||
"elt.removeEventListener('click', handler, true);",
|
||||
"No corresponding 'removeEventListener(click)' was found."),
|
||||
"No corresponding 'removeEventListener(click)' was found."
|
||||
),
|
||||
|
||||
error("elt.addEventListener('click', handler, {capture: false});" +
|
||||
error(
|
||||
"elt.addEventListener('click', handler, {capture: false});" +
|
||||
"elt.removeEventListener('click', handler, true);",
|
||||
"No corresponding 'removeEventListener(click)' was found."),
|
||||
"No corresponding 'removeEventListener(click)' was found."
|
||||
),
|
||||
|
||||
error("elt.addEventListener('click', handler, {capture: true});" +
|
||||
error(
|
||||
"elt.addEventListener('click', handler, {capture: true});" +
|
||||
"elt.removeEventListener('click', handler);",
|
||||
"No corresponding 'removeEventListener(click)' was found."),
|
||||
"No corresponding 'removeEventListener(click)' was found."
|
||||
),
|
||||
|
||||
error("elt.addEventListener('click', handler, true);" +
|
||||
error(
|
||||
"elt.addEventListener('click', handler, true);" +
|
||||
"elt.removeEventListener('click', handler);",
|
||||
"No corresponding 'removeEventListener(click)' was found."),
|
||||
"No corresponding 'removeEventListener(click)' was found."
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -26,11 +26,20 @@ ruleTester.run("mark-exported-symbols-as-used", rule, {
|
|||
"this.EXPORTED_SYMBOLS = ['foo'];",
|
||||
],
|
||||
invalid: [
|
||||
invalidCode("let EXPORTED_SYMBOLS = ['foo'];", "VariableDeclaration",
|
||||
"EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`"),
|
||||
invalidCode("var EXPORTED_SYMBOLS = 'foo';", "VariableDeclaration",
|
||||
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS"),
|
||||
invalidCode("this.EXPORTED_SYMBOLS = 'foo';", "AssignmentExpression",
|
||||
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS"),
|
||||
invalidCode(
|
||||
"let EXPORTED_SYMBOLS = ['foo'];",
|
||||
"VariableDeclaration",
|
||||
"EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`"
|
||||
),
|
||||
invalidCode(
|
||||
"var EXPORTED_SYMBOLS = 'foo';",
|
||||
"VariableDeclaration",
|
||||
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS"
|
||||
),
|
||||
invalidCode(
|
||||
"this.EXPORTED_SYMBOLS = 'foo';",
|
||||
"AssignmentExpression",
|
||||
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -21,7 +21,8 @@ function wrapCode(code, filename = "xpcshell/test_foo.js") {
|
|||
}
|
||||
|
||||
function invalidCode(code) {
|
||||
let message = "listen for events instead of setTimeout() with arbitrary delay";
|
||||
let message =
|
||||
"listen for events instead of setTimeout() with arbitrary delay";
|
||||
let obj = wrapCode(code);
|
||||
obj.errors = [{ message, type: "CallExpression" }];
|
||||
return obj;
|
||||
|
@ -38,4 +39,3 @@ ruleTester.run("no-arbitrary-setTimeout", rule, {
|
|||
invalidCode("setTimeout(function() {}, timeout);"),
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -23,10 +23,7 @@ function callError(message) {
|
|||
const MESSAGE = "Don't compare for inexact equality against boolean literals";
|
||||
|
||||
ruleTester.run("no-compare-against-boolean-literals", rule, {
|
||||
valid: [
|
||||
`if (!foo) {}`,
|
||||
`if (!!foo) {}`,
|
||||
],
|
||||
valid: [`if (!foo) {}`, `if (!!foo) {}`],
|
||||
invalid: [
|
||||
{
|
||||
code: `if (foo == true) {}`,
|
||||
|
@ -62,4 +59,3 @@ ruleTester.run("no-compare-against-boolean-literals", rule, {
|
|||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -21,10 +21,13 @@ function invalidCode(code, varNames) {
|
|||
varNames = [varNames];
|
||||
}
|
||||
return {
|
||||
code, errors: varNames.map(name => [{
|
||||
code,
|
||||
errors: varNames.map(name => [
|
||||
{
|
||||
message: `${name} is now defined in global scope, a separate definition is no longer necessary.`,
|
||||
type: "VariableDeclarator",
|
||||
}]),
|
||||
},
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,7 +50,13 @@ ruleTester.run("no-define-cc-etc", rule, {
|
|||
invalidCode("const {classes: Cc} = Components;", "Cc"),
|
||||
invalidCode("let {classes: Cc, manager: Cm} = Components", "Cc"),
|
||||
invalidCode("const Cu = Components.utils;", "Cu"),
|
||||
invalidCode("var Ci = Components.interfaces, Cc = Components.classes;", ["Ci", "Cc"]),
|
||||
invalidCode("var {'interfaces': Ci, 'classes': Cc} = Components;", ["Ci", "Cc"]),
|
||||
invalidCode("var Ci = Components.interfaces, Cc = Components.classes;", [
|
||||
"Ci",
|
||||
"Cc",
|
||||
]),
|
||||
invalidCode("var {'interfaces': Ci, 'classes': Cc} = Components;", [
|
||||
"Ci",
|
||||
"Cc",
|
||||
]),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -91,47 +91,47 @@ ruleTester.run("no-useless-parameters", rule, {
|
|||
code: "elt.addEventListener('click', handler, false);",
|
||||
output: "elt.addEventListener('click', handler);",
|
||||
errors: callError(
|
||||
"addEventListener's third parameter can be omitted when it's false."),
|
||||
"addEventListener's third parameter can be omitted when it's false."
|
||||
),
|
||||
},
|
||||
{
|
||||
code: "elt.removeEventListener('click', handler, false);",
|
||||
output: "elt.removeEventListener('click', handler);",
|
||||
errors: callError(
|
||||
"removeEventListener's third parameter can be omitted when it's" +
|
||||
" false."),
|
||||
" false."
|
||||
),
|
||||
},
|
||||
{
|
||||
code: "Services.obs.addObserver(this, 'topic', false);",
|
||||
output: "Services.obs.addObserver(this, 'topic');",
|
||||
errors: callError(
|
||||
"addObserver's third parameter can be omitted when it's" +
|
||||
" false."),
|
||||
"addObserver's third parameter can be omitted when it's" + " false."
|
||||
),
|
||||
},
|
||||
{
|
||||
code: "Services.prefs.addObserver('branch', this, false);",
|
||||
output: "Services.prefs.addObserver('branch', this);",
|
||||
errors: callError(
|
||||
"addObserver's third parameter can be omitted when it's" +
|
||||
" false."),
|
||||
"addObserver's third parameter can be omitted when it's" + " false."
|
||||
),
|
||||
},
|
||||
{
|
||||
code: "array.appendElement(elt, false);",
|
||||
output: "array.appendElement(elt);",
|
||||
errors: callError(
|
||||
"appendElement's second parameter can be omitted when it's" +
|
||||
" false."),
|
||||
"appendElement's second parameter can be omitted when it's" + " false."
|
||||
),
|
||||
},
|
||||
{
|
||||
code: "Services.obs.notifyObservers(obj, 'topic', null);",
|
||||
output: "Services.obs.notifyObservers(obj, 'topic');",
|
||||
errors: callError(
|
||||
"notifyObservers's third parameter can be omitted."),
|
||||
errors: callError("notifyObservers's third parameter can be omitted."),
|
||||
},
|
||||
{
|
||||
code: "Services.obs.notifyObservers(obj, 'topic', '');",
|
||||
output: "Services.obs.notifyObservers(obj, 'topic');",
|
||||
errors: callError(
|
||||
"notifyObservers's third parameter can be omitted."),
|
||||
errors: callError("notifyObservers's third parameter can be omitted."),
|
||||
},
|
||||
{
|
||||
code: "window.getComputedStyle(elt, null);",
|
||||
|
|
|
@ -17,7 +17,8 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
|
|||
// ------------------------------------------------------------------------------
|
||||
|
||||
function invalidCode(code) {
|
||||
let message = "use {once: true} instead of removeEventListener " +
|
||||
let message =
|
||||
"use {once: true} instead of removeEventListener " +
|
||||
"as the first instruction of the listener";
|
||||
return { code, errors: [{ message, type: "CallExpression" }] };
|
||||
}
|
||||
|
@ -63,24 +64,36 @@ ruleTester.run("no-useless-removeEventListener", rule, {
|
|||
"myfunc.addEventListener(listener);",
|
||||
],
|
||||
invalid: [
|
||||
invalidCode("elt.addEventListener('click', function listener() {" +
|
||||
invalidCode(
|
||||
"elt.addEventListener('click', function listener() {" +
|
||||
" elt.removeEventListener('click', listener);" +
|
||||
"});"),
|
||||
invalidCode("elt.addEventListener('click', function listener() {" +
|
||||
"});"
|
||||
),
|
||||
invalidCode(
|
||||
"elt.addEventListener('click', function listener() {" +
|
||||
" elt.removeEventListener('click', listener, true);" +
|
||||
"}, true);"),
|
||||
invalidCode("elt.addEventListener('click', function listener() {" +
|
||||
"}, true);"
|
||||
),
|
||||
invalidCode(
|
||||
"elt.addEventListener('click', function listener() {" +
|
||||
" elt.removeEventListener('click', listener);" +
|
||||
"}, {once: true});"),
|
||||
invalidCode("elt.addEventListener('click', function listener() {" +
|
||||
"}, {once: true});"
|
||||
),
|
||||
invalidCode(
|
||||
"elt.addEventListener('click', function listener() {" +
|
||||
" /* Comment */" +
|
||||
" elt.removeEventListener('click', listener);" +
|
||||
"});"),
|
||||
invalidCode("elt.addEventListener('click', function() {" +
|
||||
"});"
|
||||
),
|
||||
invalidCode(
|
||||
"elt.addEventListener('click', function() {" +
|
||||
" elt.removeEventListener('click', arguments.callee);" +
|
||||
"});"),
|
||||
invalidCode("elt.addEventListener(eventName, function listener() {" +
|
||||
"});"
|
||||
),
|
||||
invalidCode(
|
||||
"elt.addEventListener(eventName, function listener() {" +
|
||||
" elt.removeEventListener(eventName, listener);" +
|
||||
"});"),
|
||||
"});"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -30,16 +30,17 @@ ruleTester.run("no-useless-run-test", rule, {
|
|||
],
|
||||
invalid: [
|
||||
// Single-line case.
|
||||
invalidCode(
|
||||
"function run_test() { run_next_test(); }",
|
||||
""),
|
||||
invalidCode("function run_test() { run_next_test(); }", ""),
|
||||
// Multiple-line cases
|
||||
invalidCode(`
|
||||
invalidCode(
|
||||
`
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}`,
|
||||
``),
|
||||
invalidCode(`
|
||||
``
|
||||
),
|
||||
invalidCode(
|
||||
`
|
||||
foo();
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
|
@ -47,8 +48,10 @@ function run_test() {
|
|||
`,
|
||||
`
|
||||
foo();
|
||||
`),
|
||||
invalidCode(`
|
||||
`
|
||||
),
|
||||
invalidCode(
|
||||
`
|
||||
foo();
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
|
@ -58,8 +61,10 @@ bar();
|
|||
`
|
||||
foo();
|
||||
bar();
|
||||
`),
|
||||
invalidCode(`
|
||||
`
|
||||
),
|
||||
invalidCode(
|
||||
`
|
||||
foo();
|
||||
|
||||
function run_test() {
|
||||
|
@ -70,8 +75,10 @@ bar();`,
|
|||
`
|
||||
foo();
|
||||
|
||||
bar();`),
|
||||
invalidCode(`
|
||||
bar();`
|
||||
),
|
||||
invalidCode(
|
||||
`
|
||||
foo();
|
||||
|
||||
function run_test() {
|
||||
|
@ -86,8 +93,10 @@ foo();
|
|||
|
||||
// A comment
|
||||
bar();
|
||||
`),
|
||||
invalidCode(`
|
||||
`
|
||||
),
|
||||
invalidCode(
|
||||
`
|
||||
foo();
|
||||
|
||||
/**
|
||||
|
@ -109,6 +118,7 @@ foo();
|
|||
|
||||
// A comment
|
||||
bar();
|
||||
`),
|
||||
`
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -17,23 +17,30 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8 } });
|
|||
// ------------------------------------------------------------------------------
|
||||
|
||||
ruleTester.run("reject-importGlobalProperties", rule, {
|
||||
valid: [{
|
||||
valid: [
|
||||
{
|
||||
code: "Cu.something();",
|
||||
}, {
|
||||
},
|
||||
{
|
||||
options: ["allownonwebidl"],
|
||||
code: "Cu.importGlobalProperties(['fetch'])",
|
||||
}],
|
||||
invalid: [{
|
||||
},
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
code: "Cu.importGlobalProperties(['fetch'])",
|
||||
options: ["everything"],
|
||||
errors: [{ messageId: "unexpectedCall" }],
|
||||
}, {
|
||||
},
|
||||
{
|
||||
code: "Cu.importGlobalProperties(['TextEncoder'])",
|
||||
options: ["everything"],
|
||||
errors: [{ messageId: "unexpectedCall" }],
|
||||
}, {
|
||||
},
|
||||
{
|
||||
code: "Cu.importGlobalProperties(['TextEncoder'])",
|
||||
options: ["allownonwebidl"],
|
||||
errors: [{ messageId: "unexpectedCallWebIdl" }],
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -17,21 +17,39 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
|
|||
// ------------------------------------------------------------------------------
|
||||
|
||||
function invalidCode(code, originalName, newName) {
|
||||
return {code, errors: [{
|
||||
return {
|
||||
code,
|
||||
errors: [
|
||||
{
|
||||
message: `Use ${newName} rather than ${originalName}`,
|
||||
type: "MemberExpression",
|
||||
}]};
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
ruleTester.run("use-cc-etc", rule, {
|
||||
valid: [
|
||||
"Components.Constructor();",
|
||||
"let x = Components.foo;",
|
||||
],
|
||||
valid: ["Components.Constructor();", "let x = Components.foo;"],
|
||||
invalid: [
|
||||
invalidCode("let foo = Components.classes['bar'];", "Components.classes", "Cc"),
|
||||
invalidCode("let bar = Components.interfaces.bar;", "Components.interfaces", "Ci"),
|
||||
invalidCode("Components.results.NS_ERROR_ILLEGAL_INPUT;", "Components.results", "Cr"),
|
||||
invalidCode("Components.utils.reportError('fake');", "Components.utils", "Cu"),
|
||||
invalidCode(
|
||||
"let foo = Components.classes['bar'];",
|
||||
"Components.classes",
|
||||
"Cc"
|
||||
),
|
||||
invalidCode(
|
||||
"let bar = Components.interfaces.bar;",
|
||||
"Components.interfaces",
|
||||
"Ci"
|
||||
),
|
||||
invalidCode(
|
||||
"Components.results.NS_ERROR_ILLEGAL_INPUT;",
|
||||
"Components.results",
|
||||
"Cr"
|
||||
),
|
||||
invalidCode(
|
||||
"Components.utils.reportError('fake');",
|
||||
"Components.utils",
|
||||
"Cu"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -23,19 +23,21 @@ function error(message, type) {
|
|||
return [{ message, type }];
|
||||
}
|
||||
|
||||
const MSG_NO_JS_QUERY_INTERFACE = (
|
||||
const MSG_NO_JS_QUERY_INTERFACE =
|
||||
"Please use ChromeUtils.generateQI rather than manually creating " +
|
||||
"JavaScript QueryInterface functions");
|
||||
"JavaScript QueryInterface functions";
|
||||
|
||||
const MSG_NO_XPCOMUTILS_GENERATEQI = (
|
||||
"Please use ChromeUtils.generateQI instead of XPCOMUtils.generateQI");
|
||||
const MSG_NO_XPCOMUTILS_GENERATEQI =
|
||||
"Please use ChromeUtils.generateQI instead of XPCOMUtils.generateQI";
|
||||
|
||||
/* globals nsIFlug */
|
||||
function QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
if (
|
||||
iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIMeh) ||
|
||||
iid.equals(nsIFlug) ||
|
||||
iid.equals(Ci.amIFoo)) {
|
||||
iid.equals(Ci.amIFoo)
|
||||
) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
|
@ -63,7 +65,10 @@ ruleTester.run("use-chromeutils-generateqi", rule, {
|
|||
errors: error(MSG_NO_JS_QUERY_INTERFACE, "Property"),
|
||||
},
|
||||
{
|
||||
code: `X.prototype = { ${String(QueryInterface).replace(/^function /, "")} };`,
|
||||
code: `X.prototype = { ${String(QueryInterface).replace(
|
||||
/^function /,
|
||||
""
|
||||
)} };`,
|
||||
output: `X.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMeh", "nsIFlug", "amIFoo"]) };`,
|
||||
errors: error(MSG_NO_JS_QUERY_INTERFACE, "Property"),
|
||||
},
|
||||
|
@ -74,4 +79,3 @@ ruleTester.run("use-chromeutils-generateqi", rule, {
|
|||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@ function callError(message) {
|
|||
}
|
||||
|
||||
const MESSAGE_IMPORT = "Please use ChromeUtils.import instead of Cu.import";
|
||||
const MESSAGE_DEFINE = ("Please use ChromeUtils.defineModuleGetter instead of " +
|
||||
"XPCOMUtils.defineLazyModuleGetter");
|
||||
const MESSAGE_DEFINE =
|
||||
"Please use ChromeUtils.defineModuleGetter instead of " +
|
||||
"XPCOMUtils.defineLazyModuleGetter";
|
||||
|
||||
ruleTester.run("use-chromeutils-import", rule, {
|
||||
valid: [
|
||||
|
@ -77,4 +78,3 @@ ruleTester.run("use-chromeutils-import", rule, {
|
|||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -28,12 +28,15 @@ ruleTester.run("use-default-preference-values", rule, {
|
|||
valid: [].concat(
|
||||
methods.map(m => "blah = branch." + m + "('blah', true);"),
|
||||
methods.map(m => "blah = branch." + m + "('blah');"),
|
||||
methods.map(m => "try { canThrow();" +
|
||||
" blah = branch." + m + "('blah'); } catch(e) {}")
|
||||
methods.map(
|
||||
m =>
|
||||
"try { canThrow();" + " blah = branch." + m + "('blah'); } catch(e) {}"
|
||||
)
|
||||
),
|
||||
|
||||
invalid: [].concat(
|
||||
methods.map(m =>
|
||||
invalidCode("try { blah = branch." + m + "('blah'); } catch(e) {}"))
|
||||
invalidCode("try { blah = branch." + m + "('blah'); } catch(e) {}")
|
||||
)
|
||||
),
|
||||
});
|
||||
|
|
|
@ -29,8 +29,7 @@ ruleTester.run("use-ownerGlobal", rule, {
|
|||
],
|
||||
invalid: [
|
||||
invalidCode("aEvent.target.ownerDocument.defaultView;"),
|
||||
invalidCode(
|
||||
"this.DOMPointNode.ownerDocument.defaultView.getSelection();"),
|
||||
invalidCode("this.DOMPointNode.ownerDocument.defaultView.getSelection();"),
|
||||
invalidCode("windowToMessageManager(node.ownerDocument.defaultView);"),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -28,10 +28,13 @@ ruleTester.run("use-services", rule, {
|
|||
"Services.wm.addListener()",
|
||||
],
|
||||
invalid: [
|
||||
invalidCode('Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);',
|
||||
"wm"),
|
||||
invalidCode(
|
||||
'Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);',
|
||||
"wm"
|
||||
),
|
||||
invalidCode(
|
||||
'Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(Components.interfaces.nsIAppStartup);',
|
||||
"startup"),
|
||||
"startup"
|
||||
),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -11,27 +11,41 @@ add_task(async function test_profile_feature_jsallocations() {
|
|||
if (!AppConstants.MOZ_GECKO_PROFILER) {
|
||||
return;
|
||||
}
|
||||
Assert.ok(!Services.profiler.IsActive(), "The profiler is not currently active");
|
||||
Assert.ok(
|
||||
!Services.profiler.IsActive(),
|
||||
"The profiler is not currently active"
|
||||
);
|
||||
|
||||
startProfiler({ features: ["threads", "js", "jsallocations"] });
|
||||
|
||||
const url = BASE_URL + "do_work_500ms.html";
|
||||
await BrowserTestUtils.withNewTab(url, async (contentBrowser) => {
|
||||
const contentPid = await ContentTask.spawn(contentBrowser, null,
|
||||
() => Services.appinfo.processID);
|
||||
await BrowserTestUtils.withNewTab(url, async contentBrowser => {
|
||||
const contentPid = await ContentTask.spawn(
|
||||
contentBrowser,
|
||||
null,
|
||||
() => Services.appinfo.processID
|
||||
);
|
||||
|
||||
// Wait 500ms so that the tab finishes executing.
|
||||
await wait(500);
|
||||
|
||||
// Check that we can get some allocations when the feature is turned on.
|
||||
{
|
||||
const { parentThread, contentThread } = await stopProfilerAndGetThreads(contentPid);
|
||||
Assert.greater(getPayloadsOfType(parentThread, "JS allocation").length, 0,
|
||||
const { parentThread, contentThread } = await stopProfilerAndGetThreads(
|
||||
contentPid
|
||||
);
|
||||
Assert.greater(
|
||||
getPayloadsOfType(parentThread, "JS allocation").length,
|
||||
0,
|
||||
"Allocations were recorded for the parent process' main thread when the " +
|
||||
"JS Allocation feature was turned on.");
|
||||
Assert.greater(getPayloadsOfType(contentThread, "JS allocation").length, 0,
|
||||
"JS Allocation feature was turned on."
|
||||
);
|
||||
Assert.greater(
|
||||
getPayloadsOfType(contentThread, "JS allocation").length,
|
||||
0,
|
||||
"Allocations were recorded for the content process' main thread when the " +
|
||||
"JS Allocation feature was turned on.");
|
||||
"JS Allocation feature was turned on."
|
||||
);
|
||||
}
|
||||
|
||||
// Flush out any straggling allocation markers that may have not been collected
|
||||
|
@ -47,16 +61,22 @@ add_task(async function test_profile_feature_jsallocations() {
|
|||
// Check that no allocations were recorded, and allocation tracking was correctly
|
||||
// turned off.
|
||||
{
|
||||
const { parentThread, contentThread } = await stopProfilerAndGetThreads(contentPid);
|
||||
const { parentThread, contentThread } = await stopProfilerAndGetThreads(
|
||||
contentPid
|
||||
);
|
||||
Assert.equal(
|
||||
getPayloadsOfType(parentThread, "JS allocation").length, 0,
|
||||
getPayloadsOfType(parentThread, "JS allocation").length,
|
||||
0,
|
||||
"No allocations were recorded for the parent processes' main thread when " +
|
||||
"JS allocation was not turned on.");
|
||||
"JS allocation was not turned on."
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
getPayloadsOfType(contentThread, "JS allocation").length, 0,
|
||||
getPayloadsOfType(contentThread, "JS allocation").length,
|
||||
0,
|
||||
"No allocations were recorded for the content processes' main thread when " +
|
||||
"JS allocation was not turned on.");
|
||||
"JS allocation was not turned on."
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -74,7 +94,7 @@ async function doAtLeastOnePeriodicSample() {
|
|||
const sampleCount = await getProfileSampleCount();
|
||||
// Create an infinite loop until a sample has been collected.
|
||||
while (true) {
|
||||
if (sampleCount < await getProfileSampleCount()) {
|
||||
if (sampleCount < (await getProfileSampleCount())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +107,9 @@ async function stopProfilerAndGetThreads(contentPid) {
|
|||
Services.profiler.StopProfiler();
|
||||
|
||||
const parentThread = profile.threads[0];
|
||||
const contentProcess = profile.processes.find(p => p.threads[0].pid == contentPid);
|
||||
const contentProcess = profile.processes.find(
|
||||
p => p.threads[0].pid == contentPid
|
||||
);
|
||||
if (!contentProcess) {
|
||||
throw new Error("Could not find the content process.");
|
||||
}
|
||||
|
|
|
@ -24,7 +24,9 @@ add_task(async function test_profile_single_frame_page_info() {
|
|||
|
||||
let pageFound = false;
|
||||
// We need to find the correct content process for that tab.
|
||||
let contentProcess = profile.processes.find(p => p.threads[0].pid == contentPid);
|
||||
let contentProcess = profile.processes.find(
|
||||
p => p.threads[0].pid == contentPid
|
||||
);
|
||||
for (const page of contentProcess.pages) {
|
||||
if (page.url == url) {
|
||||
Assert.equal(page.url, url);
|
||||
|
|
|
@ -24,7 +24,9 @@ add_task(async function test_profile_pushstate_page_info() {
|
|||
|
||||
let foundPage = 0;
|
||||
// We need to find the correct content process for that tab.
|
||||
let contentProcess = profile.processes.find(p => p.threads[0].pid == contentPid);
|
||||
let contentProcess = profile.processes.find(
|
||||
p => p.threads[0].pid == contentPid
|
||||
);
|
||||
for (const page of contentProcess.pages) {
|
||||
// Before pushState
|
||||
if (page.url == url) {
|
||||
|
|
|
@ -24,7 +24,9 @@ add_task(async function test_profile_replacestate_page_info() {
|
|||
|
||||
let foundPage = 0;
|
||||
// We need to find the correct content process for that tab.
|
||||
let contentProcess = profile.processes.find(p => p.threads[0].pid == contentPid);
|
||||
let contentProcess = profile.processes.find(
|
||||
p => p.threads[0].pid == contentPid
|
||||
);
|
||||
for (const page of contentProcess.pages) {
|
||||
// Before replaceState
|
||||
if (page.url == url) {
|
||||
|
|
|
@ -25,7 +25,9 @@ add_task(async function test_profile_multi_frame_page_info() {
|
|||
|
||||
let foundPage = 0;
|
||||
// We need to find the correct content process for that tab.
|
||||
let contentProcess = profile.processes.find(p => p.threads[0].pid == contentPid);
|
||||
let contentProcess = profile.processes.find(
|
||||
p => p.threads[0].pid == contentPid
|
||||
);
|
||||
for (const page of contentProcess.pages) {
|
||||
// Parent page
|
||||
if (page.url == url) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
const { BrowserTestUtils } = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
|
||||
const { BrowserTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/BrowserTestUtils.jsm"
|
||||
);
|
||||
|
||||
const BASE_URL = "http://example.com/browser/tools/profiler/tests/browser/";
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
(function() {
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { Services } = ChromeUtils.import(
|
||||
"resource://gre/modules/Services.jsm"
|
||||
);
|
||||
|
||||
function startProfiler(settings) {
|
||||
Services.profiler.StartProfiler(
|
||||
|
@ -17,7 +19,9 @@ function startProfiler(settings) {
|
|||
|
||||
function getProfile() {
|
||||
const profile = Services.profiler.getProfileData();
|
||||
info("We got a profile, run the mochitest with `--keep-open true` to see the logged profile in the Web Console.");
|
||||
info(
|
||||
"We got a profile, run the mochitest with `--keep-open true` to see the logged profile in the Web Console."
|
||||
);
|
||||
|
||||
// Run the mochitest with `--keep-open true` to see the logged profile in the
|
||||
// Web console.
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
var {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
var { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
var { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
/**
|
||||
|
@ -31,7 +33,6 @@ function getAllPayloadsOfType(profile, type, payloadTarget = []) {
|
|||
return payloadTarget;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a helper function be able to run `await wait(500)`. Unfortunately this
|
||||
* is needed as the act of collecting functions relies on the periodic sampling of
|
||||
|
|
|
@ -11,8 +11,9 @@ function run_test() {
|
|||
Assert.ok(!Services.profiler.IsActive());
|
||||
|
||||
let jsFuns = Cu.getJSTestingFunctions();
|
||||
if (!jsFuns.isAsmJSCompilationAvailable())
|
||||
if (!jsFuns.isAsmJSCompilationAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ms = 10;
|
||||
Services.profiler.StartProfiler(10000, ms, ["js"]);
|
||||
|
@ -28,20 +29,23 @@ function run_test() {
|
|||
|
||||
var thread0 = Services.profiler.getProfileData().threads[0];
|
||||
|
||||
if (delayMS > 30000)
|
||||
if (delayMS > 30000) {
|
||||
return;
|
||||
}
|
||||
|
||||
delayMS *= 2;
|
||||
|
||||
if (thread0.samples.data.length == 0)
|
||||
if (thread0.samples.data.length == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var lastSample = thread0.samples.data[thread0.samples.data.length - 1];
|
||||
stack = String(getInflatedStackLocations(thread0, lastSample));
|
||||
if (stack.includes("trampoline"))
|
||||
if (stack.includes("trampoline")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function asmjs_module(global, ffis) {
|
||||
"use asm";
|
||||
|
|
|
@ -23,7 +23,7 @@ function run_test() {
|
|||
const then = Date.now();
|
||||
do {
|
||||
let n = 10000;
|
||||
while (--n); // OSR happens here
|
||||
while (--n) {} // OSR happens here
|
||||
// Spin in the hope of getting a sample.
|
||||
} while (Date.now() - then < delayMS);
|
||||
let profile = Services.profiler.getProfileData().threads[0];
|
||||
|
@ -47,6 +47,9 @@ function run_test() {
|
|||
}
|
||||
}
|
||||
}
|
||||
Assert.ok(has_arbitrary_name_in_stack(), "A JS frame was found before the test timeout.");
|
||||
Assert.ok(
|
||||
has_arbitrary_name_in_stack(),
|
||||
"A JS frame was found before the test timeout."
|
||||
);
|
||||
Services.profiler.StopProfiler();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ function run_test() {
|
|||
(function() {
|
||||
Services.profiler.StopProfiler();
|
||||
let n = 10000;
|
||||
while (--n); // OSR happens here with the profiler disabled.
|
||||
while (--n) {} // OSR happens here with the profiler disabled.
|
||||
// An assertion will fail when this function returns, if the
|
||||
// profiler stack was misbalanced.
|
||||
})();
|
||||
|
|
|
@ -9,7 +9,7 @@ function run_test() {
|
|||
(function() {
|
||||
Services.profiler.StartProfiler(100, 10, ["js"]);
|
||||
let n = 10000;
|
||||
while (--n); // OSR happens here with the profiler enabled.
|
||||
while (--n) {} // OSR happens here with the profiler enabled.
|
||||
// An assertion will fail when this function returns, if the
|
||||
// profiler stack was misbalanced.
|
||||
})();
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* 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/. */
|
||||
|
||||
const {FileUtils} = ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
|
||||
const { FileUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/FileUtils.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* Test that the IOInterposer is working correctly to capture main thread IO.
|
||||
|
@ -21,10 +23,16 @@ add_task(async () => {
|
|||
|
||||
{
|
||||
const filename = "profiler-mainthreadio-test-firstrun";
|
||||
const payloads = await startProfilerAndgetFileIOPayloads(["mainthreadio"], filename);
|
||||
const payloads = await startProfilerAndgetFileIOPayloads(
|
||||
["mainthreadio"],
|
||||
filename
|
||||
);
|
||||
|
||||
greater(payloads.length, 0,
|
||||
"FileIO markers were found when using the mainthreadio feature on the profiler.");
|
||||
greater(
|
||||
payloads.length,
|
||||
0,
|
||||
"FileIO markers were found when using the mainthreadio feature on the profiler."
|
||||
);
|
||||
|
||||
// It would be better to check on the filename, but Linux does not currently include
|
||||
// it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1533531
|
||||
|
@ -36,18 +44,27 @@ add_task(async () => {
|
|||
const filename = "profiler-mainthreadio-test-no-instrumentation";
|
||||
const payloads = await startProfilerAndgetFileIOPayloads([], filename);
|
||||
|
||||
equal(payloads.length, 0,
|
||||
equal(
|
||||
payloads.length,
|
||||
0,
|
||||
"No FileIO markers are found when the mainthreadio feature is not turned on " +
|
||||
"in the profiler.");
|
||||
"in the profiler."
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const filename = "profiler-mainthreadio-test-secondrun";
|
||||
const payloads = await startProfilerAndgetFileIOPayloads(["mainthreadio"], filename);
|
||||
const payloads = await startProfilerAndgetFileIOPayloads(
|
||||
["mainthreadio"],
|
||||
filename
|
||||
);
|
||||
|
||||
greater(payloads.length, 0,
|
||||
greater(
|
||||
payloads.length,
|
||||
0,
|
||||
"FileIO markers were found when re-starting the mainthreadio feature on the " +
|
||||
"profiler.");
|
||||
"profiler."
|
||||
);
|
||||
// It would be better to check on the filename, but Linux does not currently include
|
||||
// it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1533531
|
||||
// ok(hasWritePayload(payloads, filename),
|
||||
|
@ -67,7 +84,6 @@ async function startProfilerAndgetFileIOPayloads(features, filename) {
|
|||
const threads = [];
|
||||
Services.profiler.StartProfiler(entries, interval, features, threads);
|
||||
|
||||
|
||||
const file = FileUtils.getFile("TmpD", [filename]);
|
||||
if (file.exists()) {
|
||||
console.warn(
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
/* eslint-env webextensions */
|
||||
|
||||
const Quitter = {
|
||||
quit() { browser.runtime.sendMessage("quit"); },
|
||||
quit() {
|
||||
browser.runtime.sendMessage("quit");
|
||||
},
|
||||
};
|
||||
|
||||
window.wrappedJSObject.Quitter = cloneInto(Quitter, window, {cloneFunctions: true});
|
||||
window.wrappedJSObject.Quitter = cloneInto(Quitter, window, {
|
||||
cloneFunctions: true,
|
||||
});
|
||||
|
|
|
@ -9,7 +9,9 @@ this.quitter = class extends ExtensionAPI {
|
|||
return {
|
||||
quitter: {
|
||||
async quit() {
|
||||
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let browserWindow = Services.wm.getMostRecentWindow(
|
||||
"navigator:browser"
|
||||
);
|
||||
if (browserWindow && browserWindow.gBrowserInit) {
|
||||
await browserWindow.gBrowserInit.idleTasksFinishedPromise;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,17 @@ var apply = () => {
|
|||
|
||||
$(".filter:checked").each(function(index) {
|
||||
for (let kind of this.name.split(",")) {
|
||||
if (!(kinds.includes(kind)))
|
||||
if (!kinds.includes(kind)) {
|
||||
kinds.push(kind);
|
||||
}
|
||||
}
|
||||
|
||||
// Checkbox element values are generated by Section.get_context() in app.py
|
||||
let attrs = JSON.parse(this.value);
|
||||
for (let attr in attrs) {
|
||||
if (!(attr in filters))
|
||||
if (!(attr in filters)) {
|
||||
filters[attr] = [];
|
||||
}
|
||||
|
||||
let values = attrs[attr];
|
||||
filters[attr] = filters[attr].concat(values);
|
||||
|
@ -35,24 +37,29 @@ var apply = () => {
|
|||
});
|
||||
updateLabels();
|
||||
|
||||
if (Object.keys(filters).length == 0 || (Object.keys(filters).length == 1 && "build_type" in filters)) {
|
||||
if (
|
||||
Object.keys(filters).length == 0 ||
|
||||
(Object.keys(filters).length == 1 && "build_type" in filters)
|
||||
) {
|
||||
selection.value = "";
|
||||
count.innerHTML = "0 tasks selected";
|
||||
return;
|
||||
}
|
||||
|
||||
var taskMatches = (label) => {
|
||||
var taskMatches = label => {
|
||||
let task = tasks[label];
|
||||
|
||||
// If no box for the given kind has been checked, this task is
|
||||
// automatically not selected.
|
||||
if (!(kinds.includes(task.kind)))
|
||||
if (!kinds.includes(task.kind)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let attr in filters) {
|
||||
let values = filters[attr];
|
||||
if (!(attr in task) || values.includes(task[attr]))
|
||||
if (!(attr in task) || values.includes(task[attr])) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -4,8 +4,9 @@ var lastChecked = {};
|
|||
|
||||
// implements shift+click
|
||||
labels.click(function(e) {
|
||||
if (e.target.tagName === "INPUT")
|
||||
if (e.target.tagName === "INPUT") {
|
||||
return;
|
||||
}
|
||||
|
||||
let box = $("#" + this.htmlFor)[0];
|
||||
let activeSection = $("div.tab-pane.active")[0].id;
|
||||
|
@ -15,13 +16,16 @@ labels.click(function(e) {
|
|||
let isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1;
|
||||
|
||||
if (e.shiftKey) {
|
||||
if (isFirefox)
|
||||
if (isFirefox) {
|
||||
box.checked = !box.checked;
|
||||
}
|
||||
|
||||
let start = boxes.index(box);
|
||||
let end = boxes.index(lastChecked[activeSection]);
|
||||
|
||||
boxes.slice(Math.min(start, end), Math.max(start, end) + 1).prop("checked", box.checked);
|
||||
boxes
|
||||
.slice(Math.min(start, end), Math.max(start, end) + 1)
|
||||
.prop("checked", box.checked);
|
||||
apply();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче