From a62416c6e48d3501d41ab18a54c5c430fec26d4a Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Tue, 22 Dec 2020 15:07:45 -0800 Subject: [PATCH] fix(language-service): include compilerOptions.rootDir in rootDirs (#40243) When resolving references, the Ivy compiler has a few strategies it could use. For relative path, one of strategies is [`RelativePathStrategy`]( https://github.com/angular/angular/blob/master/packages/compiler-cli/src/ ngtsc/imports/README.md#relativepathstrategy). This strategy relies on `compilerOptions.rootDir` and `compilerOptions.rootDirs` to perform the resolution, but language service only passes `rootDirs` to the compiler, and not `rootDir`. In reality, `rootDir` is very different from `rootDirs` even though they sound the same. According to the official [TS documentation][1], > `rootDir` specifies the root directory of input files. Only use to control > the output directory structure with --outDir. > `rootDirs` is a list of root folders whose combined content represent the > structure of the project at runtime. See [Module Resolution documentation]( > https://www.typescriptlang.org/docs/handbook/ > module-resolution.html#virtual-directories-with-rootdirs) > for more details. For now, we keep the behavior between compiler and language service consistent, but we will revisit the notion of `rootDir` and how it is used later. Fix angular/vscode-ng-language-service#1039 [1]: https://www.typescriptlang.org/docs/handbook/compiler-options.html PR Close #40243 --- packages/compiler-cli/src/ngtsc/util/src/typescript.ts | 4 +++- packages/language-service/ivy/BUILD.bazel | 1 + packages/language-service/ivy/adapters.ts | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts index f8ca1fb619..63af2e8206 100644 --- a/packages/compiler-cli/src/ngtsc/util/src/typescript.ts +++ b/packages/compiler-cli/src/ngtsc/util/src/typescript.ts @@ -92,7 +92,9 @@ export function isExported(node: DeclarationNode): boolean { topLevel.modifiers.some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword); } -export function getRootDirs(host: ts.CompilerHost, options: ts.CompilerOptions): AbsoluteFsPath[] { +export function getRootDirs( + host: Pick, + options: ts.CompilerOptions): AbsoluteFsPath[] { const rootDirs: string[] = []; if (options.rootDirs !== undefined) { rootDirs.push(...options.rootDirs); diff --git a/packages/language-service/ivy/BUILD.bazel b/packages/language-service/ivy/BUILD.bazel index 044974cee2..37b67f6c39 100644 --- a/packages/language-service/ivy/BUILD.bazel +++ b/packages/language-service/ivy/BUILD.bazel @@ -18,6 +18,7 @@ ts_library( "//packages/compiler-cli/src/ngtsc/shims", "//packages/compiler-cli/src/ngtsc/typecheck", "//packages/compiler-cli/src/ngtsc/typecheck/api", + "//packages/compiler-cli/src/ngtsc/util", "@npm//@types/node", "@npm//typescript", ], diff --git a/packages/language-service/ivy/adapters.ts b/packages/language-service/ivy/adapters.ts index c95d326688..bd02eaa562 100644 --- a/packages/language-service/ivy/adapters.ts +++ b/packages/language-service/ivy/adapters.ts @@ -10,8 +10,9 @@ import {ConfigurationHost} from '@angular/compiler-cli'; import {NgCompilerAdapter} from '@angular/compiler-cli/src/ngtsc/core/api'; -import {absoluteFrom, AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system'; +import {AbsoluteFsPath, FileStats, PathSegment, PathString} from '@angular/compiler-cli/src/ngtsc/file_system'; import {isShim} from '@angular/compiler-cli/src/ngtsc/shims'; +import {getRootDirs} from '@angular/compiler-cli/src/ngtsc/util/src/typescript'; import * as p from 'path'; import * as ts from 'typescript/lib/tsserverlibrary'; @@ -27,7 +28,7 @@ export class LanguageServiceAdapter implements NgCompilerAdapter { private readonly templateVersion = new Map(); constructor(private readonly project: ts.server.Project) { - this.rootDirs = project.getCompilationSettings().rootDirs?.map(absoluteFrom) || []; + this.rootDirs = getRootDirs(this, project.getCompilationSettings()); } isShim(sf: ts.SourceFile): boolean {