/** * Copyright 2017 Matt Acosta * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { AnonymousClassNode, AnonymousFunctionNode, ArrayElementNode, ArrayNode, ArrowFunctionNode, BreakNode, ClassConstantDeclarationNode, ClassConstantElementNode, ClassDeclarationNode, CloneNode, ClosureUseNode, ConditionalNode, ConstantDeclarationNode, ConstantElementNode, ContinueNode, DeclareBlockNode, DeclareNode, DoWhileNode, EchoNode, ElementAccessNode, ElseIfBlockNode, ElseIfNode, EmptyIntrinsicNode, ErrorControlNode, EvalIntrinsicNode, ExitIntrinsicNode, ExpressionNode, FlexibleHeredocElementNode, FlexibleHeredocTemplateNode, ForBlockNode, ForEachBlockNode, ForEachNode, ForNode, FullyQualifiedNameNode, FunctionDeclarationNode, FunctionInvocationNode, GlobalNode, GoToNode, HaltCompilerNode, HeredocTemplateNode, IfBlockNode, IfNode, IndirectStringVariableNode, InstanceOfNode, InterfaceDeclarationNode, IsSetIntrinsicNode, LexicalVariableNode, ListDestructureElementNode, ListDestructureNode, LiteralNode, MemberAccessNode, MemberInvocationNode, MethodDeclarationNode, MethodReferenceNode, NamedTypeNode, NameNode, NamespaceDeclarationNode, NamespaceGroupDeclarationNode, ObjectCreationNode, ParameterNode, PartiallyQualifiedNameNode, PredefinedTypeNode, PrintIntrinsicNode, PropertyDeclarationNode, PropertyElementNode, RelativeNameNode, ReturnNode, ScriptInclusionNode, ShellCommandTemplateNode, StatementBlockNode, StatementNode, StaticElementNode, StaticNode, StringTemplateNode, SwitchBlockNode, SwitchCaseNode, SwitchNode, ThrowNode, TraitAliasNode, TraitDeclarationNode, TraitUseGroupNode, TraitUseNode, TryCatchNode, TryFinallyNode, TryNode, UnsetNode, UseDeclarationNode, UseElementNode, UseGroupDeclarationNode, VariableNode, WhileBlockNode, WhileNode, YieldFromNode, YieldNode } from '../language/node/Node.Generated'; import { ErrorCode } from '../diagnostics/ErrorCode.Generated'; import { ExpressionType } from './ExpressionType'; import { INode } from '../language/node/INode'; import { IParser } from './Parser'; import { ModifierFlags } from './ModifierFlags'; import { Node } from '../language/node/Node'; import { NodeFactory } from '../language/node/NodeFactory'; import { NodeList } from '../language/node/NodeList'; import { ParseContext } from './ParseContext'; import { PhpLexer } from './PhpLexer'; import { PhpLexerState } from './PhpLexerState'; import { PhpParserOptions } from './PhpParserOptions'; import { PhpVersion } from './PhpVersion'; import { Precedence } from './Precedence'; import { SourceTextNode } from '../language/node/SourceTextNode'; import { SourceTextSyntaxNode } from '../language/syntax/SourceTextSyntaxNode'; import { SyntaxDiagnostic } from '../diagnostics/SyntaxDiagnostic'; import { Token } from './Token'; import { TokenKind } from '../language/TokenKind'; import { TokenNode } from '../language/node/TokenNode'; import { TriviaNode } from '../language/node/TriviaNode'; /** * A container for a parsed expression (or statement) node and its type. */ export declare class Expression { readonly node: ExpressionNode | StatementNode; readonly type: ExpressionType; constructor(node: ExpressionNode | StatementNode, type: ExpressionType); } /** * A container for the arguments of an invocation expression. */ export declare class InvocationArguments { readonly openParen: TokenNode; readonly argumentList: NodeList | null; readonly closeParen: TokenNode; constructor(openParen: TokenNode, argumentList: NodeList | null, closeParen: TokenNode); } /** * A container for the parameters of a function or method declaration. */ export declare class Parameters { readonly openParen: TokenNode; readonly parameterList: NodeList | null; readonly closeParen: TokenNode; constructor(openParen: TokenNode, parameterList: NodeList | null, closeParen: TokenNode); } /** * Parses a PHP file into an abstract syntax tree. */ export declare class PhpParser implements IParser { /** * The contexts that the parser has encountered. * * Contexts are typically used when parsing arbitrarily long lists in order * to help determine a proper recovery action when an error occurs. * * For example, while parsing a list of statements inside a while loop, the * parser will know that it has encountered a block statement (the parent * function or method) and while statement contexts. * * Note that care must be used when changing contexts. For example, when * parsing a while loop that is inside another while loop, removing the * nested loop's context using * * `this.currentContext &= ~ParseContext.WhileBlockElements;` * * would incorrectly remove the parent context as well. Instead, save the * current context, and when the action is complete, restore that context * (since the context may not have actually changed). */ protected currentContext: ParseContext; /** * The current token from the lexer. */ protected currentToken: Token; /** * A factory service for creating tokens, trivia, and node lists. */ protected factory: NodeFactory; /** * A list of trivia nodes that preceed the current token. */ protected leadingTrivia: TriviaNode[]; /** * The width of the current token's leading trivia. */ protected leadingTriviaWidth: number; /** * A PHP tokenizer. */ protected lexer: PhpLexer; /** * The current state of the PHP tokenizer. */ protected lexerState: PhpLexerState; /** * An object containing configuration options for the parser. */ protected options: PhpParserOptions; /** * Constructs a `PhpParser` object. * * @todo Implement incremental parsing. * @todo Implement cancellation token support. */ constructor(lexer: PhpLexer, options?: PhpParserOptions); /** * @inheritDoc */ parse(): SourceTextSyntaxNode; /** * Force the parser to skip any remaining content. * * @todo Experimental. */ protected forceEndOfFile(): void; /** * Determines if the given version requirements are satisfied. * * @param {PhpVersion} minVersion * The earliest supported PHP version. * @param {PhpVersion} maxVersion * The latest supported PHP version. */ protected isSupportedVersion(minVersion: PhpVersion, maxVersion?: PhpVersion): boolean; /** * @todo Document parseSourceText(). */ protected parseSourceText(): SourceTextNode; /** * Creates a missing token. * * @param {TokenKind} expected * The expected token kind. * @param {TokenKind} actual * The actual token kind that was parsed. * @param {boolean} reportError * If `true`, the created token will contain a diagnostic using a generic * error code (depending on the expected and actual tokens found). */ protected createMissingToken(expected: TokenKind, actual: TokenKind, reportError: boolean): TokenNode; /** * Creates a missing token using the given error code. */ protected createMissingTokenWithError(expected: TokenKind, code: ErrorCode, ...args: any[]): TokenNode; /** * Creates a missing token with the given diagnostics. * * NOTE: This method should not be called directly from parsing methods. * Use `createMissingToken()` or `createMissingTokenWithError()` instead. */ protected createMissingTokenWithDiagnostic(expected: TokenKind, diagnostics: SyntaxDiagnostic[]): TokenNode; /** * Creates a `TokenNode` from a token generated by the lexer. * * If there was leading trivia prior to this token, it will also be added * to the token. * * @param {Token} token * A token generated by the lexer. */ protected createToken(token: Token): TokenNode; /** * Creates a token node. * * If expected, the lexer will also be moved to the next token. * * @param {TokenKind} kind * The expected type of the token to parse. * * @return {TokenNode} * A token node. If the expected token does not match the current token, * this node will be flagged as missing. */ protected eat(kind: TokenKind): TokenNode; /** * Creates a token node only if the expected token matches the current token. * * If expected, the lexer will also be moved to the next token. * * @param {TokenKind} kind * The expected type of token to parse. * * @return {TokenNode|null} * A token node, or `null` if the current token was not expected. */ protected eatOptional(kind: TokenKind): TokenNode | null; /** * Moves the lexer to the next non-trivia token. */ protected nextToken(): void; /** * @todo Document scanToken(). * * @todo Merge into nextToken() if not needed for incremental parsing. */ protected scanToken(): void; /** * Adds the current token to the leading trivia of the next token. The token * will be given a generic diagnostic as well. */ protected skipToken(): void; /** * Adds the current token to the leading trivia of the next token with a * given error code. */ protected skipTokenWithError(code: ErrorCode, ...args: any[]): void; /** * Appends a diagnostic to the given node. */ protected addError(node: T, code: ErrorCode, ...args: any[]): T; /** * Creates a diagnostic for a node. */ protected createDiagnostic(offset: number, width: number, code: ErrorCode, ...args: any[]): SyntaxDiagnostic; /** * Creates a diagnostic for a token node with no width. */ protected createDiagnosticForMissingToken(code: ErrorCode, ...args: any[]): SyntaxDiagnostic; /** * Creates a diagnostic for a node that has already been created. */ protected createDiagnosticForNode(node: INode, code: ErrorCode, ...args: any[]): SyntaxDiagnostic; /** * Creates a diagnostic for a trivia node containing a skipped token. */ protected createDiagnosticForSkippedToken(code: ErrorCode, ...args: any[]): SyntaxDiagnostic; /** * Creates a diagnostic at a specified location using an error code * appropriate for the expected and actual token kinds. */ protected createExpectedDiagnostic(expected: TokenKind, actual: TokenKind, offset: number, width: number): SyntaxDiagnostic; /** * Gets an appropriate error code given the expected and actual token kinds. */ protected getExpectedTokenErrorCode(expected: TokenKind, actual: TokenKind): ErrorCode; /** * Gets the offset of the last non-whitespace token in the leading trivia. * * This method is required to properly place diagnostics when multiple tokens * have been skipped. */ protected getOffsetForMissingToken(): number; /** * Adds a context flag to the parser's currently active contexts. */ protected addParseContext(context: ParseContext): void; /** * Determines if the parser is currently in the given context. */ protected isInContext(context: ParseContext): boolean; /** * Determines if the token kind starts or ends any active contexts. */ protected isTokenValidInContexts(kind: TokenKind): boolean; /** * Determines if a token terminates a specified context. * * @param {ParseContext} context * The context to check. * @param {TokenKind} kind * The token kind. */ protected tokenEndsContext(context: ParseContext, kind: TokenKind): boolean; /** * Determines if a token could start a node within the specified context. * * @param {ParseContext} context * The context to check. * @param {TokenKind} kind * The token kind. */ protected tokenStartsContext(context: ParseContext, kind: TokenKind): boolean; /** * Determines if a token starts an argument in an invocation expression. */ protected isArgumentStart(kind: TokenKind): boolean; /** * Determines if a token starts an element within an array. */ protected isArrayElementStart(kind: TokenKind): boolean; /** * Determines if a token represents an assignment operation. */ protected isAssignmentOperator(kind: TokenKind): boolean; /** * Determines if a token represents a binary operation. */ protected isBinaryOperator(kind: TokenKind): boolean; /** * Determines if a token is a valid identifier for a class member. */ protected isClassMemberIdentifier(kind: TokenKind): boolean; /** * Determines if a token starts a class member declaration. */ protected isClassMemberStart(kind: TokenKind): boolean; /** * Determines if a token starts a class name reference found after an * `instanceof` or `new` keyword. */ protected isClassNameReferenceStart(kind: TokenKind): boolean; /** * Determines if a token starts a postfix expression within a class name * reference. */ protected isClassNameReferenceExpressionStart(kind: TokenKind): boolean; /** * Determines if a token starts a dereference of an object. * * @see PhpParser.isElementAccessStart() */ protected isDereferenceStart(kind: TokenKind): boolean; /** * Determines if a token starts a dereference of a non-object. * * @see isDereferenceStart() */ protected isElementAccessStart(kind: TokenKind): boolean; /** * Determines if a token starts an expression. */ protected isExpressionStart(kind: TokenKind): boolean; /** * Determines if the token starts a line within a flexible heredoc. */ protected isFlexdocTemplateLineStart(kind: TokenKind): boolean; /** * Determines if a token is a valid identifier for a function. */ protected isFunctionIdentifier(kind: TokenKind): boolean; /** * Determines if a token starts an expression or nested list deconstruction. */ protected isListIntrinsicElementStart(kind: TokenKind): boolean; /** * Determines if a token is a type or visibility modifier. */ protected isModifier(kind: TokenKind): boolean; /** * Determines if a token starts a fully qualified, partially qualified, or * relative name. */ protected isNameStart(kind: TokenKind): boolean; /** * Determines if a token is a non-associative binary operator. */ protected isNonAssociative(kind: TokenKind): boolean; /** * Determines if a token starts a parameter in a function or method declaration. */ protected isParameterStart(kind: TokenKind): boolean; /** * Determines if a token starts a property declaration. */ protected isPropertyStart(kind: TokenKind): boolean; /** * Determines if a token is a right-associative *binary* operator. */ protected isRightAssociative(kind: TokenKind): boolean; /** * Determines if a token starts a declaration or statement within a * `compound-statement`. */ protected isStatementBlockStart(kind: TokenKind): boolean; /** * Determines if a token is a semicolon or close tag. */ protected isStatementEnd(kind: TokenKind): boolean; /** * Determines if a token is the start of a statement. */ protected isStatementStart(kind: TokenKind): boolean; /** * Determines if a token ends a string template. */ protected isStringTemplateEnd(kind: TokenKind, terminator: TokenKind): boolean; /** * Determines if a token starts a variable offset within an interpolated * element access expression. */ protected isStringTemplateVariableOffset(kind: TokenKind): boolean; /** * Determines if a token is the start of an interpolation within a string * template. */ protected isStringTemplateElementStart(kind: TokenKind): boolean; /** * Determines if a token starts a branch within a switch statement. */ protected isSwitchCaseStart(kind: TokenKind): boolean; /** * Determines if a token is the start of a top-level statement, which * includes other statements and expressions. */ protected isTopStatementStart(kind: TokenKind): boolean; /** * Determines if a token starts a class or method name. */ protected isTraitAdaptationStart(kind: TokenKind): boolean; /** * Determines if a token is a predefined type or starts a user-defined type. */ protected isTypeStart(kind: TokenKind): boolean; /** * Determines if a token represents a unary operation. */ protected isUnaryOperator(kind: TokenKind): boolean; /** * Determines if a token starts a type, function, or constant import. */ protected isUseGroupElementStart(kind: TokenKind): boolean; /** * Parses a list of elements separated by a delimiter. */ protected parseDelimitedList(context: ParseContext, delimiter: TokenKind, terminator: TokenKind): NodeList; /** * Parses a element based on the given context. */ protected parseElement(context: ParseContext): Node; /** * Parses a list of elements based on the given context. */ protected parseList(context: ParseContext): NodeList | null; /** * Parses a nested statement. */ protected parseStatementBlockElement(): StatementNode; /** * Parses a top-level statement. */ protected parseSourceElement(): StatementNode; /** * Parses a statement. */ protected parseStatement(): StatementNode; /** * Parses a break statement. * * Syntax: `BREAK optional-expr ;` */ protected parseBreak(): BreakNode; /** * Parses the iteration depth of a `break` or `continue` statement. * * Syntax: `expr` * * This syntax is only for compatibility purposes. The node should actually * be equivalent to `LNUMBER` or `( LNUMBER )`. */ protected parseBreakOrContinueDepth(keyword: TokenKind): ExpressionNode; /** * Parses a list of class constants. * * Syntax: `visibility-modifier CONST const-elements ;` * * Where `const-elements` is: * - `const-elements , const-element` * - `const-element` */ protected parseClassConstantDeclaration(modifiers: TokenNode[], context: ParseContext): ClassConstantDeclarationNode; /** * Parses a single constant within a class constant declaration. * * Syntax: `member-name = expression` */ protected parseClassConstantElement(): ClassConstantElementNode; /** * Parses a class declaration statement. * * Syntax: `class-modifier CLASS IDENTIFIER class-base-clause class-interface-clause { class-member-declarations }` * * Where `class-base-clause` is: * - `EXTENDS qualified-name` * * Where `class-interface-clause` is: * - `IMPLEMENTS qualified-name-list` */ protected parseClassDeclaration(): ClassDeclarationNode; /** * Parses a list of member declarations within a type declaration. */ protected parseClassMembers(context: ParseContext): NodeList | null; /** * @todo Document parseClassMemberDeclaration(). */ protected parseClassMemberDeclaration(context: ParseContext): StatementNode; /** * Parses the modifiers of a class member declaration. */ protected parseClassMemberModifiers(tokens: TokenNode[], context: ParseContext): ModifierFlags; /** * Parses a class member name. * * Syntax: `member-name` * * Where `member-name` is: * - `IDENTIFIER` * - `semi-reserved-keyword` */ protected parseClassMemberName(code: ErrorCode, ...args: any[]): TokenNode; /** * Parses the modifiers of a class declaration. * * All modifiers except `abstract` and `final` will generate a diagnostic. */ protected parseClassModifiers(): NodeList | null; /** * Parses a constant declaration statement. * * Syntax: `CONST const-list ;` * * Where `const-list` is: * - `const-list , const-element` * - `const-element` */ protected parseConstantDeclaration(): ConstantDeclarationNode; /** * Parses a single constant from a constant declaration statement. * * Syntax: `IDENTIFIER = expression` */ protected parseConstantElement(): ConstantElementNode; /** * Parses a continue statement. * * Syntax: `CONTINUE optional-expr ;` */ protected parseContinue(): ContinueNode; /** * Parses a declare statement. * * Syntax: * - `DECLARE ( const-list ) statement` * - `DECLARE ( const-list ) : statement-list ENDDECLARE ;` */ protected parseDeclare(): DeclareNode | DeclareBlockNode; /** * Parses a do-while statement. * * Syntax: `DO statement WHILE ( expression ) ;` */ protected parseDoWhile(): DoWhileNode; /** * Parses an echo expression. * * Syntax: `ECHO echo-list ;` * * Where `echo-list` is: * - `echo-list , expr` * - `expr` */ protected parseEcho(): EchoNode; /** * Parses an `elseif` clause of an if statement. * * Syntax: `ELSEIF ( expr ) statement` */ protected parseElseIf(): ElseIfNode; /** * Parses an `elseif` clause of an if statement (alternate syntax). * * Syntax: `ELSEIF ( expr ) : statement-list` */ protected parseElseIfBlock(): ElseIfBlockNode; /** * Parses a single statement or, if the statement is missing, an empty * statement is created with a diagnostic. * * @param {boolean} warnIfEmpty * If `true` and the next token is a semicolon, then a warning is added to * the generated empty statement. * @param {ErrorCode} code * An error code to use if the statement is missing. * @param {...any[]} args * A list of arguments given to the diagnostic created if the statement is * missing. */ protected parseEmbeddedStatement(warnIfEmpty: boolean, code: ErrorCode, ...args: any[]): StatementNode; /** * Parses a for statement (or its alternate syntax). * * Syntax: * - `FOR ( for-expr ; for-expr ; for-expr ) statement` * - `FOR ( for-expr ; for-expr ; for-expr ) : statement-list ENDFOR ;` */ protected parseFor(): ForNode | ForBlockNode; /** * Parses a comma-separated list of expressions within a for statement. */ protected parseForExpressionList(terminator: TokenKind): Array; /** * Parses a foreach statement. * * Syntax: * - `FOREACH ( expr AS foreach-value ) statement` * - `FOREACH ( expr AS foreach-value ) : statement-list ENDFOREACH ;` * - `FOREACH ( expr AS expr => foreach-value ) statement` * - `FOREACH ( expr AS expr => foreach-value ) : statement-list ENDFOREACH ;` * * Where `foreach-value` is: * - `expr` * - `& expr` * - `LIST ( list-elements )` * - `[ list-elements ]` */ protected parseForEach(): ForEachNode | ForEachBlockNode; /** * @todo Document parseForEachVariable(). */ protected parseForEachVariable(): ExpressionNode; /** * Parses a qualified name that begins with a namespace separator. */ protected parseFullyQualifiedName(): FullyQualifiedNameNode; /** * Parses a function declaration statement. * * Syntax: `FUNCTION & IDENTIFIER ( parameter-list ) return-type statement-block` */ protected parseFunctionDeclaration(functionKeyword: TokenNode, ampersand: TokenNode | null): FunctionDeclarationNode; /** * Parses a global variable declaration statement. * * Syntax: `GLOBAL global-variable-list ;` * * Where `global-variable-list` is: * - `global-variable-list , simple-variable` * - `simple-variable` */ protected parseGlobal(): GlobalNode; /** * Parses a goto statement. * * Syntax: `GOTO IDENTIFIER ;` */ protected parseGoTo(): GoToNode; /** * Parses a halt compiler statement. * * Syntax: `HALT_COMPILER ( ) ;` */ protected parseHaltCompiler(): HaltCompilerNode; /** * Parses an if statement. * * Syntax: * - `if-statement` * - `if-statement ELSE statement` * * Where `if-statement` is: * - `IF ( expr ) statement` * - `IF ( expr ) statement elseif-clause` */ protected parseIf(): IfNode | IfBlockNode; /** * Parses inline text (which actually gets treated as an echo statement). * * Syntax: `INLINE_TEXT` */ protected parseInlineText(): EchoNode; /** * Parses an interface declaration statement. * * Syntax: `INTERFACE IDENTIFIER interface-base-clause { interface-member-declarations }` * * Where `interface-base-clause` is: * - `EXTENDS qualified-name-list` */ protected parseInterfaceDeclaration(): InterfaceDeclarationNode; /** * Parses a method declaration statement. * * Syntax: `modifiers FUNCTION & member-name ( parameter-list ) return-type method-body` * * Where `method-body` is: * - `statement-block` * - `;` * * @param {TokenNode[]} modifiers * A list of previously parsed modifier keywords. * @param {ModifierFlags} modifierFlags * A bit field representing all the modifiers that were parsed. * @param {ParseContext} context * The context that this declaration should be parsed in. */ protected parseMethodDeclaration(modifiers: TokenNode[], modifierFlags: ModifierFlags, context: ParseContext): MethodDeclarationNode; /** * Parses a namespace declaration. * * Syntax: * - `NAMESPACE name;` * - `NAMESPACE name { namespaced-statement-list }` * - `NAMESPACE { namespaced-statement-list }` */ protected parseNamespaceDeclaration(namespaceKeyword: TokenNode): NamespaceDeclarationNode | NamespaceGroupDeclarationNode; /** * Parses a delimited list of tokens representing a name. * * @param {boolean=} noTrailingBackslash * If `true`, a missing identifier is appended to the list of returned * tokens if an unrecognized token is found after a namespace separator. * * @return {TokenNode[]} * A list of tokens making up the name. An actual node to contain these * tokens must be created by the caller. */ protected parseNamespaceName(noTrailingBackslash?: boolean): TokenNode[]; /** * Parses a single parameter within a function or method's parameter list. * * Syntax: * - `type & ELLIPSIS VARIABLE` * - `type & ELLIPSIS VARIABLE = expr` */ protected parseParameter(): ParameterNode; /** * Parses a comma separated list of parameters. * * Syntax: `( parameter-list )` * * Where `parameter-list` is: * - `parameter-list , parameter` * - `parameter` */ protected parseParameterList(): Parameters; /** * Parses a name that starts with an identifier and may include namespaces. * * Syntax: `name` * * Where `name` is: * - `name \ IDENTIFIER` * - `IDENTIFIER` * * @see parseQualifiedName() */ protected parsePartiallyQualifiedName(): PartiallyQualifiedNameNode; /** * Parses a property declaration statement. * * Syntax: `property-modifiers type property-list ;` * * Where `property-modifiers` is: * - `modifiers` * - `VAR` * * Where `property-list` is: * - `property-list , property-element` * - `property-element` * * @param {TokenNode[]} modifiers * Previously parsed modifier keywords. * @param {ParseContext} context * The parent parsing context (class, interface, or trait members). */ protected parsePropertyDeclaration(modifiers: TokenNode[], context: ParseContext): PropertyDeclarationNode; /** * Parses the declaration of an individual property. * * Syntax: `property-element` * * Where `property-element` is: * - `VARIABLE` * - `VARIABLE = expression` (technically `constant-expression`) */ protected parsePropertyElement(): PropertyElementNode; /** * Parses a property name. * * Syntax: `VARIABLE` */ protected parsePropertyName(): TokenNode; /** * Parses a potentially qualified identifier for name resolution. * * Syntax: `qualified-name` * * Where `qualified-name` is: * - `name` * - `\ name` (fully qualified) * - `NAMESPACE \ name` (relative) */ protected parseQualifiedName(allowRelativeNames?: boolean): NameNode; /** * Parses a comma separated list of qualified names. */ protected parseQualifiedNameList(): NodeList; /** * Parses a name that begins with a `NAMESPACE` token. */ protected parseRelativeName(): RelativeNameNode; /** * Parses a return statement. * * Syntax: `RETURN optional-expr ;` */ protected parseReturn(): ReturnNode; /** * Parses a static variable declaration statement. * * Syntax: `STATIC static-variable-list ;` * * Where `static-variable-list` is: * - `static-variable-list , static-variable` * - `static-variable` */ protected parseStatic(staticKeyword: TokenNode): StaticNode; /** * Parses a static variable with an optional initialization expression. * * Syntax: * - `VARIABLE` * - `VARIABLE = expr` */ protected parseStaticElement(): StaticElementNode; /** * Parses a list of statements within surrounding braces. * * Syntax: `{ statement-list }` * * Alias: `compound-statement` */ protected parseStatementBlock(): StatementBlockNode; /** * Parses a semicolon or closing tag. * * Syntax: * - `;` * - `?>` */ protected parseStatementEnd(): TokenNode; /** * Parses a switch statement. * * Syntax: * - `SWITCH ( expr ) { ; switch-case-list }` * - `SWITCH ( expr ) : ; switch-case-list ENDSWITCH ;` */ protected parseSwitch(): SwitchNode | SwitchBlockNode; /** * Parses a switch case or default clause. * * Syntax: * - `CASE expression case-separator statement-list` * - `DEFAULT case-separator statement-list` */ protected parseSwitchCase(label: TokenNode): SwitchCaseNode; /** * Parses a list of switch case or default clauses. * * Syntax: `switch-case-list` * * Where `switch-case-list` is: * - `switch-case-list switch-case-clause` * - `switch-case-list switch-default-clause` */ protected parseSwitchElements(context: ParseContext): NodeList | null; /** * Parses a throw statement. * * Syntax: `THROW expr ;` */ protected parseThrow(): ThrowNode; /** * Parses a list of trait adaptations. * * Syntax: `trait-adaptation-list` * * Where `trait-adaptation-list` is: * - `trait-adaptation-list trait-adaptation` * - `trait-adaptation` * * Where `trait-adaptation` is: * - `trait-alias ;` * - `trait-precedence ;` * * Where `trait-precedence` is: * - `method-reference INSTEADOF qualified-name-list` */ protected parseTraitAdaptationList(): NodeList | null; /** * Parses a trait alias adaptation. * * Syntax: * - `trait-method AS IDENTIFIER` * - `trait-method AS non-modifier-keywords` * - `trait-method AS modifier member-name` * - `trait-method AS modifier` * * Where `trait-method` is: * - `member-name` * - `method-reference` */ protected parseTraitAlias(methodNameOrReference: MethodReferenceNode | TokenNode): TraitAliasNode; /** * Parses a trait declaration statement. * * Syntax: `TRAIT name { trait-member-declarations }` */ protected parseTraitDeclaration(): TraitDeclarationNode; /** * Parses a trait import statement (also known as a trait use clause). * * Syntax: * - `USE qualified-name-list ;` * - `USE qualified-name-list { trait-adaptation-list }` */ protected parseTraitUse(context: ParseContext): TraitUseNode | TraitUseGroupNode; /** * Parses a try statement. * * Syntax: * - `TRY { statement-list } catch-list` * - `TRY { statement-list } catch-list finally-clause` * - `TRY { statement-list } finally-clause` * * Where `catch-list` is: * - `catch-list catch-clause` * - `catch-clause` */ protected parseTry(): TryNode; /** * Parses a try statement's catch clause. * * Syntax: `CATCH ( catch-name-list VARIABLE ) { statement-list }` * * Where `catch-name-list` is: * - `catch-name-list | qualified-name` * - `qualified-name` */ protected parseTryCatch(): TryCatchNode; /** * Parses a try statement's finally clause. * * Syntax: `FINALLY { statement-list }` */ protected parseTryFinally(): TryFinallyNode; /** * Parses a (nullable) type. * * Syntax: `? type` */ protected parseType(): NamedTypeNode | PredefinedTypeNode; /** * Parses a qualified name that should be a type. * * This method is equivalent to `parseQualifiedName()`, but uses a custom * error message when the name is missing. */ protected parseTypeName(): NameNode; /** * Parses an unset statement. * * Syntax: `UNSET ( unset-list ) ;` * * Where `unset-list` is: * - `unset-list , expr` * - `expr` */ protected parseUnset(): UnsetNode; /** * @todo Document parseUseDeclaration(). */ protected parseUseDeclaration(): UseDeclarationNode | UseGroupDeclarationNode; /** * Parses a use element. * * Syntax: `use-inline-name AS IDENTIFIER` * * Where `use-inline-name` is: * - `name` * - `\ name` */ protected parseUseElement(): UseElementNode; /** * Parses a group use element. * * Syntax: `use-type name AS IDENTIFIER` * * Where `use-type` is: * - `CONST` * - `FUNCTION` * * @param {boolean} hasGroupUseType * When `true`, the use declaration already specifies a type, and any use * types found inside this clause should generate an error. */ protected parseUseGroupElement(hasGroupUseType: boolean): UseElementNode; /** * Parses a while statement. * * Syntax: * - `WHILE ( expr ) statement` * - `WHILE ( expr ) : statement-list ENDWHILE ;` */ protected parseWhile(): WhileNode | WhileBlockNode; /** * Parses an expression. */ protected parseExpression(expectedType?: ExpressionType, precedence?: Precedence): ExpressionNode; /** * Parses an expression or, if possible, a statement. */ protected parseExpressionOrTopStatement(): StatementNode; /** * Parses a sequence of one or more operands and zero or more operators into * a tree-like structure representing an expression. * * @param {ExpressionType=} expectedType * The expected type of the term. * @param {Precedence=} precedence * The precedence of the operator prior to this expression term. * @param {boolean=} isStatementExpected * If `true`, a statement may be parsed instead of an expression. Defaults * to `false`. */ protected parseExpressionTree(expectedType?: ExpressionType, precedence?: Precedence, isStatementExpected?: boolean): Expression; /** * @todo Document parseBinaryExpression(). */ protected parseBinaryExpression(leftTerm: Expression, precedence?: Precedence): Expression; /** * @todo Document parsePostfixExpression(). */ protected parsePostfixExpression(term: Expression, expectedType: ExpressionType): Expression; /** * @todo Document parsePrimaryExpression(). */ protected parsePrimaryExpression(expectedType: ExpressionType): Expression; /** * Parses an anonymous class. * * Syntax: * - `CLASS class-base-clause class-interface-clause { class-member-declarations }` * - `CLASS ( argument-list ) class-base-clause class-interface-clause { class-member-declarations }` * * @see PhpParser.parseObjectCreationExpression() */ protected parseAnonymousClass(): AnonymousClassNode; /** * Parses a list of arguments in an anonymous class, invocation, or object * creation expression. * * Syntax: `( argument-list )` * * Where `argument-list` is: * - `argument-list , argument` * - `argument` * * Where `argument` is: * - `ELLIPSIS expr` * - `expr` */ protected parseArgumentList(): InvocationArguments; /** * Parses an array initializer or list deconstruction. * * Syntax: * - `ARRAY ( array-elements )` * - `[ array-elements ]` */ protected parseArray(): ArrayNode; /** * Parses a comma-separated list of array elements. * * @param {TokenKind} end * The token used to terminate the array. */ protected parseArrayElementList(end: TokenKind): Array; /** * Parses an element of an array initializer. * * Syntax: * - `expr` * - `expr => expr` * - `& expr` * - `expr => & expr` * - `... expr` */ protected parseArrayElement(): ArrayElementNode; /** * @todo Document parseArrayOrDeconstruction(). */ protected parseArrayOrDeconstruction(): Expression; /** * Parses an anonymous function (closure) that returns an expression. * * Syntax: * - `FN & ( parameter-list ) return-type => expr` * - `STATIC FN & ( parameter-list ) return-type => expr` */ protected parseArrowFunction(staticKeyword: TokenNode | null): ArrowFunctionNode; /** * Parses a reference to a class name. * * Syntax: * - `class-name` * - `class-reference` * * Where `class-name` is: * - `qualified-name` * - `STATIC` * * Where `class-reference` is: * - `simple-variable` * - `class-name :: simple-variable` * - `class-reference [ expr ]` * - `class-reference { expr }` * - `class-reference -> property-name` * - `class-reference :: simple-variable` */ protected parseClassNameReference(): ExpressionNode | NameNode; /** * Parses a clone expression. * * Syntax: `CLONE expr` */ protected parseClone(): CloneNode; /** * Parses an anonymous function (closure). * * Syntax: * - `FUNCTION & ( parameter-list ) closure-use return-type statement-block` * - `STATIC FUNCTION & ( parameter-list ) closure-use return-type statement-block` */ protected parseClosure(staticKeyword: TokenNode | null, functionKeyword: TokenNode, ampersand: TokenNode | null): AnonymousFunctionNode; /** * Parses a closure use clause. * * Syntax: `USE ( lexical-variables )` * * Where `lexical-variables` is: * - `lexical-variables , lexical-variable` * - `lexical-variable` */ protected parseClosureUseClause(): ClosureUseNode; /** * Parses a conditional (ternary) expression. * * Syntax: * - `expr ? expr : expr` * - `expr ? : expr` */ protected parseConditionalExpression(condition: ExpressionNode, question: TokenNode): ConditionalNode; /** * Parses an element access (subscript) expression. * * Syntax: * - `dereferenceable [ expr ]` * - `dereferenceable { expr }` */ protected parseElementAccess(dereferenceable: ExpressionNode): ElementAccessNode; /** * Parses an empty intrinsic expression. * * Syntax: `EMPTY ( expr )` */ protected parseEmpty(): EmptyIntrinsicNode; /** * Parses an error control expression. * * Syntax: `@ expr` */ protected parseErrorControl(): ErrorControlNode; /** * Parses an eval expression. * * Syntax: `EVAL ( expr )` */ protected parseEval(): EvalIntrinsicNode; /** * Parses an exit intrinsic expression. * * Syntax: * - `EXIT` * - `EXIT ( )` * - `EXIT ( expr )` */ protected parseExit(): ExitIntrinsicNode; /** * Parses an expression wrapped in parenthesis. * * Syntax: `( expr )` */ protected parseExpressionGroup(): Expression; /** * Parses a flexible heredoc template. * * Syntax: * - `HEREDOC_START flexdoc-element-list HEREDOC_END` */ protected parseFlexdocTemplate(): FlexibleHeredocTemplateNode; /** * Parses a list of optional lines in a flexible heredoc template. * * Syntax: `flexdoc-element-list` * * Where `flexdoc-element-list` is: * - `flexdoc-element-list STRING_NEWLINE flexdoc-element` * - `flexdoc-element` */ protected parseFlexdocTemplateElements(): NodeList; /** * Parses a line in a flexible heredoc template. * * Syntax: * - `STRING_INDENT` * - `STRING_INDENT STRING_TEMPLATE_LITERAL` * - `STRING_INDENT string-template-list` */ protected parseFlexdocTemplateLine(): FlexibleHeredocElementNode; /** * @todo Document parseFunctionDeclarationOrClosure(). */ protected parseFunctionDeclarationOrClosure(isStatementExpected: boolean): Expression; /** * Parses a function invocation expression. * * Syntax: * - `name ( argument-list )` * - `expression ( argument-list )` * * @see PhpParser.parseMemberAccessOrInvocation() * @see PhpParser.parseScopedAccessOrInvocation() */ protected parseFunctionInvocation(reference: ExpressionNode | NameNode): FunctionInvocationNode; /** * Parses a heredoc (or nowdoc) template. * * Syntax: * - `HEREDOC_START HEREDOC_END` * - `HEREDOC_START STRING_TEMPLATE_LITERAL HEREDOC_END` * - `HEREDOC_START string-template-list HEREDOC_END` * * @see PhpParser.parseFlexdocTemplate() * @see PhpParser.parseShellCommandTemplate() * @see PhpParser.parseStringTemplate() */ protected parseHeredocTemplate(): HeredocTemplateNode; /** * Parses an instanceof expression * * Syntax: `expr INSTANCEOF class-name-reference` */ protected parseInstanceOf(leftOperand: ExpressionNode, operator: TokenNode): InstanceOfNode; /** * Parses an isset intrinsic expression. * * Syntax: `ISSET ( isset-list )` * * Where `isset-list` is: * - `isset-list , expr` * - `expr` */ protected parseIsSet(): IsSetIntrinsicNode; /** * @todo Document parseLabelOrExpression(). */ protected parseLabelOrExpression(isStatementExpected: boolean): Expression; /** * Parses a lexical variable. * * Syntax: * - `VARIABLE` * - `& VARIABLE` */ protected parseLexicalVariable(): LexicalVariableNode; /** * Parses a deconstruction (list intrinsic). * * Syntax: `LIST ( list-variables )` * * Where `list-variables` is: * - `list-variables , list-element` * - `list-element` */ protected parseListDestructure(): ListDestructureNode; /** * Parses an element of a deconstruction (list intrinsic). * * Syntax: * - `expr` * - `expr => expr` * - `list-destructure` * - `expr => list-destructure` */ protected parseListDestructureElement(): ListDestructureElementNode; /** * Parses a member access expression. * * Syntax: * - `dereferenceable -> property-name` * - `dereferenceable -> property-name ( argument-list )` * * Where `property-name` is: * - `member-name` * - `simple-variable` * - `{ expr }` * * @param {ExpressionNode} dereferenceable * An addressable expression. * @param {boolean} allowInvocation * If `true`, parse an invocation expression when possible. */ protected parseMemberAccessOrInvocation(dereferenceable: ExpressionNode, allowInvocation: boolean): MemberAccessNode | MemberInvocationNode; /** * @todo Document parseNamedExpression(). */ protected parseNamedExpression(name: NameNode): Expression; /** * @todo Document parseNamespaceDeclarationOrExpression(). */ protected parseNamespaceDeclarationOrExpression(isStatementExpected: boolean): Expression; /** * Parses an object creation (new) expression. * * Syntax: * - `NEW anonymous-class-declaration` * - `NEW class-name-reference` * - `NEW class-name-reference ( argument-list )` */ protected parseObjectCreationExpression(): ObjectCreationNode; /** * Parses a print intrinsic expression. * * Syntax: `PRINT expr` */ protected parsePrint(): PrintIntrinsicNode; /** * @todo Document parseScopedAccessOrInvocation(). */ protected parseScopedAccessOrInvocation(qualifier: ExpressionNode | NameNode, doubleColon: TokenNode): Expression; /** * Parses an import or require expression. * * Syntax: `inclusion-keyword expr` * * Where `inclusion-keyword` is: * - `INCLUDE` * - `INCLUDE_ONCE` * - `REQUIRE` * - `REQUIRE_ONCE` */ protected parseScriptInclusion(): ScriptInclusionNode; /** * Parses a shell command (backquote) template. * * Syntax: * - `BACKQUOTE BACKQUOTE` * - `BACKQUOTE STRING_TEMPLATE_LITERAL BACKQUOTE` * - `BACKQUOTE string-template-list BACKQUOTE` */ protected parseShellCommandTemplate(): ShellCommandTemplateNode; /** * Parses a simple variable. * * Syntax: * - `VARIABLE` * - `$ { expression }` * - `$ simple-variable` */ protected parseSimpleVariable(): VariableNode; /** * @todo Document parseStaticDeclartionOrExpression(). */ protected parseStaticDeclarationOrExpression(isStatementExpected: boolean): Expression; /** * Parses a single-quoted string. */ protected parseStringLiteral(): Expression; /** * Parses a double-quoted template. * * Syntax: `" string-template-list "` */ protected parseStringTemplate(): StringTemplateNode; /** * Parses an interpolation in a string template. * * Syntax: * - `string-indirection` * - `string-variable` * - `{ expr }` */ protected parseStringTemplateElement(): ExpressionNode; /** * Parses a list of literal strings and interpolations within a string template. * * Syntax: `string-template-list` * * Where `string-template-list` is: * - `string-template-list string-template-element` * - `string-template-list STRING_TEMPLATE_LITERAL` * - `string-template-element` * - `STRING_TEMPLATE_LITERAL string-template-element` * * @param {LiteralNode|null} templateLiteral * The first literal within a string template. * @param {TokenKind} terminator * The token used to terminate the string template. */ protected parseStringTemplateElementList(templateLiteral: LiteralNode | null, terminator: TokenKind): NodeList; /** * Parses an expression that is used to determine a variable name within a * string template. * * Syntax: * - `${ expr }` * - `${ STRING_IDENTIFIER }` * - `${ STRING_IDENTIFIER [ expr ] }` */ protected parseStringTemplateIndirection(): IndirectStringVariableNode; /** * Parses the text within a string template. */ protected parseStringTemplateLiteral(): LiteralNode; /** * Parses a variable within a string template. * * Syntax: * - `VARIABLE` * - `VARIABLE [ string-offset ]` * - `VARIABLE -> member-name` * * Where `string-offset` is: * - `IDENTIFIER` * - `STRING_NUMBER` * - `- STRING_NUMBER` * - `VARIABLE` */ protected parseStringTemplateVariable(): ExpressionNode; /** * Parses a yield expression. * * Syntax: * - `YIELD` * - `YIELD expr` * - `YIELD expr => expr` */ protected parseYield(): YieldNode; /** * Parses a yield from expression. * * Syntax: `YIELD FROM expr` */ protected parseYieldFrom(): YieldFromNode; /** * Gets a `ModifierFlag` for modifier keywords. */ protected getModifierFlag(kind: TokenKind): ModifierFlags; /** * Gets the precedence of a specified *binary* operator. * * @param {TokenKind} kind * An expression operator. * * @return {Precedence} * The operator's precedence or `Precedence.None` if the token is not * a known operator. */ protected getPrecedence(kind: TokenKind): Precedence; /** * Determines if the given modifier would make the declaration abstract * and private. */ protected isAbstractAndPrivate(currentFlags: ModifierFlags, modifier: ModifierFlags): boolean; /** * Determines if the specified binary operator is expected given the expression * type that has been parsed. * * @param {TokenKind} operator * A binary operator. * @param {ExpressionType} type * The expression type of the left operand. */ protected isBinaryOperatorExpected(operator: TokenKind, type: ExpressionType): boolean; /** * Determines if a parameter is entirely missing. */ protected isParameterMissing(parameter: ParameterNode): boolean; /** * Determines if the next token may start a member declaration and is on a * different line. */ protected isPossibleMemberDeclarationStart(): boolean; /** * Determines if the specified unary operator is expected given the expression * type that should be parsed. * * @param {TokenKind} operator * A unary operator. * @param {ExpressionType} type * The expected expression type. */ protected isUnaryOperatorExpected(operator: TokenKind, type: ExpressionType): boolean; /** * @todo Document skipBadArgumentListTokens(). */ protected skipBadArgumentListTokens(): void; /** * @todo Document skipBadForExpressionListTokens(). */ protected skipBadForExpressionListTokens(terminator: TokenKind): void; /** * A custom recovery strategy that matches opening and closing braces. */ protected skipBadMemberTokens(): void; /** * @todo Document skipBadParameterListTokens(). */ protected skipBadParameterListTokens(): void; /** * @todo Document skipBadStringTemplateTokens(). */ protected skipBadStringTemplateTokens(terminator: TokenKind): void; /** * @todo Document skipBadTraitUseTokens(). */ protected skipBadTraitUseTokens(): void; }