Skip to content

Commit

Permalink
refactor(compiler): enable resolve phase for local compilation
Browse files Browse the repository at this point in the history
This commit update the logic to enable `resolve` phase for local compilation. The `resolve` phase will be useful for local compilation in certain cases (will be used in followup PRs).
  • Loading branch information
AndrewKushnir committed Jan 12, 2024
1 parent a2087a1 commit 8224163
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,10 @@ export class ComponentDecoratorHandler implements
resolve(
node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>,
symbol: ComponentSymbol): ResolveResult<ComponentResolutionData> {
if (this.compilationMode === CompilationMode.LOCAL) {
return {};
}

if (this.semanticDepGraphUpdater !== null && analysis.baseClass instanceof Reference) {
symbol.baseClass = this.semanticDepGraphUpdater.getSymbol(analysis.baseClass.node);
}
Expand Down Expand Up @@ -1100,7 +1104,7 @@ export class ComponentDecoratorHandler implements

compileLocal(
node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>,
pool: ConstantPool): CompileResult[] {
resolution: Readonly<Partial<ComponentResolutionData>>, pool: ConstantPool): CompileResult[] {
if (analysis.template.errors !== null && analysis.template.errors.length > 0) {
return [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export class DirectiveDecoratorHandler implements

compileLocal(
node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>,
pool: ConstantPool): CompileResult[] {
resolution: Readonly<unknown>, pool: ConstantPool): CompileResult[] {
const fac = compileNgFactoryDefField(toFactoryMetadata(analysis.meta, FactoryTarget.Directive));
const def = compileDirectiveFromMetadata(analysis.meta, pool, makeBindingParser());
const inputTransformFields = compileInputTransformFields(analysis.inputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,10 @@ export class NgModuleDecoratorHandler implements

resolve(node: ClassDeclaration, analysis: Readonly<NgModuleAnalysis>):
ResolveResult<NgModuleResolution> {
if (this.compilationMode === CompilationMode.LOCAL) {
return {};
}

const scope = this.scopeRegistry.getScopeOfModule(node);
const diagnostics: ts.Diagnostic[] = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ export class InjectableDecoratorHandler implements
});
}

resolve(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>, symbol: null):
resolve(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>):
ResolveResult<unknown> {
if (this.compilationMode === CompilationMode.LOCAL) {
return {};
}

if (requiresValidCtor(analysis.meta)) {
const diagnostic = checkInheritanceOfInjectable(
node, this.injectableRegistry, this.reflector, this.evaluator, this.strictCtorDeps,
Expand Down
4 changes: 4 additions & 0 deletions packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ export class PipeDecoratorHandler implements
}

resolve(node: ClassDeclaration): ResolveResult<unknown> {
if (this.compilationMode === CompilationMode.LOCAL) {
return {};
}

const duplicateDeclData = this.scopeRegistry.getDuplicateDeclarations(node);
if (duplicateDeclData !== null) {
// This pipe was declared twice (or more).
Expand Down
5 changes: 3 additions & 2 deletions packages/compiler-cli/src/ngtsc/transform/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ export interface DecoratorHandler<D, A, S extends SemanticSymbol|null, R> {
* Generates code based on each individual source file without using its
* dependencies (suitable for local dev edit/refresh workflow)
*/
compileLocal(node: ClassDeclaration, analysis: Readonly<A>, constantPool: ConstantPool):
CompileResult|CompileResult[];
compileLocal(
node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<Partial<R>>,
constantPool: ConstantPool): CompileResult|CompileResult[];
}

/**
Expand Down
34 changes: 14 additions & 20 deletions packages/compiler-cli/src/ngtsc/transform/src/compilation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,6 @@ export class TraitCompiler implements ProgramTypeCheckAdapter {
}

resolve(): void {
// No resolving needed for local compilation (only analysis and compile will be done in this
// mode)
if (this.compilationMode === CompilationMode.LOCAL) {
return;
}

const classes = this.classes.keys();
for (const clazz of classes) {
const record = this.classes.get(clazz)!;
Expand Down Expand Up @@ -465,6 +459,10 @@ export class TraitCompiler implements ProgramTypeCheckAdapter {

trait = trait.toResolved(result.data ?? null, result.diagnostics ?? null);

if (this.compilationMode === CompilationMode.LOCAL) {
continue;
}

if (result.reexports !== undefined) {
const fileName = clazz.getSourceFile().fileName;
if (!this.reexportMap.has(fileName)) {
Expand All @@ -484,7 +482,7 @@ export class TraitCompiler implements ProgramTypeCheckAdapter {
* `ts.SourceFile`.
*/
typeCheck(sf: ts.SourceFile, ctx: TypeCheckContext): void {
if (!this.fileToClasses.has(sf)) {
if (!this.fileToClasses.has(sf) || this.compilationMode === CompilationMode.LOCAL) {
return;
}

Expand Down Expand Up @@ -596,24 +594,20 @@ export class TraitCompiler implements ProgramTypeCheckAdapter {

for (const trait of record.traits) {
let compileRes: CompileResult|CompileResult[];

if (trait.state !== TraitState.Resolved || containsErrors(trait.analysisDiagnostics) ||
containsErrors(trait.resolveDiagnostics)) {
// Cannot compile a trait that is not resolved, or had any errors in its declaration.
continue;
}

if (this.compilationMode === CompilationMode.LOCAL) {
if (trait.state !== TraitState.Analyzed || trait.analysis === null ||
containsErrors(trait.analysisDiagnostics)) {
// Cannot compile a trait in local mode that is not analyzed, or had any errors in its
// declaration.
continue;
}
// `trait.analysis` is non-null asserted here because TypeScript does not recognize that
// `Readonly<unknown>` is nullable (as `unknown` itself is nullable) due to the way that
// `Readonly` works.
compileRes = trait.handler.compileLocal(clazz, trait.analysis!, constantPool);
compileRes =
trait.handler.compileLocal(clazz, trait.analysis!, trait.resolution!, constantPool);
} else {
if (trait.state !== TraitState.Resolved || containsErrors(trait.analysisDiagnostics) ||
containsErrors(trait.resolveDiagnostics)) {
// Cannot compile a trait in global mode that is not resolved, or had any errors in its
// declaration.
continue;
}
// `trait.resolution` is non-null asserted below because TypeScript does not recognize that
// `Readonly<unknown>` is nullable (as `unknown` itself is nullable) due to the way that
// `Readonly` works.
Expand Down
14 changes: 0 additions & 14 deletions packages/compiler-cli/src/ngtsc/transform/test/compilation_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,20 +340,6 @@ runInEachFileSystem(() => {
}
}

it('should not run resolve phase', () => {
const contents = `
export class Test {}
`;
const handler = new TestDecoratorHandler();
spyOn(handler, 'resolve');
const {compiler, sourceFile} = setup(contents, [handler], CompilationMode.LOCAL);

compiler.analyzeSync(sourceFile);
compiler.resolve();

expect(handler.resolve).not.toHaveBeenCalled();
});

it('should not register', () => {
const contents = `
export class Test {}
Expand Down

0 comments on commit 8224163

Please sign in to comment.