fix(language-service): LSParseConfigHost.resolve should not concat abs paths (#40242)

`ts.server.ServerHost.resolvePath()` is different from Angular's
`FileSystem.resolve()` because the signature of the former is

```ts
resolvePath(path: string): string;	// ts.server.ServerHost
```

whereas the signature of the latter is
```ts
resolve(...paths: string[]): AbsoluteFsPath; // FileSystem on compiler-cli
```

The current implementation calls `path.join()` to concatenate all the input
paths and pass the result to `ts.server.ServerHost.resolvePath()`, but doing
so results in filenames like
```
/foo/bar/baz/foo/bar/baz/tsconfig.json
```
if both input paths are absolute.

`ts.server.ServerHost` should not be used to implement the
`resolve()` method expected by Angular's `FileSystem`.
We should use Node's `path.resolve()` instead, which will correctly collapse
the absolute paths.

Fix https://github.com/angular/vscode-ng-language-service/issues/1035

PR Close #40242
This commit is contained in:
Keen Yee Liau 2020-12-22 14:15:49 -08:00 committed by Joey Perrott
parent a62416c6e4
commit 0264f76e94
2 changed files with 22 additions and 1 deletions

View File

@ -123,7 +123,7 @@ export class LSParseConfigHost implements ConfigurationHost {
return p.extname(path);
}
resolve(...paths: string[]): AbsoluteFsPath {
return this.serverHost.resolvePath(this.join(paths[0], ...paths.slice(1))) as AbsoluteFsPath;
return p.resolve(...paths) as AbsoluteFsPath;
}
dirname<T extends PathString>(file: T): T {
return p.dirname(file) as T;

View File

@ -0,0 +1,21 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript/lib/tsserverlibrary';
import {LSParseConfigHost} from '../adapters';
describe('LSParseConfigHost.resolve()', () => {
it('should collapse absolute paths', () => {
const p1 = '/foo/bar/baz';
const p2 = '/foo/bar/baz/tsconfig.json';
const host = new LSParseConfigHost(ts.sys as ts.server.ServerHost);
const resolved = host.resolve(p1, p2);
expect(resolved).toBe('/foo/bar/baz/tsconfig.json');
});
});