Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make createInstance stricter #83472

Merged
merged 10 commits into from
Oct 28, 2019
4 changes: 1 addition & 3 deletions src/vs/editor/contrib/referenceSearch/referencesWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ import { activeContrastBorder, contrastBorder, registerColor } from 'vs/platform
import { ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { PeekViewWidget, IPeekViewService } from './peekViewWidget';
import { FileReferences, OneReference, ReferencesModel } from './referencesModel';
import { ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
import { IAsyncDataTreeOptions } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { FuzzyScore } from 'vs/base/common/filters';
import { SplitView, Sizing } from 'vs/base/browser/ui/splitview/splitview';

Expand Down Expand Up @@ -311,7 +309,7 @@ export class ReferenceWidget extends PeekViewWidget {
keyboardNavigationLabelProvider: this._instantiationService.createInstance(StringRepresentationProvider),
identityProvider: new IdentityProvider()
};
this._tree = this._instantiationService.createInstance<string, HTMLElement, IListVirtualDelegate<TreeElement>, ITreeRenderer<any, FuzzyScore, any>[], IAsyncDataSource<ReferencesModel | FileReferences, TreeElement>, IAsyncDataTreeOptions<TreeElement, FuzzyScore>, WorkbenchAsyncDataTree<ReferencesModel | FileReferences, TreeElement, FuzzyScore>>(
this._tree = this._instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<ReferencesModel | FileReferences, TreeElement, FuzzyScore>>(
WorkbenchAsyncDataTree,
'ReferencesWidget',
this._treeContainer,
Expand Down
26 changes: 17 additions & 9 deletions src/vs/platform/instantiation/common/instantiation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ export interface ServicesAccessor {

export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');

/**
* Given a list of arguments as a tuple, attempt to extract the leading, non-service arguments
* to their own tuple.
*/
type GetLeadingNonServiceArgs<Args> =
Args extends [...BrandedService[]] ? []
: Args extends [infer A1, ...BrandedService[]] ? [A1]
: Args extends [infer A1, infer A2, ...BrandedService[]] ? [A1, A2]
: Args extends [infer A1, infer A2, infer A3, ...BrandedService[]] ? [A1, A2, A3]
: Args extends [infer A1, infer A2, infer A3, infer A4, ...BrandedService[]] ? [A1, A2, A3, A4]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, ...BrandedService[]] ? [A1, A2, A3, A4, A5]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6, A7]
: Args extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8, ...BrandedService[]] ? [A1, A2, A3, A4, A5, A6, A7, A8]
: never;

export interface IInstantiationService {

_serviceBrand: undefined;
Expand All @@ -85,15 +101,7 @@ export interface IInstantiationService {
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(descriptor: descriptors.SyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(descriptor: descriptors.SyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): T;

createInstance<T>(ctor: IConstructorSignature0<T>): T;
createInstance<A1, T>(ctor: IConstructorSignature1<A1, T>, first: A1): T;
createInstance<A1, A2, T>(ctor: IConstructorSignature2<A1, A2, T>, first: A1, second: A2): T;
createInstance<A1, A2, A3, T>(ctor: IConstructorSignature3<A1, A2, A3, T>, first: A1, second: A2, third: A3): T;
createInstance<A1, A2, A3, A4, T>(ctor: IConstructorSignature4<A1, A2, A3, A4, T>, first: A1, second: A2, third: A3, fourth: A4): T;
createInstance<A1, A2, A3, A4, A5, T>(ctor: IConstructorSignature5<A1, A2, A3, A4, A5, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): T;
createInstance<A1, A2, A3, A4, A5, A6, T>(ctor: IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(ctor: IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): T;
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): T;
createInstance<Ctor extends new (...args: any) => any, R extends InstanceType<Ctor>>(t: Ctor, ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>): R;

/**
*
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/compositePart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
// Instantiate composite from registry otherwise
const compositeDescriptor = this.registry.getComposite(id);
if (compositeDescriptor) {
const compositeProgressIndicator = this.instantiationService.createInstance(CompositeProgressIndicator, this.progressBar, compositeDescriptor.id, !!isActive);
const compositeProgressIndicator = this.instantiationService.createInstance(CompositeProgressIndicator, assertIsDefined(this.progressBar), compositeDescriptor.id, !!isActive);
const compositeInstantiationService = this.instantiationService.createChild(new ServiceCollection(
[IEditorProgressService, compositeProgressIndicator] // provide the editor progress service for any editors instantiated within the composite
));
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
const labels = this._instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER /* TODO@Jo visibility propagation */);
this._disposables.add(labels);

return this._instantiationService.createInstance(WorkbenchAsyncDataTree, 'BreadcrumbsFilePicker', container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), {
return this._instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<IWorkspace | URI, IWorkspaceFolder | IFileStat, FuzzyScore>>(WorkbenchAsyncDataTree, 'BreadcrumbsFilePicker', container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), {
multipleSelectionSupport: false,
sorter: new FileSorter(),
filter: this._instantiationService.createInstance(FileFilter),
Expand Down Expand Up @@ -438,7 +438,7 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker {
}

protected _createTree(container: HTMLElement) {
return this._instantiationService.createInstance(
return this._instantiationService.createInstance<typeof WorkbenchDataTree, WorkbenchDataTree<OutlineModel, any, FuzzyScore>>(
WorkbenchDataTree,
'BreadcrumbsOutlinePicker',
container,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class NotificationsList extends Themable {
const renderer = this.instantiationService.createInstance(NotificationRenderer, actionRunner);

// List
const list = this.list = this._register(this.instantiationService.createInstance(
const list = this.list = this._register(this.instantiationService.createInstance<typeof WorkbenchList, WorkbenchList<INotificationViewItem>>(
WorkbenchList,
'NotificationsList',
this.listContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export class CallHierarchyTreePeekWidget extends PeekViewWidget {
ariaLabel: localize('tree.aria', "Call Hierarchy"),
expandOnlyOnTwistieClick: true,
};
this._tree = <any>this._instantiationService.createInstance(
this._tree = this._instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<callHTree.CallHierarchyRoot, callHTree.Call, FuzzyScore>>(
WorkbenchAsyncDataTree,
'CallHierarchyPeek',
treeContainer,
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/debug/browser/callStackView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class CallStackView extends ViewletPanel {
const treeContainer = renderViewTree(container);

this.dataSource = new CallStackDataSource(this.debugService);
this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'CallStackView', treeContainer, new CallStackDelegate(), [
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<CallStackItem | IDebugModel, CallStackItem, FuzzyScore>>(WorkbenchAsyncDataTree, 'CallStackView', treeContainer, new CallStackDelegate(), [
new SessionsRenderer(this.instantiationService),
new ThreadsRenderer(this.instantiationService),
this.instantiationService.createInstance(StackFramesRenderer),
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/debug/browser/debugHover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class DebugHoverWidget implements IContentWidget {
this.treeContainer.setAttribute('role', 'tree');
const dataSource = new DebugHoverDataSource();

this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'DebugHover', this.treeContainer, new DebugHoverDelegate(), [this.instantiationService.createInstance(VariablesRenderer)],
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<IExpression, IExpression, any>>(WorkbenchAsyncDataTree, 'DebugHover', this.treeContainer, new DebugHoverDelegate(), [this.instantiationService.createInstance(VariablesRenderer)],
dataSource, {
ariaLabel: nls.localize('treeAriaLabel', "Debug Hover"),
accessibilityProvider: new DebugHoverAccessibilityProvider(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export class LoadedScriptsView extends ViewletPanel {
this.treeLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility });
this._register(this.treeLabels);

this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'LoadedScriptsView', this.treeContainer, new LoadedScriptsDelegate(),
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<LoadedScriptsItem, LoadedScriptsItem, FuzzyScore>>(WorkbenchAsyncDataTree, 'LoadedScriptsView', this.treeContainer, new LoadedScriptsDelegate(),
[new LoadedScriptsRenderer(this.treeLabels)],
new LoadedScriptsDataSource(),
{
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/debug/browser/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
const wordWrap = this.configurationService.getValue<IDebugConfiguration>('debug').console.wordWrap;
dom.toggleClass(treeContainer, 'word-wrap', wordWrap);
const linkDetector = this.instantiationService.createInstance(LinkDetector);
this.tree = this.instantiationService.createInstance(
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<IDebugSession, IReplElement, FuzzyScore>>(
WorkbenchAsyncDataTree,
'DebugRepl',
treeContainer,
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/debug/browser/variablesView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class VariablesView extends ViewletPanel {
dom.addClass(container, 'debug-variables');
const treeContainer = renderViewTree(container);

this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'VariablesView', treeContainer, new VariablesDelegate(),
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<IViewModel | IExpression | IScope, IExpression | IScope, FuzzyScore>>(WorkbenchAsyncDataTree, 'VariablesView', treeContainer, new VariablesDelegate(),
[this.instantiationService.createInstance(VariablesRenderer), new ScopesRenderer()],
new VariablesDataSource(), {
ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class WatchExpressionsView extends ViewletPanel {
const treeContainer = renderViewTree(container);

const expressionsRenderer = this.instantiationService.createInstance(WatchExpressionsRenderer);
this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'WatchExpressions', treeContainer, new WatchExpressionsDelegate(), [expressionsRenderer, this.instantiationService.createInstance(VariablesRenderer)],
this.tree = this.instantiationService.createInstance<typeof WorkbenchAsyncDataTree, WorkbenchAsyncDataTree<IDebugService | IExpression, IExpression, FuzzyScore>>(WorkbenchAsyncDataTree, 'WatchExpressions', treeContainer, new WatchExpressionsDelegate(), [expressionsRenderer, this.instantiationService.createInstance(VariablesRenderer)],
new WatchExpressionsDataSource(), {
ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'watchAriaTreeLabel' }, "Debug Watch Expressions"),
accessibilityProvider: new WatchExpressionsAccessibilityProvider(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export class ExtensionsListView extends ViewletPanel {
const delegate = new Delegate();
const extensionsViewState = new ExtensionsViewState();
const renderer = this.instantiationService.createInstance(Renderer, extensionsViewState);
this.list = this.instantiationService.createInstance(WorkbenchPagedList, 'Extensions', extensionsList, delegate, [renderer], {
this.list = this.instantiationService.createInstance<typeof WorkbenchPagedList, WorkbenchPagedList<IExtension>>(WorkbenchPagedList, 'Extensions', extensionsList, delegate, [renderer], {
ariaLabel: localize('extensions', "Extensions"),
multipleSelectionSupport: false,
setRowLineHeight: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
@IProductService private readonly productService: IProductService
) {
super();
if (this.extensionManagementServerService.localExtensionManagementServer) {
if (extensionManagementServerService.localExtensionManagementServer) {
this.localExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.localExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.localExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
this._register(Event.filter(this.localExtensions.onChange, e => !!e && e.operation === InstallOperation.Install)(e => this.onDidInstallExtension(e!.extension)));
}
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
if (extensionManagementServerService.remoteExtensionManagementServer) {
this.remoteExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.remoteExtensionManagementServer, ext => this.getExtensionState(ext)));
this._register(this.remoteExtensions.onChange(e => this._onChange.fire(e ? e.extension : undefined)));
this._register(Event.filter(this.remoteExtensions.onChange, e => !!e && e.operation === InstallOperation.Install)(e => this.onDidInstallExtension(e!.extension)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ export class RuntimeExtensionsEditor extends BaseEditor {
}
};

this._list = this._instantiationService.createInstance(WorkbenchList,
this._list = this._instantiationService.createInstance<typeof WorkbenchList, WorkbenchList<IRuntimeExtension>>(WorkbenchList,
'RuntimeExtensions',
parent, delegate, [renderer], {
multipleSelectionSupport: false,
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/markers/browser/markers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class MarkersWorkbenchService extends Disposable implements IMarkersWorkb
@IInstantiationService instantiationService: IInstantiationService,
) {
super();
this.markersModel = this._register(instantiationService.createInstance(MarkersModel, this.readMarkers()));
this.markersModel = this._register(instantiationService.createInstance(MarkersModel));

this.markersModel.setResourceMarkers(groupBy(this.readMarkers(), compareMarkersByUri).map(group => [group[0].resource, group]));
this._register(Event.debounce<readonly URI[], ResourceMap<URI>>(markerService.onMarkerChanged, (resourcesMap, resources) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class MarkerWidget extends Disposable {
) {
super();
this.actionBar = this._register(new ActionBar(dom.append(parent, dom.$('.actions')), {
actionViewItemProvider: (action) => action.id === QuickFixAction.ID ? instantiationService.createInstance(QuickFixActionViewItem, action) : undefined
actionViewItemProvider: (action: QuickFixAction) => action.id === QuickFixAction.ID ? instantiationService.createInstance(QuickFixActionViewItem, action) : undefined
}));
this.icon = dom.append(parent, dom.$(''));
this.multilineActionbar = this._register(new ActionBar(dom.append(parent, dom.$('.multiline-actions'))));
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/output/browser/logViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class LogViewerInput extends ResourceEditorInput {

public static readonly ID = 'workbench.editorinputs.output';

constructor(private outputChannelDescriptor: IFileOutputChannelDescriptor,
constructor(private readonly outputChannelDescriptor: IFileOutputChannelDescriptor,
@ITextModelService textModelResolverService: ITextModelService
) {
super(basename(outputChannelDescriptor.file.path), dirname(outputChannelDescriptor.file.path), URI.from({ scheme: LOG_SCHEME, path: outputChannelDescriptor.id }), undefined, textModelResolverService);
Expand Down
4 changes: 3 additions & 1 deletion src/vs/workbench/contrib/output/browser/outputActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { LogViewerInput } from 'vs/workbench/contrib/output/browser/logViewer';
import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox';
import { assertIsDefined } from 'vs/base/common/types';

export class ToggleOutputAction extends TogglePanelAction {

Expand Down Expand Up @@ -262,7 +263,8 @@ export class OpenOutputLogFileAction extends Action {
return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlogFile', "Select Log file") })
.then(entry => {
if (entry) {
return this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, entry.channel)).then(() => undefined);
assertIsDefined(entry.channel.file);
return this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, entry.channel as IFileOutputChannelDescriptor)).then(() => undefined);
}
return undefined;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export class DefineKeybindingWidget extends Widget {
readonly onShowExistingKeybidings: Event<string | null> = this._onShowExistingKeybindings.event;

constructor(
parent: HTMLElement,
parent: HTMLElement | null,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IThemeService private readonly themeService: IThemeService
) {
Expand Down