fix(language-service): Return empty external files during project initialization (#32519)
This PR partially fixes a circular dependency problem whereby the creation of a project queries Angular plugin for external files, but the discovery of external files requires root files to be defined in a Project. The right approach is to return empty array if Project has no root files. PR Close #32519
This commit is contained in:
parent
b5eda603a2
commit
a65d3fa1de
|
@ -7,6 +7,7 @@ ls_rollup_bundle(
|
|||
"fs": "fs",
|
||||
"path": "path",
|
||||
"typescript": "ts",
|
||||
"typescript/lib/tsserverlibrary": "tss",
|
||||
},
|
||||
license_banner = "banner.js.txt",
|
||||
visibility = ["//packages/language-service:__pkg__"],
|
||||
|
|
|
@ -8,7 +8,10 @@ var $reflect = {defineMetadata: function() {}, getOwnMetadata: function() {}};
|
|||
var Reflect = (typeof global !== 'undefined' ? global : {})['Reflect'] || {};
|
||||
Object.keys($reflect).forEach(function(key) { Reflect[key] = Reflect[key] || $reflect[key]; });
|
||||
var $deferred, $resolved, $provided;
|
||||
function $getModule(name) { return $provided[name] || require(name); }
|
||||
function $getModule(name) {
|
||||
if (name === 'typescript/lib/tsserverlibrary') return $provided['typescript'] || require(name);
|
||||
return $provided[name] || require(name);
|
||||
}
|
||||
function define(modules, cb) { $deferred = { modules: modules, cb: cb }; }
|
||||
module.exports = function(provided) {
|
||||
if ($resolved) return $resolved;
|
||||
|
|
|
@ -6,20 +6,52 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as tss from 'typescript/lib/tsserverlibrary'; // used as type only
|
||||
import * as tss from 'typescript/lib/tsserverlibrary';
|
||||
|
||||
import {createLanguageService} from './language_service';
|
||||
import {TypeScriptServiceHost} from './typescript_host';
|
||||
|
||||
/**
|
||||
* A note about importing TypeScript module.
|
||||
* The TypeScript module is supplied by tsserver at runtime to ensure version
|
||||
* compatibility. In Angular language service, the rollup output is augmented
|
||||
* with a "banner" shim that overwrites 'typescript' and
|
||||
* 'typescript/lib/tsserverlibrary' imports with the value supplied by tsserver.
|
||||
* This means import of either modules will not be "required", but they'll work
|
||||
* just like regular imports.
|
||||
*/
|
||||
|
||||
const projectHostMap = new WeakMap<tss.server.Project, TypeScriptServiceHost>();
|
||||
|
||||
export function getExternalFiles(project: tss.server.Project): string[]|undefined {
|
||||
const host = projectHostMap.get(project);
|
||||
if (host) {
|
||||
host.getAnalyzedModules();
|
||||
const externalFiles = host.getTemplateReferences();
|
||||
return externalFiles;
|
||||
/**
|
||||
* Return the external templates discovered through processing all NgModules in
|
||||
* the specified `project`.
|
||||
* This function is called in a few situations:
|
||||
* 1. When a ConfiguredProject is created
|
||||
* https://github.com/microsoft/TypeScript/blob/c26c44d5fceb04ea14da20b6ed23449df777ff34/src/server/editorServices.ts#L1755
|
||||
* 2. When updateGraph() is called on a Project
|
||||
* https://github.com/microsoft/TypeScript/blob/c26c44d5fceb04ea14da20b6ed23449df777ff34/src/server/project.ts#L915
|
||||
* @param project Most likely a ConfiguredProject
|
||||
*/
|
||||
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 = projectHostMap.get(project);
|
||||
if (!ngLSHost) {
|
||||
// Without an Angular host there is no way to get template references.
|
||||
return [];
|
||||
}
|
||||
ngLSHost.getAnalyzedModules();
|
||||
const templates = ngLSHost.getTemplateReferences();
|
||||
const logger = project.projectService.logger;
|
||||
if (logger.hasLevel(tss.server.LogLevel.verbose)) {
|
||||
// Log external files to help debugging.
|
||||
logger.info(`External files in ${project.projectName}: ${JSON.stringify(templates)}`);
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
export function create(info: tss.server.PluginCreateInfo): tss.LanguageService {
|
||||
|
|
Loading…
Reference in New Issue