Skip to content

Commit

Permalink
refactor(compiler): add flag to disable block syntax in language serv…
Browse files Browse the repository at this point in the history
…ice (#52683)

Adds the private `_enableBlockSyntax` flag that can be used by the language service to disable blocks on apps that aren't on Angular v17.

PR Close #52683
  • Loading branch information
crisbeto authored and atscott committed Nov 8, 2023
1 parent a46c8cb commit 227de98
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ export class ComponentDecoratorHandler implements
private hostDirectivesResolver: HostDirectivesResolver, private includeClassMetadata: boolean,
private readonly compilationMode: CompilationMode,
private readonly deferredSymbolTracker: DeferredSymbolTracker,
private readonly forbidOrphanRendering: boolean) {
private readonly forbidOrphanRendering: boolean,
private readonly enableBlockSyntax: boolean) {
this.extractTemplateOptions = {
enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs,
usePoisonedData: this.usePoisonedData,
enableBlockSyntax: this.enableBlockSyntax,
};
}

Expand All @@ -106,6 +108,7 @@ export class ComponentDecoratorHandler implements
enableI18nLegacyMessageIdFormat: boolean,
i18nNormalizeLineEndingsInICUs: boolean,
usePoisonedData: boolean,
enableBlockSyntax: boolean,
};

readonly precedence = HandlerPrecedence.PRIMARY;
Expand Down Expand Up @@ -360,6 +363,7 @@ export class ComponentDecoratorHandler implements
enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs,
usePoisonedData: this.usePoisonedData,
enableBlockSyntax: this.enableBlockSyntax,
},
this.compilationMode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export interface ExtractTemplateOptions {
usePoisonedData: boolean;
enableI18nLegacyMessageIdFormat: boolean;
i18nNormalizeLineEndingsInICUs: boolean;
enableBlockSyntax: boolean;
}

export function extractTemplate(
Expand Down Expand Up @@ -237,6 +238,7 @@ function parseExtractedTemplate(
enableI18nLegacyMessageIdFormat: options.enableI18nLegacyMessageIdFormat,
i18nNormalizeLineEndingsInICUs,
alwaysAttemptHtmlToR3AstConversion: options.usePoisonedData,
enableBlockSyntax: options.enableBlockSyntax,
});

// Unfortunately, the primary parse of the template above may not contain accurate source map
Expand Down Expand Up @@ -264,6 +266,7 @@ function parseExtractedTemplate(
i18nNormalizeLineEndingsInICUs,
leadingTriviaChars: [],
alwaysAttemptHtmlToR3AstConversion: options.usePoisonedData,
enableBlockSyntax: options.enableBlockSyntax,
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ function setup(
compilationMode,
new DeferredSymbolTracker(checker),
/* forbidOrphanRenderering */ false,
/* enableBlockSyntax */ true,
);
return {reflectionHost, handler, resourceLoader, metaRegistry};
}
Expand Down
8 changes: 8 additions & 0 deletions packages/compiler-cli/src/ngtsc/core/api/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ export interface InternalOptions {
* @internal
*/
supportJitMode?: boolean;

/**
* Whether block syntax is enabled in the compiler. Defaults to true.
* Used in the language service to disable the new syntax for projects that aren't on v17.
*
* @internal
*/
_enableBlockSyntax?: boolean;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion packages/compiler-cli/src/ngtsc/core/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ export class NgCompiler {
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
readonly ignoreForEmit: Set<ts.SourceFile>;
readonly enableTemplateTypeChecker: boolean;
private readonly enableBlockSyntax: boolean;

/**
* `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
Expand Down Expand Up @@ -322,6 +323,7 @@ export class NgCompiler {
) {
this.enableTemplateTypeChecker =
enableTemplateTypeChecker || (options['_enableTemplateTypeChecker'] ?? false);
this.enableBlockSyntax = options['_enableBlockSyntax'] ?? true;
this.constructionDiagnostics.push(
...this.adapter.constructionDiagnostics, ...verifyCompatibleTypeCheckOptions(this.options));

Expand Down Expand Up @@ -1106,7 +1108,7 @@ export class NgCompiler {
this.incrementalCompilation.depGraph, injectableRegistry, semanticDepGraphUpdater,
this.closureCompilerEnabled, this.delegatingPerfRecorder, hostDirectivesResolver,
supportTestBed, compilationMode, deferredSymbolsTracker,
!!this.options.forbidOrphanComponents),
!!this.options.forbidOrphanComponents, this.enableBlockSyntax),

// TODO(alxhub): understand why the cast here is necessary (something to do with `null`
// not being assignable to `unknown` when wrapped in `Readonly`).
Expand Down
19 changes: 19 additions & 0 deletions packages/compiler-cli/test/ngtsc/ngtsc_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8495,6 +8495,25 @@ function allTests(os: string) {
expect(codes).toEqual([ngErrorCode(ErrorCode.NGMODULE_BOOTSTRAP_IS_STANDALONE)]);
});

it('should be able to turn off control flow using a compiler flag', () => {
env.tsconfig({_enableBlockSyntax: false});
env.write('/test.ts', `
import { Component } from '@angular/core';
@Component({
standalone: true,
template: 'My email is foo@bar.com',
})
export class TestCmp {}
`);

env.driveMain();

// If blocks are enabled, this test will fail since `@bar.com` is an incomplete block.
const jsContents = env.getContents('test.js');
expect(jsContents).toContain('text(0, "My email is foo@bar.com")');
});

describe('InjectorDef emit optimizations for standalone', () => {
it('should not filter components out of NgModule.imports', () => {
env.write('test.ts', `
Expand Down

0 comments on commit 227de98

Please sign in to comment.