Skip to content

Commit 250c8da

Browse files
chuckjazjasonaden
authored andcommitted
fix(language-service): ensure correct paths are passed to TypeScript (#21812)
The 2.6 version of TypeScript's `resolveModuleName` started to require paths passed to be separated by '/' instead of being able to handle '\'. `ngc` and `ng` already do this transformation. Fixes: #21811 PR Close #21812
1 parent 778e6e7 commit 250c8da

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

packages/language-service/src/reflector_host.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class ReflectorHost implements StaticSymbolResolverHost {
6969
throw new Error('Resolution of relative paths requires a containing file.');
7070
}
7171
// Any containing file gives the same result for absolute imports
72-
containingFile = path.join(this.options.basePath !, 'index.ts');
72+
containingFile = path.join(this.options.basePath !, 'index.ts').replace(/\\/g, '/');
7373
}
7474
const resolved =
7575
ts.resolveModuleName(moduleName, containingFile !, this.options, this.hostAdapter)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import * as path from 'path';
10+
import * as ts from 'typescript';
11+
12+
import {createLanguageService} from '../src/language_service';
13+
import {ReflectorHost} from '../src/reflector_host';
14+
import {Completions, LanguageService} from '../src/types';
15+
import {TypeScriptServiceHost} from '../src/typescript_host';
16+
17+
import {toh} from './test_data';
18+
import {MockTypescriptHost} from './test_utils';
19+
20+
describe('reflector_host_spec', () => {
21+
22+
// Regression #21811
23+
it('should be able to find angular under windows', () => {
24+
const originalJoin = path.join;
25+
let mockHost = new MockTypescriptHost(
26+
['/app/main.ts', '/app/parsing-cases.ts'], toh, 'app/node_modules',
27+
{...path, join: (...args: string[]) => originalJoin.apply(path, args)});
28+
let service = ts.createLanguageService(mockHost);
29+
let ngHost = new TypeScriptServiceHost(mockHost, service);
30+
let ngService = createLanguageService(ngHost);
31+
const reflectorHost = new ReflectorHost(() => undefined as any, mockHost, {basePath: '\\app'});
32+
33+
spyOn(path, 'join').and.callFake((...args: string[]) => { return path.win32.join(...args); });
34+
const result = reflectorHost.moduleNameToFileName('@angular/core');
35+
expect(result).not.toBeNull('could not find @angular/core using path.win32');
36+
});
37+
});

packages/language-service/test/test_utils.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,16 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
7171
private options: ts.CompilerOptions;
7272
private overrideDirectory = new Set<string>();
7373

74-
constructor(private scriptNames: string[], private data: MockData) {
74+
constructor(
75+
private scriptNames: string[], private data: MockData,
76+
private node_modules: string = 'node_modules', private myPath: typeof path = path) {
7577
const moduleFilename = module.filename.replace(/\\/g, '/');
7678
let angularIndex = moduleFilename.indexOf('@angular');
7779
if (angularIndex >= 0)
7880
this.angularPath = moduleFilename.substr(0, angularIndex).replace('/all/', '/all/@angular/');
7981
let distIndex = moduleFilename.indexOf('/dist/all');
8082
if (distIndex >= 0)
81-
this.nodeModulesPath = path.join(moduleFilename.substr(0, distIndex), 'node_modules');
83+
this.nodeModulesPath = myPath.join(moduleFilename.substr(0, distIndex), 'node_modules');
8284
this.options = {
8385
target: ts.ScriptTarget.ES5,
8486
module: ts.ModuleKind.CommonJS,
@@ -141,10 +143,13 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
141143
directoryExists(directoryName: string): boolean {
142144
if (this.overrideDirectory.has(directoryName)) return true;
143145
let effectiveName = this.getEffectiveName(directoryName);
144-
if (effectiveName === directoryName)
146+
if (effectiveName === directoryName) {
145147
return directoryExists(directoryName, this.data);
146-
else
148+
} else if (effectiveName == '/' + this.node_modules) {
149+
return true;
150+
} else {
147151
return fs.existsSync(effectiveName);
152+
}
148153
}
149154

150155
fileExists(fileName: string): boolean { return this.getRawFileContent(fileName) != null; }
@@ -175,7 +180,7 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
175180
let basename = path.basename(fileName);
176181
if (/^lib.*\.d\.ts$/.test(basename)) {
177182
let libPath = ts.getDefaultLibFilePath(this.getCompilationSettings());
178-
return fs.readFileSync(path.join(path.dirname(libPath), basename), 'utf8');
183+
return fs.readFileSync(this.myPath.join(path.dirname(libPath), basename), 'utf8');
179184
} else {
180185
if (missingCache.has(fileName)) {
181186
cacheUsed.add(fileName);
@@ -199,18 +204,18 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
199204
}
200205

201206
private getEffectiveName(name: string): string {
202-
const node_modules = 'node_modules';
207+
const node_modules = this.node_modules;
203208
const at_angular = '/@angular';
204209
if (name.startsWith('/' + node_modules)) {
205210
if (this.nodeModulesPath && !name.startsWith('/' + node_modules + at_angular)) {
206-
let result = path.join(this.nodeModulesPath, name.substr(node_modules.length + 1));
211+
let result = this.myPath.join(this.nodeModulesPath, name.substr(node_modules.length + 1));
207212
if (!name.match(rxjsts))
208213
if (fs.existsSync(result)) {
209214
return result;
210215
}
211216
}
212217
if (this.angularPath && name.startsWith('/' + node_modules + at_angular)) {
213-
return path.join(
218+
return this.myPath.join(
214219
this.angularPath, name.substr(node_modules.length + at_angular.length + 1));
215220
}
216221
}

0 commit comments

Comments
 (0)