From 405e4dda9215a207bc74986c66070fd5f3ba8f48 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 1 May 2024 14:13:15 +0200 Subject: [PATCH] refactor(compiler-cli): add compiler flag for testing let declarations (#56199) Adds a private `_enableLetSyntax` flag that allows for let declarations to be enabled in tests. PR Close #56199 --- packages/bazel/src/ngc-wrapped/index.ts | 1 + .../annotations/component/src/handler.ts | 4 ++++ .../annotations/component/src/resources.ts | 22 +++++++++---------- .../component/test/component_spec.ts | 1 + .../src/ngtsc/core/api/src/options.ts | 8 +++++++ .../src/ngtsc/core/src/compiler.ts | 3 +++ .../compiler/src/render3/view/template.ts | 4 ++++ .../src/template/pipeline/src/ingest.ts | 2 ++ 8 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/bazel/src/ngc-wrapped/index.ts b/packages/bazel/src/ngc-wrapped/index.ts index e635da896d7..424d1e645fe 100644 --- a/packages/bazel/src/ngc-wrapped/index.ts +++ b/packages/bazel/src/ngc-wrapped/index.ts @@ -91,6 +91,7 @@ export async function runOneBuild( 'forbidOrphanComponents', 'onlyExplicitDeferDependencyImports', 'generateExtraImportsInLocalMode', + '_enableLetSyntax', ]); const userOverrides = Object.entries(userOptions) diff --git a/packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts b/packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts index ae47eb79189..b0391aaf13c 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts @@ -246,6 +246,7 @@ export class ComponentDecoratorHandler private readonly deferredSymbolTracker: DeferredSymbolTracker, private readonly forbidOrphanRendering: boolean, private readonly enableBlockSyntax: boolean, + private readonly enableLetSyntax: boolean, private readonly localCompilationExtraImportsTracker: LocalCompilationExtraImportsTracker | null, ) { this.extractTemplateOptions = { @@ -253,6 +254,7 @@ export class ComponentDecoratorHandler i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs, usePoisonedData: this.usePoisonedData, enableBlockSyntax: this.enableBlockSyntax, + enableLetSyntax: this.enableLetSyntax, }; } @@ -272,6 +274,7 @@ export class ComponentDecoratorHandler i18nNormalizeLineEndingsInICUs: boolean; usePoisonedData: boolean; enableBlockSyntax: boolean; + enableLetSyntax: boolean; }; readonly precedence = HandlerPrecedence.PRIMARY; @@ -621,6 +624,7 @@ export class ComponentDecoratorHandler i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs, usePoisonedData: this.usePoisonedData, enableBlockSyntax: this.enableBlockSyntax, + enableLetSyntax: this.enableLetSyntax, }, this.compilationMode, ); diff --git a/packages/compiler-cli/src/ngtsc/annotations/component/src/resources.ts b/packages/compiler-cli/src/ngtsc/annotations/component/src/resources.ts index 65b670d4ac4..e17bce45512 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/component/src/resources.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/component/src/resources.ts @@ -13,6 +13,7 @@ import { ParsedTemplate, ParseSourceFile, parseTemplate, + ParseTemplateOptions, TmplAstNode, } from '@angular/compiler'; import ts from 'typescript'; @@ -131,6 +132,7 @@ export interface ExtractTemplateOptions { enableI18nLegacyMessageIdFormat: boolean; i18nNormalizeLineEndingsInICUs: boolean; enableBlockSyntax: boolean; + enableLetSyntax: boolean; } export function extractTemplate( @@ -259,16 +261,20 @@ function parseExtractedTemplate( ): ParsedComponentTemplate { // We always normalize line endings if the template has been escaped (i.e. is inline). const i18nNormalizeLineEndingsInICUs = escapedString || options.i18nNormalizeLineEndingsInICUs; - - const parsedTemplate = parseTemplate(sourceStr, sourceMapUrl ?? '', { - preserveWhitespaces: template.preserveWhitespaces, + const commonParseOptions: ParseTemplateOptions = { interpolationConfig: template.interpolationConfig, range: sourceParseRange ?? undefined, - escapedString, enableI18nLegacyMessageIdFormat: options.enableI18nLegacyMessageIdFormat, i18nNormalizeLineEndingsInICUs, alwaysAttemptHtmlToR3AstConversion: options.usePoisonedData, + escapedString, enableBlockSyntax: options.enableBlockSyntax, + enableLetSyntax: options.enableLetSyntax, + }; + + const parsedTemplate = parseTemplate(sourceStr, sourceMapUrl ?? '', { + ...commonParseOptions, + preserveWhitespaces: template.preserveWhitespaces, }); // Unfortunately, the primary parse of the template above may not contain accurate source map @@ -287,16 +293,10 @@ function parseExtractedTemplate( // with the above options set to preserve source mappings. const {nodes: diagNodes} = parseTemplate(sourceStr, sourceMapUrl ?? '', { + ...commonParseOptions, preserveWhitespaces: true, preserveLineEndings: true, - interpolationConfig: template.interpolationConfig, - range: sourceParseRange ?? undefined, - escapedString, - enableI18nLegacyMessageIdFormat: options.enableI18nLegacyMessageIdFormat, - i18nNormalizeLineEndingsInICUs, leadingTriviaChars: [], - alwaysAttemptHtmlToR3AstConversion: options.usePoisonedData, - enableBlockSyntax: options.enableBlockSyntax, }); return { diff --git a/packages/compiler-cli/src/ngtsc/annotations/component/test/component_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/component/test/component_spec.ts index ddeee72a4aa..1e677de6c32 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/component/test/component_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/component/test/component_spec.ts @@ -142,6 +142,7 @@ function setup( new DeferredSymbolTracker(checker, /* onlyExplicitDeferDependencyImports */ false), /* forbidOrphanRenderering */ false, /* enableBlockSyntax */ true, + /* enableLetSyntax */ false, /* localCompilationExtraImportsTracker */ null, ); return {reflectionHost, handler, resourceLoader, metaRegistry}; diff --git a/packages/compiler-cli/src/ngtsc/core/api/src/options.ts b/packages/compiler-cli/src/ngtsc/core/api/src/options.ts index c858135153c..b0878179a58 100644 --- a/packages/compiler-cli/src/ngtsc/core/api/src/options.ts +++ b/packages/compiler-cli/src/ngtsc/core/api/src/options.ts @@ -82,6 +82,14 @@ export interface InternalOptions { */ _enableBlockSyntax?: boolean; + /** + * Whether `@let` syntax is enabled in the compiler. + * Defaults to false while the feature is being developed. + * + * @internal + */ + _enableLetSyntax?: boolean; + /** * Detected version of `@angular/core` in the workspace. Used by the * compiler to adjust the output depending on the available symbols. diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index dbe44053041..01993087081 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -384,6 +384,7 @@ export class NgCompiler { readonly ignoreForEmit: Set; readonly enableTemplateTypeChecker: boolean; private readonly enableBlockSyntax: boolean; + private readonly enableLetSyntax: boolean; private readonly angularCoreVersion: string | null; /** @@ -454,6 +455,7 @@ export class NgCompiler { enableTemplateTypeChecker || (options['_enableTemplateTypeChecker'] ?? false); // TODO(crisbeto): remove this flag and base `enableBlockSyntax` on the `angularCoreVersion`. this.enableBlockSyntax = options['_enableBlockSyntax'] ?? true; + this.enableLetSyntax = options['_enableLetSyntax'] ?? false; this.angularCoreVersion = options['_angularCoreVersion'] ?? null; this.constructionDiagnostics.push( ...this.adapter.constructionDiagnostics, @@ -1397,6 +1399,7 @@ export class NgCompiler { deferredSymbolsTracker, !!this.options.forbidOrphanComponents, this.enableBlockSyntax, + this.enableLetSyntax, localCompilationExtraImportsTracker, ), diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index c83f97622f2..aab2e2bfbaf 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -124,6 +124,9 @@ export interface ParseTemplateOptions { /** Whether the @ block syntax is enabled. */ enableBlockSyntax?: boolean; + /** Whether the `@let` syntax is enabled. */ + enableLetSyntax?: boolean; + // TODO(crisbeto): delete this option when the migration is deleted. /** * Whether the parser should allow invalid two-way bindings. @@ -158,6 +161,7 @@ export function parseTemplate( ...options, tokenizeExpansionForms: true, tokenizeBlocks: options.enableBlockSyntax ?? true, + tokenizeLet: options.enableLetSyntax ?? false, }); if ( diff --git a/packages/compiler/src/template/pipeline/src/ingest.ts b/packages/compiler/src/template/pipeline/src/ingest.ts index e5a3b54b101..8d15ecc4f95 100644 --- a/packages/compiler/src/template/pipeline/src/ingest.ts +++ b/packages/compiler/src/template/pipeline/src/ingest.ts @@ -225,6 +225,8 @@ function ingestNodes(unit: ViewCompilationUnit, template: t.Node[]): void { ingestIcu(unit, node); } else if (node instanceof t.ForLoopBlock) { ingestForBlock(unit, node); + } else if (node instanceof t.LetDeclaration) { + // TODO(crisbeto): needs further integration } else { throw new Error(`Unsupported template node: ${node.constructor.name}`); }