Repository: microsoft/vscode (TypeScript)
Date: 2022-08-18 14:32:31+00:00
Task type: Bug Fix

Issue:
Matches should correctly work with all untyped editor inputs 
Right now a lot of the matches functions used a call to `super.matches` which would possibly incorrectly report diff or merge as the active editor when in fact only a normal `FileEditorInput` is active. 

https://github.com/microsoft/vscode/pull/158377#discussion_r948892583

These places should be investigated
Matches should correctly work with all untyped editor inputs 
Right now a lot of the matches functions used a call to `super.matches` which would possibly incorrectly report diff or merge as the active editor when in fact only a normal `FileEditorInput` is active. 

https://github.com/microsoft/vscode/pull/158377#discussion_r948892583

These places should be investigated


Issue discussion:

Solution patch:
diff --git a/src/vs/workbench/common/editor/textResourceEditorInput.ts b/src/vs/workbench/common/editor/textResourceEditorInput.ts
--- a/src/vs/workbench/common/editor/textResourceEditorInput.ts
+++ b/src/vs/workbench/common/editor/textResourceEditorInput.ts
@@ -3,7 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import { DEFAULT_EDITOR_ASSOCIATION, GroupIdentifier, IRevertOptions, IUntypedEditorInput } from 'vs/workbench/common/editor';
+import { DEFAULT_EDITOR_ASSOCIATION, GroupIdentifier, IRevertOptions, isResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor';
 import { EditorInput } from 'vs/workbench/common/editor/editorInput';
 import { AbstractResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
 import { URI } from 'vs/base/common/uri';
@@ -182,7 +182,7 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp
 	}
 
 	override matches(otherInput: EditorInput | IUntypedEditorInput): boolean {
-		if (super.matches(otherInput)) {
+		if (this === otherInput) {
 			return true;
 		}
 
@@ -190,6 +190,10 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp
 			return isEqual(otherInput.resource, this.resource);
 		}
 
+		if (isResourceEditorInput(otherInput)) {
+			return super.matches(otherInput);
+		}
+
 		return false;
 	}
 
diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts
--- a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts
+++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts
@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import { URI } from 'vs/base/common/uri';
-import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, EditorInputCapabilities, IEditorDescriptor, IEditorPane, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, IUntypedFileEditorInput, findViewStateForEditor, isResourceMergeEditorInput } from 'vs/workbench/common/editor';
+import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, EditorInputCapabilities, IEditorDescriptor, IEditorPane, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, IUntypedFileEditorInput, findViewStateForEditor, isResourceEditorInput } from 'vs/workbench/common/editor';
 import { EditorInput } from 'vs/workbench/common/editor/editorInput';
 import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
 import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
@@ -421,11 +421,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
 	}
 
 	override matches(otherInput: EditorInput | IUntypedEditorInput): boolean {
-		if (isResourceMergeEditorInput(otherInput)) {
-			return false;
-		}
-
-		if (super.matches(otherInput)) {
+		if (this === otherInput) {
 			return true;
 		}
 
@@ -433,6 +429,10 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
 			return isEqual(otherInput.resource, this.resource);
 		}
 
+		if (isResourceEditorInput(otherInput)) {
+			return super.matches(otherInput);
+		}
+
 		return false;
 	}
 
diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts
--- a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts
+++ b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts
@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import { URI } from 'vs/base/common/uri';
-import { DEFAULT_EDITOR_ASSOCIATION, findViewStateForEditor, GroupIdentifier, IUntitledTextResourceEditorInput, IUntypedEditorInput, Verbosity } from 'vs/workbench/common/editor';
+import { DEFAULT_EDITOR_ASSOCIATION, findViewStateForEditor, GroupIdentifier, isUntitledResourceEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput, Verbosity } from 'vs/workbench/common/editor';
 import { EditorInput } from 'vs/workbench/common/editor/editorInput';
 import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
 import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
@@ -158,7 +158,7 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp
 	}
 
 	override matches(otherInput: EditorInput | IUntypedEditorInput): boolean {
-		if (super.matches(otherInput)) {
+		if (this === otherInput) {
 			return true;
 		}
 
@@ -166,6 +166,10 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp
 			return isEqual(otherInput.resource, this.resource);
 		}
 
+		if (isUntitledResourceEditorInput(otherInput)) {
+			return super.matches(otherInput);
+		}
+
 		return false;
 	}
 


Test patch:
diff --git a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts
--- a/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts
+++ b/src/vs/workbench/test/browser/parts/editor/editorInput.test.ts
@@ -4,13 +4,43 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as assert from 'assert';
+import { DisposableStore } from 'vs/base/common/lifecycle';
+import { Schemas } from 'vs/base/common/network';
 import { URI } from 'vs/base/common/uri';
-import { isEditorInput, isResourceDiffEditorInput, isResourceEditorInput, isResourceMergeEditorInput, isResourceSideBySideEditorInput, isUntitledResourceEditorInput } from 'vs/workbench/common/editor';
+import { IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { DEFAULT_EDITOR_ASSOCIATION, IResourceDiffEditorInput, IResourceMergeEditorInput, IResourceSideBySideEditorInput, isEditorInput, isResourceDiffEditorInput, isResourceEditorInput, isResourceMergeEditorInput, isResourceSideBySideEditorInput, isUntitledResourceEditorInput, IUntitledTextResourceEditorInput } from 'vs/workbench/common/editor';
 import { EditorInput } from 'vs/workbench/common/editor/editorInput';
-import { TestEditorInput } from 'vs/workbench/test/browser/workbenchTestServices';
+import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
+import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput';
+import { MergeEditorInput, MergeEditorInputData } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput';
+import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
+import { TestEditorInput, TestServiceAccessor, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
 
 suite('EditorInput', () => {
 
+	let instantiationService: IInstantiationService;
+	let accessor: TestServiceAccessor;
+	let disposables: DisposableStore;
+
+	const testResource: URI = URI.from({ scheme: 'random', path: '/path' });
+	const untypedResourceEditorInput: IResourceEditorInput = { resource: testResource, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+	const untypedTextResourceEditorInput: ITextResourceEditorInput = { resource: testResource, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+	const untypedResourceSideBySideEditorInput: IResourceSideBySideEditorInput = { primary: untypedResourceEditorInput, secondary: untypedResourceEditorInput, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+	const untypedUntitledResourceEditorinput: IUntitledTextResourceEditorInput = { resource: URI.from({ scheme: Schemas.untitled, path: '/path' }), options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+	const untypedResourceDiffEditorInput: IResourceDiffEditorInput = { original: untypedResourceEditorInput, modified: untypedResourceEditorInput, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+	const untypedResourceMergeEditorInput: IResourceMergeEditorInput = { base: untypedResourceEditorInput, input1: untypedResourceEditorInput, input2: untypedResourceEditorInput, result: untypedResourceEditorInput, options: { override: DEFAULT_EDITOR_ASSOCIATION.id } };
+
+	setup(() => {
+		disposables = new DisposableStore();
+		instantiationService = workbenchInstantiationService(undefined, disposables);
+		accessor = instantiationService.createInstance(TestServiceAccessor);
+	});
+
+	teardown(() => {
+		disposables.dispose();
+	});
+
 	class MyEditorInput extends EditorInput {
 		readonly resource = undefined;
 
@@ -62,4 +92,58 @@ suite('EditorInput', () => {
 		assert.ok(!testInput.matches(testUntypedInputWrong));
 
 	});
+
+	test('Untpyed inputs properly match TextResourceEditorInput', () => {
+		const textResourceEditorInput = instantiationService.createInstance(TextResourceEditorInput, testResource, undefined, undefined, undefined, undefined);
+
+		assert.ok(textResourceEditorInput.matches(untypedResourceEditorInput));
+		assert.ok(textResourceEditorInput.matches(untypedTextResourceEditorInput));
+		assert.ok(!textResourceEditorInput.matches(untypedResourceSideBySideEditorInput));
+		assert.ok(!textResourceEditorInput.matches(untypedUntitledResourceEditorinput));
+		assert.ok(!textResourceEditorInput.matches(untypedResourceDiffEditorInput));
+		assert.ok(!textResourceEditorInput.matches(untypedResourceMergeEditorInput));
+
+		textResourceEditorInput.dispose();
+	});
+
+	test('Untyped inputs properly match FileEditorInput', () => {
+		const fileEditorInput = instantiationService.createInstance(FileEditorInput, testResource, undefined, undefined, undefined, undefined, undefined, undefined);
+
+		assert.ok(fileEditorInput.matches(untypedResourceEditorInput));
+		assert.ok(fileEditorInput.matches(untypedTextResourceEditorInput));
+		assert.ok(!fileEditorInput.matches(untypedResourceSideBySideEditorInput));
+		assert.ok(!fileEditorInput.matches(untypedUntitledResourceEditorinput));
+		assert.ok(!fileEditorInput.matches(untypedResourceDiffEditorInput));
+		assert.ok(!fileEditorInput.matches(untypedResourceMergeEditorInput));
+
+		fileEditorInput.dispose();
+	});
+
+	test('Untyped inputs properly match MergeEditorInput', () => {
+		const mergeData: MergeEditorInputData = { uri: testResource, description: undefined, detail: undefined, title: undefined };
+		const mergeEditorInput = instantiationService.createInstance(MergeEditorInput, testResource, mergeData, mergeData, testResource);
+
+		assert.ok(!mergeEditorInput.matches(untypedResourceEditorInput));
+		assert.ok(!mergeEditorInput.matches(untypedTextResourceEditorInput));
+		assert.ok(!mergeEditorInput.matches(untypedResourceSideBySideEditorInput));
+		assert.ok(!mergeEditorInput.matches(untypedUntitledResourceEditorinput));
+		assert.ok(!mergeEditorInput.matches(untypedResourceDiffEditorInput));
+		assert.ok(mergeEditorInput.matches(untypedResourceMergeEditorInput));
+
+		mergeEditorInput.dispose();
+	});
+
+	test('Untyped inputs properly match UntitledTextEditorInput', () => {
+		const untitledModel = accessor.untitledTextEditorService.create({ associatedResource: { authority: '', path: '/path', fragment: '', query: '' } });
+		const untitledTextEditorInput: UntitledTextEditorInput = instantiationService.createInstance(UntitledTextEditorInput, untitledModel);
+
+		assert.ok(!untitledTextEditorInput.matches(untypedResourceEditorInput));
+		assert.ok(!untitledTextEditorInput.matches(untypedTextResourceEditorInput));
+		assert.ok(!untitledTextEditorInput.matches(untypedResourceSideBySideEditorInput));
+		assert.ok(untitledTextEditorInput.matches(untypedUntitledResourceEditorinput));
+		assert.ok(!untitledTextEditorInput.matches(untypedResourceDiffEditorInput));
+		assert.ok(!untitledTextEditorInput.matches(untypedResourceMergeEditorInput));
+
+		untitledTextEditorInput.dispose();
+	});
 });