refactor(compiler-cli): extract NgCompilerAdapter interface (#37118)
`NgCompiler` is the heart of ngtsc and can be used to analyze and compile Angular programs in a variety of environments. Most of these integrations rely on `NgProgram` and the creation of an `NgCompilerHost` in order to create a `ts.Program` with the right shape for `NgCompiler`. However, certain environments (such as the Angular Language Service) have their own mechanisms for creating `ts.Program`s that don't make use of a `ts.CompilerHost`. In such environments, an `NgCompilerHost` does not make sense. This commit breaks the dependency of `NgCompiler` on `NgCompilerHost` and extracts the specific interface of the host on which `NgCompiler` depends into a new interface, `NgCompilerAdapter`. This interface includes methods from `ts.CompilerHost`, the `ExtendedTsCompilerHost`, as well as APIs from `NgCompilerHost`. A consumer such as the language service can implement this API without needing to jump through hoops to create an `NgCompilerHost` implementation that somehow wraps its specific environment. PR Close #37118
This commit is contained in:
parent
965a688c97
commit
e648a0c4ca
|
@ -20,7 +20,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/reflection",
|
"//packages/compiler-cli/src/ngtsc/reflection",
|
||||||
"//packages/compiler-cli/src/ngtsc/routing",
|
"//packages/compiler-cli/src/ngtsc/routing",
|
||||||
"//packages/compiler-cli/src/ngtsc/scope",
|
"//packages/compiler-cli/src/ngtsc/scope",
|
||||||
"//packages/compiler-cli/src/ngtsc/shims",
|
"//packages/compiler-cli/src/ngtsc/shims:api",
|
||||||
"//packages/compiler-cli/src/ngtsc/transform",
|
"//packages/compiler-cli/src/ngtsc/transform",
|
||||||
"//packages/compiler-cli/src/ngtsc/typecheck",
|
"//packages/compiler-cli/src/ngtsc/typecheck",
|
||||||
"//packages/compiler-cli/src/ngtsc/util",
|
"//packages/compiler-cli/src/ngtsc/util",
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {PartialEvaluator, ResolvedValue, ResolvedValueArray} from '../../partial
|
||||||
import {ClassDeclaration, Decorator, ReflectionHost, reflectObjectLiteral, typeNodeToValueExpr} from '../../reflection';
|
import {ClassDeclaration, Decorator, ReflectionHost, reflectObjectLiteral, typeNodeToValueExpr} from '../../reflection';
|
||||||
import {NgModuleRouteAnalyzer} from '../../routing';
|
import {NgModuleRouteAnalyzer} from '../../routing';
|
||||||
import {LocalModuleScopeRegistry, ScopeData} from '../../scope';
|
import {LocalModuleScopeRegistry, ScopeData} from '../../scope';
|
||||||
import {FactoryTracker} from '../../shims';
|
import {FactoryTracker} from '../../shims/api';
|
||||||
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult} from '../../transform';
|
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult} from '../../transform';
|
||||||
import {getSourceFile} from '../../util/src/typescript';
|
import {getSourceFile} from '../../util/src/typescript';
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ ts_library(
|
||||||
srcs = glob(["api/**/*.ts"]),
|
srcs = glob(["api/**/*.ts"]),
|
||||||
deps = [
|
deps = [
|
||||||
"//packages/compiler-cli/src/ngtsc/file_system",
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
||||||
|
"//packages/compiler-cli/src/ngtsc/shims:api",
|
||||||
"@npm//typescript",
|
"@npm//typescript",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export * from './src/adapter';
|
||||||
export * from './src/interfaces';
|
export * from './src/interfaces';
|
||||||
export * from './src/options';
|
export * from './src/options';
|
||||||
export * from './src/public_options';
|
export * from './src/public_options';
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
|
import {AbsoluteFsPath} from '../../../file_system';
|
||||||
|
import {FactoryTracker} from '../../../shims/api';
|
||||||
|
|
||||||
|
import {ExtendedTsCompilerHost, UnifiedModulesHost} from './interfaces';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Names of methods from `ExtendedTsCompilerHost` that need to be provided by the
|
||||||
|
* `NgCompilerAdapter`.
|
||||||
|
*/
|
||||||
|
export type ExtendedCompilerHostMethods =
|
||||||
|
// Used to normalize filenames for the host system. Important for proper case-sensitive file
|
||||||
|
// handling.
|
||||||
|
'getCanonicalFileName'|
|
||||||
|
// An optional method of `ts.CompilerHost` where an implementer can override module resolution.
|
||||||
|
'resolveModuleNames'|
|
||||||
|
// Retrieve the current working directory. Unlike in `ts.ModuleResolutionHost`, this is a
|
||||||
|
// required method.
|
||||||
|
'getCurrentDirectory'|
|
||||||
|
// Additional methods of `ExtendedTsCompilerHost` related to resource files (e.g. HTML
|
||||||
|
// templates). These are optional.
|
||||||
|
'getModifiedResourceFiles'|'readResource'|'resourceNameToFileName';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter for `NgCompiler` that allows it to be used in various circumstances, such as
|
||||||
|
* command-line `ngc`, as a plugin to `ts_library` in Bazel, or from the Language Service.
|
||||||
|
*
|
||||||
|
* `NgCompilerAdapter` is a subset of the `NgCompilerHost` implementation of `ts.CompilerHost`
|
||||||
|
* which is relied upon by `NgCompiler`. A consumer of `NgCompiler` can therefore use the
|
||||||
|
* `NgCompilerHost` or implement `NgCompilerAdapter` itself.
|
||||||
|
*/
|
||||||
|
export interface NgCompilerAdapter extends
|
||||||
|
// getCurrentDirectory is removed from `ts.ModuleResolutionHost` because it's optional, and
|
||||||
|
// incompatible with the `ts.CompilerHost` version which isn't. The combination of these two
|
||||||
|
// still satisfies `ts.ModuleResolutionHost`.
|
||||||
|
Omit<ts.ModuleResolutionHost, 'getCurrentDirectory'>,
|
||||||
|
Pick<ExtendedTsCompilerHost, 'getCurrentDirectory'|ExtendedCompilerHostMethods> {
|
||||||
|
/**
|
||||||
|
* A path to a single file which represents the entrypoint of an Angular Package Format library,
|
||||||
|
* if the current program is one.
|
||||||
|
*
|
||||||
|
* This is used to emit a flat module index if requested, and can be left `null` if that is not
|
||||||
|
* required.
|
||||||
|
*/
|
||||||
|
readonly entryPoint: AbsoluteFsPath|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of `ts.Diagnostic`s that occurred during construction of the `ts.Program`.
|
||||||
|
*/
|
||||||
|
readonly constructionDiagnostics: ts.Diagnostic[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Set` of `ts.SourceFile`s which are internal to the program and should not be emitted as JS
|
||||||
|
* files.
|
||||||
|
*
|
||||||
|
* Often these are shim files such as `ngtypecheck` shims used for template type-checking in
|
||||||
|
* command-line ngc.
|
||||||
|
*/
|
||||||
|
readonly ignoreForEmit: Set<ts.SourceFile>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tracker for usage of symbols in `.ngfactory` shims.
|
||||||
|
*
|
||||||
|
* This can be left `null` if such shims are not a part of the `ts.Program`.
|
||||||
|
*/
|
||||||
|
readonly factoryTracker: FactoryTracker|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized interface provided in some environments (such as Bazel) which overrides how
|
||||||
|
* import specifiers are generated.
|
||||||
|
*
|
||||||
|
* If not required, this can be `null`.
|
||||||
|
*/
|
||||||
|
readonly unifiedModulesHost: UnifiedModulesHost|null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolved list of root directories explicitly set in, or inferred from, the tsconfig.
|
||||||
|
*/
|
||||||
|
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distinguishes between shim files added by Angular to the compilation process (both those
|
||||||
|
* intended for output, like ngfactory files, as well as internal shims like ngtypecheck files)
|
||||||
|
* and original files in the user's program.
|
||||||
|
*
|
||||||
|
* This is mostly used to limit type-checking operations to only user files. It should return
|
||||||
|
* `true` if a file was written by the user, and `false` if a file was added by the compiler.
|
||||||
|
*/
|
||||||
|
isShim(sf: ts.SourceFile): boolean;
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ import {ModuleWithProvidersScanner} from '../../modulewithproviders';
|
||||||
import {PartialEvaluator} from '../../partial_evaluator';
|
import {PartialEvaluator} from '../../partial_evaluator';
|
||||||
import {NOOP_PERF_RECORDER, PerfRecorder} from '../../perf';
|
import {NOOP_PERF_RECORDER, PerfRecorder} from '../../perf';
|
||||||
import {TypeScriptReflectionHost} from '../../reflection';
|
import {TypeScriptReflectionHost} from '../../reflection';
|
||||||
import {HostResourceLoader} from '../../resource';
|
import {AdapterResourceLoader} from '../../resource';
|
||||||
import {entryPointKeyFor, NgModuleRouteAnalyzer} from '../../routing';
|
import {entryPointKeyFor, NgModuleRouteAnalyzer} from '../../routing';
|
||||||
import {ComponentScopeReader, LocalModuleScopeRegistry, MetadataDtsModuleScopeResolver} from '../../scope';
|
import {ComponentScopeReader, LocalModuleScopeRegistry, MetadataDtsModuleScopeResolver} from '../../scope';
|
||||||
import {generatedFactoryTransform} from '../../shims';
|
import {generatedFactoryTransform} from '../../shims';
|
||||||
|
@ -30,11 +30,7 @@ import {ivySwitchTransform} from '../../switch';
|
||||||
import {aliasTransformFactory, declarationTransformFactory, DecoratorHandler, DtsTransformRegistry, ivyTransformFactory, TraitCompiler} from '../../transform';
|
import {aliasTransformFactory, declarationTransformFactory, DecoratorHandler, DtsTransformRegistry, ivyTransformFactory, TraitCompiler} from '../../transform';
|
||||||
import {isTemplateDiagnostic, TemplateTypeChecker, TypeCheckContext, TypeCheckingConfig, TypeCheckingProgramStrategy} from '../../typecheck';
|
import {isTemplateDiagnostic, TemplateTypeChecker, TypeCheckContext, TypeCheckingConfig, TypeCheckingProgramStrategy} from '../../typecheck';
|
||||||
import {getSourceFileOrNull, isDtsPath, resolveModuleName} from '../../util/src/typescript';
|
import {getSourceFileOrNull, isDtsPath, resolveModuleName} from '../../util/src/typescript';
|
||||||
import {LazyRoute, NgCompilerOptions} from '../api';
|
import {LazyRoute, NgCompilerAdapter, NgCompilerOptions} from '../api';
|
||||||
|
|
||||||
import {NgCompilerHost} from './host';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State information about a compilation which is only generated once some data is requested from
|
* State information about a compilation which is only generated once some data is requested from
|
||||||
|
@ -94,18 +90,18 @@ export class NgCompiler {
|
||||||
private nextProgram: ts.Program;
|
private nextProgram: ts.Program;
|
||||||
private entryPoint: ts.SourceFile|null;
|
private entryPoint: ts.SourceFile|null;
|
||||||
private moduleResolver: ModuleResolver;
|
private moduleResolver: ModuleResolver;
|
||||||
private resourceManager: HostResourceLoader;
|
private resourceManager: AdapterResourceLoader;
|
||||||
private cycleAnalyzer: CycleAnalyzer;
|
private cycleAnalyzer: CycleAnalyzer;
|
||||||
readonly incrementalDriver: IncrementalDriver;
|
readonly incrementalDriver: IncrementalDriver;
|
||||||
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
|
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
|
||||||
readonly ignoreForEmit: Set<ts.SourceFile>;
|
readonly ignoreForEmit: Set<ts.SourceFile>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private host: NgCompilerHost, private options: NgCompilerOptions,
|
private adapter: NgCompilerAdapter, private options: NgCompilerOptions,
|
||||||
private tsProgram: ts.Program,
|
private tsProgram: ts.Program,
|
||||||
private typeCheckingProgramStrategy: TypeCheckingProgramStrategy,
|
private typeCheckingProgramStrategy: TypeCheckingProgramStrategy,
|
||||||
oldProgram: ts.Program|null = null, private perfRecorder: PerfRecorder = NOOP_PERF_RECORDER) {
|
oldProgram: ts.Program|null = null, private perfRecorder: PerfRecorder = NOOP_PERF_RECORDER) {
|
||||||
this.constructionDiagnostics.push(...this.host.diagnostics);
|
this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics);
|
||||||
const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(this.options);
|
const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(this.options);
|
||||||
if (incompatibleTypeCheckOptionsDiagnostic !== null) {
|
if (incompatibleTypeCheckOptionsDiagnostic !== null) {
|
||||||
this.constructionDiagnostics.push(incompatibleTypeCheckOptionsDiagnostic);
|
this.constructionDiagnostics.push(incompatibleTypeCheckOptionsDiagnostic);
|
||||||
|
@ -115,18 +111,19 @@ export class NgCompiler {
|
||||||
this.closureCompilerEnabled = !!this.options.annotateForClosureCompiler;
|
this.closureCompilerEnabled = !!this.options.annotateForClosureCompiler;
|
||||||
|
|
||||||
this.entryPoint =
|
this.entryPoint =
|
||||||
host.entryPoint !== null ? getSourceFileOrNull(tsProgram, host.entryPoint) : null;
|
adapter.entryPoint !== null ? getSourceFileOrNull(tsProgram, adapter.entryPoint) : null;
|
||||||
|
|
||||||
const moduleResolutionCache = ts.createModuleResolutionCache(
|
const moduleResolutionCache = ts.createModuleResolutionCache(
|
||||||
this.host.getCurrentDirectory(), fileName => this.host.getCanonicalFileName(fileName));
|
this.adapter.getCurrentDirectory(),
|
||||||
|
fileName => this.adapter.getCanonicalFileName(fileName));
|
||||||
this.moduleResolver =
|
this.moduleResolver =
|
||||||
new ModuleResolver(tsProgram, this.options, this.host, moduleResolutionCache);
|
new ModuleResolver(tsProgram, this.options, this.adapter, moduleResolutionCache);
|
||||||
this.resourceManager = new HostResourceLoader(host, this.options);
|
this.resourceManager = new AdapterResourceLoader(adapter, this.options);
|
||||||
this.cycleAnalyzer = new CycleAnalyzer(new ImportGraph(this.moduleResolver));
|
this.cycleAnalyzer = new CycleAnalyzer(new ImportGraph(this.moduleResolver));
|
||||||
|
|
||||||
let modifiedResourceFiles: Set<string>|null = null;
|
let modifiedResourceFiles: Set<string>|null = null;
|
||||||
if (this.host.getModifiedResourceFiles !== undefined) {
|
if (this.adapter.getModifiedResourceFiles !== undefined) {
|
||||||
modifiedResourceFiles = this.host.getModifiedResourceFiles() || null;
|
modifiedResourceFiles = this.adapter.getModifiedResourceFiles() || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldProgram === null) {
|
if (oldProgram === null) {
|
||||||
|
@ -146,9 +143,9 @@ export class NgCompiler {
|
||||||
setIncrementalDriver(tsProgram, this.incrementalDriver);
|
setIncrementalDriver(tsProgram, this.incrementalDriver);
|
||||||
|
|
||||||
this.ignoreForDiagnostics =
|
this.ignoreForDiagnostics =
|
||||||
new Set(tsProgram.getSourceFiles().filter(sf => this.host.isShim(sf)));
|
new Set(tsProgram.getSourceFiles().filter(sf => this.adapter.isShim(sf)));
|
||||||
|
|
||||||
this.ignoreForEmit = this.host.ignoreForEmit;
|
this.ignoreForEmit = this.adapter.ignoreForEmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -279,7 +276,7 @@ export class NgCompiler {
|
||||||
const containingFile = this.tsProgram.getRootFileNames()[0];
|
const containingFile = this.tsProgram.getRootFileNames()[0];
|
||||||
const [entryPath, moduleName] = entryRoute.split('#');
|
const [entryPath, moduleName] = entryRoute.split('#');
|
||||||
const resolvedModule =
|
const resolvedModule =
|
||||||
resolveModuleName(entryPath, containingFile, this.options, this.host, null);
|
resolveModuleName(entryPath, containingFile, this.options, this.adapter, null);
|
||||||
|
|
||||||
if (resolvedModule) {
|
if (resolvedModule) {
|
||||||
entryRoute = entryPointKeyFor(resolvedModule.resolvedFileName, moduleName);
|
entryRoute = entryPointKeyFor(resolvedModule.resolvedFileName, moduleName);
|
||||||
|
@ -326,8 +323,9 @@ export class NgCompiler {
|
||||||
afterDeclarations.push(aliasTransformFactory(compilation.traitCompiler.exportStatements));
|
afterDeclarations.push(aliasTransformFactory(compilation.traitCompiler.exportStatements));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.host.factoryTracker !== null) {
|
if (this.adapter.factoryTracker !== null) {
|
||||||
before.push(generatedFactoryTransform(this.host.factoryTracker.sourceInfo, importRewriter));
|
before.push(
|
||||||
|
generatedFactoryTransform(this.adapter.factoryTracker.sourceInfo, importRewriter));
|
||||||
}
|
}
|
||||||
before.push(ivySwitchTransform);
|
before.push(ivySwitchTransform);
|
||||||
|
|
||||||
|
@ -499,7 +497,7 @@ export class NgCompiler {
|
||||||
const typeCheckSpan = this.perfRecorder.start('typeCheckDiagnostics');
|
const typeCheckSpan = this.perfRecorder.start('typeCheckDiagnostics');
|
||||||
const diagnostics: ts.Diagnostic[] = [];
|
const diagnostics: ts.Diagnostic[] = [];
|
||||||
for (const sf of this.tsProgram.getSourceFiles()) {
|
for (const sf of this.tsProgram.getSourceFiles()) {
|
||||||
if (sf.isDeclarationFile || this.host.isShim(sf)) {
|
if (sf.isDeclarationFile || this.adapter.isShim(sf)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +598,7 @@ export class NgCompiler {
|
||||||
// Construct the ReferenceEmitter.
|
// Construct the ReferenceEmitter.
|
||||||
let refEmitter: ReferenceEmitter;
|
let refEmitter: ReferenceEmitter;
|
||||||
let aliasingHost: AliasingHost|null = null;
|
let aliasingHost: AliasingHost|null = null;
|
||||||
if (this.host.unifiedModulesHost === null || !this.options._useHostForImportGeneration) {
|
if (this.adapter.unifiedModulesHost === null || !this.options._useHostForImportGeneration) {
|
||||||
let localImportStrategy: ReferenceEmitStrategy;
|
let localImportStrategy: ReferenceEmitStrategy;
|
||||||
|
|
||||||
// The strategy used for local, in-project imports depends on whether TS has been configured
|
// The strategy used for local, in-project imports depends on whether TS has been configured
|
||||||
|
@ -613,7 +611,7 @@ export class NgCompiler {
|
||||||
// rootDirs logic is in effect - use the `LogicalProjectStrategy` for in-project relative
|
// rootDirs logic is in effect - use the `LogicalProjectStrategy` for in-project relative
|
||||||
// imports.
|
// imports.
|
||||||
localImportStrategy = new LogicalProjectStrategy(
|
localImportStrategy = new LogicalProjectStrategy(
|
||||||
reflector, new LogicalFileSystem([...this.host.rootDirs], this.host));
|
reflector, new LogicalFileSystem([...this.adapter.rootDirs], this.adapter));
|
||||||
} else {
|
} else {
|
||||||
// Plain relative imports are all that's needed.
|
// Plain relative imports are all that's needed.
|
||||||
localImportStrategy = new RelativePathStrategy(reflector);
|
localImportStrategy = new RelativePathStrategy(reflector);
|
||||||
|
@ -648,9 +646,9 @@ export class NgCompiler {
|
||||||
// Then use aliased references (this is a workaround to StrictDeps checks).
|
// Then use aliased references (this is a workaround to StrictDeps checks).
|
||||||
new AliasStrategy(),
|
new AliasStrategy(),
|
||||||
// Then use fileNameToModuleName to emit imports.
|
// Then use fileNameToModuleName to emit imports.
|
||||||
new UnifiedModulesStrategy(reflector, this.host.unifiedModulesHost),
|
new UnifiedModulesStrategy(reflector, this.adapter.unifiedModulesHost),
|
||||||
]);
|
]);
|
||||||
aliasingHost = new UnifiedModulesAliasingHost(this.host.unifiedModulesHost);
|
aliasingHost = new UnifiedModulesAliasingHost(this.adapter.unifiedModulesHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
const evaluator = new PartialEvaluator(reflector, checker, this.incrementalDriver.depGraph);
|
const evaluator = new PartialEvaluator(reflector, checker, this.incrementalDriver.depGraph);
|
||||||
|
@ -693,7 +691,7 @@ export class NgCompiler {
|
||||||
const handlers: DecoratorHandler<unknown, unknown, unknown>[] = [
|
const handlers: DecoratorHandler<unknown, unknown, unknown>[] = [
|
||||||
new ComponentDecoratorHandler(
|
new ComponentDecoratorHandler(
|
||||||
reflector, evaluator, metaRegistry, metaReader, scopeReader, scopeRegistry, isCore,
|
reflector, evaluator, metaRegistry, metaReader, scopeReader, scopeRegistry, isCore,
|
||||||
this.resourceManager, this.host.rootDirs, this.options.preserveWhitespaces || false,
|
this.resourceManager, this.adapter.rootDirs, this.options.preserveWhitespaces || false,
|
||||||
this.options.i18nUseExternalIds !== false,
|
this.options.i18nUseExternalIds !== false,
|
||||||
this.options.enableI18nLegacyMessageIdFormat !== false,
|
this.options.enableI18nLegacyMessageIdFormat !== false,
|
||||||
this.options.i18nNormalizeLineEndingsInICUs, this.moduleResolver, this.cycleAnalyzer,
|
this.options.i18nNormalizeLineEndingsInICUs, this.moduleResolver, this.cycleAnalyzer,
|
||||||
|
@ -721,7 +719,7 @@ export class NgCompiler {
|
||||||
injectableRegistry),
|
injectableRegistry),
|
||||||
new NgModuleDecoratorHandler(
|
new NgModuleDecoratorHandler(
|
||||||
reflector, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, isCore,
|
reflector, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, isCore,
|
||||||
routeAnalyzer, refEmitter, this.host.factoryTracker, defaultImportTracker,
|
routeAnalyzer, refEmitter, this.adapter.factoryTracker, defaultImportTracker,
|
||||||
this.closureCompilerEnabled, injectableRegistry, this.options.i18nInLocale),
|
this.closureCompilerEnabled, injectableRegistry, this.options.i18nInLocale),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -731,7 +729,7 @@ export class NgCompiler {
|
||||||
|
|
||||||
const templateTypeChecker = new TemplateTypeChecker(
|
const templateTypeChecker = new TemplateTypeChecker(
|
||||||
this.tsProgram, this.typeCheckingProgramStrategy, traitCompiler,
|
this.tsProgram, this.typeCheckingProgramStrategy, traitCompiler,
|
||||||
this.getTypeCheckingConfig(), refEmitter, reflector, this.host, this.incrementalDriver);
|
this.getTypeCheckingConfig(), refEmitter, reflector, this.adapter, this.incrementalDriver);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isCore,
|
isCore,
|
||||||
|
|
|
@ -11,12 +11,12 @@ import * as ts from 'typescript';
|
||||||
import {ErrorCode, ngErrorCode} from '../../diagnostics';
|
import {ErrorCode, ngErrorCode} from '../../diagnostics';
|
||||||
import {findFlatIndexEntryPoint, FlatIndexGenerator} from '../../entry_point';
|
import {findFlatIndexEntryPoint, FlatIndexGenerator} from '../../entry_point';
|
||||||
import {AbsoluteFsPath, resolve} from '../../file_system';
|
import {AbsoluteFsPath, resolve} from '../../file_system';
|
||||||
import {FactoryGenerator, FactoryTracker, isShim, ShimAdapter, ShimReferenceTagger, SummaryGenerator} from '../../shims';
|
import {FactoryGenerator, isShim, ShimAdapter, ShimReferenceTagger, SummaryGenerator} from '../../shims';
|
||||||
import {PerFileShimGenerator, TopLevelShimGenerator} from '../../shims/api';
|
import {FactoryTracker, PerFileShimGenerator, TopLevelShimGenerator} from '../../shims/api';
|
||||||
import {TypeCheckShimGenerator} from '../../typecheck';
|
import {TypeCheckShimGenerator} from '../../typecheck';
|
||||||
import {normalizeSeparators} from '../../util/src/path';
|
import {normalizeSeparators} from '../../util/src/path';
|
||||||
import {getRootDirs, isDtsPath, isNonDeclarationTsPath} from '../../util/src/typescript';
|
import {getRootDirs, isDtsPath, isNonDeclarationTsPath} from '../../util/src/typescript';
|
||||||
import {ExtendedTsCompilerHost, NgCompilerOptions, UnifiedModulesHost} from '../api';
|
import {ExtendedTsCompilerHost, NgCompilerAdapter, NgCompilerOptions, UnifiedModulesHost} from '../api';
|
||||||
|
|
||||||
// A persistent source of bugs in CompilerHost delegation has been the addition by TS of new,
|
// A persistent source of bugs in CompilerHost delegation has been the addition by TS of new,
|
||||||
// optional methods on ts.CompilerHost. Since these methods are optional, it's not a type error that
|
// optional methods on ts.CompilerHost. Since these methods are optional, it's not a type error that
|
||||||
|
@ -89,10 +89,10 @@ export class DelegatingCompilerHost implements
|
||||||
* `ExtendedTsCompilerHost` methods whenever present.
|
* `ExtendedTsCompilerHost` methods whenever present.
|
||||||
*/
|
*/
|
||||||
export class NgCompilerHost extends DelegatingCompilerHost implements
|
export class NgCompilerHost extends DelegatingCompilerHost implements
|
||||||
RequiredCompilerHostDelegations, ExtendedTsCompilerHost {
|
RequiredCompilerHostDelegations, ExtendedTsCompilerHost, NgCompilerAdapter {
|
||||||
readonly factoryTracker: FactoryTracker|null = null;
|
readonly factoryTracker: FactoryTracker|null = null;
|
||||||
readonly entryPoint: AbsoluteFsPath|null = null;
|
readonly entryPoint: AbsoluteFsPath|null = null;
|
||||||
readonly diagnostics: ts.Diagnostic[];
|
readonly constructionDiagnostics: ts.Diagnostic[];
|
||||||
|
|
||||||
readonly inputFiles: ReadonlyArray<string>;
|
readonly inputFiles: ReadonlyArray<string>;
|
||||||
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
|
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
|
||||||
|
@ -107,7 +107,7 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
|
||||||
|
|
||||||
this.factoryTracker = factoryTracker;
|
this.factoryTracker = factoryTracker;
|
||||||
this.entryPoint = entryPoint;
|
this.entryPoint = entryPoint;
|
||||||
this.diagnostics = diagnostics;
|
this.constructionDiagnostics = diagnostics;
|
||||||
this.inputFiles = [...inputFiles, ...shimAdapter.extraInputFiles];
|
this.inputFiles = [...inputFiles, ...shimAdapter.extraInputFiles];
|
||||||
this.rootDirs = rootDirs;
|
this.rootDirs = rootDirs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ ts_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//packages/compiler-cli/src/ngtsc/diagnostics",
|
"//packages/compiler-cli/src/ngtsc/diagnostics",
|
||||||
"//packages/compiler-cli/src/ngtsc/file_system",
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
||||||
"//packages/compiler-cli/src/ngtsc/shims",
|
"//packages/compiler-cli/src/ngtsc/shims:api",
|
||||||
"//packages/compiler-cli/src/ngtsc/util",
|
"//packages/compiler-cli/src/ngtsc/util",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
"@npm//typescript",
|
"@npm//typescript",
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {AbsoluteFsPath, dirname, join} from '../../file_system';
|
import {AbsoluteFsPath, dirname, join} from '../../file_system';
|
||||||
import {TopLevelShimGenerator} from '../../shims';
|
import {TopLevelShimGenerator} from '../../shims/api';
|
||||||
import {relativePathBetween} from '../../util/src/path';
|
import {relativePathBetween} from '../../util/src/path';
|
||||||
|
|
||||||
export class FlatIndexGenerator implements TopLevelShimGenerator {
|
export class FlatIndexGenerator implements TopLevelShimGenerator {
|
||||||
|
|
|
@ -59,7 +59,9 @@ export class LogicalFileSystem {
|
||||||
*/
|
*/
|
||||||
private cache: Map<AbsoluteFsPath, LogicalProjectPath|null> = new Map();
|
private cache: Map<AbsoluteFsPath, LogicalProjectPath|null> = new Map();
|
||||||
|
|
||||||
constructor(rootDirs: AbsoluteFsPath[], private compilerHost: ts.CompilerHost) {
|
constructor(
|
||||||
|
rootDirs: AbsoluteFsPath[],
|
||||||
|
private compilerHost: Pick<ts.CompilerHost, 'getCanonicalFileName'>) {
|
||||||
// Make a copy and sort it by length in reverse order (longest first). This speeds up lookups,
|
// Make a copy and sort it by length in reverse order (longest first). This speeds up lookups,
|
||||||
// since there's no need to keep going through the array once a match is found.
|
// since there's no need to keep going through the array once a match is found.
|
||||||
this.rootDirs = rootDirs.concat([]).sort((a, b) => b.length - a.length);
|
this.rootDirs = rootDirs.concat([]).sort((a, b) => b.length - a.length);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {absoluteFrom} from '../../file_system';
|
import {absoluteFrom} from '../../file_system';
|
||||||
import {getSourceFileOrNull, resolveModuleName} from '../../util/src/typescript';
|
import {getSourceFileOrNull, resolveModuleName} from '../../util/src/typescript';
|
||||||
|
|
||||||
|
@ -18,8 +19,8 @@ import {getSourceFileOrNull, resolveModuleName} from '../../util/src/typescript'
|
||||||
export class ModuleResolver {
|
export class ModuleResolver {
|
||||||
constructor(
|
constructor(
|
||||||
private program: ts.Program, private compilerOptions: ts.CompilerOptions,
|
private program: ts.Program, private compilerOptions: ts.CompilerOptions,
|
||||||
private host: ts.CompilerHost, private moduleResolutionCache: ts.ModuleResolutionCache|null) {
|
private host: ts.ModuleResolutionHost&Pick<ts.CompilerHost, 'resolveModuleNames'>,
|
||||||
}
|
private moduleResolutionCache: ts.ModuleResolutionCache|null) {}
|
||||||
|
|
||||||
resolveModule(moduleName: string, containingFile: string): ts.SourceFile|null {
|
resolveModule(moduleName: string, containingFile: string): ts.SourceFile|null {
|
||||||
const resolved = resolveModuleName(
|
const resolved = resolveModuleName(
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {HostResourceLoader} from './src/loader';
|
export {AdapterResourceLoader} from './src/loader';
|
||||||
|
|
|
@ -9,26 +9,21 @@
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {ResourceLoader} from '../../annotations';
|
import {ResourceLoader} from '../../annotations';
|
||||||
import {ExtendedTsCompilerHost} from '../../core/api';
|
import {NgCompilerAdapter} from '../../core/api';
|
||||||
import {AbsoluteFsPath, join, PathSegment} from '../../file_system';
|
import {AbsoluteFsPath, join, PathSegment} from '../../file_system';
|
||||||
import {getRootDirs} from '../../util/src/typescript';
|
|
||||||
|
|
||||||
const CSS_PREPROCESSOR_EXT = /(\.scss|\.sass|\.less|\.styl)$/;
|
const CSS_PREPROCESSOR_EXT = /(\.scss|\.sass|\.less|\.styl)$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `ResourceLoader` which delegates to a `CompilerHost` resource loading method.
|
* `ResourceLoader` which delegates to an `NgCompilerAdapter`'s resource loading methods.
|
||||||
*/
|
*/
|
||||||
export class HostResourceLoader implements ResourceLoader {
|
export class AdapterResourceLoader implements ResourceLoader {
|
||||||
private cache = new Map<string, string>();
|
private cache = new Map<string, string>();
|
||||||
private fetching = new Map<string, Promise<void>>();
|
private fetching = new Map<string, Promise<void>>();
|
||||||
|
|
||||||
private rootDirs: AbsoluteFsPath[];
|
canPreload = !!this.adapter.readResource;
|
||||||
|
|
||||||
canPreload = !!this.host.readResource;
|
constructor(private adapter: NgCompilerAdapter, private options: ts.CompilerOptions) {}
|
||||||
|
|
||||||
constructor(private host: ExtendedTsCompilerHost, private options: ts.CompilerOptions) {
|
|
||||||
this.rootDirs = getRootDirs(host, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the url of a resource relative to the file that contains the reference to it.
|
* Resolve the url of a resource relative to the file that contains the reference to it.
|
||||||
|
@ -44,8 +39,8 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
*/
|
*/
|
||||||
resolve(url: string, fromFile: string): string {
|
resolve(url: string, fromFile: string): string {
|
||||||
let resolvedUrl: string|null = null;
|
let resolvedUrl: string|null = null;
|
||||||
if (this.host.resourceNameToFileName) {
|
if (this.adapter.resourceNameToFileName) {
|
||||||
resolvedUrl = this.host.resourceNameToFileName(url, fromFile);
|
resolvedUrl = this.adapter.resourceNameToFileName(url, fromFile);
|
||||||
} else {
|
} else {
|
||||||
resolvedUrl = this.fallbackResolve(url, fromFile);
|
resolvedUrl = this.fallbackResolve(url, fromFile);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +62,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
* @throws An Error if pre-loading is not available.
|
* @throws An Error if pre-loading is not available.
|
||||||
*/
|
*/
|
||||||
preload(resolvedUrl: string): Promise<void>|undefined {
|
preload(resolvedUrl: string): Promise<void>|undefined {
|
||||||
if (!this.host.readResource) {
|
if (!this.adapter.readResource) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'HostResourceLoader: the CompilerHost provided does not support pre-loading resources.');
|
'HostResourceLoader: the CompilerHost provided does not support pre-loading resources.');
|
||||||
}
|
}
|
||||||
|
@ -77,7 +72,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
return this.fetching.get(resolvedUrl);
|
return this.fetching.get(resolvedUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this.host.readResource(resolvedUrl);
|
const result = this.adapter.readResource(resolvedUrl);
|
||||||
if (typeof result === 'string') {
|
if (typeof result === 'string') {
|
||||||
this.cache.set(resolvedUrl, result);
|
this.cache.set(resolvedUrl, result);
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -104,8 +99,8 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
return this.cache.get(resolvedUrl)!;
|
return this.cache.get(resolvedUrl)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this.host.readResource ? this.host.readResource(resolvedUrl) :
|
const result = this.adapter.readResource ? this.adapter.readResource(resolvedUrl) :
|
||||||
this.host.readFile(resolvedUrl);
|
this.adapter.readFile(resolvedUrl);
|
||||||
if (typeof result !== 'string') {
|
if (typeof result !== 'string') {
|
||||||
throw new Error(`HostResourceLoader: loader(${resolvedUrl}) returned a Promise`);
|
throw new Error(`HostResourceLoader: loader(${resolvedUrl}) returned a Promise`);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +129,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const candidate of candidateLocations) {
|
for (const candidate of candidateLocations) {
|
||||||
if (this.host.fileExists(candidate)) {
|
if (this.adapter.fileExists(candidate)) {
|
||||||
return candidate;
|
return candidate;
|
||||||
} else if (CSS_PREPROCESSOR_EXT.test(candidate)) {
|
} else if (CSS_PREPROCESSOR_EXT.test(candidate)) {
|
||||||
/**
|
/**
|
||||||
|
@ -143,7 +138,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
* again.
|
* again.
|
||||||
*/
|
*/
|
||||||
const cssFallbackUrl = candidate.replace(CSS_PREPROCESSOR_EXT, '.css');
|
const cssFallbackUrl = candidate.replace(CSS_PREPROCESSOR_EXT, '.css');
|
||||||
if (this.host.fileExists(cssFallbackUrl)) {
|
if (this.adapter.fileExists(cssFallbackUrl)) {
|
||||||
return cssFallbackUrl;
|
return cssFallbackUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +149,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
private getRootedCandidateLocations(url: string): AbsoluteFsPath[] {
|
private getRootedCandidateLocations(url: string): AbsoluteFsPath[] {
|
||||||
// The path already starts with '/', so add a '.' to make it relative.
|
// The path already starts with '/', so add a '.' to make it relative.
|
||||||
const segment: PathSegment = ('.' + url) as PathSegment;
|
const segment: PathSegment = ('.' + url) as PathSegment;
|
||||||
return this.rootDirs.map(rootDir => join(rootDir, segment));
|
return this.adapter.rootDirs.map(rootDir => join(rootDir, segment));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,7 +167,7 @@ export class HostResourceLoader implements ResourceLoader {
|
||||||
ts.ResolvedModuleWithFailedLookupLocations&{failedLookupLocations: ReadonlyArray<string>};
|
ts.ResolvedModuleWithFailedLookupLocations&{failedLookupLocations: ReadonlyArray<string>};
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const failedLookup = ts.resolveModuleName(url + '.$ngresource$', fromFile, this.options, this.host) as ResolvedModuleWithFailedLookupLocations;
|
const failedLookup = ts.resolveModuleName(url + '.$ngresource$', fromFile, this.options, this.adapter) as ResolvedModuleWithFailedLookupLocations;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
if (failedLookup.failedLookupLocations === undefined) {
|
if (failedLookup.failedLookupLocations === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
|
@ -49,3 +49,22 @@ export interface PerFileShimGenerator {
|
||||||
sf: ts.SourceFile, genFilePath: AbsoluteFsPath,
|
sf: ts.SourceFile, genFilePath: AbsoluteFsPath,
|
||||||
priorShimSf: ts.SourceFile|null): ts.SourceFile;
|
priorShimSf: ts.SourceFile|null): ts.SourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintains a mapping of which symbols in a .ngfactory file have been used.
|
||||||
|
*
|
||||||
|
* .ngfactory files are generated with one symbol per defined class in the source file, regardless
|
||||||
|
* of whether the classes in the source files are NgModules (because that isn't known at the time
|
||||||
|
* the factory files are generated). A `FactoryTracker` supports removing factory symbols which
|
||||||
|
* didn't end up being NgModules, by tracking the ones which are.
|
||||||
|
*/
|
||||||
|
export interface FactoryTracker {
|
||||||
|
readonly sourceInfo: Map<string, FactoryInfo>;
|
||||||
|
|
||||||
|
track(sf: ts.SourceFile, factorySymbolName: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FactoryInfo {
|
||||||
|
sourceFilePath: string;
|
||||||
|
moduleSymbolNames: Set<string>;
|
||||||
|
}
|
|
@ -8,9 +8,8 @@
|
||||||
|
|
||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
|
|
||||||
export {PerFileShimGenerator, TopLevelShimGenerator} from './api';
|
|
||||||
export {ShimAdapter} from './src/adapter';
|
export {ShimAdapter} from './src/adapter';
|
||||||
export {copyFileShimData, isShim} from './src/expando';
|
export {copyFileShimData, isShim} from './src/expando';
|
||||||
export {FactoryGenerator, FactoryInfo, FactoryTracker, generatedFactoryTransform} from './src/factory_generator';
|
export {FactoryGenerator, generatedFactoryTransform} from './src/factory_generator';
|
||||||
export {ShimReferenceTagger} from './src/reference_tagger';
|
export {ShimReferenceTagger} from './src/reference_tagger';
|
||||||
export {SummaryGenerator} from './src/summary_generator';
|
export {SummaryGenerator} from './src/summary_generator';
|
||||||
|
|
|
@ -9,27 +9,13 @@ import * as ts from 'typescript';
|
||||||
|
|
||||||
import {absoluteFromSourceFile, AbsoluteFsPath, basename} from '../../file_system';
|
import {absoluteFromSourceFile, AbsoluteFsPath, basename} from '../../file_system';
|
||||||
import {ImportRewriter} from '../../imports';
|
import {ImportRewriter} from '../../imports';
|
||||||
import {PerFileShimGenerator} from '../api';
|
import {FactoryInfo, FactoryTracker, PerFileShimGenerator} from '../api';
|
||||||
|
|
||||||
import {generatedModuleName} from './util';
|
import {generatedModuleName} from './util';
|
||||||
|
|
||||||
const TS_DTS_SUFFIX = /(\.d)?\.ts$/;
|
const TS_DTS_SUFFIX = /(\.d)?\.ts$/;
|
||||||
const STRIP_NG_FACTORY = /(.*)NgFactory$/;
|
const STRIP_NG_FACTORY = /(.*)NgFactory$/;
|
||||||
|
|
||||||
/**
|
|
||||||
* Maintains a mapping of which symbols in a .ngfactory file have been used.
|
|
||||||
*
|
|
||||||
* .ngfactory files are generated with one symbol per defined class in the source file, regardless
|
|
||||||
* of whether the classes in the source files are NgModules (because that isn't known at the time
|
|
||||||
* the factory files are generated). A `FactoryTracker` supports removing factory symbols which
|
|
||||||
* didn't end up being NgModules, by tracking the ones which are.
|
|
||||||
*/
|
|
||||||
export interface FactoryTracker {
|
|
||||||
readonly sourceInfo: Map<string, FactoryInfo>;
|
|
||||||
|
|
||||||
track(sf: ts.SourceFile, factorySymbolName: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ts.SourceFiles which contain variable declarations for NgFactories for every exported
|
* Generates ts.SourceFiles which contain variable declarations for NgFactories for every exported
|
||||||
* class of an input ts.SourceFile.
|
* class of an input ts.SourceFile.
|
||||||
|
@ -118,11 +104,6 @@ function isExported(decl: ts.Declaration): boolean {
|
||||||
decl.modifiers.some(mod => mod.kind == ts.SyntaxKind.ExportKeyword);
|
decl.modifiers.some(mod => mod.kind == ts.SyntaxKind.ExportKeyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FactoryInfo {
|
|
||||||
sourceFilePath: string;
|
|
||||||
moduleSymbolNames: Set<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generatedFactoryTransform(
|
export function generatedFactoryTransform(
|
||||||
factoryMap: Map<string, FactoryInfo>,
|
factoryMap: Map<string, FactoryInfo>,
|
||||||
importRewriter: ImportRewriter): ts.TransformerFactory<ts.SourceFile> {
|
importRewriter: ImportRewriter): ts.TransformerFactory<ts.SourceFile> {
|
||||||
|
|
|
@ -39,7 +39,7 @@ export class TemplateTypeChecker {
|
||||||
private typeCheckingStrategy: TypeCheckingProgramStrategy,
|
private typeCheckingStrategy: TypeCheckingProgramStrategy,
|
||||||
private typeCheckAdapter: ProgramTypeCheckAdapter, private config: TypeCheckingConfig,
|
private typeCheckAdapter: ProgramTypeCheckAdapter, private config: TypeCheckingConfig,
|
||||||
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost,
|
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost,
|
||||||
private compilerHost: ts.CompilerHost,
|
private compilerHost: Pick<ts.CompilerHost, 'getCanonicalFileName'>,
|
||||||
private priorBuild: IncrementalBuild<unknown, FileTypeCheckingData>) {}
|
private priorBuild: IncrementalBuild<unknown, FileTypeCheckingData>) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -113,7 +113,8 @@ export class TypeCheckContext {
|
||||||
private fileMap = new Map<AbsoluteFsPath, PendingFileTypeCheckingData>();
|
private fileMap = new Map<AbsoluteFsPath, PendingFileTypeCheckingData>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private config: TypeCheckingConfig, private compilerHost: ts.CompilerHost,
|
private config: TypeCheckingConfig,
|
||||||
|
private compilerHost: Pick<ts.CompilerHost, 'getCanonicalFileName'>,
|
||||||
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost) {}
|
private refEmitter: ReferenceEmitter, private reflector: ReflectionHost) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,7 @@ export class TypeCheckFile extends Environment {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly fileName: AbsoluteFsPath, config: TypeCheckingConfig, refEmitter: ReferenceEmitter,
|
readonly fileName: AbsoluteFsPath, config: TypeCheckingConfig, refEmitter: ReferenceEmitter,
|
||||||
reflector: ReflectionHost, compilerHost: ts.CompilerHost) {
|
reflector: ReflectionHost, compilerHost: Pick<ts.CompilerHost, 'getCanonicalFileName'>) {
|
||||||
super(
|
super(
|
||||||
config, new ImportManager(new NoopImportRewriter(), 'i'), refEmitter, reflector,
|
config, new ImportManager(new NoopImportRewriter(), 'i'), refEmitter, reflector,
|
||||||
ts.createSourceFile(
|
ts.createSourceFile(
|
||||||
|
|
|
@ -122,7 +122,7 @@ export function nodeDebugInfo(node: ts.Node): string {
|
||||||
*/
|
*/
|
||||||
export function resolveModuleName(
|
export function resolveModuleName(
|
||||||
moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions,
|
moduleName: string, containingFile: string, compilerOptions: ts.CompilerOptions,
|
||||||
compilerHost: ts.CompilerHost,
|
compilerHost: ts.ModuleResolutionHost&Pick<ts.CompilerHost, 'resolveModuleNames'>,
|
||||||
moduleResolutionCache: ts.ModuleResolutionCache|null): ts.ResolvedModule|undefined {
|
moduleResolutionCache: ts.ModuleResolutionCache|null): ts.ResolvedModule|undefined {
|
||||||
if (compilerHost.resolveModuleNames) {
|
if (compilerHost.resolveModuleNames) {
|
||||||
// FIXME: Additional parameters are required in TS3.6, but ignored in 3.5.
|
// FIXME: Additional parameters are required in TS3.6, but ignored in 3.5.
|
||||||
|
|
Loading…
Reference in New Issue