Bug 1880899 - add lint rule that prevents adding more browser.js globals, r=Standard8

Differential Revision: https://phabricator.services.mozilla.com/D202804
This commit is contained in:
Gijs Kruitbosch 2024-03-16 15:14:07 +00:00
parent ec2b6d65c6
commit 51a4c7d0e9
7 changed files with 440 additions and 0 deletions

View file

@ -252,6 +252,12 @@ module.exports = {
"mozilla/no-comparison-or-assignment-inside-ok": "off",
},
},
{
files: ["browser/base/content/browser.js"],
rules: {
"mozilla/no-more-globals": "error",
},
},
{
// Bug 881389 - Complete switching to console.createInstance from custom
// modules. To support the gradual switch, we log these as warnings until

View file

@ -0,0 +1,305 @@
[
"XPCOMUtils",
"AppConstants",
"gBrowser",
"gContextMenu",
"gMultiProcessBrowser",
"gFissionBrowser",
"gBrowserAllowScriptsToCloseInitialTabs",
"gEditUIVisible",
"gReduceMotionSetting",
"gReduceMotionOverride",
"shouldSuppressPopupNotifications",
"gLazyFindCommand",
"gPageIcons",
"gInitialPages",
"isInitialPage",
"browserWindows",
"updateBookmarkToolbarVisibility",
"gNavigatorBundle",
"gScreenshots",
"updateFxaToolbarMenu",
"UpdateBackForwardCommands",
"updatePrintCommands",
"SetClickAndHoldHandlers",
"gClickAndHoldListenersOnElement",
"gSessionHistoryObserver",
"gStoragePressureObserver",
"gPopupBlockerObserver",
"gKeywordURIFixup",
"_createNullPrincipalFromTabUserContextId",
"_resolveDelayedStartup",
"delayedStartupPromise",
"gBrowserInit",
"HandleAppCommandEvent",
"gotoHistoryIndex",
"BrowserForward",
"BrowserBack",
"BrowserHandleBackspace",
"BrowserHandleShiftBackspace",
"BrowserStop",
"BrowserReloadOrDuplicate",
"BrowserReload",
"kSkipCacheFlags",
"BrowserReloadSkipCache",
"BrowserHome",
"loadOneOrMoreURIs",
"openLocation",
"BrowserOpenTab",
"gLastOpenDirectory",
"BrowserOpenFileWindow",
"BrowserCloseTabOrWindow",
"BrowserTryToCloseWindow",
"getLoadContext",
"readFromClipboard",
"BrowserViewSourceOfDocument",
"BrowserViewSource",
"BrowserPageInfo",
"UpdateUrlbarSearchSplitterState",
"UpdatePopupNotificationsVisibility",
"PageProxyClickHandler",
"BrowserOnClick",
"getMeOutOfHere",
"getDefaultHomePage",
"BrowserFullScreen",
"BrowserReloadWithFlags",
"getPEMString",
"browserDragAndDrop",
"homeButtonObserver",
"openHomeDialog",
"newTabButtonObserver",
"newWindowButtonObserver",
"BrowserSearch",
"CreateContainerTabMenu",
"FillHistoryMenu",
"BrowserDownloadsUI",
"toOpenWindowByType",
"OpenBrowserWindow",
"updateEditUIVisibility",
"gFileMenu",
"gShareUtils",
"openNewUserContextTab",
"XULBrowserWindow",
"LinkTargetDisplay",
"CombinedStopReload",
"TabsProgressListener",
"nsBrowserAccess",
"showFullScreenViewContextMenuItems",
"onViewToolbarsPopupShowing",
"onViewToolbarCommand",
"setToolbarVisibility",
"updateToggleControlLabel",
"TabletModeUpdater",
"gTabletModePageCounter",
"displaySecurityInfo",
"gUIDensity",
"nodeToTooltipMap",
"nodeToShortcutMap",
"gDynamicTooltipCache",
"GetDynamicShortcutTooltipText",
"UpdateDynamicShortcutTooltipText",
"hrefAndLinkNodeForClickEvent",
"contentAreaClick",
"handleLinkClick",
"middleMousePaste",
"handleDroppedLink",
"BrowserForceEncodingDetection",
"ToolbarContextMenu",
"BrowserOffline",
"CanvasPermissionPromptHelper",
"WebAuthnPromptHelper",
"CanCloseWindow",
"WindowIsClosing",
"warnAboutClosingWindow",
"MailIntegration",
"BrowserOpenAddonsMgr",
"AddKeywordForSearchField",
"restoreLastClosedTabOrWindowOrSession",
"undoCloseTab",
"undoCloseWindow",
"ReportFalseDeceptiveSite",
"ReportSiteIssue",
"gRemoteControl",
"gPrivateBrowsingUI",
"switchToTabHavingURI",
"RestoreLastSessionObserver",
"MenuTouchModeObserver",
"safeModeRestart",
"duplicateTabIn",
"MousePosTracker",
"ToolbarIconColor",
"PanicButtonNotifier",
"SafeBrowsingNotificationBox",
"TabDialogBox",
"TabModalPromptBox",
"gDialogBox",
"ConfirmationHint",
"FirefoxViewHandler",
"AMTelemetry",
"AboutNewTab",
"AboutReaderParent",
"AddonManager",
"BrowserSearchTelemetry",
"BrowserTelemetryUtils",
"BrowserUIUtils",
"BrowserUsageTelemetry",
"BrowserWindowTracker",
"CFRPageActions",
"Color",
"ContentAnalysis",
"ContextualIdentityService",
"CustomizableUI",
"DevToolsSocketStatus",
"DownloadUtils",
"DownloadsCommon",
"E10SUtils",
"ExtensionsUI",
"FirefoxViewNotificationManager",
"HomePage",
"isProductURL",
"LightweightThemeConsumer",
"LoginHelper",
"LoginManagerParent",
"MigrationUtils",
"NetUtil",
"NewTabPagePreloading",
"NewTabUtils",
"NimbusFeatures",
"OpenInTabsUtils",
"PageActions",
"PageThumbs",
"PanelMultiView",
"PanelView",
"PictureInPicture",
"PlacesTransactions",
"PlacesUIUtils",
"PlacesUtils",
"Pocket",
"PrivateBrowsingUtils",
"ProcessHangMonitor",
"PromptUtils",
"ReaderMode",
"ResetPBMPanel",
"ReportBrokenSite",
"SafeBrowsing",
"Sanitizer",
"SaveToPocket",
"ScreenshotsUtils",
"SearchUIUtils",
"SessionStartup",
"SessionStore",
"ShoppingSidebarParent",
"ShoppingSidebarManager",
"ShortcutUtils",
"SiteDataManager",
"SitePermissions",
"SubDialog",
"SubDialogManager",
"TabCrashHandler",
"TabModalPrompt",
"TabsSetupFlowManager",
"TelemetryEnvironment",
"TranslationsParent",
"UITour",
"UpdateUtils",
"URILoadingHelper",
"UrlbarInput",
"UrlbarPrefs",
"UrlbarProviderSearchTips",
"UrlbarTokenizer",
"UrlbarUtils",
"UrlbarValueFormatter",
"Weave",
"WebNavigationFrames",
"webrtcUI",
"WebsiteFilter",
"ZoomUI",
"fxAccounts",
"PlacesTreeView",
"PlacesInsertionPoint",
"PlacesController",
"PlacesControllerDragHelper",
"PrintUtils",
"ZoomManager",
"FullZoom",
"PanelUI",
"gViewSourceUtils",
"gTabsPanel",
"BrowserAddonUI",
"gExtensionsNotifications",
"gUnifiedExtensions",
"gXPInstallObserver",
"ctrlTab",
"CustomizationHandler",
"AutoHideMenubar",
"PointerLock",
"FullScreen",
"gIdentityHandler",
"gPermissionPanel",
"SelectTranslationsPanel",
"FullPageTranslationsPanel",
"gProtectionsHandler",
"gGestureSupport",
"gHistorySwipeAnimation",
"gSafeBrowsing",
"gSync",
"gBrowserThumbnails",
"openContextMenu",
"nsContextMenu",
"DownloadsPanel",
"DownloadsOverlayLoader",
"DownloadsView",
"DownloadsViewUI",
"DownloadsViewController",
"DownloadsSummary",
"DownloadsFooter",
"DownloadsBlockedSubview",
"DownloadsButton",
"DownloadsIndicatorView",
"gEditItemOverlay",
"gGfxUtils",
"pktUI",
"ToolbarKeyboardNavigator",
"A11yUtils",
"gSharedTabWarning",
"gPageStyleMenu",
"gProfiles",
"ContentPrefService2",
"classifierService",
"Favicons",
"WindowsUIUtils",
"BrowserHandler",
"Marionette",
"RemoteAgent",
"Marionette",
"RemoteAgent",
"RTL_UI",
"gBrandBundle",
"gBrowserBundle",
"gCustomizeMode",
"gNavToolbox",
"gURLBar",
"ReferrerInfo",
"gNotificationBox",
"InlineSpellCheckerUI",
"PopupNotifications",
"MacUserActivityUpdater",
"Win7Features",
"gToolbarKeyNavEnabled",
"gBookmarksToolbarVisibility",
"gFxaToolbarEnabled",
"gFxaToolbarAccessed",
"gAddonAbuseReportEnabled",
"gAlwaysOpenPanel",
"gMiddleClickNewTabUsesPasteboard",
"gScreenshotsDisabled",
"gPrintEnabled",
"gScreenshotsComponentEnabled",
"gTranslationsEnabled",
"gUseFeltPrivacyUI",
"gReduceMotion",
"gFindBar",
"gFindBarInitialized",
"gFindBarPromise",
"BrowserSearch"
]

View file

@ -0,0 +1,20 @@
no-more-globals
===============
This rule is used to discourage people from adding ever more global variables to
files where the rule is run.
For any file ``example.js`` where the rule is applied, the rule will read
an allowlist of globals from a sibling ``example.js.globals`` file. The rule
will warn for any globals defined in ``example.js`` that are not listed in the
``globals`` file, and will also warn for any items on the allowlist in
the ``globals`` file that are no longer present in ``example.js``, encouraging
people to remove them from the ``globals`` list.
If you see errors from this rule about new globals, **do not just add items to
the allowlist**. Instead, work to find a way to run your code so that it does
not add to the list of globals.
If you see errors when removing globals, simply remove them from the allowlist
to make sure it is up-to-date and things do not inadvertently end up getting
put back in.

View file

@ -59,6 +59,7 @@ module.exports = {
"no-comparison-or-assignment-inside-ok": require("../lib/rules/no-comparison-or-assignment-inside-ok"),
"no-cu-reportError": require("../lib/rules/no-cu-reportError"),
"no-define-cc-etc": require("../lib/rules/no-define-cc-etc"),
"no-more-globals": require("../lib/rules/no-more-globals"),
"no-redeclare-with-import-autofix": require("../lib/rules/no-redeclare-with-import-autofix"),
"no-throw-cr-literal": require("../lib/rules/no-throw-cr-literal"),
"no-useless-parameters": require("../lib/rules/no-useless-parameters"),

View file

@ -0,0 +1,69 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
"use strict";
const globals = require("../globals");
const fs = require("fs");
module.exports = {
meta: {
docs: {
url: "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/rules/no-more-globals.html",
},
messages: {
newGlobal:
"The global {{ name }} was not previously in this file, where new global variables are not permitted.",
removedGlobal:
"The global {{ name }} was expected to be defined in this file but isn't. Please remove it from the .globals file.",
missingGlobalsFile:
"This file has mozilla/no-more-globals enabled but has no .globals sibling file. Please create one.",
},
schema: [],
type: "problem",
},
create(context) {
return {
Program(node) {
let filename = context.filename;
let code = context.sourceCode.getText();
let currentGlobals = globals.getGlobalsForCode(code, {}, false);
let knownGlobals;
try {
knownGlobals = new Set(
JSON.parse(fs.readFileSync(filename + ".globals"))
);
} catch (ex) {
context.report({
node,
messageId: "missingGlobalsFile",
});
return;
}
for (let { name } of currentGlobals) {
if (!knownGlobals.has(name)) {
context.report({
node,
messageId: "newGlobal",
data: { name },
});
}
}
for (let known of knownGlobals) {
if (!currentGlobals.some(n => n.name == known)) {
context.report({
node,
messageId: "removedGlobal",
data: { name: known },
});
}
}
},
};
},
};

View file

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
var rule = require("../lib/rules/no-more-globals");
var RuleTester = require("eslint").RuleTester;
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: "latest" } });
function makeTest(code, errors = []) {
return {
code,
errors,
filename: __dirname + "/helper-no-more-globals.js",
};
}
ruleTester.run("no-more-globals", rule, {
valid: [
makeTest("function foo() {}"),
makeTest("var foo = 5;"),
makeTest("let foo = 42;"),
],
invalid: [
makeTest("console.log('hello');", [
{ messageId: "removedGlobal", data: { name: "foo" } },
]),
makeTest("let bar = 42;", [
{ messageId: "newGlobal", data: { name: "bar" } },
{ messageId: "removedGlobal", data: { name: "foo" } },
]),
],
});