diff --git a/.eslintplugin/code-parameter-properties-must-have-explicit-accessibility.ts b/.eslintplugin/code-parameter-properties-must-have-explicit-accessibility.ts new file mode 100644 index 00000000000..458afd5b0ba --- /dev/null +++ b/.eslintplugin/code-parameter-properties-must-have-explicit-accessibility.ts @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as eslint from 'eslint'; +import { TSESTree } from '@typescript-eslint/experimental-utils'; + +/** + * Enforces that all parameter properties have an explicit access modifier (public, protected, private). + * + * This catches a common bug where a service is accidentally made public by simply writing: `readonly prop: Foo` + */ +export = new class implements eslint.Rule.RuleModule { + + create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { + function check(inNode: any) { + const node: TSESTree.TSParameterProperty = inNode; + + // For now, only apply to injected services + const firstDecorator = node.decorators?.at(0); + if ( + firstDecorator?.expression.type !== 'Identifier' + || !firstDecorator.expression.name.endsWith('Service') + ) { + return; + } + + if (!node.accessibility) { + context.report({ + node: inNode, + message: 'Parameter properties must have an explicit access modifier.' + }); + } + } + + return { + ['TSParameterProperty']: check, + }; + } +}; diff --git a/.eslintrc.json b/.eslintrc.json index 7b8936e0703..a6d8b3e5e33 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -70,6 +70,7 @@ ], "local/code-translation-remind": "warn", "local/code-no-native-private": "warn", + "local/code-parameter-properties-must-have-explicit-accessibility": "warn", "local/code-no-nls-in-standalone-editor": "warn", "local/code-no-standalone-editor": "warn", "local/code-no-unexternalized-strings": "warn", diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts index 231052024c6..48b0bf1d76b 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollModelProvider.ts @@ -52,8 +52,8 @@ export class StickyModelProvider extends Disposable implements IStickyModelProvi constructor( private readonly _editor: IActiveCodeEditor, onProviderUpdate: () => void, - @IInstantiationService readonly _languageConfigurationService: ILanguageConfigurationService, - @ILanguageFeaturesService readonly _languageFeaturesService: ILanguageFeaturesService, + @IInstantiationService _languageConfigurationService: ILanguageConfigurationService, + @ILanguageFeaturesService _languageFeaturesService: ILanguageFeaturesService, ) { super(); diff --git a/src/vs/workbench/contrib/accountEntitlements/browser/accountsEntitlements.contribution.ts b/src/vs/workbench/contrib/accountEntitlements/browser/accountsEntitlements.contribution.ts index eef0da25d57..f453fbbb662 100644 --- a/src/vs/workbench/contrib/accountEntitlements/browser/accountsEntitlements.contribution.ts +++ b/src/vs/workbench/contrib/accountEntitlements/browser/accountsEntitlements.contribution.ts @@ -51,17 +51,16 @@ class EntitlementsContribution extends Disposable implements IWorkbenchContribut private accountsMenuBadgeDisposable = this._register(new MutableDisposable()); constructor( - @IContextKeyService readonly contextService: IContextKeyService, - @ICommandService readonly commandService: ICommandService, - @ITelemetryService readonly telemetryService: ITelemetryService, - @IAuthenticationService readonly authenticationService: IAuthenticationService, - @IProductService readonly productService: IProductService, - @IStorageService readonly storageService: IStorageService, - @IExtensionManagementService readonly extensionManagementService: IExtensionManagementService, - @IActivityService readonly activityService: IActivityService, - @IExtensionService readonly extensionService: IExtensionService, - @IConfigurationService readonly configurationService: IConfigurationService, - @IRequestService readonly requestService: IRequestService) { + @IContextKeyService private readonly contextService: IContextKeyService, + @ITelemetryService private readonly telemetryService: ITelemetryService, + @IAuthenticationService private readonly authenticationService: IAuthenticationService, + @IProductService private readonly productService: IProductService, + @IStorageService private readonly storageService: IStorageService, + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @IActivityService private readonly activityService: IActivityService, + @IExtensionService private readonly extensionService: IExtensionService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IRequestService private readonly requestService: IRequestService) { super(); if (!this.productService.gitHubEntitlement || isWeb) { diff --git a/src/vs/workbench/contrib/chat/browser/chatOptions.ts b/src/vs/workbench/contrib/chat/browser/chatOptions.ts index e76519d260a..1995598eba9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatOptions.ts +++ b/src/vs/workbench/contrib/chat/browser/chatOptions.ts @@ -79,7 +79,7 @@ export class ChatEditorOptions extends Disposable { private readonly resultEditorBackgroundColor: string, @IConfigurationService private readonly configurationService: IConfigurationService, @IThemeService private readonly themeService: IThemeService, - @IViewDescriptorService readonly viewDescriptorService: IViewDescriptorService + @IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService ) { super(); diff --git a/src/vs/workbench/contrib/chat/common/chatViewModel.ts b/src/vs/workbench/contrib/chat/common/chatViewModel.ts index 37290ed2015..0892f679d49 100644 --- a/src/vs/workbench/contrib/chat/common/chatViewModel.ts +++ b/src/vs/workbench/contrib/chat/common/chatViewModel.ts @@ -348,7 +348,7 @@ export class ChatRequestViewModel implements IChatRequestViewModel { currentRenderedHeight: number | undefined; constructor( - readonly _model: IChatRequestModel, + private readonly _model: IChatRequestModel, ) { } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 9028eca7755..b8a9da62b56 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -303,8 +303,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD @INotebookExecutionService private readonly notebookExecutionService: INotebookExecutionService, @INotebookExecutionStateService private readonly notebookExecutionStateService: INotebookExecutionStateService, @IEditorProgressService private editorProgressService: IEditorProgressService, - @INotebookLoggingService readonly logService: INotebookLoggingService, - @IKeybindingService readonly keybindingService: IKeybindingService, + @INotebookLoggingService private readonly logService: INotebookLoggingService, + @IKeybindingService private readonly keybindingService: IKeybindingService, @ICodeEditorService codeEditorService: ICodeEditorService ) { super(); diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts index fddd0c63854..4be07da63b7 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookEditorServiceImpl.ts @@ -37,7 +37,7 @@ export class NotebookEditorWidgetService implements INotebookEditorService { private readonly _borrowableEditors = new Map>(); constructor( - @IEditorGroupsService readonly editorGroupService: IEditorGroupsService, + @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @IEditorService editorService: IEditorService, @IContextKeyService contextKeyService: IContextKeyService ) { diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index e9b9ce16497..39636afde89 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -185,11 +185,11 @@ export class AutomaticPortForwarding extends Disposable implements IWorkbenchCon @IOpenerService private readonly openerService: IOpenerService, @IExternalUriOpenerService private readonly externalOpenerService: IExternalUriOpenerService, @IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService, - @IWorkbenchEnvironmentService readonly environmentService: IWorkbenchEnvironmentService, + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, @IDebugService private readonly debugService: IDebugService, - @IRemoteAgentService readonly remoteAgentService: IRemoteAgentService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService, @ITunnelService private readonly tunnelService: ITunnelService, @IHostService private readonly hostService: IHostService, @ILogService private readonly logService: ILogService, diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index f36a4d80bb1..54cd24fa32d 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -799,12 +799,12 @@ class HistoryItemGroupRenderer implements ICompressibleTreeRenderer(); this._backendRegistration.set(remoteAuthority, { promise, resolve }); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalVoice.ts b/src/vs/workbench/contrib/terminal/browser/terminalVoice.ts index 042cd3de2ab..df40dd18c5a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalVoice.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalVoice.ts @@ -67,9 +67,8 @@ export class TerminalVoiceSession extends Disposable { private readonly _disposables: DisposableStore; constructor( @ISpeechService private readonly _speechService: ISpeechService, - @ITerminalService readonly _terminalService: ITerminalService, - @IConfigurationService readonly configurationService: IConfigurationService, - @IInstantiationService readonly _instantationService: IInstantiationService + @ITerminalService private readonly _terminalService: ITerminalService, + @IConfigurationService private readonly configurationService: IConfigurationService, ) { super(); this._register(this._terminalService.onDidChangeActiveInstance(() => this.stop())); diff --git a/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts index 9fcc7bb449f..5829f86670a 100644 --- a/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts +++ b/src/vs/workbench/contrib/welcomeDialog/browser/welcomeDialog.contribution.ts @@ -33,13 +33,13 @@ class WelcomeDialogContribution extends Disposable implements IWorkbenchContribu @IStorageService storageService: IStorageService, @IBrowserWorkbenchEnvironmentService environmentService: IBrowserWorkbenchEnvironmentService, @IConfigurationService configurationService: IConfigurationService, - @IContextKeyService readonly contextService: IContextKeyService, - @ICodeEditorService readonly codeEditorService: ICodeEditorService, - @IInstantiationService readonly instantiationService: IInstantiationService, - @ICommandService readonly commandService: ICommandService, - @ITelemetryService readonly telemetryService: ITelemetryService, - @IOpenerService readonly openerService: IOpenerService, - @IEditorService readonly editorService: IEditorService + @IContextKeyService contextService: IContextKeyService, + @ICodeEditorService codeEditorService: ICodeEditorService, + @IInstantiationService instantiationService: IInstantiationService, + @ICommandService commandService: ICommandService, + @ITelemetryService telemetryService: ITelemetryService, + @IOpenerService openerService: IOpenerService, + @IEditorService editorService: IEditorService ) { super();