fix(language-service): return all typecheck files via getExternalFiles (#40162)
We need a means to preserve typecheck files when a project is reloaded, otherwise the Ivy compiler will throw an error when it's unable to find them. This commit implements `getExternalFiles()` called by the langauge server to achieve this goal. For more info see https://github.com/angular/vscode-ng-language-service/issues/1030 PR Close #40162
This commit is contained in:
parent
0264f76e94
commit
183fb7e7b9
|
@ -244,7 +244,9 @@ function getOrCreateTypeCheckScriptInfo(
|
||||||
ts.server.toNormalizedPath(tcf),
|
ts.server.toNormalizedPath(tcf),
|
||||||
true, // openedByClient
|
true, // openedByClient
|
||||||
'', // fileContent
|
'', // fileContent
|
||||||
ts.ScriptKind.TS, // scriptKind
|
// script info added by plugins should be marked as external, see
|
||||||
|
// https://github.com/microsoft/TypeScript/blob/b217f22e798c781f55d17da72ed099a9dee5c650/src/compiler/program.ts#L1897-L1899
|
||||||
|
ts.ScriptKind.External, // scriptKind
|
||||||
);
|
);
|
||||||
if (!scriptInfo) {
|
if (!scriptInfo) {
|
||||||
throw new Error(`Failed to create script info for ${tcf}`);
|
throw new Error(`Failed to create script info for ${tcf}`);
|
||||||
|
|
|
@ -245,7 +245,7 @@ export class MockService {
|
||||||
ts.server.toNormalizedPath(fileName),
|
ts.server.toNormalizedPath(fileName),
|
||||||
true, // openedByClient
|
true, // openedByClient
|
||||||
'', // fileContent
|
'', // fileContent
|
||||||
ts.ScriptKind.External, // scriptKind
|
ts.ScriptKind.Unknown, // scriptKind
|
||||||
);
|
);
|
||||||
if (!newScriptInfo) {
|
if (!newScriptInfo) {
|
||||||
throw new Error(`Failed to create new script info for ${fileName}`);
|
throw new Error(`Failed to create new script info for ${fileName}`);
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* @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 {LanguageService} from '../../language_service';
|
||||||
|
import {getExternalFiles} from '../../ts_plugin';
|
||||||
|
|
||||||
|
import {APP_COMPONENT, setup} from './mock_host';
|
||||||
|
|
||||||
|
describe('getExternalFiles()', () => {
|
||||||
|
it('should return all typecheck files', () => {
|
||||||
|
const {project, tsLS} = setup();
|
||||||
|
let externalFiles = getExternalFiles(project);
|
||||||
|
// Initially there are no external files because Ivy compiler hasn't done
|
||||||
|
// a global analysis
|
||||||
|
expect(externalFiles).toEqual([]);
|
||||||
|
// Trigger global analysis
|
||||||
|
const ngLS = new LanguageService(project, tsLS);
|
||||||
|
ngLS.getSemanticDiagnostics(APP_COMPONENT);
|
||||||
|
// Now that global analysis is run, we should have all the typecheck files
|
||||||
|
externalFiles = getExternalFiles(project);
|
||||||
|
expect(externalFiles.length).toBe(1);
|
||||||
|
expect(externalFiles[0].endsWith('app.component.ngtypecheck.ts')).toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
|
@ -120,3 +120,19 @@ export function create(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||||
getCompletionEntrySymbol,
|
getCompletionEntrySymbol,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getExternalFiles(project: ts.server.Project): string[] {
|
||||||
|
if (!project.hasRoots()) {
|
||||||
|
return []; // project has not been initialized
|
||||||
|
}
|
||||||
|
const typecheckFiles: string[] = [];
|
||||||
|
for (const scriptInfo of project.getScriptInfos()) {
|
||||||
|
if (scriptInfo.scriptKind === ts.ScriptKind.External) {
|
||||||
|
// script info for typecheck file is marked as external, see
|
||||||
|
// getOrCreateTypeCheckScriptInfo() in
|
||||||
|
// packages/language-service/ivy/language_service.ts
|
||||||
|
typecheckFiles.push(scriptInfo.fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typecheckFiles;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue