eclipse-theia / theia

Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript.
http://theia-ide.org
Eclipse Public License 2.0
20.07k stars 2.5k forks source link

Mismatching normalized URI in plugin system #11179

Open colin-grant-work opened 2 years ago

colin-grant-work commented 2 years ago

Bug Description:

This plugin uses the following sequence of calls to open, reveal, and set the selection in an editor:

https://github.com/alefragnani/vscode-bookmarks/blob/83483c19da24c2246436592b262f871f1cd39a17/src/extension.ts#L205-L213

For whatever reason - likely to do with workspace handling - the URI sometimes contains a double slash, e.g.

file:///home/colin/code/open/theia//packages/monaco/src/browser/monaco-editor-provider.ts
                                  ^^

This gets through the openTextDocument call fine, but in showTextDocument we have this code:

https://github.com/eclipse-theia/theia/blob/f4409b0003e61c06a36f1ba6b5693271b29170b2/packages/plugin-ext/src/plugin/plugin-context.ts#L385-L391

The URI that is given by editor.document.uri.toString() is normalized to something like

file:///home/colin/code/open/theia/packages/monaco/src/browser/monaco-editor-provider.ts
                                  ^

with no double slash, so the .find call returns undefined, and we throw an error in line 390, even though the document has actually been shown.

Steps to Reproduce:

  1. Install this plugin uri-normalization-problems-0.0.1.zip. Source here.
  2. Open Theia with Theia as workspace. Close any existing editors.
  3. Run the command 'VSCode API: Open document and reveal range'
  4. Note that the file is opened, but you are at the top of the file

Additional Information

colin-grant-work commented 2 years ago

@msujew, do you have any thoughts here? Is the mistake allowing the ill-formed URI in the first place (and we should modify our URI implementations to do some normalization when the URI is created), or is the mistake the fact that we do normalize at some point - probably resource resolution - and so depart from the input we've received? VSCode recently added a UriIdentityService to handle the kinds of comparisons we're currently doing in the showTextDocument find, as another approach.

msujew commented 2 years ago

@colin-grant-work I guess it's a combination of both. Something that irked me quite for a while already was the fact that we effectively use two different URI/path implementations. See for example:

const uri = new URI('file:///tmp//doubleslash');
const vscodeUriString = uri.toString(); // this will result in file:///tmp//doubleslash'
const theiaUriString = uri.schema + uri.path.toString(); // this will result in 'file:///tmp/doubleslash'

Note the missing doubleslash in the theiaUriString, since the Theia URI path is normalized, but the path of the vscode URI isn't.

We could go the same way as vscode and implement such an identity service. Alternatively, we could feed the normalized path back into the vscode URI after parsing it from a string, but I'm not sure how safe this is, considering we have parts of the app (plugin side) which almost exclusively deals in vscode URIs.

colin-grant-work commented 2 years ago
const uri = new URI('file:///tmp//doubleslash');
const vscodeUriString = uri.toString(); // this will result in file:///tmp//doubleslash'
const theiaUriString = uri.schema + uri.path.toString(); // this will result in 'file:///tmp/doubleslash'

Yikes - that's no good at all!

msujew commented 2 years ago

@colin-grant-work Nvm, I believe it does only do that if we actually manually call Path.normalize(), but there's still a normalization step when constructing paths:

https://github.com/eclipse-theia/theia/blob/d8a6ab45ef342982c36e805d5eff5d8f3cb8239e/packages/core/src/common/path.ts#L145-L146