Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(language-service): reinstate getExternalFiles() #37750

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 24 additions & 1 deletion packages/language-service/src/ts_plugin.ts
Expand Up @@ -11,8 +11,30 @@ import * as tss from 'typescript/lib/tsserverlibrary';
import {createLanguageService} from './language_service';
import {TypeScriptServiceHost} from './typescript_host';

// Use a WeakMap to keep track of Project to Host mapping so that when Project
// is deleted Host could be garbage collected.
const PROJECT_MAP = new WeakMap<tss.server.Project, TypeScriptServiceHost>();

/**
* This function is called by tsserver to retrieve the external (non-TS) files
* that should belong to the specified `project`. For Angular, these files are
* external templates. This is called once when the project is loaded, then
* every time when the program is updated.
* @param project Project for which external files should be retrieved.
*/
export function getExternalFiles(project: tss.server.Project): string[] {
if (!project.hasRoots()) {
// During project initialization where there is no root files yet we should
// not do any work.
return [];
}
const ngLsHost = PROJECT_MAP.get(project);
ngLsHost?.getAnalyzedModules();
return ngLsHost?.getExternalTemplates() || [];
}

export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
const {languageService: tsLS, languageServiceHost: tsLSHost, config} = info;
const {languageService: tsLS, languageServiceHost: tsLSHost, config, project} = info;
// This plugin could operate under two different modes:
// 1. TS + Angular
// Plugin augments TS language service to provide additional Angular
Expand All @@ -25,6 +47,7 @@ export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
const angularOnly = config ? config.angularOnly === true : false;
const ngLSHost = new TypeScriptServiceHost(tsLSHost, tsLS);
const ngLS = createLanguageService(ngLSHost);
PROJECT_MAP.set(project, ngLSHost);

function getCompletionsAtPosition(
fileName: string, position: number, options: tss.GetCompletionsAtPositionOptions|undefined) {
Expand Down
7 changes: 7 additions & 0 deletions packages/language-service/src/typescript_host.ts
Expand Up @@ -151,6 +151,13 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
return this.resolver.getReflector() as StaticReflector;
}

/**
* Return all known external templates.
*/
getExternalTemplates(): string[] {
return [...this.fileToComponent.keys()];
}

/**
* Checks whether the program has changed and returns all analyzed modules.
* If program has changed, invalidate all caches and update fileToComponent
Expand Down
9 changes: 8 additions & 1 deletion packages/language-service/test/ts_plugin_spec.ts
Expand Up @@ -8,7 +8,7 @@

import * as ts from 'typescript';

import {create} from '../src/ts_plugin';
import {create, getExternalFiles} from '../src/ts_plugin';
import {CompletionKind} from '../src/types';

import {MockTypescriptHost} from './test_utils';
Expand Down Expand Up @@ -129,6 +129,13 @@ describe('plugin', () => {
},
]);
});

it('should return external templates when getExternalFiles() is called', () => {
const externalTemplates = getExternalFiles(mockProject);
expect(externalTemplates).toEqual([
'/app/test.ng',
]);
});
});

describe(`with config 'angularOnly = true`, () => {
Expand Down