[6a3a178] | 1 | /**
|
---|
| 2 | * @license
|
---|
| 3 | * Copyright Google LLC All Rights Reserved.
|
---|
| 4 | *
|
---|
| 5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
| 6 | * found in the LICENSE file at https://angular.io/license
|
---|
| 7 | */
|
---|
| 8 | import { InterpolationConfig } from '../ml_parser/interpolation_config';
|
---|
| 9 | import { AbsoluteSourceSpan, AST, AstVisitor, ASTWithSource, Binary, BindingPipe, Chain, Conditional, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, NonNullAssert, ParserError, ParseSpan, PrefixNot, PropertyRead, PropertyWrite, Quote, RecursiveAstVisitor, SafeKeyedRead, SafeMethodCall, SafePropertyRead, TemplateBinding, TemplateBindingIdentifier, ThisReceiver, Unary } from './ast';
|
---|
| 10 | import { Lexer, Token } from './lexer';
|
---|
| 11 | export interface InterpolationPiece {
|
---|
| 12 | text: string;
|
---|
| 13 | start: number;
|
---|
| 14 | end: number;
|
---|
| 15 | }
|
---|
| 16 | export declare class SplitInterpolation {
|
---|
| 17 | strings: InterpolationPiece[];
|
---|
| 18 | expressions: InterpolationPiece[];
|
---|
| 19 | offsets: number[];
|
---|
| 20 | constructor(strings: InterpolationPiece[], expressions: InterpolationPiece[], offsets: number[]);
|
---|
| 21 | }
|
---|
| 22 | export declare class TemplateBindingParseResult {
|
---|
| 23 | templateBindings: TemplateBinding[];
|
---|
| 24 | warnings: string[];
|
---|
| 25 | errors: ParserError[];
|
---|
| 26 | constructor(templateBindings: TemplateBinding[], warnings: string[], errors: ParserError[]);
|
---|
| 27 | }
|
---|
| 28 | export declare class Parser {
|
---|
| 29 | private _lexer;
|
---|
| 30 | private errors;
|
---|
| 31 | constructor(_lexer: Lexer);
|
---|
| 32 | simpleExpressionChecker: typeof SimpleExpressionChecker;
|
---|
| 33 | parseAction(input: string, location: string, absoluteOffset: number, interpolationConfig?: InterpolationConfig): ASTWithSource;
|
---|
| 34 | parseBinding(input: string, location: string, absoluteOffset: number, interpolationConfig?: InterpolationConfig): ASTWithSource;
|
---|
| 35 | private checkSimpleExpression;
|
---|
| 36 | parseSimpleBinding(input: string, location: string, absoluteOffset: number, interpolationConfig?: InterpolationConfig): ASTWithSource;
|
---|
| 37 | private _reportError;
|
---|
| 38 | private _parseBindingAst;
|
---|
| 39 | private _parseQuote;
|
---|
| 40 | /**
|
---|
| 41 | * Parse microsyntax template expression and return a list of bindings or
|
---|
| 42 | * parsing errors in case the given expression is invalid.
|
---|
| 43 | *
|
---|
| 44 | * For example,
|
---|
| 45 | * ```
|
---|
| 46 | * <div *ngFor="let item of items">
|
---|
| 47 | * ^ ^ absoluteValueOffset for `templateValue`
|
---|
| 48 | * absoluteKeyOffset for `templateKey`
|
---|
| 49 | * ```
|
---|
| 50 | * contains three bindings:
|
---|
| 51 | * 1. ngFor -> null
|
---|
| 52 | * 2. item -> NgForOfContext.$implicit
|
---|
| 53 | * 3. ngForOf -> items
|
---|
| 54 | *
|
---|
| 55 | * This is apparent from the de-sugared template:
|
---|
| 56 | * ```
|
---|
| 57 | * <ng-template ngFor let-item [ngForOf]="items">
|
---|
| 58 | * ```
|
---|
| 59 | *
|
---|
| 60 | * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor
|
---|
| 61 | * @param templateValue RHS of the microsyntax attribute
|
---|
| 62 | * @param templateUrl template filename if it's external, component filename if it's inline
|
---|
| 63 | * @param absoluteKeyOffset start of the `templateKey`
|
---|
| 64 | * @param absoluteValueOffset start of the `templateValue`
|
---|
| 65 | */
|
---|
| 66 | parseTemplateBindings(templateKey: string, templateValue: string, templateUrl: string, absoluteKeyOffset: number, absoluteValueOffset: number): TemplateBindingParseResult;
|
---|
| 67 | parseInterpolation(input: string, location: string, absoluteOffset: number, interpolationConfig?: InterpolationConfig): ASTWithSource | null;
|
---|
| 68 | /**
|
---|
| 69 | * Similar to `parseInterpolation`, but treats the provided string as a single expression
|
---|
| 70 | * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
|
---|
| 71 | * This is used for parsing the switch expression in ICUs.
|
---|
| 72 | */
|
---|
| 73 | parseInterpolationExpression(expression: string, location: string, absoluteOffset: number): ASTWithSource;
|
---|
| 74 | private createInterpolationAst;
|
---|
| 75 | /**
|
---|
| 76 | * Splits a string of text into "raw" text segments and expressions present in interpolations in
|
---|
| 77 | * the string.
|
---|
| 78 | * Returns `null` if there are no interpolations, otherwise a
|
---|
| 79 | * `SplitInterpolation` with splits that look like
|
---|
| 80 | * <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
|
---|
| 81 | */
|
---|
| 82 | splitInterpolation(input: string, location: string, interpolationConfig?: InterpolationConfig): SplitInterpolation;
|
---|
| 83 | wrapLiteralPrimitive(input: string | null, location: string, absoluteOffset: number): ASTWithSource;
|
---|
| 84 | private _stripComments;
|
---|
| 85 | private _commentStart;
|
---|
| 86 | private _checkNoInterpolation;
|
---|
| 87 | /**
|
---|
| 88 | * Finds the index of the end of an interpolation expression
|
---|
| 89 | * while ignoring comments and quoted content.
|
---|
| 90 | */
|
---|
| 91 | private _getInterpolationEndIndex;
|
---|
| 92 | /**
|
---|
| 93 | * Generator used to iterate over the character indexes of a string that are outside of quotes.
|
---|
| 94 | * @param input String to loop through.
|
---|
| 95 | * @param start Index within the string at which to start.
|
---|
| 96 | */
|
---|
| 97 | private _forEachUnquotedChar;
|
---|
| 98 | }
|
---|
| 99 | export declare class IvyParser extends Parser {
|
---|
| 100 | simpleExpressionChecker: typeof IvySimpleExpressionChecker;
|
---|
| 101 | }
|
---|
| 102 | export declare class _ParseAST {
|
---|
| 103 | input: string;
|
---|
| 104 | location: string;
|
---|
| 105 | absoluteOffset: number;
|
---|
| 106 | tokens: Token[];
|
---|
| 107 | inputLength: number;
|
---|
| 108 | parseAction: boolean;
|
---|
| 109 | private errors;
|
---|
| 110 | private offset;
|
---|
| 111 | private rparensExpected;
|
---|
| 112 | private rbracketsExpected;
|
---|
| 113 | private rbracesExpected;
|
---|
| 114 | private context;
|
---|
| 115 | private sourceSpanCache;
|
---|
| 116 | index: number;
|
---|
| 117 | constructor(input: string, location: string, absoluteOffset: number, tokens: Token[], inputLength: number, parseAction: boolean, errors: ParserError[], offset: number);
|
---|
| 118 | peek(offset: number): Token;
|
---|
| 119 | get next(): Token;
|
---|
| 120 | /** Whether all the parser input has been processed. */
|
---|
| 121 | get atEOF(): boolean;
|
---|
| 122 | /**
|
---|
| 123 | * Index of the next token to be processed, or the end of the last token if all have been
|
---|
| 124 | * processed.
|
---|
| 125 | */
|
---|
| 126 | get inputIndex(): number;
|
---|
| 127 | /**
|
---|
| 128 | * End index of the last processed token, or the start of the first token if none have been
|
---|
| 129 | * processed.
|
---|
| 130 | */
|
---|
| 131 | get currentEndIndex(): number;
|
---|
| 132 | /**
|
---|
| 133 | * Returns the absolute offset of the start of the current token.
|
---|
| 134 | */
|
---|
| 135 | get currentAbsoluteOffset(): number;
|
---|
| 136 | /**
|
---|
| 137 | * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if
|
---|
| 138 | * provided).
|
---|
| 139 | *
|
---|
| 140 | * @param start Position from which the `ParseSpan` will start.
|
---|
| 141 | * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the
|
---|
| 142 | * natural ending index)
|
---|
| 143 | */
|
---|
| 144 | span(start: number, artificialEndIndex?: number): ParseSpan;
|
---|
| 145 | sourceSpan(start: number, artificialEndIndex?: number): AbsoluteSourceSpan;
|
---|
| 146 | advance(): void;
|
---|
| 147 | /**
|
---|
| 148 | * Executes a callback in the provided context.
|
---|
| 149 | */
|
---|
| 150 | private withContext;
|
---|
| 151 | consumeOptionalCharacter(code: number): boolean;
|
---|
| 152 | peekKeywordLet(): boolean;
|
---|
| 153 | peekKeywordAs(): boolean;
|
---|
| 154 | /**
|
---|
| 155 | * Consumes an expected character, otherwise emits an error about the missing expected character
|
---|
| 156 | * and skips over the token stream until reaching a recoverable point.
|
---|
| 157 | *
|
---|
| 158 | * See `this.error` and `this.skip` for more details.
|
---|
| 159 | */
|
---|
| 160 | expectCharacter(code: number): void;
|
---|
| 161 | consumeOptionalOperator(op: string): boolean;
|
---|
| 162 | expectOperator(operator: string): void;
|
---|
| 163 | prettyPrintToken(tok: Token): string;
|
---|
| 164 | expectIdentifierOrKeyword(): string | null;
|
---|
| 165 | expectIdentifierOrKeywordOrString(): string;
|
---|
| 166 | parseChain(): AST;
|
---|
| 167 | parsePipe(): AST;
|
---|
| 168 | parseExpression(): AST;
|
---|
| 169 | parseConditional(): AST;
|
---|
| 170 | parseLogicalOr(): AST;
|
---|
| 171 | parseLogicalAnd(): AST;
|
---|
| 172 | parseNullishCoalescing(): AST;
|
---|
| 173 | parseEquality(): AST;
|
---|
| 174 | parseRelational(): AST;
|
---|
| 175 | parseAdditive(): AST;
|
---|
| 176 | parseMultiplicative(): AST;
|
---|
| 177 | parsePrefix(): AST;
|
---|
| 178 | parseCallChain(): AST;
|
---|
| 179 | parsePrimary(): AST;
|
---|
| 180 | parseExpressionList(terminator: number): AST[];
|
---|
| 181 | parseLiteralMap(): LiteralMap;
|
---|
| 182 | parseAccessMemberOrMethodCall(receiver: AST, start: number, isSafe: boolean): AST;
|
---|
| 183 | parseCallArguments(): BindingPipe[];
|
---|
| 184 | /**
|
---|
| 185 | * Parses an identifier, a keyword, a string with an optional `-` in between,
|
---|
| 186 | * and returns the string along with its absolute source span.
|
---|
| 187 | */
|
---|
| 188 | expectTemplateBindingKey(): TemplateBindingIdentifier;
|
---|
| 189 | /**
|
---|
| 190 | * Parse microsyntax template expression and return a list of bindings or
|
---|
| 191 | * parsing errors in case the given expression is invalid.
|
---|
| 192 | *
|
---|
| 193 | * For example,
|
---|
| 194 | * ```
|
---|
| 195 | * <div *ngFor="let item of items; index as i; trackBy: func">
|
---|
| 196 | * ```
|
---|
| 197 | * contains five bindings:
|
---|
| 198 | * 1. ngFor -> null
|
---|
| 199 | * 2. item -> NgForOfContext.$implicit
|
---|
| 200 | * 3. ngForOf -> items
|
---|
| 201 | * 4. i -> NgForOfContext.index
|
---|
| 202 | * 5. ngForTrackBy -> func
|
---|
| 203 | *
|
---|
| 204 | * For a full description of the microsyntax grammar, see
|
---|
| 205 | * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
|
---|
| 206 | *
|
---|
| 207 | * @param templateKey name of the microsyntax directive, like ngIf, ngFor,
|
---|
| 208 | * without the *, along with its absolute span.
|
---|
| 209 | */
|
---|
| 210 | parseTemplateBindings(templateKey: TemplateBindingIdentifier): TemplateBindingParseResult;
|
---|
| 211 | parseKeyedReadOrWrite(receiver: AST, start: number, isSafe: boolean): AST;
|
---|
| 212 | /**
|
---|
| 213 | * Parse a directive keyword, followed by a mandatory expression.
|
---|
| 214 | * For example, "of items", "trackBy: func".
|
---|
| 215 | * The bindings are: ngForOf -> items, ngForTrackBy -> func
|
---|
| 216 | * There could be an optional "as" binding that follows the expression.
|
---|
| 217 | * For example,
|
---|
| 218 | * ```
|
---|
| 219 | * *ngFor="let item of items | slice:0:1 as collection".
|
---|
| 220 | * ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
|
---|
| 221 | * keyword bound target optional 'as' binding
|
---|
| 222 | * ```
|
---|
| 223 | *
|
---|
| 224 | * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its
|
---|
| 225 | * absolute span.
|
---|
| 226 | */
|
---|
| 227 | private parseDirectiveKeywordBindings;
|
---|
| 228 | /**
|
---|
| 229 | * Return the expression AST for the bound target of a directive keyword
|
---|
| 230 | * binding. For example,
|
---|
| 231 | * ```
|
---|
| 232 | * *ngIf="condition | pipe"
|
---|
| 233 | * ^^^^^^^^^^^^^^^^ bound target for "ngIf"
|
---|
| 234 | * *ngFor="let item of items"
|
---|
| 235 | * ^^^^^ bound target for "ngForOf"
|
---|
| 236 | * ```
|
---|
| 237 | */
|
---|
| 238 | private getDirectiveBoundTarget;
|
---|
| 239 | /**
|
---|
| 240 | * Return the binding for a variable declared using `as`. Note that the order
|
---|
| 241 | * of the key-value pair in this declaration is reversed. For example,
|
---|
| 242 | * ```
|
---|
| 243 | * *ngFor="let item of items; index as i"
|
---|
| 244 | * ^^^^^ ^
|
---|
| 245 | * value key
|
---|
| 246 | * ```
|
---|
| 247 | *
|
---|
| 248 | * @param value name of the value in the declaration, "ngIf" in the example
|
---|
| 249 | * above, along with its absolute span.
|
---|
| 250 | */
|
---|
| 251 | private parseAsBinding;
|
---|
| 252 | /**
|
---|
| 253 | * Return the binding for a variable declared using `let`. For example,
|
---|
| 254 | * ```
|
---|
| 255 | * *ngFor="let item of items; let i=index;"
|
---|
| 256 | * ^^^^^^^^ ^^^^^^^^^^^
|
---|
| 257 | * ```
|
---|
| 258 | * In the first binding, `item` is bound to `NgForOfContext.$implicit`.
|
---|
| 259 | * In the second binding, `i` is bound to `NgForOfContext.index`.
|
---|
| 260 | */
|
---|
| 261 | private parseLetBinding;
|
---|
| 262 | /**
|
---|
| 263 | * Consume the optional statement terminator: semicolon or comma.
|
---|
| 264 | */
|
---|
| 265 | private consumeStatementTerminator;
|
---|
| 266 | /**
|
---|
| 267 | * Records an error and skips over the token stream until reaching a recoverable point. See
|
---|
| 268 | * `this.skip` for more details on token skipping.
|
---|
| 269 | */
|
---|
| 270 | error(message: string, index?: number | null): void;
|
---|
| 271 | private locationText;
|
---|
| 272 | /**
|
---|
| 273 | * Records an error for an unexpected private identifier being discovered.
|
---|
| 274 | * @param token Token representing a private identifier.
|
---|
| 275 | * @param extraMessage Optional additional message being appended to the error.
|
---|
| 276 | */
|
---|
| 277 | private _reportErrorForPrivateIdentifier;
|
---|
| 278 | /**
|
---|
| 279 | * Error recovery should skip tokens until it encounters a recovery point.
|
---|
| 280 | *
|
---|
| 281 | * The following are treated as unconditional recovery points:
|
---|
| 282 | * - end of input
|
---|
| 283 | * - ';' (parseChain() is always the root production, and it expects a ';')
|
---|
| 284 | * - '|' (since pipes may be chained and each pipe expression may be treated independently)
|
---|
| 285 | *
|
---|
| 286 | * The following are conditional recovery points:
|
---|
| 287 | * - ')', '}', ']' if one of calling productions is expecting one of these symbols
|
---|
| 288 | * - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to
|
---|
| 289 | * be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins
|
---|
| 290 | * an '(' <expr> ')' production).
|
---|
| 291 | * The recovery points of grouping symbols must be conditional as they must be skipped if
|
---|
| 292 | * none of the calling productions are not expecting the closing token else we will never
|
---|
| 293 | * make progress in the case of an extraneous group closing symbol (such as a stray ')').
|
---|
| 294 | * That is, we skip a closing symbol if we are not in a grouping production.
|
---|
| 295 | * - '=' in a `Writable` context
|
---|
| 296 | * - In this context, we are able to recover after seeing the `=` operator, which
|
---|
| 297 | * signals the presence of an independent rvalue expression following the `=` operator.
|
---|
| 298 | *
|
---|
| 299 | * If a production expects one of these token it increments the corresponding nesting count,
|
---|
| 300 | * and then decrements it just prior to checking if the token is in the input.
|
---|
| 301 | */
|
---|
| 302 | private skip;
|
---|
| 303 | }
|
---|
| 304 | declare class SimpleExpressionChecker implements AstVisitor {
|
---|
| 305 | errors: string[];
|
---|
| 306 | visitImplicitReceiver(ast: ImplicitReceiver, context: any): void;
|
---|
| 307 | visitThisReceiver(ast: ThisReceiver, context: any): void;
|
---|
| 308 | visitInterpolation(ast: Interpolation, context: any): void;
|
---|
| 309 | visitLiteralPrimitive(ast: LiteralPrimitive, context: any): void;
|
---|
| 310 | visitPropertyRead(ast: PropertyRead, context: any): void;
|
---|
| 311 | visitPropertyWrite(ast: PropertyWrite, context: any): void;
|
---|
| 312 | visitSafePropertyRead(ast: SafePropertyRead, context: any): void;
|
---|
| 313 | visitMethodCall(ast: MethodCall, context: any): void;
|
---|
| 314 | visitSafeMethodCall(ast: SafeMethodCall, context: any): void;
|
---|
| 315 | visitFunctionCall(ast: FunctionCall, context: any): void;
|
---|
| 316 | visitLiteralArray(ast: LiteralArray, context: any): void;
|
---|
| 317 | visitLiteralMap(ast: LiteralMap, context: any): void;
|
---|
| 318 | visitUnary(ast: Unary, context: any): void;
|
---|
| 319 | visitBinary(ast: Binary, context: any): void;
|
---|
| 320 | visitPrefixNot(ast: PrefixNot, context: any): void;
|
---|
| 321 | visitNonNullAssert(ast: NonNullAssert, context: any): void;
|
---|
| 322 | visitConditional(ast: Conditional, context: any): void;
|
---|
| 323 | visitPipe(ast: BindingPipe, context: any): void;
|
---|
| 324 | visitKeyedRead(ast: KeyedRead, context: any): void;
|
---|
| 325 | visitKeyedWrite(ast: KeyedWrite, context: any): void;
|
---|
| 326 | visitAll(asts: any[], context: any): any[];
|
---|
| 327 | visitChain(ast: Chain, context: any): void;
|
---|
| 328 | visitQuote(ast: Quote, context: any): void;
|
---|
| 329 | visitSafeKeyedRead(ast: SafeKeyedRead, context: any): void;
|
---|
| 330 | }
|
---|
| 331 | /**
|
---|
| 332 | * This class implements SimpleExpressionChecker used in View Engine and performs more strict checks
|
---|
| 333 | * to make sure host bindings do not contain pipes. In View Engine, having pipes in host bindings is
|
---|
| 334 | * not supported as well, but in some cases (like `!(value | async)`) the error is not triggered at
|
---|
| 335 | * compile time. In order to preserve View Engine behavior, more strict checks are introduced for
|
---|
| 336 | * Ivy mode only.
|
---|
| 337 | */
|
---|
| 338 | declare class IvySimpleExpressionChecker extends RecursiveAstVisitor implements SimpleExpressionChecker {
|
---|
| 339 | errors: string[];
|
---|
| 340 | visitPipe(): void;
|
---|
| 341 | }
|
---|
| 342 | export {};
|
---|