Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 274f866

Browse files
committed
Bug 1479515 - Extend the ESLint rule for checking Ci properties to check for unknown interfaces as well. r=Gijs,application-update-reviewers,nalexander
Differential Revision: https://phabricator.services.mozilla.com/D156425
1 parent fd89200 commit 274f866

6 files changed

Lines changed: 132 additions & 21 deletions

File tree

docs/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
valid-ci-uses
22
=============
33

4-
Ensures that property access on ``Ci.<interface>`` are valid.
4+
Ensures that interface accesses on ``Ci`` are valid, and property accesses on
5+
``Ci.<interface>`` are also valid.
56

67
This rule requires a full build to run, and is not turned on by default. To run
78
this rule manually, use:
@@ -13,6 +14,12 @@ this rule manually, use:
1314
Examples of incorrect code for this rule:
1415
-----------------------------------------
1516

17+
``nsIFoo`` does not exist.
18+
19+
.. code-block:: js
20+
21+
Ci.nsIFoo
22+
1623
``UNKNOWN_CONSTANT`` does not exist on nsIURIFixup.
1724

1825
.. code-block:: js
@@ -22,6 +29,12 @@ Examples of incorrect code for this rule:
2229
Examples of correct code for this rule:
2330
---------------------------------------
2431

32+
``nsIFile`` does exist.
33+
34+
.. code-block:: js
35+
36+
Ci.nsIFile
37+
2538
``FIXUP_FLAG_NONE`` does exist on nsIURIFixup.
2639

2740
.. code-block:: js

dom/cache/test/xpcshell/make_profile.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,13 @@ function exactGC() {
8787

8888
function resetQuotaManager() {
8989
return new Promise(function(resolve) {
90-
var qm = Cc["@mozilla.org/dom/quota/manager;1"].getService(
91-
Ci.nsIQuotaManager
92-
);
93-
9490
var prefService = Services.prefs;
9591

9692
// enable quota manager testing mode
9793
var pref = "dom.quotaManager.testing";
9894
prefService.getBranch(null).setBoolPref(pref, true);
9995

100-
var request = qm.reset();
96+
var request = Services.qms.reset();
10197
request.callback = resolve;
10298

10399
// disable quota manager testing mode

extensions/pref/autoconfig/src/prefcalls.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66

77
/* globals gSandbox */
88

9-
const nsILDAPURL = Ci.nsILDAPURL;
10-
const LDAPURLContractID = "@mozilla.org/network/ldap-url;1";
11-
const nsILDAPSyncQuery = Ci.nsILDAPSyncQuery;
129
const LDAPSyncQueryContractID = "@mozilla.org/ldapsyncquery;1";
1310

1411
var gVersion;
@@ -133,13 +130,17 @@ function getLDAPAttributes(host, base, filter, attribs, isSecure) {
133130
"?sub?" +
134131
filter;
135132

133+
// nsILDAP* are only defined in comm-central.
134+
// eslint-disable-next-line mozilla/valid-ci-uses
136135
var url = Services.io.newURI(urlSpec).QueryInterface(Ci.nsILDAPURL);
137136

138137
var ldapquery = Cc[LDAPSyncQueryContractID].createInstance(
139-
nsILDAPSyncQuery
138+
// eslint-disable-next-line mozilla/valid-ci-uses
139+
Ci.nsILDAPSyncQuery
140140
);
141141
// default to LDAP v3
142142
if (!gVersion) {
143+
// eslint-disable-next-line mozilla/valid-ci-uses
143144
gVersion = Ci.nsILDAPConnection.VERSION3;
144145
}
145146
// user supplied method

toolkit/mozapps/update/tests/data/shared.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,6 @@ XPCOMUtils.defineLazyGetter(this, "gUpdateChecker", function test_gUC() {
141141
);
142142
});
143143

144-
XPCOMUtils.defineLazyGetter(this, "gUP", function test_gUP() {
145-
return Cc["@mozilla.org/updates/update-prompt;1"].createInstance(
146-
Ci.nsIUpdatePrompt
147-
);
148-
});
149-
150144
XPCOMUtils.defineLazyGetter(this, "gDefaultPrefBranch", function test_gDPB() {
151145
return Services.prefs.getDefaultBranch(null);
152146
});

tools/lint/eslint/eslint-plugin-mozilla/lib/rules/valid-ci-uses.js

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
2-
* @fileoverview Reject uses of unknown properties on Ci.<interface>.
2+
* @fileoverview Reject uses of unknown interfaces on Ci and properties of those
3+
* interfaces.
34
*
45
* This Source Code Form is subject to the terms of the Mozilla Public
56
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -8,8 +9,55 @@
89

910
"use strict";
1011

12+
const os = require("os");
1113
const helpers = require("../helpers");
1214

15+
// These interfaces are all platform specific, so may be not present
16+
// on all platforms.
17+
const platformSpecificInterfaces = new Map([
18+
["nsIAboutThirdParty", "windows"],
19+
["nsIJumpListItem", "windows"],
20+
["nsIJumpListLink", "windows"],
21+
["nsIJumpListSeparator", "windows"],
22+
["nsIJumpListShortcut", "windows"],
23+
["nsITaskbarWindowPreview", "windows"],
24+
["nsIWindowsAlertsService", "windows"],
25+
["nsIWinAppHelper", "windows"],
26+
["nsIWinTaskbar", "windows"],
27+
["nsIWinTaskSchedulerService", "windows"],
28+
["nsIWindowsRegKey", "windows"],
29+
["nsIWindowsPackageManager", "windows"],
30+
["nsIWindowsShellService", "windows"],
31+
["nsIMacShellService", "darwin"],
32+
["nsIMacDockSupport", "darwin"],
33+
["nsIMacFinderProgress", "darwin"],
34+
["nsIMacSharingService", "darwin"],
35+
["nsIMacUserActivityUpdater", "darwin"],
36+
["nsIMacWebAppUtils", "darwin"],
37+
["nsIStandaloneNativeMenu", "darwin"],
38+
["nsITouchBarHelper", "darwin"],
39+
["nsITouchBarInput", "darwin"],
40+
["nsITouchBarUpdater", "darwin"],
41+
["mozISandboxReporter", "linux"],
42+
["nsIApplicationChooser", "linux"],
43+
["nsIGNOMEShellService", "linux"],
44+
["nsIGtkTaskbarProgress", "linux"],
45+
46+
// These are used in the ESLint test code.
47+
["amIFoo", "any"],
48+
["nsIMeh", "any"],
49+
// Can't easily detect android builds from ESLint at the moment.
50+
["nsIAndroidBridge", "any"],
51+
["nsIAndroidView", "any"],
52+
// Code coverage is enabled only for certain builds (MOZ_CODE_COVERAGE).
53+
["nsICodeCoverage", "any"],
54+
// Layout debugging is enabled only for certain builds (MOZ_LAYOUT_DEBUGGER).
55+
["nsILayoutDebuggingTools", "any"],
56+
// Sandbox test is only enabled for certain configurations (MOZ_SANDBOX,
57+
// MOZ_DEBUG, ENABLE_TESTS).
58+
["mozISandboxTest", "any"],
59+
]);
60+
1361
function interfaceHasProperty(interfaceName, propertyName) {
1462
// `Ci.nsIFoo.number` is valid, it returns the iid.
1563
if (propertyName == "number") {
@@ -18,7 +66,6 @@ function interfaceHasProperty(interfaceName, propertyName) {
1866

1967
let interfaceInfo = helpers.xpidlData.get(interfaceName);
2068

21-
// TODO: Check for missing interfaces.
2269
if (!interfaceInfo) {
2370
return true;
2471
}
@@ -41,6 +88,9 @@ module.exports = {
4188
"https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/valid-ci-uses.html",
4289
},
4390
messages: {
91+
missingInterface:
92+
"{{ interface }} is defined in this rule's platform specific list, but is not available",
93+
unknownInterface: "Use of unknown interface Ci.{{ interface}}",
4494
unknownProperty:
4595
"Use of unknown property Ci.{{ interface }}.{{ property }}",
4696
},
@@ -50,6 +100,38 @@ module.exports = {
50100
create(context) {
51101
return {
52102
MemberExpression(node) {
103+
if (
104+
node.computed === false &&
105+
node.type === "MemberExpression" &&
106+
node.object.type === "Identifier" &&
107+
node.object.name === "Ci" &&
108+
node.property.type === "Identifier" &&
109+
node.property.name.includes("I")
110+
) {
111+
if (!helpers.xpidlData.get(node.property.name)) {
112+
let platformSpecific = platformSpecificInterfaces.get(
113+
node.property.name
114+
);
115+
if (!platformSpecific) {
116+
context.report({
117+
node,
118+
messageId: "unknownInterface",
119+
data: {
120+
interface: node.property.name,
121+
},
122+
});
123+
} else if (platformSpecific == os.platform) {
124+
context.report({
125+
node,
126+
messageId: "missingInterface",
127+
data: {
128+
interface: node.property.name,
129+
},
130+
});
131+
}
132+
}
133+
}
134+
53135
if (
54136
node.computed === false &&
55137
node.object.type === "MemberExpression" &&

tools/lint/eslint/eslint-plugin-mozilla/tests/valid-ci-uses.js

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// Requirements
88
// ------------------------------------------------------------------------------
99

10+
var os = require("os");
1011
var rule = require("../lib/rules/valid-ci-uses");
1112
var RuleTester = require("eslint").RuleTester;
1213

@@ -22,12 +23,36 @@ function invalidCode(code, messageId, data) {
2223

2324
process.env.TEST_XPIDLDIR = `${__dirname}/xpidl`;
2425

25-
ruleTester.run("valid-ci-uses", rule, {
26-
valid: ["Ci.nsIURIFixup.FIXUP_FLAG_NONE"],
26+
const tests = {
27+
valid: ["Ci.nsIURIFixup", "Ci.nsIURIFixup.FIXUP_FLAG_NONE"],
2728
invalid: [
2829
invalidCode("Ci.nsIURIFixup.UNKNOWN_CONSTANT", "unknownProperty", {
2930
interface: "nsIURIFixup",
3031
property: "UNKNOWN_CONSTANT",
3132
}),
33+
invalidCode("Ci.nsIFoo", "unknownInterface", {
34+
interface: "nsIFoo",
35+
}),
3236
],
33-
});
37+
};
38+
39+
// For ESLint tests, we only have a couple of xpt examples in the xpidl directory.
40+
// Therefore we can pretend that these interfaces no longer exist.
41+
switch (os.platform) {
42+
case "windows":
43+
tests.invalid.push(
44+
invalidCode("Ci.nsIJumpListShortcut", "missingInterface")
45+
);
46+
break;
47+
case "darwin":
48+
tests.invalid.push(
49+
invalidCode("Ci.nsIMacShellService", "missingInterface")
50+
);
51+
break;
52+
case "linux":
53+
tests.invalid.push(
54+
invalidCode("Ci.mozISandboxReporter", "missingInterface")
55+
);
56+
}
57+
58+
ruleTester.run("valid-ci-uses", rule, tests);

0 commit comments

Comments
 (0)