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';

1010

import {SchemaMetadata, ViewEncapsulation, ɵConsole as Console} from '@angular/core';

11+

import * as path from 'path';

1112

import * as tss from 'typescript/lib/tsserverlibrary';

12131314

import {createLanguageService} from './language_service';

@@ -64,6 +65,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {

6465

private readonly fileToComponent = new Map<string, StaticSymbol>();

6566

private readonly collectedErrors = new Map<string, any[]>();

6667

private readonly fileVersions = new Map<string, string>();

68+

private readonly urlResolver: UrlResolver;

67696870

private lastProgram: tss.Program|undefined = undefined;

6971

private analyzedModules: NgAnalyzedModules = {

@@ -93,6 +95,16 @@ export class TypeScriptServiceHost implements LanguageServiceHost {

9395

this.staticSymbolResolver = new StaticSymbolResolver(

9496

this.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 {

125137

const pipeResolver = new PipeResolver(staticReflector);

126138

const elementSchemaRegistry = new DomElementSchemaRegistry();

127139

const resourceLoader = new DummyResourceLoader();

128-

const urlResolver = createOfflineCompileUrlResolver();

129140

const 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 {

134145

useJit: false,

135146

});

136147

const directiveNormalizer =

137-

new DirectiveNormalizer(resourceLoader, urlResolver, htmlParser, config);

148+

new DirectiveNormalizer(resourceLoader, this.urlResolver, htmlParser, config);

138149

this._resolver = new CompileMetadataResolver(

139150

config, htmlParser, moduleResolver, directiveResolver, pipeResolver,

140151

new 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();

196206

for (const ngModule of this.analyzedModules.ngModules) {

197207

for (const directive of ngModule.declaredDirectives) {

198208

const {metadata} = this.resolver.getNonNormalizedDirectiveMetadata(directive.reference)!;

199209

if (metadata.isComponent && metadata.template && metadata.template.templateUrl) {

200-

const templateName = urlResolver.resolve(

210+

const templateName = this.urlResolver.resolve(

201211

this.reflector.componentModuleUrl(directive.reference),

202212

metadata.template.templateUrl);

203213

this.fileToComponent.set(templateName, directive.reference);