-
Notifications
You must be signed in to change notification settings - Fork 27.1k
Description
Which @angular/* package(s) are the source of the bug?
compiler
Is this a regression?
Yes
Description
Prior to the introduction of the new control flow, the compiler was successfully handling the custom interpolation marker set to the @ sign in the component interpolation config such as:
@component({
selector: 'x',
template: 'Heya, @p@'
interpolation: ['@', '@']
})
export class X {
p = 'wassup!'
}
now after the introduction of the new control flow, the example above throws
1. [ERROR] NG5002: Incomplete block "p". If you meant to write the @ character, you should use the @ HTML entity instead. [plugin angular-compiler]
IMHO
1 - This seems to be a regression
2- The error failure should not be about the incomplete block which is being thrown right here:
private _consumeIncompleteBlock(token: IncompleteBlockOpenToken) {
const parameters: html.BlockParameter[] = [];
while (this._peek.type === TokenType.BLOCK_PARAMETER) {
const paramToken = this._advance<BlockParameterToken>();
parameters.push(new html.BlockParameter(paramToken.parts[0], paramToken.sourceSpan));
}
const end = this._peek.sourceSpan.fullStart;
const span = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
const startSpan = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
const block = new html.Block(token.parts[0], parameters, [], span, token.sourceSpan, startSpan);
this._pushContainer(block, false);
// Incomplete blocks don't have children so we close them immediately and report an error.
this._popContainer(null, html.Block, null);
this.errors.push(
TreeError.create(
token.parts[0],
span,
`Incomplete block "${token.parts[0]}". If you meant to write the @ character, ` +
`you should use the "@" HTML entity instead.`,
),
);
}
But rather about unusable interpolation symbol..
As the new control flow is reserving @ for its usage, I would suggest adding it to the UNUSABLE_INTERPOLATION_REGEXPS in the compiler assertion file as follows:
const UNUSABLE_INTERPOLATION_REGEXPS = [
/@/, //reserved control flow syntax <------------------------ Addition
/^\s*$/, // empty
/[<>]/, // html tag
/^[{}]$/, // i18n expansion
/&(#|[a-z])/i, // character reference,
/^\/\//, // comment
];
function assertInterpolationSymbols(identifier, value) {
if (value != null && !(Array.isArray(value) && value.length == 2)) {
throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
}
else if (value != null) {
const start = value[0];
const end = value[1];
// Check for unusable interpolation symbols
UNUSABLE_INTERPOLATION_REGEXPS.forEach((regexp) => {
if (regexp.test(start) || regexp.test(end)) {
throw new Error(`['${start}', '${end}'] contains unusable interpolation symbol.`);
}
});
}
}
With that we fail properly as follows:
If there is a plan to allow this interpolation case with the new control flow, that might require a more subtle refactor.
I have a PR ready to add the new control flow marker to the unusable/banned interpolation const in the complier/assertions so we provide proper feedback
As of now, if this regression is valid, any existing app that uses the reserved control flow @ sign as a custom interpolation, it will fail upon upgrade to control flow usage.
Looking forward to the team's feedback on this
Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
No response
Anything else?
No response