fix(language-service): do not treat file URIs as general URLs (#39917) · angular/angular@829988b
@@ -6,8 +6,9 @@
66 * found in the LICENSE file at https://angular.io/license
77 */
889-import {analyzeNgModules, AotSummaryResolver, CompileDirectiveSummary, CompileMetadataResolver, CompileNgModuleMetadata, CompilePipeSummary, CompilerConfig, createOfflineCompileUrlResolver, DirectiveNormalizer, DirectiveResolver, DomElementSchemaRegistry, FormattedError, FormattedMessageChain, HtmlParser, isFormattedError, JitSummaryResolver, Lexer, NgAnalyzedModules, NgModuleResolver, Parser, ParseTreeResult, PipeResolver, ResourceLoader, StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, TemplateParser} from '@angular/compiler';
9+import {analyzeNgModules, AotSummaryResolver, CompileDirectiveSummary, CompileMetadataResolver, CompileNgModuleMetadata, CompilePipeSummary, CompilerConfig, DirectiveNormalizer, DirectiveResolver, DomElementSchemaRegistry, FormattedError, FormattedMessageChain, HtmlParser, isFormattedError, JitSummaryResolver, Lexer, NgAnalyzedModules, NgModuleResolver, Parser, ParseTreeResult, PipeResolver, ResourceLoader, StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, TemplateParser, UrlResolver} from '@angular/compiler';
1010import {SchemaMetadata, ViewEncapsulation, ɵConsole as Console} from '@angular/core';
11+import * as path from 'path';
1112import * as tss from 'typescript/lib/tsserverlibrary';
12131314import {createLanguageService} from './language_service';
@@ -64,6 +65,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
6465private readonly fileToComponent = new Map<string, StaticSymbol>();
6566private readonly collectedErrors = new Map<string, any[]>();
6667private readonly fileVersions = new Map<string, string>();
68+private readonly urlResolver: UrlResolver;
67696870private lastProgram: tss.Program|undefined = undefined;
6971private analyzedModules: NgAnalyzedModules = {
@@ -93,6 +95,16 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
9395this.staticSymbolResolver = new StaticSymbolResolver(
9496this.reflectorHost, this.staticSymbolCache, this.summaryResolver,
9597(e, filePath) => this.collectError(e, filePath));
98+this.urlResolver = {
99+resolve: (baseUrl: string, url: string) => {
100+// In practice, `directoryExists` is always defined.
101+// https://github.com/microsoft/TypeScript/blob/0b6c9254a850dd07056259d4eefca7721745af75/src/server/project.ts#L1608-L1614
102+if (tsLsHost.directoryExists!(baseUrl)) {
103+return path.resolve(baseUrl, url);
104+}
105+return path.resolve(path.dirname(baseUrl), url);
106+}
107+};
96108}
9710998110// The resolver is instantiated lazily and should not be accessed directly.
@@ -125,7 +137,6 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
125137const pipeResolver = new PipeResolver(staticReflector);
126138const elementSchemaRegistry = new DomElementSchemaRegistry();
127139const resourceLoader = new DummyResourceLoader();
128-const urlResolver = createOfflineCompileUrlResolver();
129140const htmlParser = new DummyHtmlParser();
130141// This tracks the CompileConfig in codegen.ts. Currently these options
131142// are hard-coded.
@@ -134,7 +145,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
134145useJit: false,
135146});
136147const directiveNormalizer =
137-new DirectiveNormalizer(resourceLoader, urlResolver, htmlParser, config);
148+new DirectiveNormalizer(resourceLoader, this.urlResolver, htmlParser, config);
138149this._resolver = new CompileMetadataResolver(
139150config, htmlParser, moduleResolver, directiveResolver, pipeResolver,
140151new JitSummaryResolver(), elementSchemaRegistry, directiveNormalizer, new Console(),
@@ -192,12 +203,11 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
192203}
193204194205// update template references and fileToComponent
195-const urlResolver = createOfflineCompileUrlResolver();
196206for (const ngModule of this.analyzedModules.ngModules) {
197207for (const directive of ngModule.declaredDirectives) {
198208const {metadata} = this.resolver.getNonNormalizedDirectiveMetadata(directive.reference)!;
199209if (metadata.isComponent && metadata.template && metadata.template.templateUrl) {
200-const templateName = urlResolver.resolve(
210+const templateName = this.urlResolver.resolve(
201211this.reflector.componentModuleUrl(directive.reference),
202212metadata.template.templateUrl);
203213this.fileToComponent.set(templateName, directive.reference);