├── .codeclimate.yml ├── .coveralls.yml ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ └── test.yml ├── .gitignore ├── .husky └── pre-commit ├── .istanbul.yml ├── .jsdoc.json ├── .npmignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASE.md ├── babel.config.js ├── cachegrind.py ├── docs ├── AST.html ├── Array.html ├── Assign.html ├── Bin.html ├── Block.html ├── Boolean.html ├── Break.html ├── Call.html ├── Case.html ├── Cast.html ├── Catch.html ├── Class.html ├── ClassConstant.html ├── ClassReference.html ├── Clone.html ├── Closure.html ├── Comment.html ├── CommentBlock.html ├── CommentLine.html ├── ConstRef.html ├── Constant.html ├── ConstantStatement.html ├── Continue.html ├── Declaration.html ├── Declare.html ├── DeclareDirective.html ├── Do.html ├── Echo.html ├── Empty.html ├── Encapsed.html ├── EncapsedPart.html ├── Entry.html ├── Error.html ├── Eval.html ├── Exit.html ├── Expression.html ├── ExpressionStatement.html ├── For.html ├── Foreach.html ├── Function.html ├── Global_.html ├── Goto.html ├── Halt.html ├── Identifier.html ├── If.html ├── Include.html ├── Inline.html ├── Interface.html ├── Isset.html ├── Label.html ├── List.html ├── Literal.html ├── Location.html ├── Lookup.html ├── Magic.html ├── Method.html ├── Namespace.html ├── New.html ├── Node.html ├── Noop.html ├── NowDoc.html ├── Number.html ├── OffsetLookup.html ├── Operation.html ├── Parameter.html ├── ParentReference.html ├── Parenthesis.html ├── Position.html ├── Post.html ├── Pre.html ├── Print.html ├── Program.html ├── Property.html ├── PropertyLookup.html ├── PropertyStatement.html ├── Reference.html ├── RetIf.html ├── Return.html ├── SelfReference.html ├── Silent.html ├── Statement.html ├── Static.html ├── StaticLookup.html ├── StaticReference.html ├── StaticVariable.html ├── String.html ├── Switch.html ├── Sys.html ├── Throw.html ├── Trait.html ├── TraitAlias.html ├── TraitPrecedence.html ├── TraitUse.html ├── Try.html ├── TypeReference.html ├── Unary.html ├── Unset.html ├── UseGroup.html ├── UseItem.html ├── Variable.html ├── While.html ├── Yield.html ├── YieldFrom.html ├── ast.js.html ├── ast_array.js.html ├── ast_assign.js.html ├── ast_bin.js.html ├── ast_block.js.html ├── ast_boolean.js.html ├── ast_break.js.html ├── ast_call.js.html ├── ast_case.js.html ├── ast_cast.js.html ├── ast_catch.js.html ├── ast_class.js.html ├── ast_classconstant.js.html ├── ast_classreference.js.html ├── ast_clone.js.html ├── ast_closure.js.html ├── ast_comment.js.html ├── ast_commentblock.js.html ├── ast_commentline.js.html ├── ast_constant.js.html ├── ast_constantstatement.js.html ├── ast_constref.js.html ├── ast_continue.js.html ├── ast_declaration.js.html ├── ast_declare.js.html ├── ast_declaredirective.js.html ├── ast_do.js.html ├── ast_echo.js.html ├── ast_empty.js.html ├── ast_encapsed.js.html ├── ast_encapsedpart.js.html ├── ast_entry.js.html ├── ast_error.js.html ├── ast_eval.js.html ├── ast_exit.js.html ├── ast_expression.js.html ├── ast_expressionstatement.js.html ├── ast_for.js.html ├── ast_foreach.js.html ├── ast_function.js.html ├── ast_global.js.html ├── ast_goto.js.html ├── ast_halt.js.html ├── ast_identifier.js.html ├── ast_if.js.html ├── ast_include.js.html ├── ast_inline.js.html ├── ast_interface.js.html ├── ast_isset.js.html ├── ast_label.js.html ├── ast_list.js.html ├── ast_literal.js.html ├── ast_location.js.html ├── ast_lookup.js.html ├── ast_magic.js.html ├── ast_method.js.html ├── ast_namespace.js.html ├── ast_new.js.html ├── ast_node.js.html ├── ast_noop.js.html ├── ast_nowdoc.js.html ├── ast_number.js.html ├── ast_offsetlookup.js.html ├── ast_operation.js.html ├── ast_parameter.js.html ├── ast_parenthesis.js.html ├── ast_parentreference.js.html ├── ast_position.js.html ├── ast_post.js.html ├── ast_pre.js.html ├── ast_print.js.html ├── ast_program.js.html ├── ast_property.js.html ├── ast_propertylookup.js.html ├── ast_propertystatement.js.html ├── ast_reference.js.html ├── ast_retif.js.html ├── ast_return.js.html ├── ast_selfreference.js.html ├── ast_silent.js.html ├── ast_statement.js.html ├── ast_static.js.html ├── ast_staticlookup.js.html ├── ast_staticreference.js.html ├── ast_staticvariable.js.html ├── ast_string.js.html ├── ast_switch.js.html ├── ast_sys.js.html ├── ast_throw.js.html ├── ast_trait.js.html ├── ast_traitalias.js.html ├── ast_traitprecedence.js.html ├── ast_traituse.js.html ├── ast_try.js.html ├── ast_typereference.js.html ├── ast_unary.js.html ├── ast_unset.js.html ├── ast_usegroup.js.html ├── ast_useitem.js.html ├── ast_variable.js.html ├── ast_variadic.js.html ├── ast_while.js.html ├── ast_yield.js.html ├── ast_yieldfrom.js.html ├── engine.html ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ ├── OpenSans-Regular-webfont.woff │ ├── OpenSans-Semibold-webfont.eot │ ├── OpenSans-Semibold-webfont.svg │ ├── OpenSans-Semibold-webfont.ttf │ ├── OpenSans-Semibold-webfont.woff │ ├── OpenSans-SemiboldItalic-webfont.eot │ ├── OpenSans-SemiboldItalic-webfont.svg │ ├── OpenSans-SemiboldItalic-webfont.ttf │ └── OpenSans-SemiboldItalic-webfont.woff ├── global.html ├── icons │ ├── home.svg │ └── search.svg ├── index.html ├── index.js.html ├── lexer.html ├── lexer.js.html ├── lexer_comments.js.html ├── lexer_strings.js.html ├── parser.html ├── parser.js.html ├── parser_array.js.html ├── parser_class.js.html ├── parser_comment.js.html ├── parser_expr.js.html ├── parser_function.js.html ├── parser_if.js.html ├── parser_loops.js.html ├── parser_main.js.html ├── parser_namespace.js.html ├── parser_scalar.js.html ├── parser_statement.js.html ├── parser_switch.js.html ├── parser_try.js.html ├── parser_utils.js.html ├── parser_variable.js.html ├── scripts │ ├── linenumber.js │ └── pagelocation.js ├── styles │ ├── collapse.css │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── tokens.js.html ├── tutorial-AST_.html ├── tutorial-Engine_.html ├── tutorial-Options.html ├── tutorial-Parser_.html └── variadic.html ├── eslint.config.mjs ├── jest.config.js ├── package.json ├── src ├── ast.js ├── ast │ ├── array.js │ ├── arrowfunc.js │ ├── assign.js │ ├── assignref.js │ ├── attrgroup.js │ ├── attribute.js │ ├── bin.js │ ├── block.js │ ├── boolean.js │ ├── break.js │ ├── byref.js │ ├── call.js │ ├── case.js │ ├── cast.js │ ├── catch.js │ ├── class.js │ ├── classconstant.js │ ├── clone.js │ ├── closure.js │ ├── comment.js │ ├── commentblock.js │ ├── commentline.js │ ├── constant.js │ ├── constantstatement.js │ ├── continue.js │ ├── declaration.js │ ├── declare.js │ ├── declaredirective.js │ ├── do.js │ ├── echo.js │ ├── empty.js │ ├── encapsed.js │ ├── encapsedpart.js │ ├── entry.js │ ├── enum.js │ ├── enumcase.js │ ├── error.js │ ├── eval.js │ ├── exit.js │ ├── expression.js │ ├── expressionstatement.js │ ├── for.js │ ├── foreach.js │ ├── function.js │ ├── global.js │ ├── goto.js │ ├── halt.js │ ├── identifier.js │ ├── if.js │ ├── include.js │ ├── inline.js │ ├── interface.js │ ├── intersectiontype.js │ ├── isset.js │ ├── label.js │ ├── list.js │ ├── literal.js │ ├── location.js │ ├── lookup.js │ ├── magic.js │ ├── match.js │ ├── matcharm.js │ ├── method.js │ ├── name.js │ ├── namedargument.js │ ├── namespace.js │ ├── new.js │ ├── node.js │ ├── noop.js │ ├── nowdoc.js │ ├── nullkeyword.js │ ├── nullsafepropertylookup.js │ ├── number.js │ ├── offsetlookup.js │ ├── operation.js │ ├── parameter.js │ ├── parentreference.js │ ├── position.js │ ├── post.js │ ├── pre.js │ ├── print.js │ ├── program.js │ ├── property.js │ ├── propertylookup.js │ ├── propertystatement.js │ ├── reference.js │ ├── retif.js │ ├── return.js │ ├── selfreference.js │ ├── silent.js │ ├── statement.js │ ├── static.js │ ├── staticlookup.js │ ├── staticreference.js │ ├── staticvariable.js │ ├── string.js │ ├── switch.js │ ├── throw.js │ ├── trait.js │ ├── traitalias.js │ ├── traitprecedence.js │ ├── traituse.js │ ├── try.js │ ├── typereference.js │ ├── unary.js │ ├── uniontype.js │ ├── unset.js │ ├── usegroup.js │ ├── useitem.js │ ├── variable.js │ ├── variadic.js │ ├── variadicplaceholder.js │ ├── while.js │ ├── yield.js │ └── yieldfrom.js ├── index.js ├── lexer.js ├── lexer │ ├── attribute.js │ ├── comments.js │ ├── initial.js │ ├── numbers.js │ ├── property.js │ ├── scripting.js │ ├── strings.js │ ├── tokens.js │ └── utils.js ├── parser.js ├── parser │ ├── array.js │ ├── class.js │ ├── comment.js │ ├── enum.js │ ├── expr.js │ ├── function.js │ ├── if.js │ ├── loops.js │ ├── main.js │ ├── namespace.js │ ├── scalar.js │ ├── statement.js │ ├── switch.js │ ├── try.js │ ├── utils.js │ └── variable.js └── tokens.js ├── test ├── ast.test.js ├── benchmark.js ├── benchmark2.js ├── debug.js ├── location.test.js ├── main.js ├── precedence.test.js ├── snapshot │ ├── __snapshots__ │ │ ├── acid.test.js.snap │ │ ├── array.test.js.snap │ │ ├── arrowfunc.test.js.snap │ │ ├── assign.test.js.snap │ │ ├── ast.test.js.snap │ │ ├── attributes.test.js.snap │ │ ├── bin.test.js.snap │ │ ├── block.test.js.snap │ │ ├── boolean.test.js.snap │ │ ├── break.test.js.snap │ │ ├── buffer.test.js.snap │ │ ├── byref.test.js.snap │ │ ├── call.test.js.snap │ │ ├── class.test.js.snap │ │ ├── classconstant.test.js.snap │ │ ├── classreference.test.js.snap │ │ ├── clone.test.js.snap │ │ ├── closure.test.js.snap │ │ ├── comment.test.js.snap │ │ ├── constantstatement.test.js.snap │ │ ├── continue.test.js.snap │ │ ├── declare.test.js.snap │ │ ├── echo.test.js.snap │ │ ├── empty.test.js.snap │ │ ├── encapsed.test.js.snap │ │ ├── enum.test.js.snap │ │ ├── eval.test.js.snap │ │ ├── exit.test.js.snap │ │ ├── expr.test.js.snap │ │ ├── foreach.test.js.snap │ │ ├── function.test.js.snap │ │ ├── global.test.js.snap │ │ ├── goto.test.js.snap │ │ ├── graceful.test.js.snap │ │ ├── heredoc.test.js.snap │ │ ├── if.test.js.snap │ │ ├── include.test.js.snap │ │ ├── interface.test.js.snap │ │ ├── isset.test.js.snap │ │ ├── label.test.js.snap │ │ ├── lexer.test.js.snap │ │ ├── list.test.js.snap │ │ ├── location.test.js.snap │ │ ├── loop.test.js.snap │ │ ├── magic.test.js.snap │ │ ├── match.test.js.snap │ │ ├── namespace.test.js.snap │ │ ├── new.test.js.snap │ │ ├── nowdoc.test.js.snap │ │ ├── nullsavepropertylookup.test.js.snap │ │ ├── number.test.js.snap │ │ ├── offsetlookup.test.js.snap │ │ ├── parentreference.test.js.snap │ │ ├── php5.test.js.snap │ │ ├── php73.test.js.snap │ │ ├── post.test.js.snap │ │ ├── pre.test.js.snap │ │ ├── print.test.js.snap │ │ ├── property.test.js.snap │ │ ├── propertylookup.test.js.snap │ │ ├── propertystatement.test.js.snap │ │ ├── return.test.js.snap │ │ ├── scalar.test.js.snap │ │ ├── selfreference.test.js.snap │ │ ├── silent.test.js.snap │ │ ├── statement.test.js.snap │ │ ├── static.test.js.snap │ │ ├── staticlookup.test.js.snap │ │ ├── staticreference.test.js.snap │ │ ├── string.test.js.snap │ │ ├── switch.test.js.snap │ │ ├── throw.test.js.snap │ │ ├── token.test.js.snap │ │ ├── trait.test.js.snap │ │ ├── traitprecedence.test.js.snap │ │ ├── try.test.js.snap │ │ ├── typereference.test.js.snap │ │ ├── unary.test.js.snap │ │ ├── union.test.js.snap │ │ ├── unset.test.js.snap │ │ ├── usegroup.test.js.snap │ │ ├── useitem.test.js.snap │ │ ├── variable.test.js.snap │ │ ├── yield.test.js.snap │ │ └── yieldfrom.test.js.snap │ ├── acid.test.js │ ├── array.test.js │ ├── arrowfunc.test.js │ ├── assign.test.js │ ├── ast.test.js │ ├── attributes.test.js │ ├── bin.test.js │ ├── block.test.js │ ├── boolean.test.js │ ├── break.test.js │ ├── buffer.test.js │ ├── byref.test.js │ ├── call.test.js │ ├── class.test.js │ ├── classconstant.test.js │ ├── classreference.test.js │ ├── clone.test.js │ ├── closure.test.js │ ├── comment.test.js │ ├── constantstatement.test.js │ ├── continue.test.js │ ├── declare.test.js │ ├── echo.test.js │ ├── empty.test.js │ ├── encapsed.test.js │ ├── enum.test.js │ ├── eval.test.js │ ├── exit.test.js │ ├── expr.test.js │ ├── foreach.test.js │ ├── function.test.js │ ├── global.test.js │ ├── goto.test.js │ ├── graceful.test.js │ ├── heredoc.test.js │ ├── if.test.js │ ├── include.test.js │ ├── interface.test.js │ ├── isset.test.js │ ├── label.test.js │ ├── lexer.test.js │ ├── list.test.js │ ├── location.test.js │ ├── loop.test.js │ ├── magic.test.js │ ├── match.test.js │ ├── namespace.test.js │ ├── new.test.js │ ├── nowdoc.test.js │ ├── nullsavepropertylookup.test.js │ ├── number.test.js │ ├── offsetlookup.test.js │ ├── parentreference.test.js │ ├── php5.test.js │ ├── php73.test.js │ ├── post.test.js │ ├── pre.test.js │ ├── print.test.js │ ├── property.test.js │ ├── propertylookup.test.js │ ├── propertystatement.test.js │ ├── return.test.js │ ├── scalar.test.js │ ├── selfreference.test.js │ ├── silent.test.js │ ├── statement.test.js │ ├── static.test.js │ ├── staticlookup.test.js │ ├── staticreference.test.js │ ├── string.test.js │ ├── switch.test.js │ ├── throw.test.js │ ├── token.test.js │ ├── trait.test.js │ ├── traitprecedence.test.js │ ├── try.test.js │ ├── typereference.test.js │ ├── unary.test.js │ ├── union.test.js │ ├── unset.test.js │ ├── usegroup.test.js │ ├── useitem.test.js │ ├── variable.test.js │ ├── yield.test.js │ └── yieldfrom.test.js └── version.test.js ├── tutorials ├── AST.md ├── Engine.md ├── Options.md └── Parser.md ├── types.d.ts ├── webpack.config.js └── yarn.lock /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | exclude_patterns: 2 | - "coverage/" 3 | - "node_modules/" 4 | - "test/" 5 | - "tutorials/" 6 | - "docs/" 7 | - "dist/" 8 | - "example/" 9 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: de6RJbSSDNAPxIegg5fAEjIPHRrVhxRiF -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: ichiriac # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ${{ matrix.os }} 8 | 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest] 12 | node-version: [18.x, 20.x, 22.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | 22 | - name: npm install, test 23 | run: | 24 | yarn 25 | yarn test 26 | 27 | - name: type check 28 | run: | 29 | yarn build-types 30 | [ $(git diff types.d.ts | wc -l) -gt 0 ] && echo 'Diff exists in types.d.ts. Please change jsdoc.' && exit 1 31 | tsc --noEmit types.d.ts 32 | 33 | - name: install valgrind 34 | run: sudo apt-get install -y valgrind 35 | 36 | - name: benchmark 37 | run: python cachegrind.py node test/benchmark2.js > output.txt 38 | 39 | - name: Download previous benchmark result 40 | uses: actions/cache@v1 41 | with: 42 | path: ./cache 43 | key: ${{ runner.os }}-${{matrix.node-version}}-benchmark 44 | 45 | - name: Store benchmark result 46 | uses: benchmark-action/github-action-benchmark@v1 47 | with: 48 | tool: "customSmallerIsBetter" 49 | output-file-path: output.txt 50 | external-data-json-path: ./cache/benchmark-data.json 51 | alert-threshold: "105%" 52 | fail-on-alert: true 53 | env: 54 | CI: true 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /.project 3 | /npm-debug.log 4 | /nbproject 5 | /coverage 6 | /.vscode 7 | /vendor 8 | /dist 9 | *.swp 10 | composer.lock 11 | composer.json 12 | .idea/ 13 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | yarpm test 2 | -------------------------------------------------------------------------------- /.istanbul.yml: -------------------------------------------------------------------------------- 1 | verbose: false 2 | instrumentation: 3 | root: . 4 | extensions: 5 | - .js 6 | default-excludes: true 7 | excludes: [] 8 | embed-source: false 9 | variable: __coverage__ 10 | compact: true 11 | preserve-comments: false 12 | complete-copy: false 13 | save-baseline: false 14 | baseline-file: ./coverage/coverage-baseline.json 15 | include-all-sources: false 16 | include-pid: false 17 | reporting: 18 | print: summary 19 | reports: 20 | - lcov 21 | dir: ./coverage 22 | watermarks: 23 | statements: [50, 80] 24 | lines: [50, 80] 25 | functions: [50, 80] 26 | branches: [50, 80] 27 | report-config: 28 | clover: {file: clover.xml} 29 | cobertura: {file: cobertura-coverage.xml} 30 | json: {file: coverage-final.json} 31 | json-summary: {file: coverage-summary.json} 32 | lcovonly: {file: lcov.info} 33 | teamcity: {file: null, blockName: Code Coverage Summary} 34 | text: {file: null, maxCols: 0} 35 | text-lcov: {file: lcov.info} 36 | text-summary: {file: null} 37 | hooks: 38 | hook-run-in-context: false 39 | post-require-hook: null 40 | handle-sigint: false 41 | check: 42 | global: 43 | statements: 0 44 | lines: 0 45 | branches: 0 46 | functions: 0 47 | excludes: [] 48 | each: 49 | statements: 0 50 | lines: 0 51 | branches: 0 52 | functions: 0 53 | excludes: [] -------------------------------------------------------------------------------- /.jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true 4 | }, 5 | "source": { 6 | "include": ["src"], 7 | "includePattern": ".+\\.js(doc|x)?$", 8 | "excludePattern": "(^|\\/|\\\\)_" 9 | }, 10 | "plugins": ["plugins/markdown"], 11 | "markdown": { 12 | "idInHeadings": true 13 | }, 14 | "templates": { 15 | "referenceTitle": "php-parser", 16 | "cleverLinks": true, 17 | "monospaceLinks": true, 18 | "default": { 19 | "outputSourceFiles": true 20 | }, 21 | "search": { 22 | "apiKey": "d7422763b31425c3da8b220f22ff04d2", 23 | "indexName": "glayzzle" 24 | } 25 | }, 26 | "opts": { 27 | "template": "./node_modules/jsdoc-template/", 28 | "tutorials": "tutorials", 29 | "destination": "docs", 30 | "readme": "README.md", 31 | "recurse": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /docs/ 2 | /test/ 3 | /example/ 4 | /tutorials/ 5 | /coverage/ 6 | /.vscode/ 7 | /.babelrc 8 | /.codeclimate.yml 9 | /.coveralls.yml 10 | /.eslintrc.js 11 | /.eslintignore 12 | /.jsdoc.json 13 | /.istanbul.yml 14 | /.travis.yml 15 | /webpack.config.js -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Everyone is welcome to contribute, just use the same coding style, and cover with tests your code. 2 | 3 | Any PR is welcomed :) 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Glayzzle 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of test-bsd nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | 4 | const presets = ["@babel/preset-env"]; 5 | const plugins = []; 6 | 7 | return { 8 | presets, 9 | plugins, 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Semibold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-Semibold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-SemiboldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/glayzzle/php-parser/c702357f7435af363051a947b64d1e064cca014b/docs/fonts/OpenSans-SemiboldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* global document */ 4 | (function () { 5 | var lineId, lines, totalLines, anchorHash; 6 | var source = document.getElementsByClassName('prettyprint source linenums'); 7 | var i = 0; 8 | var lineNumber = 0; 9 | 10 | if (source && source[0]) { 11 | anchorHash = document.location.hash.substring(1); 12 | lines = source[0].getElementsByTagName('li'); 13 | totalLines = lines.length; 14 | 15 | for (; i < totalLines; i++) { 16 | lineNumber++; 17 | lineId = 'line' + lineNumber; 18 | lines[i].id = lineId; 19 | if (lineId === anchorHash) { 20 | lines[i].className += ' selected'; 21 | } 22 | } 23 | } 24 | })(); 25 | -------------------------------------------------------------------------------- /docs/styles/collapse.css: -------------------------------------------------------------------------------- 1 | @media only screen and (min-width: 681px) { 2 | nav > ul > li:hover .methods, 3 | .active .methods { 4 | display: block; 5 | } 6 | 7 | .methods { 8 | display: none; 9 | } 10 | 11 | nav > ul > li { 12 | padding: 20px 0; 13 | } 14 | 15 | nav > ul > li > a { 16 | padding: 0; 17 | } 18 | 19 | nav > ul > li.active a { 20 | margin-bottom: 10px; 21 | } 22 | 23 | nav > ul > li:hover > a, 24 | nav > ul > li.active > a { 25 | margin-bottom: 15px; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: hsl(104, 100%, 24%); 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import jest from "eslint-plugin-jest"; 3 | import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; 4 | import globals from "globals"; 5 | 6 | export default [ 7 | { 8 | ignores: ["dist", "docs", "example", "tutorials"], 9 | }, 10 | js.configs.recommended, 11 | { 12 | files: ["test/**"], 13 | ...jest.configs["flat/recommended"], 14 | rules: { 15 | ...jest.configs["flat/recommended"].rules, 16 | "no-console": "off", 17 | }, 18 | languageOptions: { 19 | globals: jest.environments.globals.globals, 20 | }, 21 | }, 22 | { 23 | languageOptions: { 24 | globals: { 25 | ...globals.browser, 26 | ...globals.node, 27 | }, 28 | sourceType: "commonjs", 29 | }, 30 | 31 | rules: { 32 | "prefer-const": "error", 33 | "no-var": "error", 34 | curly: ["error", "multi-line"], 35 | }, 36 | }, 37 | eslintPluginPrettierRecommended, 38 | ]; 39 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const ENABLE_COVERAGE = !!process.env.CI || !!process.env.COVERAGE; 4 | 5 | module.exports = { 6 | collectCoverage: ENABLE_COVERAGE, 7 | coverageDirectory: "coverage/", 8 | coverageThreshold: { 9 | global: { 10 | statements: 96.4, 11 | branches: 90.1, 12 | functions: 99.4, 13 | lines: 96.9, 14 | }, 15 | }, 16 | projects: [ 17 | { 18 | displayName: "test", 19 | testEnvironment: "node", 20 | }, 21 | { 22 | runner: "jest-runner-eslint", 23 | displayName: "lint", 24 | testMatch: ["/**/*.js"], 25 | testPathIgnorePatterns: [ 26 | "/node_modules/", 27 | "/coverage/", 28 | ], 29 | }, 30 | ], 31 | }; 32 | -------------------------------------------------------------------------------- /src/ast/array.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expr = require("./expression"); 9 | const KIND = "array"; 10 | 11 | /** 12 | * Defines an array structure 13 | * @constructor Array 14 | * @memberOf module:php-parser 15 | * @example 16 | * // PHP code : 17 | * [1, 'foo' => 'bar', 3] 18 | * 19 | * // AST structure : 20 | * { 21 | * "kind": "array", 22 | * "shortForm": true 23 | * "items": [ 24 | * {"kind": "number", "value": "1"}, 25 | * { 26 | * "kind": "entry", 27 | * "key": {"kind": "string", "value": "foo", "isDoubleQuote": false}, 28 | * "value": {"kind": "string", "value": "bar", "isDoubleQuote": false} 29 | * }, 30 | * {"kind": "number", "value": "3"} 31 | * ] 32 | * } 33 | * @extends {Expression} 34 | * @property {Array} items List of array items 35 | * @property {boolean} shortForm Indicate if the short array syntax is used, ex `[]` instead `array()` 36 | */ 37 | module.exports = Expr.extends( 38 | KIND, 39 | function Array(shortForm, items, docs, location) { 40 | Expr.apply(this, [KIND, docs, location]); 41 | this.items = items; 42 | this.shortForm = shortForm; 43 | }, 44 | ); 45 | -------------------------------------------------------------------------------- /src/ast/arrowfunc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "arrowfunc"; 10 | 11 | /** 12 | * Defines an arrow function (it's like a closure) 13 | * @constructor ArrowFunc 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Parameter[]} arguments 17 | * @property {Identifier} type 18 | * @property {Expression} body 19 | * @property {boolean} byref 20 | * @property {boolean} nullable 21 | * @property {boolean} isStatic 22 | */ 23 | module.exports = Expression.extends( 24 | KIND, 25 | function Closure( 26 | args, 27 | byref, 28 | body, 29 | type, 30 | nullable, 31 | isStatic, 32 | docs, 33 | location, 34 | ) { 35 | Expression.apply(this, [KIND, docs, location]); 36 | this.arguments = args; 37 | this.byref = byref; 38 | this.body = body; 39 | this.type = type; 40 | this.nullable = nullable; 41 | this.isStatic = isStatic || false; 42 | }, 43 | ); 44 | -------------------------------------------------------------------------------- /src/ast/assign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "assign"; 10 | 11 | /** 12 | * Assigns a value to the specified target 13 | * @constructor Assign 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} left 17 | * @property {Expression} right 18 | * @property {String} operator 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function Assign(left, right, operator, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.left = left; 25 | this.right = right; 26 | this.operator = operator; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/assignref.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "assignref"; 10 | 11 | /** 12 | * Assigns a value to the specified target 13 | * @constructor AssignRef 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} left 17 | * @property {Expression} right 18 | * @property {String} operator 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function AssignRef(left, right, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.left = left; 25 | this.right = right; 26 | }, 27 | ); 28 | -------------------------------------------------------------------------------- /src/ast/attrgroup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "attrgroup"; 10 | 11 | /** 12 | * Attribute group 13 | * @memberOf module:php-parser 14 | * @constructor AttrGroup 15 | * @extends {Node} 16 | * @property {Attribute[]} attrs 17 | */ 18 | module.exports = Node.extends(KIND, function AttrGroup(attrs, docs, location) { 19 | Node.apply(this, [KIND, docs, location]); 20 | this.attrs = attrs || []; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/attribute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "attribute"; 10 | 11 | /** 12 | * Attribute Value 13 | * @memberOf module:php-parser 14 | * @constructor Attribute 15 | * @extends {Node} 16 | * @property {String} name 17 | * @property {Parameter[]} args 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function Attribute(name, args, docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | this.name = name; 24 | this.args = args; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/bin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Operation = require("./operation"); 9 | const KIND = "bin"; 10 | /** 11 | * Binary operations 12 | * @constructor Bin 13 | * @memberOf module:php-parser 14 | * @extends {Operation} 15 | * @property {String} type 16 | * @property {Expression} left 17 | * @property {Expression} right 18 | */ 19 | module.exports = Operation.extends( 20 | KIND, 21 | function Bin(type, left, right, docs, location) { 22 | Operation.apply(this, [KIND, docs, location]); 23 | this.type = type; 24 | this.left = left; 25 | this.right = right; 26 | }, 27 | ); 28 | -------------------------------------------------------------------------------- /src/ast/block.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "block"; 10 | 11 | /** 12 | * A block statement, i.e., a sequence of statements surrounded by braces. 13 | * @constructor Block 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Node[]} children 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function Block(kind, children, docs, location) { 21 | Statement.apply(this, [kind || KIND, docs, location]); 22 | this.children = children.filter(Boolean); 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/boolean.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "boolean"; 10 | 11 | /** 12 | * Defines a boolean value (true/false) 13 | * @constructor Boolean 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | * @property {boolean} value 17 | */ 18 | module.exports = Literal.extends( 19 | KIND, 20 | function Boolean(value, raw, docs, location) { 21 | Literal.apply(this, [KIND, value, raw, docs, location]); 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/break.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "break"; 10 | 11 | /** 12 | * A break statement 13 | * @constructor Break 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Number|Null} level 17 | */ 18 | module.exports = Statement.extends(KIND, function Break(level, docs, location) { 19 | Statement.apply(this, [KIND, docs, location]); 20 | this.level = level; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/byref.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "byref"; 10 | 11 | /** 12 | * Passing by Reference - so the function can modify the variable 13 | * @constructor ByRef 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {ExpressionStatement} what 17 | */ 18 | module.exports = Expression.extends(KIND, function ByRef(what, docs, location) { 19 | Expression.apply(this, [KIND, docs, location]); 20 | this.what = what; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/call.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "call"; 10 | 11 | /** 12 | * Executes a call statement 13 | * @constructor Call 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Identifier|Variable} what 17 | * @property {Expression[]} arguments 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function Call(what, args, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.what = what; 24 | this.arguments = args; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/case.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "case"; 10 | 11 | /** 12 | * A switch case statement 13 | * @constructor Case 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression|null} test - if null, means that the default case 17 | * @property {Block|null} body 18 | */ 19 | module.exports = Statement.extends( 20 | KIND, 21 | function Case(test, body, docs, location) { 22 | Statement.apply(this, [KIND, docs, location]); 23 | this.test = test; 24 | this.body = body; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/cast.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Operation = require("./operation"); 9 | const KIND = "cast"; 10 | 11 | /** 12 | * Binary operations 13 | * @constructor Cast 14 | * @memberOf module:php-parser 15 | * @extends {Operation} 16 | * @property {String} type 17 | * @property {String} raw 18 | * @property {Expression} expr 19 | */ 20 | module.exports = Operation.extends( 21 | KIND, 22 | function Cast(type, raw, expr, docs, location) { 23 | Operation.apply(this, [KIND, docs, location]); 24 | this.type = type; 25 | this.raw = raw; 26 | this.expr = expr; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/catch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "catch"; 10 | 11 | /** 12 | * Defines a catch statement 13 | * @constructor Catch 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Name[]} what 17 | * @property {Variable} variable 18 | * @property {Block} body 19 | * @see http://php.net/manual/en/language.exceptions.php 20 | */ 21 | module.exports = Statement.extends( 22 | KIND, 23 | function Catch(body, what, variable, docs, location) { 24 | Statement.apply(this, [KIND, docs, location]); 25 | this.body = body; 26 | this.what = what; 27 | this.variable = variable; 28 | }, 29 | ); 30 | -------------------------------------------------------------------------------- /src/ast/class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "class"; 10 | 11 | /** 12 | * A class definition 13 | * @constructor Class 14 | * @memberOf module:php-parser 15 | * @extends {Declaration} 16 | * @property {Identifier|null} extends 17 | * @property {Identifier[]|null} implements 18 | * @property {Declaration[]} body 19 | * @property {boolean} isAnonymous 20 | * @property {boolean} isAbstract 21 | * @property {boolean} isFinal 22 | * @property {boolean} isReadonly 23 | * @property {AttrGroup[]} attrGroups 24 | */ 25 | module.exports = Declaration.extends( 26 | KIND, 27 | function Class(name, ext, impl, body, flags, docs, location) { 28 | Declaration.apply(this, [KIND, name, docs, location]); 29 | this.isAnonymous = name ? false : true; 30 | this.extends = ext; 31 | this.implements = impl; 32 | this.body = body; 33 | this.attrGroups = []; 34 | this.parseFlags(flags); 35 | }, 36 | ); 37 | -------------------------------------------------------------------------------- /src/ast/classconstant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const ConstantStatement = require("./constantstatement"); 9 | const KIND = "classconstant"; 10 | 11 | const IS_UNDEFINED = ""; 12 | const IS_PUBLIC = "public"; 13 | const IS_PROTECTED = "protected"; 14 | const IS_PRIVATE = "private"; 15 | 16 | /** 17 | * Defines a class/interface/trait constant 18 | * @constructor ClassConstant 19 | * @memberOf module:php-parser 20 | * @extends {ConstantStatement} 21 | * @property {string} visibility 22 | * @property {boolean} final 23 | * @property {boolean} nullable 24 | * @property {TypeReference|IntersectionType|UnionType|null} type 25 | * @property {AttrGroup[]} attrGroups 26 | */ 27 | const ClassConstant = ConstantStatement.extends( 28 | KIND, 29 | function ClassConstant( 30 | kind, 31 | constants, 32 | flags, 33 | nullable, 34 | type, 35 | attrGroups, 36 | docs, 37 | location, 38 | ) { 39 | ConstantStatement.apply(this, [kind || KIND, constants, docs, location]); 40 | this.parseFlags(flags); 41 | this.nullable = nullable; 42 | this.type = type; 43 | this.attrGroups = attrGroups; 44 | }, 45 | ); 46 | 47 | /** 48 | * Generic flags parser 49 | * @function 50 | * @name ClassConstant#parseFlags 51 | * @memberOf module:php-parser 52 | * @param {Array} flags 53 | * @return {void} 54 | */ 55 | ClassConstant.prototype.parseFlags = function (flags) { 56 | if (flags[0] === -1) { 57 | this.visibility = IS_UNDEFINED; 58 | } else if (flags[0] === null) { 59 | /* istanbul ignore next */ 60 | this.visibility = null; 61 | } else if (flags[0] === 0) { 62 | this.visibility = IS_PUBLIC; 63 | } else if (flags[0] === 1) { 64 | this.visibility = IS_PROTECTED; 65 | } else if (flags[0] === 2) { 66 | this.visibility = IS_PRIVATE; 67 | } 68 | this.final = flags[2] === 2; 69 | }; 70 | 71 | module.exports = ClassConstant; 72 | -------------------------------------------------------------------------------- /src/ast/clone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "clone"; 10 | 11 | /** 12 | * Defines a clone call 13 | * @constructor Clone 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} what 17 | */ 18 | module.exports = Expression.extends(KIND, function Clone(what, docs, location) { 19 | Expression.apply(this, [KIND, docs, location]); 20 | this.what = what; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/closure.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "closure"; 10 | 11 | /** 12 | * Defines a closure 13 | * @constructor Closure 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Parameter[]} arguments 17 | * @property {Variable[]} uses 18 | * @property {Identifier} type 19 | * @property {Boolean} byref 20 | * @property {boolean} nullable 21 | * @property {Block|null} body 22 | * @property {boolean} isStatic 23 | * @property {AttrGroup[]} attrGroups 24 | */ 25 | module.exports = Expression.extends( 26 | KIND, 27 | function Closure( 28 | args, 29 | byref, 30 | uses, 31 | type, 32 | nullable, 33 | isStatic, 34 | docs, 35 | location, 36 | ) { 37 | Expression.apply(this, [KIND, docs, location]); 38 | this.uses = uses; 39 | this.arguments = args; 40 | this.byref = byref; 41 | this.type = type; 42 | this.nullable = nullable; 43 | this.isStatic = isStatic || false; 44 | this.body = null; 45 | this.attrGroups = []; 46 | }, 47 | ); 48 | -------------------------------------------------------------------------------- /src/ast/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | 10 | /** 11 | * Abstract documentation node (ComentLine or CommentBlock) 12 | * @constructor Comment 13 | * @memberOf module:php-parser 14 | * @extends {Node} 15 | * @property {String} value 16 | */ 17 | module.exports = Node.extends( 18 | "comment", 19 | function Comment(kind, value, docs, location) { 20 | Node.apply(this, [kind, docs, location]); 21 | this.value = value; 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/commentblock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Comment = require("./comment"); 9 | const KIND = "commentblock"; 10 | 11 | /** 12 | * A comment block (multiline) 13 | * @constructor CommentBlock 14 | * @memberOf module:php-parser 15 | * @extends {Comment} 16 | */ 17 | module.exports = Comment.extends( 18 | KIND, 19 | function CommentBlock(value, docs, location) { 20 | Comment.apply(this, [KIND, value, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/commentline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Comment = require("./comment"); 9 | const KIND = "commentline"; 10 | 11 | /** 12 | * A single line comment 13 | * @constructor CommentLine 14 | * @memberOf module:php-parser 15 | * @extends {Comment} 16 | */ 17 | module.exports = Comment.extends( 18 | KIND, 19 | function CommentLine(value, docs, location) { 20 | Comment.apply(this, [KIND, value, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/constant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "constant"; 10 | 11 | /** 12 | * Defines a constant 13 | * @constructor Constant 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {string} name 17 | * @property {Node|string|number|boolean|null} value 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function Constant(name, value, docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | this.name = name; 24 | this.value = value; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/constantstatement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "constantstatement"; 10 | 11 | /** 12 | * Declares a constants into the current scope 13 | * @constructor ConstantStatement 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Constant[]} constants 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function ConstantStatement(kind, constants, docs, location) { 21 | Statement.apply(this, [kind || KIND, docs, location]); 22 | this.constants = constants; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/continue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "continue"; 10 | 11 | /** 12 | * A continue statement 13 | * @constructor Continue 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {number|null} level 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function Continue(level, docs, location) { 21 | Statement.apply(this, [KIND, docs, location]); 22 | this.level = level; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "declaration"; 10 | 11 | const IS_UNDEFINED = ""; 12 | const IS_PUBLIC = "public"; 13 | const IS_PROTECTED = "protected"; 14 | const IS_PRIVATE = "private"; 15 | 16 | /** 17 | * A declaration statement (function, class, interface...) 18 | * @constructor Declaration 19 | * @memberOf module:php-parser 20 | * @extends {Statement} 21 | * @property {Identifier|string} name 22 | */ 23 | const Declaration = Statement.extends( 24 | KIND, 25 | function Declaration(kind, name, docs, location) { 26 | Statement.apply(this, [kind || KIND, docs, location]); 27 | this.name = name; 28 | }, 29 | ); 30 | 31 | /** 32 | * Generic flags parser 33 | * @function 34 | * @name Declaration#parseFlags 35 | * @memberOf module:php-parser 36 | * @param {Array} flags 37 | * @return {void} 38 | */ 39 | Declaration.prototype.parseFlags = function (flags) { 40 | this.isAbstract = flags[2] === 1; 41 | this.isFinal = flags[2] === 2; 42 | this.isReadonly = flags[3] === 1; 43 | if (this.kind !== "class") { 44 | if (flags[0] === -1) { 45 | this.visibility = IS_UNDEFINED; 46 | } else if (flags[0] === null) { 47 | /* istanbul ignore next */ 48 | this.visibility = null; 49 | } else if (flags[0] === 0) { 50 | this.visibility = IS_PUBLIC; 51 | } else if (flags[0] === 1) { 52 | this.visibility = IS_PROTECTED; 53 | } else if (flags[0] === 2) { 54 | this.visibility = IS_PRIVATE; 55 | } 56 | this.isStatic = flags[1] === 1; 57 | } 58 | }; 59 | 60 | module.exports = Declaration; 61 | -------------------------------------------------------------------------------- /src/ast/declare.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Block = require("./block"); 9 | const KIND = "declare"; 10 | 11 | /** 12 | * The declare construct is used to set execution directives for a block of code 13 | * @constructor Declare 14 | * @memberOf module:php-parser 15 | * @extends {Block} 16 | * @property {DeclareDirective[]} directives 17 | * @property {string} mode 18 | * @see http://php.net/manual/en/control-structures.declare.php 19 | */ 20 | const Declare = Block.extends( 21 | KIND, 22 | function Declare(directives, body, mode, docs, location) { 23 | Block.apply(this, [KIND, body, docs, location]); 24 | this.directives = directives; 25 | this.mode = mode; 26 | }, 27 | ); 28 | 29 | /** 30 | * The node is declared as a short tag syntax : 31 | * ```php 32 | * bar_$baz; 69 | * ``` 70 | * @constant {String} Encapsed#TYPE_OFFSET - `offset` 71 | * @memberOf module:php-parser 72 | */ 73 | Encapsed.TYPE_OFFSET = "offset"; 74 | 75 | module.exports = Encapsed; 76 | -------------------------------------------------------------------------------- /src/ast/encapsedpart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "encapsedpart"; 10 | 11 | /** 12 | * Part of `Encapsed` node 13 | * @constructor EncapsedPart 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} expression 17 | * @property {String} syntax 18 | * @property {Boolean} curly 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function EncapsedPart(expression, syntax, curly, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.expression = expression; 25 | this.syntax = syntax; 26 | this.curly = curly; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/entry.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "entry"; 10 | 11 | /** 12 | * An array entry - see [Array](#array) 13 | * @memberOf module:php-parser 14 | * @constructor Entry 15 | * @extends {Expression} 16 | * @property {Node|null} key The entry key/offset 17 | * @property {Node} value The entry value 18 | * @property {Boolean} byRef By reference 19 | * @property {Boolean} unpack Argument unpacking 20 | */ 21 | module.exports = Expression.extends( 22 | KIND, 23 | function Entry(key, value, byRef, unpack, docs, location) { 24 | Expression.apply(this, [KIND, docs, location]); 25 | this.key = key; 26 | this.value = value; 27 | this.byRef = byRef; 28 | this.unpack = unpack; 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/ast/enum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "enum"; 10 | 11 | /** 12 | * A enum definition 13 | * @constructor Enum 14 | * @memberOf module:php-parser 15 | * @extends {Declaration} 16 | * @property {Identifier|null} valueType 17 | * @property {Identifier[]} implements 18 | * @property {Declaration[]} body 19 | * @property {AttrGroup[]} attrGroups 20 | */ 21 | module.exports = Declaration.extends( 22 | KIND, 23 | function Enum(name, valueType, impl, body, docs, location) { 24 | Declaration.apply(this, [KIND, name, docs, location]); 25 | this.valueType = valueType; 26 | this.implements = impl; 27 | this.body = body; 28 | this.attrGroups = []; 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/ast/enumcase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "enumcase"; 10 | 11 | /** 12 | * Declares a cases into the current scope 13 | * @constructor EnumCase 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {string} name 17 | * @property {string|number|null} value 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function EnumCase(name, value, docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | this.name = name; 24 | this.value = value; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/error.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "error"; 10 | 11 | /** 12 | * Defines an error node (used only on silentMode) 13 | * @constructor Error 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {string} message 17 | * @property {number} line 18 | * @property {number|string} token 19 | * @property {string|array} expected 20 | */ 21 | module.exports = Node.extends( 22 | KIND, 23 | function Error(message, token, line, expected, docs, location) { 24 | Node.apply(this, [KIND, docs, location]); 25 | this.message = message; 26 | this.token = token; 27 | this.line = line; 28 | this.expected = expected; 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/ast/eval.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "eval"; 10 | 11 | /** 12 | * Defines an eval statement 13 | * @constructor Eval 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Node} source 17 | */ 18 | module.exports = Expression.extends( 19 | KIND, 20 | function Eval(source, docs, location) { 21 | Expression.apply(this, [KIND, docs, location]); 22 | this.source = source; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/exit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "exit"; 10 | 11 | /** 12 | * Defines an exit / die call 13 | * @constructor Exit 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Node|null} expression 17 | * @property {boolean} useDie 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function Exit(expression, useDie, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.expression = expression; 24 | this.useDie = useDie; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "expression"; 10 | 11 | /** 12 | * Any expression node. Since the left-hand side of an assignment may 13 | * be any expression in general, an expression can also be a pattern. 14 | * @constructor Expression 15 | * @memberOf module:php-parser 16 | * @extends {Node} 17 | */ 18 | module.exports = Node.extends(KIND, function Expression(kind, docs, location) { 19 | Node.apply(this, [kind || KIND, docs, location]); 20 | }); 21 | -------------------------------------------------------------------------------- /src/ast/expressionstatement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "expressionstatement"; 10 | 11 | /** 12 | * Defines an expression based statement 13 | * @constructor ExpressionStatement 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} expression 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function ExpressionStatement(expr, docs, location) { 21 | Statement.apply(this, [KIND, docs, location]); 22 | this.expression = expr; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/for.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "for"; 10 | 11 | /** 12 | * Defines a for iterator 13 | * @constructor For 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression[]} init 17 | * @property {Expression[]} test 18 | * @property {Expression[]} increment 19 | * @property {Block | null} body 20 | * @property {boolean} shortForm 21 | * @see http://php.net/manual/en/control-structures.for.php 22 | */ 23 | module.exports = Statement.extends( 24 | KIND, 25 | function For(init, test, increment, body, shortForm, docs, location) { 26 | Statement.apply(this, [KIND, docs, location]); 27 | this.init = init; 28 | this.test = test; 29 | this.increment = increment; 30 | this.shortForm = shortForm; 31 | this.body = body; 32 | }, 33 | ); 34 | -------------------------------------------------------------------------------- /src/ast/foreach.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "foreach"; 10 | 11 | /** 12 | * Defines a foreach iterator 13 | * @constructor Foreach 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} source 17 | * @property {Expression|null} key 18 | * @property {Expression} value 19 | * @property {Block | null} body 20 | * @property {boolean} shortForm 21 | * @see http://php.net/manual/en/control-structures.foreach.php 22 | */ 23 | module.exports = Statement.extends( 24 | KIND, 25 | function Foreach(source, key, value, body, shortForm, docs, location) { 26 | Statement.apply(this, [KIND, docs, location]); 27 | this.source = source; 28 | this.key = key; 29 | this.value = value; 30 | this.shortForm = shortForm; 31 | this.body = body; 32 | }, 33 | ); 34 | -------------------------------------------------------------------------------- /src/ast/function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "function"; 10 | 11 | /** 12 | * Defines a classic function 13 | * @constructor Function 14 | * @memberOf module:php-parser 15 | * @extends {Declaration} 16 | * @property {Parameter[]} arguments 17 | * @property {Identifier} type 18 | * @property {boolean} byref 19 | * @property {boolean} nullable 20 | * @property {Block|null} body 21 | * @property {AttrGroup[]} attrGroups 22 | */ 23 | module.exports = Declaration.extends( 24 | KIND, 25 | function _Function(name, args, byref, type, nullable, docs, location) { 26 | Declaration.apply(this, [KIND, name, docs, location]); 27 | this.arguments = args; 28 | this.byref = byref; 29 | this.type = type; 30 | this.nullable = nullable; 31 | this.body = null; 32 | this.attrGroups = []; 33 | }, 34 | ); 35 | -------------------------------------------------------------------------------- /src/ast/global.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "global"; 10 | 11 | /** 12 | * Imports a variable from the global scope 13 | * @constructor Global 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Variable[]} items 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function Global(items, docs, location) { 21 | Statement.apply(this, [KIND, docs, location]); 22 | this.items = items; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/goto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "goto"; 10 | 11 | /** 12 | * Defines goto statement 13 | * @constructor Goto 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {string} label 17 | * @see {Label} 18 | */ 19 | module.exports = Statement.extends(KIND, function Goto(label, docs, location) { 20 | Statement.apply(this, [KIND, docs, location]); 21 | this.label = label; 22 | }); 23 | -------------------------------------------------------------------------------- /src/ast/halt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "halt"; 10 | 11 | /** 12 | * Halts the compiler execution 13 | * @constructor Halt 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {String} after - String after the halt statement 17 | * @see http://php.net/manual/en/function.halt-compiler.php 18 | */ 19 | module.exports = Statement.extends(KIND, function Halt(after, docs, location) { 20 | Statement.apply(this, [KIND, docs, location]); 21 | this.after = after; 22 | }); 23 | -------------------------------------------------------------------------------- /src/ast/identifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "identifier"; 10 | 11 | /** 12 | * Defines an identifier node 13 | * @constructor Identifier 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {string} name 17 | */ 18 | const Identifier = Node.extends( 19 | KIND, 20 | function Identifier(name, docs, location) { 21 | Node.apply(this, [KIND, docs, location]); 22 | this.name = name; 23 | }, 24 | ); 25 | 26 | module.exports = Identifier; 27 | -------------------------------------------------------------------------------- /src/ast/if.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "if"; 10 | 11 | /** 12 | * Defines a if statement 13 | * @constructor If 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} test 17 | * @property {Block} body 18 | * @property {Block|If|null} alternate 19 | * @property {boolean} shortForm 20 | */ 21 | module.exports = Statement.extends( 22 | KIND, 23 | function If(test, body, alternate, shortForm, docs, location) { 24 | Statement.apply(this, [KIND, docs, location]); 25 | this.test = test; 26 | this.body = body; 27 | this.alternate = alternate; 28 | this.shortForm = shortForm; 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/ast/include.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "include"; 10 | 11 | /** 12 | * Defines system include call 13 | * @constructor Include 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Node} target 17 | * @property {boolean} once 18 | * @property {boolean} require 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function Include(once, require, target, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.once = once; 25 | this.require = require; 26 | this.target = target; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/inline.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "inline"; 10 | 11 | /** 12 | * Defines inline html output (treated as echo output) 13 | * @constructor Inline 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | * @property {string} value 17 | */ 18 | module.exports = Literal.extends( 19 | KIND, 20 | function Inline(value, raw, docs, location) { 21 | Literal.apply(this, [KIND, value, raw, docs, location]); 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/interface.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "interface"; 10 | 11 | /** 12 | * An interface definition 13 | * @constructor Interface 14 | * @memberOf module:php-parser 15 | * @extends {Declaration} 16 | * @property {Identifier[]} extends 17 | * @property {Declaration[]} body 18 | * @property {AttrGroup[]} attrGroups 19 | */ 20 | module.exports = Declaration.extends( 21 | KIND, 22 | function Interface(name, ext, body, attrGroups, docs, location) { 23 | Declaration.apply(this, [KIND, name, docs, location]); 24 | this.extends = ext; 25 | this.body = body; 26 | this.attrGroups = attrGroups; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/intersectiontype.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "intersectiontype"; 10 | 11 | /** 12 | * A union of types 13 | * @memberOf module:php-parser 14 | * @constructor IntersectionType 15 | * @extends {Declaration} 16 | * @property {TypeReference[]} types 17 | */ 18 | module.exports = Declaration.extends( 19 | KIND, 20 | function IntersectionType(types, docs, location) { 21 | Declaration.apply(this, [KIND, null, docs, location]); 22 | this.types = types; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/isset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "isset"; 10 | 11 | /** 12 | * Defines an isset call 13 | * @constructor Isset 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | */ 17 | module.exports = Expression.extends( 18 | KIND, 19 | function Isset(variables, docs, location) { 20 | Expression.apply(this, [KIND, docs, location]); 21 | this.variables = variables; 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/label.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "label"; 10 | 11 | /** 12 | * A label statement (referenced by goto) 13 | * @constructor Label 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {String} name 17 | */ 18 | module.exports = Statement.extends(KIND, function Label(name, docs, location) { 19 | Statement.apply(this, [KIND, docs, location]); 20 | this.name = name; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "list"; 10 | 11 | /** 12 | * Defines list assignment 13 | * @constructor List 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {boolean} shortForm 17 | * @property {Entry[]} items 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function List(items, shortForm, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.items = items; 24 | this.shortForm = shortForm; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/literal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "literal"; 10 | 11 | /** 12 | * Defines an array structure 13 | * @constructor Literal 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {string} raw 17 | * @property {EncapsedPart[]|Node|string|number|boolean|null} value 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function Literal(kind, value, raw, docs, location) { 22 | Expression.apply(this, [kind || KIND, docs, location]); 23 | this.value = value; 24 | if (raw) { 25 | this.raw = raw; 26 | } 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/location.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | /** 9 | * Defines the location of the node (with it's source contents as string) 10 | * @constructor Location 11 | * @memberOf module:php-parser 12 | * @property {string|null} source 13 | * @property {Position} start 14 | * @property {Position} end 15 | */ 16 | const Location = function (source, start, end) { 17 | this.source = source; 18 | this.start = start; 19 | this.end = end; 20 | }; 21 | 22 | module.exports = Location; 23 | -------------------------------------------------------------------------------- /src/ast/lookup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expr = require("./expression"); 9 | const KIND = "lookup"; 10 | 11 | /** 12 | * Lookup on an offset in the specified object 13 | * @constructor Lookup 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} what 17 | * @property {Expression} offset 18 | */ 19 | module.exports = Expr.extends( 20 | KIND, 21 | function Lookup(kind, what, offset, docs, location) { 22 | Expr.apply(this, [kind || KIND, docs, location]); 23 | this.what = what; 24 | this.offset = offset; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/magic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "magic"; 10 | 11 | /** 12 | * Defines magic constant 13 | * @constructor Magic 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | */ 17 | module.exports = Literal.extends( 18 | KIND, 19 | function Magic(value, raw, docs, location) { 20 | Literal.apply(this, [KIND, value, raw, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/match.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "match"; 10 | 11 | /** 12 | * Defines a match expression 13 | * @memberOf module:php-parser 14 | * @constructor Match 15 | * @extends {Expression} 16 | * @property {Expression} cond Condition expression to match against 17 | * @property {MatchArm[]} arms Arms for comparison 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function Match(cond, arms, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.cond = cond; 24 | this.arms = arms; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/matcharm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "matcharm"; 10 | 11 | /** 12 | * An array entry - see [Array](#array) 13 | * @memberOf module:php-parser 14 | * @constructor MatchArm 15 | * @extends {Expression} 16 | * @property {Expression[]|null} conds The match condition expression list - null indicates default arm 17 | * @property {Expression} body The return value expression 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function MatchArm(conds, body, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.conds = conds; 24 | this.body = body; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/method.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Function_ = require("./function"); 9 | const KIND = "method"; 10 | 11 | /** 12 | * Defines a class/interface/trait method 13 | * @constructor Method 14 | * @memberOf module:php-parser 15 | * @extends {Function} 16 | * @property {boolean} isAbstract 17 | * @property {boolean} isFinal 18 | * @property {boolean} isStatic 19 | * @property {string} visibility 20 | */ 21 | module.exports = Function_.extends(KIND, function Method() { 22 | Function_.apply(this, arguments); 23 | this.kind = KIND; 24 | }); 25 | -------------------------------------------------------------------------------- /src/ast/name.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Reference = require("./reference"); 9 | const KIND = "name"; 10 | 11 | /** 12 | * Defines a class reference node 13 | * @constructor Name 14 | * @memberOf module:php-parser 15 | * @extends {Reference} 16 | * @property {string} name 17 | * @property {string} resolution 18 | */ 19 | const Name = Reference.extends( 20 | KIND, 21 | function Name(name, resolution, docs, location) { 22 | Reference.apply(this, [KIND, docs, location]); 23 | this.name = name.replace(/\\$/, ""); 24 | this.resolution = resolution; 25 | }, 26 | ); 27 | 28 | /** 29 | * This is an identifier without a namespace separator, such as Foo 30 | * @constant {String} Name#UNQUALIFIED_NAME 31 | * @memberOf module:php-parser 32 | */ 33 | Name.UNQUALIFIED_NAME = "uqn"; 34 | /** 35 | * This is an identifier with a namespace separator, such as Foo\Bar 36 | * @constant {String} Name#QUALIFIED_NAME 37 | * @memberOf module:php-parser 38 | */ 39 | Name.QUALIFIED_NAME = "qn"; 40 | /** 41 | * This is an identifier with a namespace separator that begins with 42 | * a namespace separator, such as \Foo\Bar. The namespace \Foo is also 43 | * a fully qualified name. 44 | * @constant {String} Name#FULL_QUALIFIED_NAME 45 | * @memberOf module:php-parser 46 | */ 47 | Name.FULL_QUALIFIED_NAME = "fqn"; 48 | /** 49 | * This is an identifier starting with namespace, such as namespace\Foo\Bar. 50 | * @constant {String} Name#RELATIVE_NAME 51 | * @memberOf module:php-parser 52 | */ 53 | Name.RELATIVE_NAME = "rn"; 54 | 55 | module.exports = Name; 56 | -------------------------------------------------------------------------------- /src/ast/namedargument.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "namedargument"; 10 | 11 | /** 12 | * Named arguments. 13 | * @memberOf module:php-parser 14 | * @constructor namedargument 15 | * @extends {Expression} 16 | * @property {String} name 17 | * @property {Expression} value 18 | * @see https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function namedargument(name, value, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.name = name; 25 | this.value = value; 26 | }, 27 | ); 28 | -------------------------------------------------------------------------------- /src/ast/namespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Block = require("./block"); 9 | const KIND = "namespace"; 10 | 11 | /** 12 | * The main program node 13 | * @constructor Namespace 14 | * @memberOf module:php-parser 15 | * @extends {Block} 16 | * @property {string} name 17 | * @property {boolean} withBrackets 18 | */ 19 | module.exports = Block.extends( 20 | KIND, 21 | function Namespace(name, children, withBrackets, docs, location) { 22 | Block.apply(this, [KIND, children, docs, location]); 23 | this.name = name; 24 | this.withBrackets = withBrackets || false; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/new.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "new"; 10 | 11 | /** 12 | * Creates a new instance of the specified class 13 | * @constructor New 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Identifier|Variable|Class} what 17 | * @property {Variable[]} arguments 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function New(what, args, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.what = what; 24 | this.arguments = args; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/noop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "noop"; 10 | 11 | /** 12 | * Ignore this node, it implies a no operation block, for example : 13 | * [$foo, $bar, /* here a noop node * /] 14 | * @constructor Noop 15 | * @memberOf module:php-parser 16 | * @extends {Node} 17 | */ 18 | module.exports = Node.extends(KIND, function Noop(docs, location) { 19 | Node.apply(this, [KIND, docs, location]); 20 | }); 21 | -------------------------------------------------------------------------------- /src/ast/nowdoc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "nowdoc"; 10 | 11 | /** 12 | * Defines a nowdoc string 13 | * @constructor NowDoc 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | * @property {string} label 17 | * @property {string} raw 18 | * @property {string} value 19 | */ 20 | module.exports = Literal.extends( 21 | KIND, 22 | function Nowdoc(value, raw, label, docs, location) { 23 | Literal.apply(this, [KIND, value, raw, docs, location]); 24 | this.label = label; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/nullkeyword.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "nullkeyword"; 10 | 11 | /** 12 | * Represents the null keyword 13 | * @constructor NullKeyword 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | */ 17 | module.exports = Node.extends(KIND, function NullKeyword(raw, docs, location) { 18 | Node.apply(this, [KIND, docs, location]); 19 | this.raw = raw; 20 | }); 21 | -------------------------------------------------------------------------------- /src/ast/nullsafepropertylookup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Lookup = require("./lookup"); 9 | const KIND = "nullsafepropertylookup"; 10 | 11 | /** 12 | * Lookup to an object property 13 | * @memberOf module:php-parser 14 | * @constructor NullSafePropertyLookup 15 | * @extends {Lookup} 16 | */ 17 | module.exports = Lookup.extends( 18 | KIND, 19 | function NullSafePropertyLookup(what, offset, docs, location) { 20 | Lookup.apply(this, [KIND, what, offset, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/number.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "number"; 10 | 11 | /** 12 | * Defines a numeric value 13 | * @constructor Number 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | * @property {number} value 17 | */ 18 | module.exports = Literal.extends( 19 | KIND, 20 | function Number(value, raw, docs, location) { 21 | Literal.apply(this, [KIND, value, raw, docs, location]); 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/offsetlookup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Lookup = require("./lookup"); 9 | const KIND = "offsetlookup"; 10 | 11 | /** 12 | * Lookup on an offset in an array 13 | * @constructor OffsetLookup 14 | * @memberOf module:php-parser 15 | * @extends {Lookup} 16 | */ 17 | module.exports = Lookup.extends( 18 | KIND, 19 | function OffsetLookup(what, offset, docs, location) { 20 | Lookup.apply(this, [KIND, what, offset, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/operation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expr = require("./expression"); 9 | const KIND = "operation"; 10 | 11 | /** 12 | * Defines binary operations 13 | * @constructor Operation 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | */ 17 | module.exports = Expr.extends(KIND, function Operation(kind, docs, location) { 18 | Expr.apply(this, [kind || KIND, docs, location]); 19 | }); 20 | -------------------------------------------------------------------------------- /src/ast/parameter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "parameter"; 10 | 11 | /** 12 | * @memberOf module:php-parser 13 | * @typedef {1} MODIFIER_PUBLIC 14 | **/ 15 | /** 16 | * @memberOf module:php-parser 17 | * @typedef {2} MODIFIER_PROTECTED 18 | **/ 19 | /** 20 | * @memberOf module:php-parser 21 | * @typedef {4} MODIFIER_PRIVATE 22 | **/ 23 | /** 24 | * Defines a function parameter 25 | * @constructor Parameter 26 | * @memberOf module:php-parser 27 | * @extends {Declaration} 28 | * @property {Identifier|null} type 29 | * @property {Node|null} value 30 | * @property {boolean} byref 31 | * @property {boolean} variadic 32 | * @property {boolean} readonly 33 | * @property {boolean} nullable 34 | * @property {AttrGroup[]} attrGroups 35 | * @property {MODIFIER_PUBLIC|MODIFIER_PROTECTED|MODIFIER_PRIVATE} flags 36 | */ 37 | module.exports = Declaration.extends( 38 | KIND, 39 | function Parameter( 40 | name, 41 | type, 42 | value, 43 | isRef, 44 | isVariadic, 45 | readonly, 46 | nullable, 47 | flags, 48 | docs, 49 | location, 50 | ) { 51 | Declaration.apply(this, [KIND, name, docs, location]); 52 | this.value = value; 53 | this.type = type; 54 | this.byref = isRef; 55 | this.variadic = isVariadic; 56 | this.readonly = readonly; 57 | this.nullable = nullable; 58 | this.flags = flags || 0; 59 | this.attrGroups = []; 60 | }, 61 | ); 62 | -------------------------------------------------------------------------------- /src/ast/parentreference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Reference = require("./reference"); 9 | const KIND = "parentreference"; 10 | 11 | /** 12 | * Defines a class reference node 13 | * @constructor ParentReference 14 | * @memberOf module:php-parser 15 | * @extends {Reference} 16 | */ 17 | const ParentReference = Reference.extends( 18 | KIND, 19 | function ParentReference(raw, docs, location) { 20 | Reference.apply(this, [KIND, docs, location]); 21 | this.raw = raw; 22 | }, 23 | ); 24 | module.exports = ParentReference; 25 | -------------------------------------------------------------------------------- /src/ast/position.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | /** 9 | * Each Position object consists of a line number (1-indexed) and a column number (0-indexed): 10 | * @constructor Position 11 | * @memberOf module:php-parser 12 | * @property {number} line 13 | * @property {number} column 14 | * @property {number} offset 15 | */ 16 | const Position = function (line, column, offset) { 17 | this.line = line; 18 | this.column = column; 19 | this.offset = offset; 20 | }; 21 | 22 | module.exports = Position; 23 | -------------------------------------------------------------------------------- /src/ast/post.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Operation = require("./operation"); 9 | const KIND = "post"; 10 | 11 | /** 12 | * Defines a post operation `$i++` or `$i--` 13 | * @constructor Post 14 | * @memberOf module:php-parser 15 | * @extends {Operation} 16 | * @property {String} type 17 | * @property {Variable} what 18 | */ 19 | module.exports = Operation.extends( 20 | KIND, 21 | function Post(type, what, docs, location) { 22 | Operation.apply(this, [KIND, docs, location]); 23 | this.type = type; 24 | this.what = what; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/pre.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Operation = require("./operation"); 9 | const KIND = "pre"; 10 | 11 | /** 12 | * Defines a pre operation `++$i` or `--$i` 13 | * @constructor Pre 14 | * @memberOf module:php-parser 15 | * @extends {Operation} 16 | * @property {String} type 17 | * @property {Variable} what 18 | */ 19 | module.exports = Operation.extends( 20 | KIND, 21 | function Pre(type, what, docs, location) { 22 | Operation.apply(this, [KIND, docs, location]); 23 | this.type = type; 24 | this.what = what; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/print.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "print"; 10 | 11 | /** 12 | * Outputs 13 | * @constructor Print 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | */ 17 | module.exports = Expression.extends( 18 | KIND, 19 | function Print(expression, docs, location) { 20 | Expression.apply(this, [KIND, docs, location]); 21 | this.expression = expression; 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/program.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Block = require("./block"); 9 | const KIND = "program"; 10 | 11 | /** 12 | * The main program node 13 | * @constructor Program 14 | * @memberOf module:php-parser 15 | * @extends {Block} 16 | * @property {Error[]} errors 17 | * @property {Comment[]|null} comments 18 | * @property {String[]|null} tokens 19 | */ 20 | module.exports = Block.extends( 21 | KIND, 22 | function Program(children, errors, comments, tokens, docs, location) { 23 | Block.apply(this, [KIND, children, docs, location]); 24 | this.errors = errors; 25 | if (comments) { 26 | this.comments = comments; 27 | } 28 | if (tokens) { 29 | this.tokens = tokens; 30 | } 31 | }, 32 | ); 33 | -------------------------------------------------------------------------------- /src/ast/property.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "property"; 10 | 11 | /** 12 | * Defines a class property 13 | * @constructor Property 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {string} name 17 | * @property {Node|null} value 18 | * @property {boolean} readonly 19 | * @property {boolean} nullable 20 | * @property {Identifier|Array|null} type 21 | * @property {AttrGroup[]} attrGroups 22 | */ 23 | module.exports = Statement.extends( 24 | KIND, 25 | function Property( 26 | name, 27 | value, 28 | readonly, 29 | nullable, 30 | type, 31 | attrGroups, 32 | docs, 33 | location, 34 | ) { 35 | Statement.apply(this, [KIND, docs, location]); 36 | this.name = name; 37 | this.value = value; 38 | this.readonly = readonly; 39 | this.nullable = nullable; 40 | this.type = type; 41 | this.attrGroups = attrGroups; 42 | }, 43 | ); 44 | -------------------------------------------------------------------------------- /src/ast/propertylookup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Lookup = require("./lookup"); 9 | const KIND = "propertylookup"; 10 | 11 | /** 12 | * Lookup to an object property 13 | * @memberOf module:php-parser 14 | * @constructor PropertyLookup 15 | * @extends {Lookup} 16 | */ 17 | module.exports = Lookup.extends( 18 | KIND, 19 | function PropertyLookup(what, offset, docs, location) { 20 | Lookup.apply(this, [KIND, what, offset, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/propertystatement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "propertystatement"; 10 | 11 | const IS_UNDEFINED = ""; 12 | const IS_PUBLIC = "public"; 13 | const IS_PROTECTED = "protected"; 14 | const IS_PRIVATE = "private"; 15 | 16 | /** 17 | * Declares a properties into the current scope 18 | * @constructor PropertyStatement 19 | * @memberOf module:php-parser 20 | * @extends {Statement} 21 | * @property {Property[]} properties 22 | * @property {string|null} visibility 23 | * @property {boolean} isStatic 24 | */ 25 | const PropertyStatement = Statement.extends( 26 | KIND, 27 | function PropertyStatement(kind, properties, flags, docs, location) { 28 | Statement.apply(this, [KIND, docs, location]); 29 | this.properties = properties; 30 | this.parseFlags(flags); 31 | }, 32 | ); 33 | 34 | /** 35 | * Generic flags parser 36 | * @function PropertyStatement#parseFlags 37 | * @memberOf module:php-parser 38 | * @param {Array} flags 39 | * @return {void} 40 | */ 41 | PropertyStatement.prototype.parseFlags = function (flags) { 42 | if (flags[0] === -1) { 43 | this.visibility = IS_UNDEFINED; 44 | } else if (flags[0] === null) { 45 | this.visibility = null; 46 | } else if (flags[0] === 0) { 47 | this.visibility = IS_PUBLIC; 48 | } else if (flags[0] === 1) { 49 | this.visibility = IS_PROTECTED; 50 | } else if (flags[0] === 2) { 51 | this.visibility = IS_PRIVATE; 52 | } 53 | 54 | this.isStatic = flags[1] === 1; 55 | }; 56 | 57 | module.exports = PropertyStatement; 58 | -------------------------------------------------------------------------------- /src/ast/reference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "reference"; 10 | 11 | /** 12 | * Defines a reference node 13 | * @constructor Reference 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | */ 17 | const Reference = Node.extends(KIND, function Reference(kind, docs, location) { 18 | Node.apply(this, [kind || KIND, docs, location]); 19 | }); 20 | 21 | module.exports = Reference; 22 | -------------------------------------------------------------------------------- /src/ast/retif.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "retif"; 10 | 11 | /** 12 | * Defines a short if statement that returns a value 13 | * @constructor RetIf 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} test 17 | * @property {Expression} trueExpr 18 | * @property {Expression} falseExpr 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function RetIf(test, trueExpr, falseExpr, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.test = test; 25 | this.trueExpr = trueExpr; 26 | this.falseExpr = falseExpr; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/return.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "return"; 10 | 11 | /** 12 | * A continue statement 13 | * @constructor Return 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression|null} expr 17 | */ 18 | module.exports = Statement.extends(KIND, function Return(expr, docs, location) { 19 | Statement.apply(this, [KIND, docs, location]); 20 | this.expr = expr; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/selfreference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Reference = require("./reference"); 9 | const KIND = "selfreference"; 10 | 11 | /** 12 | * Defines a class reference node 13 | * @constructor SelfReference 14 | * @memberOf module:php-parser 15 | * @extends {Reference} 16 | */ 17 | const SelfReference = Reference.extends( 18 | KIND, 19 | function SelfReference(raw, docs, location) { 20 | Reference.apply(this, [KIND, docs, location]); 21 | this.raw = raw; 22 | }, 23 | ); 24 | module.exports = SelfReference; 25 | -------------------------------------------------------------------------------- /src/ast/silent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "silent"; 10 | 11 | /** 12 | * Avoids to show/log warnings & notices from the inner expression 13 | * @constructor Silent 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} expr 17 | */ 18 | module.exports = Expression.extends( 19 | KIND, 20 | function Silent(expr, docs, location) { 21 | Expression.apply(this, [KIND, docs, location]); 22 | this.expr = expr; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/statement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "statement"; 10 | 11 | /** 12 | * Any statement. 13 | * @constructor Statement 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | */ 17 | module.exports = Node.extends(KIND, function Statement(kind, docs, location) { 18 | Node.apply(this, [kind || KIND, docs, location]); 19 | }); 20 | -------------------------------------------------------------------------------- /src/ast/static.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "static"; 10 | 11 | /** 12 | * Declares a static variable into the current scope 13 | * @constructor Static 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {StaticVariable[]} variables 17 | */ 18 | module.exports = Statement.extends( 19 | KIND, 20 | function Static(variables, docs, location) { 21 | Statement.apply(this, [KIND, docs, location]); 22 | this.variables = variables; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/staticlookup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Lookup = require("./lookup"); 9 | const KIND = "staticlookup"; 10 | 11 | /** 12 | * Lookup to a static property 13 | * @constructor StaticLookup 14 | * @memberOf module:php-parser 15 | * @extends {Lookup} 16 | */ 17 | module.exports = Lookup.extends( 18 | KIND, 19 | function StaticLookup(what, offset, docs, location) { 20 | Lookup.apply(this, [KIND, what, offset, docs, location]); 21 | }, 22 | ); 23 | -------------------------------------------------------------------------------- /src/ast/staticreference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Reference = require("./reference"); 9 | const KIND = "staticreference"; 10 | 11 | /** 12 | * Defines a class reference node 13 | * @constructor StaticReference 14 | * @memberOf module:php-parser 15 | * @extends {Reference} 16 | */ 17 | const StaticReference = Reference.extends( 18 | KIND, 19 | function StaticReference(raw, docs, location) { 20 | Reference.apply(this, [KIND, docs, location]); 21 | this.raw = raw; 22 | }, 23 | ); 24 | module.exports = StaticReference; 25 | -------------------------------------------------------------------------------- /src/ast/staticvariable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "staticvariable"; 10 | 11 | /** 12 | * Defines a constant 13 | * @constructor StaticVariable 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {Variable} variable 17 | * @property {Node|string|number|boolean|null} defaultValue 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function StaticVariable(variable, defaultValue, docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | this.variable = variable; 24 | this.defaultValue = defaultValue; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/string.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Literal = require("./literal"); 9 | const KIND = "string"; 10 | 11 | /** 12 | * Defines a string (simple or double quoted) - chars are already escaped 13 | * @constructor String 14 | * @memberOf module:php-parser 15 | * @extends {Literal} 16 | * @property {boolean} unicode 17 | * @property {boolean} isDoubleQuote 18 | * @see {Encapsed} 19 | * @property {string} value 20 | */ 21 | module.exports = Literal.extends( 22 | KIND, 23 | function String(isDoubleQuote, value, unicode, raw, docs, location) { 24 | Literal.apply(this, [KIND, value, raw, docs, location]); 25 | this.unicode = unicode; 26 | this.isDoubleQuote = isDoubleQuote; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/switch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "switch"; 10 | 11 | /** 12 | * Defines a switch statement 13 | * @constructor Switch 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} test 17 | * @property {Block} body 18 | * @property {boolean} shortForm 19 | */ 20 | module.exports = Statement.extends( 21 | KIND, 22 | function Switch(test, body, shortForm, docs, location) { 23 | Statement.apply(this, [KIND, docs, location]); 24 | this.test = test; 25 | this.body = body; 26 | this.shortForm = shortForm; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/throw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "throw"; 10 | 11 | /** 12 | * Defines a throw statement 13 | * @constructor Throw 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} what 17 | */ 18 | module.exports = Statement.extends(KIND, function Throw(what, docs, location) { 19 | Statement.apply(this, [KIND, docs, location]); 20 | this.what = what; 21 | }); 22 | -------------------------------------------------------------------------------- /src/ast/trait.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "trait"; 10 | 11 | /** 12 | * A trait definition 13 | * @constructor Trait 14 | * @memberOf module:php-parser 15 | * @extends {Declaration} 16 | * @property {Declaration[]} body 17 | */ 18 | module.exports = Declaration.extends( 19 | KIND, 20 | function Trait(name, body, docs, location) { 21 | Declaration.apply(this, [KIND, name, docs, location]); 22 | this.body = body; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/traitalias.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "traitalias"; 10 | 11 | const IS_UNDEFINED = ""; 12 | const IS_PUBLIC = "public"; 13 | const IS_PROTECTED = "protected"; 14 | const IS_PRIVATE = "private"; 15 | 16 | /** 17 | * Defines a trait alias 18 | * @constructor TraitAlias 19 | * @memberOf module:php-parser 20 | * @extends {Node} 21 | * @property {Identifier|null} trait 22 | * @property {Identifier} method 23 | * @property {Identifier|null} as 24 | * @property {string|null} visibility 25 | */ 26 | module.exports = Node.extends( 27 | KIND, 28 | function TraitAlias(trait, method, as, flags, docs, location) { 29 | Node.apply(this, [KIND, docs, location]); 30 | this.trait = trait; 31 | this.method = method; 32 | this.as = as; 33 | this.visibility = IS_UNDEFINED; 34 | if (flags) { 35 | if (flags[0] === 0) { 36 | this.visibility = IS_PUBLIC; 37 | } else if (flags[0] === 1) { 38 | this.visibility = IS_PROTECTED; 39 | } else if (flags[0] === 2) { 40 | this.visibility = IS_PRIVATE; 41 | } 42 | } 43 | }, 44 | ); 45 | -------------------------------------------------------------------------------- /src/ast/traitprecedence.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "traitprecedence"; 10 | 11 | /** 12 | * Defines a trait alias 13 | * @constructor TraitPrecedence 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {Identifier|null} trait 17 | * @property {Identifier} method 18 | * @property {Identifier[]} instead 19 | */ 20 | module.exports = Node.extends( 21 | KIND, 22 | function TraitPrecedence(trait, method, instead, docs, location) { 23 | Node.apply(this, [KIND, docs, location]); 24 | this.trait = trait; 25 | this.method = method; 26 | this.instead = instead; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/traituse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "traituse"; 10 | 11 | /** 12 | * Defines a trait usage 13 | * @constructor TraitUse 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @property {Identifier[]} traits 17 | * @property {Node[]|null} adaptations 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function TraitUse(traits, adaptations, docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | this.traits = traits; 24 | this.adaptations = adaptations; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/try.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "try"; 10 | 11 | /** 12 | * Defines a try statement 13 | * @constructor Try 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Block} body 17 | * @property {Catch[]} catches 18 | * @property {Block} always 19 | */ 20 | module.exports = Statement.extends( 21 | KIND, 22 | function Try(body, catches, always, docs, location) { 23 | Statement.apply(this, [KIND, docs, location]); 24 | this.body = body; 25 | this.catches = catches; 26 | this.always = always; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/typereference.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Reference = require("./reference"); 9 | const KIND = "typereference"; 10 | 11 | /** 12 | * Defines a class reference node 13 | * @constructor TypeReference 14 | * @memberOf module:php-parser 15 | * @extends {Reference} 16 | * @property {string} name 17 | */ 18 | const TypeReference = Reference.extends( 19 | KIND, 20 | function TypeReference(name, raw, docs, location) { 21 | Reference.apply(this, [KIND, docs, location]); 22 | this.name = name; 23 | this.raw = raw; 24 | }, 25 | ); 26 | 27 | TypeReference.types = [ 28 | "int", 29 | "float", 30 | "string", 31 | "bool", 32 | "object", 33 | "array", 34 | "callable", 35 | "iterable", 36 | "void", 37 | "static", 38 | ]; 39 | 40 | module.exports = TypeReference; 41 | -------------------------------------------------------------------------------- /src/ast/unary.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Operation = require("./operation"); 9 | const KIND = "unary"; 10 | 11 | /** 12 | * Unary operations 13 | * @constructor Unary 14 | * @memberOf module:php-parser 15 | * @extends {Operation} 16 | * @property {string} type 17 | * @property {Expression} what 18 | */ 19 | module.exports = Operation.extends( 20 | KIND, 21 | function Unary(type, what, docs, location) { 22 | Operation.apply(this, [KIND, docs, location]); 23 | this.type = type; 24 | this.what = what; 25 | }, 26 | ); 27 | -------------------------------------------------------------------------------- /src/ast/uniontype.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Declaration = require("./declaration"); 9 | const KIND = "uniontype"; 10 | 11 | /** 12 | * A union of types 13 | * @memberOf module:php-parser 14 | * @constructor UnionType 15 | * @extends {Declaration} 16 | * @property {TypeReference[]} types 17 | */ 18 | module.exports = Declaration.extends( 19 | KIND, 20 | function UnionType(types, docs, location) { 21 | Declaration.apply(this, [KIND, null, docs, location]); 22 | this.types = types; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/unset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "unset"; 10 | 11 | /** 12 | * Deletes references to a list of variables 13 | * @constructor Unset 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | */ 17 | module.exports = Statement.extends( 18 | KIND, 19 | function Unset(variables, docs, location) { 20 | Statement.apply(this, [KIND, docs, location]); 21 | this.variables = variables; 22 | }, 23 | ); 24 | -------------------------------------------------------------------------------- /src/ast/usegroup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "usegroup"; 10 | 11 | /** 12 | * Defines a use statement (with a list of use items) 13 | * @constructor UseGroup 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {string|null} name 17 | * @property {string|null} type - Possible value : function, const 18 | * @property {UseItem[]} item 19 | * @see {Namespace} 20 | * @see http://php.net/manual/en/language.namespaces.importing.php 21 | */ 22 | module.exports = Statement.extends( 23 | KIND, 24 | function UseGroup(name, type, items, docs, location) { 25 | Statement.apply(this, [KIND, docs, location]); 26 | this.name = name; 27 | this.type = type; 28 | this.items = items; 29 | }, 30 | ); 31 | -------------------------------------------------------------------------------- /src/ast/useitem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "useitem"; 10 | 11 | /** 12 | * Defines a use statement (from namespace) 13 | * @constructor UseItem 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {string} name 17 | * @property {string|null} type - Possible value : function, const 18 | * @property {Identifier|null} alias 19 | * @see {Namespace} 20 | * @see http://php.net/manual/en/language.namespaces.importing.php 21 | */ 22 | const UseItem = Statement.extends( 23 | KIND, 24 | function UseItem(name, alias, type, docs, location) { 25 | Statement.apply(this, [KIND, docs, location]); 26 | this.name = name; 27 | this.alias = alias; 28 | this.type = type; 29 | }, 30 | ); 31 | 32 | /** 33 | * Importing a constant 34 | * @constant {string} UseItem#TYPE_CONST 35 | * @memberOf module:php-parser 36 | */ 37 | UseItem.TYPE_CONST = "const"; 38 | /** 39 | * Importing a function 40 | * @constant {string} UseItem#TYPE_FUNC 41 | * @memberOf module:php-parser 42 | */ 43 | UseItem.TYPE_FUNCTION = "function"; 44 | 45 | module.exports = UseItem; 46 | -------------------------------------------------------------------------------- /src/ast/variable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "variable"; 10 | 11 | /** 12 | * Any expression node. Since the left-hand side of an assignment may 13 | * be any expression in general, an expression can also be a pattern. 14 | * @constructor Variable 15 | * @memberOf module:php-parser 16 | * @extends {Expression} 17 | * @example 18 | * // PHP code : 19 | * $foo 20 | * // AST output 21 | * { 22 | * "kind": "variable", 23 | * "name": "foo", 24 | * "curly": false 25 | * } 26 | * @property {string|Node} name The variable name (can be a complex expression when the name is resolved dynamically) 27 | * @property {boolean} curly Indicate if the name is defined between curlies, ex `${foo}` 28 | */ 29 | module.exports = Expression.extends( 30 | KIND, 31 | function Variable(name, curly, docs, location) { 32 | Expression.apply(this, [KIND, docs, location]); 33 | this.name = name; 34 | this.curly = curly || false; 35 | }, 36 | ); 37 | -------------------------------------------------------------------------------- /src/ast/variadic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "variadic"; 10 | 11 | /** 12 | * Introduce a list of items into the arguments of the call 13 | * @constructor Variadic 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Array|Expression} what 17 | * @see https://wiki.php.net/rfc/argument_unpacking 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function variadic(what, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.what = what; 24 | }, 25 | ); 26 | -------------------------------------------------------------------------------- /src/ast/variadicplaceholder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Node = require("./node"); 9 | const KIND = "variadicplaceholder"; 10 | 11 | /** 12 | * Defines a variadic placeholder (the ellipsis in PHP 8.1+'s first-class callable syntax) 13 | * @constructor VariadicPlaceholder 14 | * @memberOf module:php-parser 15 | * @extends {Node} 16 | * @see {Namespace} 17 | * @see http://php.net/manual/en/language.namespaces.importing.php 18 | */ 19 | module.exports = Node.extends( 20 | KIND, 21 | function VariadicPlaceholder(docs, location) { 22 | Node.apply(this, [KIND, docs, location]); 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /src/ast/while.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Statement = require("./statement"); 9 | const KIND = "while"; 10 | 11 | /** 12 | * Defines a while statement 13 | * @constructor While 14 | * @memberOf module:php-parser 15 | * @extends {Statement} 16 | * @property {Expression} test 17 | * @property {Block | null} body 18 | * @property {boolean} shortForm 19 | */ 20 | module.exports = Statement.extends( 21 | KIND, 22 | function While(test, body, shortForm, docs, location) { 23 | Statement.apply(this, [KIND, docs, location]); 24 | this.test = test; 25 | this.body = body; 26 | this.shortForm = shortForm; 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /src/ast/yield.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "yield"; 10 | 11 | /** 12 | * Defines a yield generator statement 13 | * @constructor Yield 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression|null} value 17 | * @property {Expression|null} key 18 | * @see http://php.net/manual/en/language.generators.syntax.php 19 | */ 20 | module.exports = Expression.extends( 21 | KIND, 22 | function Yield(value, key, docs, location) { 23 | Expression.apply(this, [KIND, docs, location]); 24 | this.value = value; 25 | this.key = key; 26 | }, 27 | ); 28 | -------------------------------------------------------------------------------- /src/ast/yieldfrom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | const Expression = require("./expression"); 9 | const KIND = "yieldfrom"; 10 | 11 | /** 12 | * Defines a yield from generator statement 13 | * @constructor YieldFrom 14 | * @memberOf module:php-parser 15 | * @extends {Expression} 16 | * @property {Expression} value 17 | * @see http://php.net/manual/en/language.generators.syntax.php 18 | */ 19 | module.exports = Expression.extends( 20 | KIND, 21 | function YieldFrom(value, docs, location) { 22 | Expression.apply(this, [KIND, docs, location]); 23 | this.value = value; 24 | }, 25 | ); 26 | -------------------------------------------------------------------------------- /src/lexer/comments.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | /* 10 | * Reads a single line comment 11 | */ 12 | T_COMMENT: function () { 13 | while (this.offset < this.size) { 14 | const ch = this.input(); 15 | if (ch === "\n" || ch === "\r") { 16 | return this.tok.T_COMMENT; 17 | } else if ( 18 | ch === "?" && 19 | !this.aspTagMode && 20 | this._input[this.offset] === ">" 21 | ) { 22 | this.unput(1); 23 | return this.tok.T_COMMENT; 24 | } else if ( 25 | ch === "%" && 26 | this.aspTagMode && 27 | this._input[this.offset] === ">" 28 | ) { 29 | this.unput(1); 30 | return this.tok.T_COMMENT; 31 | } 32 | } 33 | return this.tok.T_COMMENT; 34 | }, 35 | /* 36 | * Behaviour : https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1927 37 | */ 38 | T_DOC_COMMENT: function () { 39 | let ch = this.input(); 40 | let token = this.tok.T_COMMENT; 41 | if (ch === "*") { 42 | // started with '/*' , check is next is '*' 43 | ch = this.input(); 44 | if (this.is_WHITESPACE()) { 45 | // check if next is WHITESPACE 46 | token = this.tok.T_DOC_COMMENT; 47 | } 48 | if (ch === "/") { 49 | return token; 50 | } else { 51 | this.unput(1); // reset 52 | } 53 | } 54 | while (this.offset < this.size) { 55 | ch = this.input(); 56 | if (ch === "*" && this._input[this.offset] === "/") { 57 | this.input(); 58 | break; 59 | } 60 | } 61 | return token; 62 | }, 63 | }; 64 | -------------------------------------------------------------------------------- /src/lexer/initial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | nextINITIAL: function () { 10 | if ( 11 | this.conditionStack.length > 1 && 12 | this.conditionStack[this.conditionStack.length - 1] === "INITIAL" 13 | ) { 14 | // Return to HEREDOC/ST_DOUBLE_QUOTES mode 15 | this.popState(); 16 | } else { 17 | this.begin("ST_IN_SCRIPTING"); 18 | } 19 | return this; 20 | }, 21 | matchINITIAL: function () { 22 | while (this.offset < this.size) { 23 | let ch = this.input(); 24 | if (ch == "<") { 25 | ch = this.ahead(1); 26 | if (ch == "?") { 27 | if (this.tryMatch("?=")) { 28 | this.unput(1) 29 | .appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3) 30 | .nextINITIAL(); 31 | break; 32 | } else if (this.tryMatchCaseless("?php")) { 33 | ch = this._input[this.offset + 4]; 34 | if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") { 35 | this.unput(1).appendToken(this.tok.T_OPEN_TAG, 6).nextINITIAL(); 36 | break; 37 | } 38 | } 39 | if (this.short_tags) { 40 | this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL(); 41 | break; 42 | } 43 | } else if (this.asp_tags && ch == "%") { 44 | if (this.tryMatch("%=")) { 45 | this.aspTagMode = true; 46 | this.unput(1) 47 | .appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3) 48 | .nextINITIAL(); 49 | break; 50 | } else { 51 | this.aspTagMode = true; 52 | this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL(); 53 | break; 54 | } 55 | } 56 | } 57 | } 58 | if (this.yytext.length > 0) { 59 | return this.tok.T_INLINE_HTML; 60 | } else { 61 | return false; 62 | } 63 | }, 64 | }; 65 | -------------------------------------------------------------------------------- /src/parser/comment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | /* 10 | * Comments with // or # or / * ... * / 11 | */ 12 | read_comment: function () { 13 | const text = this.text(); 14 | let result = this.ast.prepare( 15 | text.substring(0, 2) === "/*" ? "commentblock" : "commentline", 16 | null, 17 | this, 18 | ); 19 | const offset = this.lexer.yylloc.first_offset; 20 | // handle location on comment 21 | const prev = this.prev; 22 | this.prev = [ 23 | this.lexer.yylloc.last_line, 24 | this.lexer.yylloc.last_column, 25 | this.lexer.offset, 26 | ]; 27 | this.lex(); 28 | result = result(text); 29 | result.offset = offset; 30 | this.prev = prev; 31 | return result; 32 | }, 33 | /* 34 | * Comments with / ** ... * / 35 | */ 36 | read_doc_comment: function () { 37 | let result = this.ast.prepare("commentblock", null, this); 38 | const offset = this.lexer.yylloc.first_offset; 39 | const text = this.text(); 40 | const prev = this.prev; 41 | this.prev = [ 42 | this.lexer.yylloc.last_line, 43 | this.lexer.yylloc.last_column, 44 | this.lexer.offset, 45 | ]; 46 | this.lex(); 47 | result = result(text); 48 | result.offset = offset; 49 | this.prev = prev; 50 | return result; 51 | }, 52 | }; 53 | -------------------------------------------------------------------------------- /src/parser/enum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | /* 10 | * reading an enum 11 | * ```ebnf 12 | * enum ::= enum_scope? T_ENUM T_STRING (':' NAMESPACE_NAME)? (T_IMPLEMENTS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' ENUM_BODY '}' 13 | * ``` 14 | */ 15 | read_enum_declaration_statement: function (attrs) { 16 | const result = this.node("enum"); 17 | // graceful mode : ignore token & go next 18 | if (!this.expect(this.tok.T_ENUM)) { 19 | return null; 20 | } 21 | this.next().expect(this.tok.T_STRING); 22 | let propName = this.node("identifier"); 23 | const name = this.text(); 24 | this.next(); 25 | propName = propName(name); 26 | const valueType = this.read_enum_value_type(); 27 | const propImplements = this.read_implements_list(); 28 | this.expect("{"); 29 | const body = this.next().read_class_body(false, true); 30 | const node = result(propName, valueType, propImplements, body); 31 | if (attrs) node.attrGroups = attrs; 32 | return node; 33 | }, 34 | 35 | read_enum_value_type: function () { 36 | if (this.token === ":") { 37 | return this.next().read_namespace_name(); 38 | } 39 | 40 | return null; 41 | }, 42 | 43 | read_enum_case: function () { 44 | this.expect(this.tok.T_CASE); 45 | const result = this.node("enumcase"); 46 | let caseName = this.node("identifier"); 47 | const name = this.next().text(); 48 | this.next(); 49 | caseName = caseName(name); 50 | 51 | const value = this.token === "=" ? this.next().read_expr() : null; 52 | this.expect(";"); 53 | 54 | return result(caseName, value); 55 | }, 56 | }; 57 | -------------------------------------------------------------------------------- /src/parser/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | /* 10 | * ```ebnf 11 | * start ::= (namespace | top_statement)* 12 | * ``` 13 | */ 14 | read_start: function () { 15 | if (this.token == this.tok.T_NAMESPACE) { 16 | return this.read_namespace(); 17 | } else { 18 | return this.read_top_statement(); 19 | } 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /src/parser/try.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2018 Glayzzle (BSD3 License) 3 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 4 | * @url http://glayzzle.com 5 | */ 6 | "use strict"; 7 | 8 | module.exports = { 9 | /* 10 | * ```ebnf 11 | * try ::= T_TRY '{' inner_statement* '}' 12 | * ( 13 | * T_CATCH '(' namespace_name (variable)? ')' '{' inner_statement* '}' 14 | * )* 15 | * (T_FINALLY '{' inner_statement* '}')? 16 | * ``` 17 | * @see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L448 18 | * @return {Try} 19 | */ 20 | read_try: function () { 21 | this.expect(this.tok.T_TRY); 22 | const result = this.node("try"); 23 | let always = null; 24 | const catches = []; 25 | const body = this.next().read_statement(); 26 | // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L455 27 | while (this.token === this.tok.T_CATCH) { 28 | const item = this.node("catch"); 29 | this.next().expect("(") && this.next(); 30 | const what = this.read_list(this.read_namespace_name, "|", false); 31 | let variable = null; 32 | if (this.version < 800 || this.token === this.tok.T_VARIABLE) { 33 | variable = this.read_variable(true, false); 34 | } 35 | this.expect(")"); 36 | catches.push(item(this.next().read_statement(), what, variable)); 37 | } 38 | if (this.token === this.tok.T_FINALLY) { 39 | always = this.next().read_statement(); 40 | } 41 | return result(body, catches, always); 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /test/ast.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("./main"); 2 | 3 | describe("Test AST class (edge cases)", function () { 4 | it("test source without location", function () { 5 | const test = parser.create({ 6 | ast: { 7 | withPositions: false, 8 | withSource: true, 9 | }, 10 | }); 11 | const ast = test.parseEval("echo $foo;"); 12 | const echo = ast.children[0]; 13 | expect(echo.loc.source).toBe("echo $foo;"); 14 | expect(echo.loc.start).not.toBeNull(); 15 | expect(echo.loc.end).not.toBeNull(); 16 | 17 | const variable = echo.expressions[0]; 18 | expect(variable.loc.source).toBe("$foo"); 19 | }); 20 | it("test undefined node", function () { 21 | const test = parser.create(); 22 | expect(() => { 23 | const node = test.parser.node("foo"); 24 | node(); 25 | }).toThrow(/foo/); 26 | }); 27 | it("test debug mode", function () { 28 | const test = parser.create({ 29 | parser: { 30 | debug: true, 31 | }, 32 | }); 33 | test.parseEval("1 + 1;"); 34 | }); 35 | it("test debug mode / errors", function () { 36 | const test = parser.create({ 37 | parser: { 38 | debug: true, 39 | }, 40 | }); 41 | expect(() => { 42 | test.parseEval("1 + ;"); 43 | }).toThrow(); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/benchmark.js: -------------------------------------------------------------------------------- 1 | const parser = require("./main"); 2 | const Benchmark = require("benchmark"); 3 | const suite = new Benchmark.Suite(); 4 | 5 | const code = ` 6 | { 29 | console.log(String(event.target)); 30 | }); 31 | suite.run(); 32 | -------------------------------------------------------------------------------- /test/benchmark2.js: -------------------------------------------------------------------------------- 1 | const parser = require("./main"); 2 | 3 | const code = ` 4 | 123; 26 | } 27 | `, 28 | { 29 | parser: { 30 | debug: true, 31 | extractDoc: true, 32 | }, 33 | ast: { 34 | withPositions: true, 35 | withSource: true, 36 | }, 37 | }, 38 | ); 39 | console.log(util.inspect(ast, false, 10, true)); 40 | -------------------------------------------------------------------------------- /test/main.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Defines a list of helpers for tests 3 | * Copyright (C) 2017 Glayzzle (BSD3 License) 4 | * @authors https://github.com/glayzzle/php-parser/graphs/contributors 5 | * @url http://glayzzle.com 6 | */ 7 | 8 | const parser = require("../src/index"); 9 | // @todo : move here the debug code 10 | // @todo : add an automated token check (with php7) 11 | module.exports = parser; 12 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/boolean.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`boolean assign (2) 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Assign { 8 | "kind": "assign", 9 | "left": Variable { 10 | "curly": false, 11 | "kind": "variable", 12 | "name": "var", 13 | }, 14 | "operator": "=", 15 | "right": Boolean { 16 | "kind": "boolean", 17 | "raw": "false", 18 | "value": false, 19 | }, 20 | }, 21 | "kind": "expressionstatement", 22 | }, 23 | ], 24 | "errors": [], 25 | "kind": "program", 26 | } 27 | `; 28 | 29 | exports[`boolean assign 1`] = ` 30 | Program { 31 | "children": [ 32 | ExpressionStatement { 33 | "expression": Assign { 34 | "kind": "assign", 35 | "left": Variable { 36 | "curly": false, 37 | "kind": "variable", 38 | "name": "var", 39 | }, 40 | "operator": "=", 41 | "right": Boolean { 42 | "kind": "boolean", 43 | "raw": "true", 44 | "value": true, 45 | }, 46 | }, 47 | "kind": "expressionstatement", 48 | }, 49 | ], 50 | "errors": [], 51 | "kind": "program", 52 | } 53 | `; 54 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/buffer.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test buffers handles buffers as input 1`] = ` 4 | Program { 5 | "children": [ 6 | Echo { 7 | "expressions": [ 8 | String { 9 | "isDoubleQuote": true, 10 | "kind": "string", 11 | "raw": ""test"", 12 | "unicode": false, 13 | "value": "test", 14 | }, 15 | ], 16 | "kind": "echo", 17 | "shortForm": false, 18 | }, 19 | ], 20 | "errors": [], 21 | "kind": "program", 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/clone.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`clone assign 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Assign { 8 | "kind": "assign", 9 | "left": Variable { 10 | "curly": false, 11 | "kind": "variable", 12 | "name": "var", 13 | }, 14 | "operator": "=", 15 | "right": Clone { 16 | "kind": "clone", 17 | "what": Variable { 18 | "curly": false, 19 | "kind": "variable", 20 | "name": "obj", 21 | }, 22 | }, 23 | }, 24 | "kind": "expressionstatement", 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`clone simple 1`] = ` 33 | Program { 34 | "children": [ 35 | ExpressionStatement { 36 | "expression": Clone { 37 | "kind": "clone", 38 | "what": Variable { 39 | "curly": false, 40 | "kind": "variable", 41 | "name": "obj", 42 | }, 43 | }, 44 | "kind": "expressionstatement", 45 | }, 46 | ], 47 | "errors": [], 48 | "kind": "program", 49 | } 50 | `; 51 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/constantstatement.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`constantstatement multiple 1`] = ` 4 | Program { 5 | "children": [ 6 | ConstantStatement { 7 | "constants": [ 8 | Constant { 9 | "kind": "constant", 10 | "name": Identifier { 11 | "kind": "identifier", 12 | "name": "CONSTANT", 13 | }, 14 | "value": String { 15 | "isDoubleQuote": true, 16 | "kind": "string", 17 | "raw": ""Hello world!"", 18 | "unicode": false, 19 | "value": "Hello world!", 20 | }, 21 | }, 22 | Constant { 23 | "kind": "constant", 24 | "name": Identifier { 25 | "kind": "identifier", 26 | "name": "OTHER_CONSTANT", 27 | }, 28 | "value": String { 29 | "isDoubleQuote": true, 30 | "kind": "string", 31 | "raw": ""Other hello world!"", 32 | "unicode": false, 33 | "value": "Other hello world!", 34 | }, 35 | }, 36 | ], 37 | "kind": "constantstatement", 38 | }, 39 | ], 40 | "errors": [], 41 | "kind": "program", 42 | } 43 | `; 44 | 45 | exports[`constantstatement simple 1`] = ` 46 | Program { 47 | "children": [ 48 | ConstantStatement { 49 | "constants": [ 50 | Constant { 51 | "kind": "constant", 52 | "name": Identifier { 53 | "kind": "identifier", 54 | "name": "CONSTANT", 55 | }, 56 | "value": String { 57 | "isDoubleQuote": true, 58 | "kind": "string", 59 | "raw": ""Hello world!"", 60 | "unicode": false, 61 | "value": "Hello world!", 62 | }, 63 | }, 64 | ], 65 | "kind": "constantstatement", 66 | }, 67 | ], 68 | "errors": [], 69 | "kind": "program", 70 | } 71 | `; 72 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/echo.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`echo multiple 1`] = ` 4 | Program { 5 | "children": [ 6 | Echo { 7 | "expressions": [ 8 | String { 9 | "isDoubleQuote": true, 10 | "kind": "string", 11 | "raw": ""string"", 12 | "unicode": false, 13 | "value": "string", 14 | }, 15 | String { 16 | "isDoubleQuote": true, 17 | "kind": "string", 18 | "raw": ""string"", 19 | "unicode": false, 20 | "value": "string", 21 | }, 22 | ], 23 | "kind": "echo", 24 | "shortForm": false, 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`echo simple 1`] = ` 33 | Program { 34 | "children": [ 35 | Echo { 36 | "expressions": [ 37 | String { 38 | "isDoubleQuote": true, 39 | "kind": "string", 40 | "raw": ""string"", 41 | "unicode": false, 42 | "value": "string", 43 | }, 44 | ], 45 | "kind": "echo", 46 | "shortForm": false, 47 | }, 48 | ], 49 | "errors": [], 50 | "kind": "program", 51 | } 52 | `; 53 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/empty.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`empty assign 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Assign { 8 | "kind": "assign", 9 | "left": Variable { 10 | "curly": false, 11 | "kind": "variable", 12 | "name": "var", 13 | }, 14 | "operator": "=", 15 | "right": Empty { 16 | "expression": Variable { 17 | "curly": false, 18 | "kind": "variable", 19 | "name": "var", 20 | }, 21 | "kind": "empty", 22 | }, 23 | }, 24 | "kind": "expressionstatement", 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`empty simple 1`] = ` 33 | Program { 34 | "children": [ 35 | ExpressionStatement { 36 | "expression": Empty { 37 | "expression": Variable { 38 | "curly": false, 39 | "kind": "variable", 40 | "name": "var", 41 | }, 42 | "kind": "empty", 43 | }, 44 | "kind": "expressionstatement", 45 | }, 46 | ], 47 | "errors": [], 48 | "kind": "program", 49 | } 50 | `; 51 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/eval.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`eval simple 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Eval { 8 | "kind": "eval", 9 | "source": String { 10 | "isDoubleQuote": true, 11 | "kind": "string", 12 | "raw": ""command"", 13 | "unicode": false, 14 | "value": "command", 15 | }, 16 | }, 17 | "kind": "expressionstatement", 18 | }, 19 | ], 20 | "errors": [], 21 | "kind": "program", 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/global.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`global mutliple 1`] = ` 4 | Program { 5 | "children": [ 6 | Global { 7 | "items": [ 8 | Variable { 9 | "curly": false, 10 | "kind": "variable", 11 | "name": "var", 12 | }, 13 | Variable { 14 | "curly": false, 15 | "kind": "variable", 16 | "name": "foo", 17 | }, 18 | ], 19 | "kind": "global", 20 | }, 21 | ], 22 | "errors": [], 23 | "kind": "program", 24 | } 25 | `; 26 | 27 | exports[`global simple 1`] = ` 28 | Program { 29 | "children": [ 30 | Global { 31 | "items": [ 32 | Variable { 33 | "curly": false, 34 | "kind": "variable", 35 | "name": "var", 36 | }, 37 | ], 38 | "kind": "global", 39 | }, 40 | ], 41 | "errors": [], 42 | "kind": "program", 43 | } 44 | `; 45 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/goto.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`goto simple 1`] = ` 4 | Program { 5 | "children": [ 6 | Goto { 7 | "kind": "goto", 8 | "label": Identifier { 9 | "kind": "identifier", 10 | "name": "a", 11 | }, 12 | }, 13 | Echo { 14 | "expressions": [ 15 | String { 16 | "isDoubleQuote": true, 17 | "kind": "string", 18 | "raw": ""Foo"", 19 | "unicode": false, 20 | "value": "Foo", 21 | }, 22 | ], 23 | "kind": "echo", 24 | "shortForm": false, 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`goto simple 2`] = ` 33 | Program { 34 | "children": [ 35 | Goto { 36 | "kind": "goto", 37 | "label": Identifier { 38 | "kind": "identifier", 39 | "name": "longName", 40 | }, 41 | }, 42 | Echo { 43 | "expressions": [ 44 | String { 45 | "isDoubleQuote": true, 46 | "kind": "string", 47 | "raw": ""Foo"", 48 | "unicode": false, 49 | "value": "Foo", 50 | }, 51 | ], 52 | "kind": "echo", 53 | "shortForm": false, 54 | }, 55 | ], 56 | "errors": [], 57 | "kind": "program", 58 | } 59 | `; 60 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/label.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`label simple 1`] = ` 4 | Program { 5 | "children": [ 6 | Label { 7 | "kind": "label", 8 | "name": Identifier { 9 | "kind": "identifier", 10 | "name": "a", 11 | }, 12 | }, 13 | Echo { 14 | "expressions": [ 15 | String { 16 | "isDoubleQuote": true, 17 | "kind": "string", 18 | "raw": ""Foo"", 19 | "unicode": false, 20 | "value": "Foo", 21 | }, 22 | ], 23 | "kind": "echo", 24 | "shortForm": false, 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`label simple 2`] = ` 33 | Program { 34 | "children": [ 35 | Label { 36 | "kind": "label", 37 | "name": Identifier { 38 | "kind": "identifier", 39 | "name": "longName", 40 | }, 41 | }, 42 | Echo { 43 | "expressions": [ 44 | String { 45 | "isDoubleQuote": true, 46 | "kind": "string", 47 | "raw": ""Foo"", 48 | "unicode": false, 49 | "value": "Foo", 50 | }, 51 | ], 52 | "kind": "echo", 53 | "shortForm": false, 54 | }, 55 | ], 56 | "errors": [], 57 | "kind": "program", 58 | } 59 | `; 60 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/print.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`print simple 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Print { 8 | "expression": String { 9 | "isDoubleQuote": true, 10 | "kind": "string", 11 | "raw": ""string"", 12 | "unicode": false, 13 | "value": "string", 14 | }, 15 | "kind": "print", 16 | }, 17 | "kind": "expressionstatement", 18 | }, 19 | ], 20 | "errors": [], 21 | "kind": "program", 22 | } 23 | `; 24 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/return.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`return no expression 1`] = ` 4 | Program { 5 | "children": [ 6 | Return { 7 | "expr": null, 8 | "kind": "return", 9 | }, 10 | ], 11 | "errors": [], 12 | "kind": "program", 13 | } 14 | `; 15 | 16 | exports[`return should fail when no ';' at end 1`] = ` 17 | Program { 18 | "children": [ 19 | Return { 20 | "expr": undefined, 21 | "kind": "return", 22 | }, 23 | ], 24 | "errors": [ 25 | Error { 26 | "expected": "EXPR", 27 | "kind": "error", 28 | "line": 1, 29 | "message": "Parse Error : syntax error on line 1", 30 | "token": "the end of file (EOF)", 31 | }, 32 | ], 33 | "kind": "program", 34 | } 35 | `; 36 | 37 | exports[`return simple 1`] = ` 38 | Program { 39 | "children": [ 40 | Return { 41 | "expr": String { 42 | "isDoubleQuote": true, 43 | "kind": "string", 44 | "raw": ""string"", 45 | "unicode": false, 46 | "value": "string", 47 | }, 48 | "kind": "return", 49 | }, 50 | ], 51 | "errors": [], 52 | "kind": "program", 53 | } 54 | `; 55 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/silent.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`silent simple 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Silent { 8 | "expr": Call { 9 | "arguments": [], 10 | "kind": "call", 11 | "what": Name { 12 | "kind": "name", 13 | "name": "call", 14 | "resolution": "uqn", 15 | }, 16 | }, 17 | "kind": "silent", 18 | }, 19 | "kind": "expressionstatement", 20 | }, 21 | ], 22 | "errors": [], 23 | "kind": "program", 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/throw.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`throw arrow function 1`] = ` 4 | Program { 5 | "children": [ 6 | ExpressionStatement { 7 | "expression": Assign { 8 | "kind": "assign", 9 | "left": Variable { 10 | "curly": false, 11 | "kind": "variable", 12 | "name": "fn", 13 | }, 14 | "operator": "=", 15 | "right": Closure { 16 | "arguments": [], 17 | "attrGroups": [], 18 | "body": Throw { 19 | "kind": "throw", 20 | "what": New { 21 | "arguments": [ 22 | String { 23 | "isDoubleQuote": true, 24 | "kind": "string", 25 | "raw": ""oops"", 26 | "unicode": false, 27 | "value": "oops", 28 | }, 29 | ], 30 | "kind": "new", 31 | "what": Name { 32 | "kind": "name", 33 | "name": "Exception", 34 | "resolution": "uqn", 35 | }, 36 | }, 37 | }, 38 | "byref": false, 39 | "isStatic": false, 40 | "kind": "arrowfunc", 41 | "nullable": false, 42 | "type": null, 43 | }, 44 | }, 45 | "kind": "expressionstatement", 46 | }, 47 | ], 48 | "errors": [], 49 | "kind": "program", 50 | } 51 | `; 52 | 53 | exports[`throw simple 1`] = ` 54 | Program { 55 | "children": [ 56 | Throw { 57 | "kind": "throw", 58 | "what": New { 59 | "arguments": [ 60 | String { 61 | "isDoubleQuote": true, 62 | "kind": "string", 63 | "raw": ""Error"", 64 | "unicode": false, 65 | "value": "Error", 66 | }, 67 | ], 68 | "kind": "new", 69 | "what": Name { 70 | "kind": "name", 71 | "name": "Exception", 72 | "resolution": "uqn", 73 | }, 74 | }, 75 | }, 76 | ], 77 | "errors": [], 78 | "kind": "program", 79 | } 80 | `; 81 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/token.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test tokens statements hello world 1`] = ` 4 | Program { 5 | "children": [ 6 | Inline { 7 | "kind": "inline", 8 | "raw": "Hello ", 9 | "value": "Hello ", 10 | }, 11 | Echo { 12 | "expressions": [ 13 | Variable { 14 | "curly": false, 15 | "kind": "variable", 16 | "name": "world", 17 | }, 18 | ], 19 | "kind": "echo", 20 | "shortForm": true, 21 | }, 22 | ], 23 | "errors": [], 24 | "kind": "program", 25 | "tokens": [ 26 | [ 27 | "T_INLINE_HTML", 28 | "Hello ", 29 | 1, 30 | 0, 31 | 6, 32 | ], 33 | [ 34 | "T_OPEN_TAG_WITH_ECHO", 35 | "", 71 | 1, 72 | 18, 73 | 20, 74 | ], 75 | ], 76 | } 77 | `; 78 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/trait.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`trait trait name as identifier 1`] = ` 4 | Program { 5 | "children": [ 6 | Trait { 7 | "body": [], 8 | "kind": "trait", 9 | "name": Identifier { 10 | "kind": "identifier", 11 | "name": "A", 12 | }, 13 | }, 14 | ], 15 | "errors": [], 16 | "kind": "program", 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /test/snapshot/__snapshots__/unset.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`unset multiple 1`] = ` 4 | Program { 5 | "children": [ 6 | Unset { 7 | "kind": "unset", 8 | "variables": [ 9 | Variable { 10 | "curly": false, 11 | "kind": "variable", 12 | "name": "var", 13 | }, 14 | Variable { 15 | "curly": false, 16 | "kind": "variable", 17 | "name": "var", 18 | }, 19 | Variable { 20 | "curly": false, 21 | "kind": "variable", 22 | "name": "var", 23 | }, 24 | ], 25 | }, 26 | ], 27 | "errors": [], 28 | "kind": "program", 29 | } 30 | `; 31 | 32 | exports[`unset simple 1`] = ` 33 | Program { 34 | "children": [ 35 | Unset { 36 | "kind": "unset", 37 | "variables": [ 38 | Variable { 39 | "curly": false, 40 | "kind": "variable", 41 | "name": "var", 42 | }, 43 | ], 44 | }, 45 | ], 46 | "errors": [], 47 | "kind": "program", 48 | } 49 | `; 50 | 51 | exports[`unset trailing comma #2 1`] = ` 52 | Program { 53 | "children": [ 54 | Unset { 55 | "kind": "unset", 56 | "variables": [ 57 | Variable { 58 | "curly": false, 59 | "kind": "variable", 60 | "name": "foo", 61 | }, 62 | Variable { 63 | "curly": false, 64 | "kind": "variable", 65 | "name": "bar", 66 | }, 67 | ], 68 | }, 69 | ], 70 | "errors": [], 71 | "kind": "program", 72 | } 73 | `; 74 | 75 | exports[`unset trailing comma 1`] = ` 76 | Program { 77 | "children": [ 78 | Unset { 79 | "kind": "unset", 80 | "variables": [ 81 | Variable { 82 | "curly": false, 83 | "kind": "variable", 84 | "name": "foo", 85 | }, 86 | ], 87 | }, 88 | ], 89 | "errors": [], 90 | "kind": "program", 91 | } 92 | `; 93 | -------------------------------------------------------------------------------- /test/snapshot/arrowfunc.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("arrow function", () => { 4 | it.each([ 5 | ["simple", '$var = fn() => "something";'], 6 | ["argument", '$var = fn($arg) => "something";'], 7 | ["argument by ref", '$var = fn(&$arg) => "something";'], 8 | ["arguments", '$var = fn($arg, $arg, $arg) => "something";'], 9 | ["return type", '$var = fn(): ?string => "something";'], 10 | ["inside call", `call(fn($arg) => $arg);`], 11 | ])("%s", function (_, code) { 12 | expect(parser.parseEval(code)).toMatchSnapshot(); 13 | }); 14 | 15 | it("error / fn passes on php7.3", () => { 16 | expect( 17 | parser.parseEval(`function fn($arg) { return $arg; }`, { 18 | parser: { 19 | version: "7.3", // disable the php 7.4 support 20 | }, 21 | }), 22 | ).toMatchSnapshot(); 23 | }); 24 | it("error / fn fails on php7.4", () => { 25 | expect( 26 | parser.parseEval(`function fn($arg) { return $arg; }`, { 27 | parser: { 28 | version: "7.4", // enable the php 7.4 support 29 | suppressErrors: true, 30 | }, 31 | }), 32 | ).toMatchSnapshot(); 33 | }); 34 | it("error / empty not allowed", () => { 35 | expect( 36 | parser.parseEval("$var = fn() => ;", { 37 | parser: { 38 | suppressErrors: true, 39 | }, 40 | }), 41 | ).toMatchSnapshot(); 42 | }); 43 | it("error / arrow functions before PHP 7.4", () => { 44 | expect( 45 | parser.parseEval(`$fn1 = fn($x) => $x + $y;`, { 46 | parser: { 47 | version: "7.3", 48 | suppressErrors: true, 49 | }, 50 | }), 51 | ).toMatchSnapshot(); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/snapshot/assign.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("assign", () => { 4 | it("simple", () => { 5 | expect(parser.parseEval("$var = 1;")).toMatchSnapshot(); 6 | }); 7 | it("variable", () => { 8 | expect(parser.parseEval("$var = $var;")).toMatchSnapshot(); 9 | }); 10 | it("multiple", () => { 11 | expect(parser.parseEval("$var = $var = $var;")).toMatchSnapshot(); 12 | }); 13 | it("+=", () => { 14 | expect(parser.parseEval("$var += $var;")).toMatchSnapshot(); 15 | }); 16 | it("-=", () => { 17 | expect(parser.parseEval("$var -= $var;")).toMatchSnapshot(); 18 | }); 19 | it("*=", () => { 20 | expect(parser.parseEval("$var *= $var;")).toMatchSnapshot(); 21 | }); 22 | it("**=", () => { 23 | expect(parser.parseEval("$var **= $var;")).toMatchSnapshot(); 24 | }); 25 | it("/=", () => { 26 | expect(parser.parseEval("$var /= $var;")).toMatchSnapshot(); 27 | }); 28 | it(".=", () => { 29 | expect(parser.parseEval("$var .= $var;")).toMatchSnapshot(); 30 | }); 31 | it("%=", () => { 32 | expect(parser.parseEval("$var %= $var;")).toMatchSnapshot(); 33 | }); 34 | it("&=", () => { 35 | expect(parser.parseEval("$var &= $var;")).toMatchSnapshot(); 36 | }); 37 | it("|=", () => { 38 | expect(parser.parseEval("$var |= $var;")).toMatchSnapshot(); 39 | }); 40 | it("^=", () => { 41 | expect(parser.parseEval("$var ^= $var;")).toMatchSnapshot(); 42 | }); 43 | it("<<=", () => { 44 | expect(parser.parseEval("$var <<= $var;")).toMatchSnapshot(); 45 | }); 46 | it(">>=", () => { 47 | expect(parser.parseEval("$var >>= $var;")).toMatchSnapshot(); 48 | }); 49 | it("??=", () => { 50 | expect(parser.parseEval("$var ??= $var;")).toMatchSnapshot(); 51 | }); 52 | it("??= with bin", () => { 53 | expect(parser.parseEval("$var ??= $var + 10;")).toMatchSnapshot(); 54 | }); 55 | it("??= (php < 7)", function () { 56 | const astErr = parser.parseEval(`$var ??= $var;`, { 57 | parser: { 58 | version: "5.6", 59 | suppressErrors: true, 60 | }, 61 | }); 62 | expect(astErr).toMatchSnapshot(); 63 | }); 64 | it("with ref", () => { 65 | expect(parser.parseEval("$bar = &$foo;")).toMatchSnapshot(); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /test/snapshot/boolean.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("boolean", () => { 4 | it("assign", () => { 5 | expect(parser.parseEval("$var = true;")).toMatchSnapshot(); 6 | }); 7 | it("assign (2)", () => { 8 | expect(parser.parseEval("$var = false;")).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/snapshot/break.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("break", () => { 4 | it("simple", () => { 5 | expect(parser.parseEval("break;")).toMatchSnapshot(); 6 | }); 7 | it("argument 0", () => { 8 | expect(parser.parseEval("break 0;")).toMatchSnapshot(); 9 | }); 10 | it("argument 1", () => { 11 | expect(parser.parseEval("break 1;")).toMatchSnapshot(); 12 | }); 13 | it("argument 2", () => { 14 | expect(parser.parseEval("break 2;")).toMatchSnapshot(); 15 | }); 16 | it("with parens", () => { 17 | expect(parser.parseEval("break (1);")).toMatchSnapshot(); 18 | }); 19 | // Deprecated since 5.4.0 20 | it("with expression", () => { 21 | expect(parser.parseEval("break $var;")).toMatchSnapshot(); 22 | }); 23 | it("should fail when no ';' at end", function () { 24 | expect( 25 | parser.parseEval("break", { 26 | parser: { suppressErrors: true }, 27 | }), 28 | ).toMatchSnapshot(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/snapshot/buffer.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test buffers", function () { 4 | it("handles buffers as input", function () { 5 | const buffer = new Buffer('echo "test"'); 6 | expect(parser.parseEval(buffer)).toMatchSnapshot(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/snapshot/classconstant.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("classconstant", () => { 4 | it("simple", () => { 5 | expect( 6 | parser.parseEval('class Foo { const CONSTANT = "Hello world!"; }'), 7 | ).toMatchSnapshot(); 8 | }); 9 | it("simple using 8.3", () => { 10 | expect( 11 | parser.parseEval(`class Foo { const CONSTANT = "Hello world!"; }`, { 12 | parser: { version: 803 }, 13 | }), 14 | ).toMatchSnapshot(); 15 | }); 16 | 17 | it("multiple", () => { 18 | expect( 19 | parser.parseEval( 20 | 'class Foo { const CONSTANT = "Hello world!", OTHER_CONSTANT = "Other hello world!"; }', 21 | ), 22 | ).toMatchSnapshot(); 23 | }); 24 | 25 | it("multiple 8.3", () => { 26 | expect( 27 | parser.parseEval( 28 | 'class Foo { const NAME_1 = "Hello world!", NAME_2 = "Other hello world!"; }', 29 | { 30 | parser: { version: 803 }, 31 | }, 32 | ), 33 | ).toMatchSnapshot(); 34 | }); 35 | 36 | it("public", () => { 37 | expect( 38 | parser.parseEval('class Foo { public const CONSTANT = "Hello world!"; }'), 39 | ).toMatchSnapshot(); 40 | }); 41 | it("protected", () => { 42 | expect( 43 | parser.parseEval( 44 | 'class Foo { protected const CONSTANT = "Hello world!"; }', 45 | ), 46 | ).toMatchSnapshot(); 47 | }); 48 | it("private", () => { 49 | expect( 50 | parser.parseEval( 51 | 'class Foo { private const CONSTANT = "Hello world!"; }', 52 | ), 53 | ).toMatchSnapshot(); 54 | }); 55 | it("final", () => { 56 | expect( 57 | parser.parseEval( 58 | 'class Foo { final public const CONSTANT = "Hello world!"; }', 59 | ), 60 | ).toMatchSnapshot(); 61 | }); 62 | it("type hinted (supported)", () => { 63 | expect( 64 | parser.parseEval( 65 | 'class Foo { public const string CONSTANT = "Hello world!"; }', 66 | { parser: { version: 803 } }, 67 | ), 68 | ).toMatchSnapshot(); 69 | }); 70 | it("type hinted (unsupported)", () => { 71 | expect(() => 72 | parser.parseEval( 73 | 'class Foo { public const string CONSTANT = "Hello world!"; }', 74 | { parser: { version: 802 } }, 75 | ), 76 | ).toThrowErrorMatchingSnapshot(); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /test/snapshot/classreference.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("classreference", function () { 4 | it("variable", function () { 5 | expect(parser.parseEval("Foo::$var;")).toMatchSnapshot(); 6 | }); 7 | it("constant", function () { 8 | expect(parser.parseEval("Foo::CONSTANT;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("Foo::call();")).toMatchSnapshot(); 12 | }); 13 | it("argument type", function () { 14 | expect(parser.parseEval("function foo(Foo $arg) {}")).toMatchSnapshot(); 15 | }); 16 | it("argument type (2)", function () { 17 | expect( 18 | parser.parseEval("function foo(Foo\\Foo $arg) {}"), 19 | ).toMatchSnapshot(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/snapshot/clone.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("clone", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("clone $obj;")).toMatchSnapshot(); 6 | }); 7 | it("assign", function () { 8 | expect(parser.parseEval("$var = clone $obj;")).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/snapshot/closure.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("closure", () => { 4 | it("simple", () => { 5 | expect( 6 | parser.parseEval('$var = function() { echo "something"; };'), 7 | ).toMatchSnapshot(); 8 | }); 9 | it("empty", () => { 10 | expect(parser.parseEval("$var = function() {};")).toMatchSnapshot(); 11 | }); 12 | it("argument", () => { 13 | expect( 14 | parser.parseEval('$var = function($arg) { echo "something"; };'), 15 | ).toMatchSnapshot(); 16 | }); 17 | it("argument by ref", () => { 18 | expect( 19 | parser.parseEval('$var = function(&$arg) { echo "something"; };'), 20 | ).toMatchSnapshot(); 21 | }); 22 | it("arguments", () => { 23 | expect( 24 | parser.parseEval( 25 | '$var = function($arg, $arg, $arg) { echo "something"; };', 26 | ), 27 | ).toMatchSnapshot(); 28 | }); 29 | it("use", () => { 30 | expect( 31 | parser.parseEval( 32 | '$var = function() use ($message) { echo "something"; };', 33 | ), 34 | ).toMatchSnapshot(); 35 | }); 36 | it("use multiple", () => { 37 | expect( 38 | parser.parseEval( 39 | '$var = function() use ($message, $message1, $message2) { echo "something"; };', 40 | ), 41 | ).toMatchSnapshot(); 42 | }); 43 | it("use by ref", () => { 44 | expect( 45 | parser.parseEval( 46 | '$var = function() use (&$message) { echo "something"; };', 47 | ), 48 | ).toMatchSnapshot(); 49 | }); 50 | it("argument and use", () => { 51 | expect( 52 | parser.parseEval( 53 | '$var = function($arg) use ($use) { echo "something"; };', 54 | ), 55 | ).toMatchSnapshot(); 56 | }); 57 | it("arguments and uses", () => { 58 | expect( 59 | parser.parseEval( 60 | '$var = function($arg, $arg, $arg) use ($use, $use, $use) { echo "something"; };', 61 | ), 62 | ).toMatchSnapshot(); 63 | }); 64 | it("inside call", () => { 65 | expect( 66 | parser.parseEval(`call(function ($arg) { return $arg; });`), 67 | ).toMatchSnapshot(); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /test/snapshot/constantstatement.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("constantstatement", () => { 4 | it("simple", () => { 5 | expect( 6 | parser.parseEval('const CONSTANT = "Hello world!";'), 7 | ).toMatchSnapshot(); 8 | }); 9 | it("multiple", () => { 10 | expect( 11 | parser.parseEval( 12 | 'const CONSTANT = "Hello world!", OTHER_CONSTANT = "Other hello world!";', 13 | ), 14 | ).toMatchSnapshot(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/snapshot/continue.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("continue", () => { 4 | it("simple", () => { 5 | expect(parser.parseEval("continue;")).toMatchSnapshot(); 6 | }); 7 | it("argument 0", () => { 8 | expect(parser.parseEval("continue 0;")).toMatchSnapshot(); 9 | }); 10 | it("argument 1", () => { 11 | expect(parser.parseEval("continue 1;")).toMatchSnapshot(); 12 | }); 13 | it("argument 2", () => { 14 | expect(parser.parseEval("continue 2;")).toMatchSnapshot(); 15 | }); 16 | it("with parens", () => { 17 | expect(parser.parseEval("continue (1);")).toMatchSnapshot(); 18 | }); 19 | // Deprecated since 5.4.0 20 | it("with expression", () => { 21 | expect(parser.parseEval("continue $var;")).toMatchSnapshot(); 22 | }); 23 | it("should fail when no ';' at end", function () { 24 | expect( 25 | parser.parseEval("continue", { 26 | parser: { suppressErrors: true }, 27 | }), 28 | ).toMatchSnapshot(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/snapshot/declare.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("declare", function () { 4 | it("strict_types", function () { 5 | expect(parser.parseEval("declare (strict_types=1);")).toMatchSnapshot(); 6 | }); 7 | it("ticks", function () { 8 | expect(parser.parseEval("declare(ticks=1);")).toMatchSnapshot(); 9 | }); 10 | it("encoding", function () { 11 | expect( 12 | parser.parseEval("declare(encoding='ISO-8859-1');"), 13 | ).toMatchSnapshot(); 14 | }); 15 | it("nested", function () { 16 | expect(parser.parseEval("declare(ticks=1) { }")).toMatchSnapshot(); 17 | }); 18 | it("mode short", function () { 19 | expect( 20 | parser.parseEval('declare(ticks=1): echo "something"; enddeclare;'), 21 | ).toMatchSnapshot(); 22 | }); 23 | it("multiple", function () { 24 | expect(parser.parseEval("declare (A='B', C='D') { }")).toMatchSnapshot(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/snapshot/echo.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("echo", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('echo "string";')).toMatchSnapshot(); 6 | }); 7 | it("multiple", function () { 8 | expect(parser.parseEval('echo "string", "string";')).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/snapshot/empty.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("empty", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("empty($var);")).toMatchSnapshot(); 6 | }); 7 | it("assign", function () { 8 | expect(parser.parseEval("$var = empty($var);")).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/snapshot/eval.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("eval", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('eval("command");')).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/snapshot/exit.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("exit", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("exit();")).toMatchSnapshot(); 6 | }); 7 | it("argument", function () { 8 | expect(parser.parseEval("exit($var);")).toMatchSnapshot(); 9 | }); 10 | it("die", function () { 11 | expect(parser.parseEval("die();")).toMatchSnapshot(); 12 | }); 13 | it("exit without expression", function () { 14 | expect(parser.parseEval("exit;")).toMatchSnapshot(); 15 | }); 16 | it("exit with empty expression", function () { 17 | expect(parser.parseEval("exit();")).toMatchSnapshot(); 18 | }); 19 | it("exit with expression", function () { 20 | expect(parser.parseEval("exit(10 + $var);")).toMatchSnapshot(); 21 | }); 22 | it("die without expression", function () { 23 | expect(parser.parseEval("die;")).toMatchSnapshot(); 24 | }); 25 | it("die with empty expression", function () { 26 | expect(parser.parseEval("die();")).toMatchSnapshot(); 27 | }); 28 | it("die with expression", function () { 29 | expect(parser.parseEval("die(10 + $var);")).toMatchSnapshot(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/snapshot/foreach.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("foreach", function () { 4 | it("as variable", function () { 5 | expect( 6 | parser.parseEval(` 7 | foreach ($array as $var) { 8 | echo $a; 9 | } 10 | `), 11 | ).toMatchSnapshot(); 12 | }); 13 | 14 | it("as variable by ref", function () { 15 | expect( 16 | parser.parseEval(` 17 | foreach ($array as &$var) { 18 | echo $a; 19 | } 20 | `), 21 | ).toMatchSnapshot(); 22 | }); 23 | 24 | it("as list", function () { 25 | expect( 26 | parser.parseEval(` 27 | foreach ($array as list($a, $b)) { 28 | echo $a; 29 | } 30 | `), 31 | ).toMatchSnapshot(); 32 | }); 33 | 34 | it("as short list", function () { 35 | expect( 36 | parser.parseEval(` 37 | foreach ($array as [$a, $b]) { 38 | echo $a; 39 | } 40 | `), 41 | ).toMatchSnapshot(); 42 | }); 43 | 44 | it("as list with key", function () { 45 | expect( 46 | parser.parseEval(` 47 | foreach ($array as $v => list($a, $b)) { 48 | echo $v; 49 | } 50 | `), 51 | ).toMatchSnapshot(); 52 | }); 53 | 54 | it("as short list with key", function () { 55 | expect( 56 | parser.parseEval(` 57 | foreach ($array as $v => [$a, $b]) { 58 | echo $v; 59 | } 60 | `), 61 | ).toMatchSnapshot(); 62 | }); 63 | 64 | it("unpacking", function () { 65 | expect( 66 | parser.parseEval(` 67 | foreach ([...$var, 2, 3, 4] as $value) { 68 | print_r($value); 69 | } 70 | `), 71 | ).toMatchSnapshot(); 72 | }); 73 | 74 | it("unpacking #2", function () { 75 | expect( 76 | parser.parseEval(` 77 | foreach (array(...$var, 2, 3, 4) as $value) { 78 | print_r($value); 79 | } 80 | `), 81 | ).toMatchSnapshot(); 82 | }); 83 | 84 | it("unpacking #3", function () { 85 | expect( 86 | parser.parseEval(` 87 | foreach ([[...$var], 2, 3, 4] as $value) { 88 | print_r($value); 89 | } 90 | `), 91 | ).toMatchSnapshot(); 92 | }); 93 | 94 | it("unpacking #4", function () { 95 | expect( 96 | parser.parseEval(` 97 | foreach (array(array(...$var), 2, 3, 4) as $value) { 98 | print_r($value); 99 | } 100 | `), 101 | ).toMatchSnapshot(); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /test/snapshot/global.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("global", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("global $var;")).toMatchSnapshot(); 6 | }); 7 | it("mutliple", function () { 8 | expect(parser.parseEval("global $var, $foo;")).toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/snapshot/goto.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("goto", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('goto a; echo "Foo";')).toMatchSnapshot(); 6 | expect(parser.parseEval('goto longName; echo "Foo";')).toMatchSnapshot(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/snapshot/include.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("include", function () { 4 | it("include", function () { 5 | expect(parser.parseEval('include "string";')).toMatchSnapshot(); 6 | }); 7 | it("include once", function () { 8 | expect(parser.parseEval('include_once "string";')).toMatchSnapshot(); 9 | }); 10 | it("require", function () { 11 | expect(parser.parseEval('require "string";')).toMatchSnapshot(); 12 | }); 13 | it("require_once", function () { 14 | expect(parser.parseEval('require_once "string";')).toMatchSnapshot(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/snapshot/interface.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("interface", function () { 4 | it("interface name as identifier", function () { 5 | expect(parser.parseEval("interface A {}")).toMatchSnapshot(); 6 | }); 7 | it("extends", function () { 8 | expect(parser.parseEval("interface A extends B {}")).toMatchSnapshot(); 9 | }); 10 | it("multiple extends", function () { 11 | expect(parser.parseEval("interface A extends B, C {}")).toMatchSnapshot(); 12 | }); 13 | it("invalid private flag", function () { 14 | expect( 15 | parser.parseEval("interface A { private const B = 1; }", { 16 | parser: { suppressErrors: true }, 17 | }), 18 | ).toMatchSnapshot(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/snapshot/isset.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("isset", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("isset($var);")).toMatchSnapshot(); 6 | }); 7 | it("multiple", function () { 8 | expect(parser.parseEval("isset($var, $var, $var);")).toMatchSnapshot(); 9 | }); 10 | it("assign", function () { 11 | expect(parser.parseEval("$var = isset($var);")).toMatchSnapshot(); 12 | }); 13 | it("trailing comma", function () { 14 | expect(parser.parseEval("isset($foo,);")).toMatchSnapshot(); 15 | }); 16 | it("trailing comma #2", function () { 17 | expect(parser.parseEval("isset($foo, $bar,);")).toMatchSnapshot(); 18 | }); 19 | it("test errors", function () { 20 | const errAst = parser.parseEval("$var = isset();", { 21 | parser: { suppressErrors: true }, 22 | }); 23 | expect(errAst).toMatchSnapshot(); 24 | expect(errAst.errors.length).not.toBe(0); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/snapshot/label.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("label", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('a: echo "Foo";')).toMatchSnapshot(); 6 | expect(parser.parseEval('longName: echo "Foo";')).toMatchSnapshot(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/snapshot/magic.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("magic", function () { 4 | it("__LINE__", function () { 5 | expect(parser.parseEval("__LINE__;")).toMatchSnapshot(); 6 | }); 7 | it("__LINE__ lowercase", function () { 8 | expect(parser.parseEval("__line__;")).toMatchSnapshot(); 9 | }); 10 | it("__FILE__", function () { 11 | expect(parser.parseEval("__FILE__;")).toMatchSnapshot(); 12 | }); 13 | it("__DIR__", function () { 14 | expect(parser.parseEval("__DIR__;")).toMatchSnapshot(); 15 | }); 16 | it("__FUNCTION__", function () { 17 | expect(parser.parseEval("__FUNCTION__;")).toMatchSnapshot(); 18 | }); 19 | it("__CLASS__", function () { 20 | expect(parser.parseEval("__CLASS__;")).toMatchSnapshot(); 21 | }); 22 | it("__TRAIT__", function () { 23 | expect(parser.parseEval("__TRAIT__;")).toMatchSnapshot(); 24 | }); 25 | it("__METHOD__", function () { 26 | expect(parser.parseEval("__METHOD__;")).toMatchSnapshot(); 27 | }); 28 | it("__NAMESPACE__", function () { 29 | expect(parser.parseEval("__NAMESPACE__;")).toMatchSnapshot(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/snapshot/match.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("match", () => { 4 | it("can be parsed", () => { 5 | const ast = parser.parseEval(` 6 | $test = match($a) { 7 | true => 'yes', 8 | false => 'no', 9 | default => null 10 | }; 11 | `); 12 | expect(ast).toMatchSnapshot(); 13 | }); 14 | 15 | it("can have lhs, functions", () => { 16 | const ast = parser.parseEval(` 17 | $test = match(true) { 18 | test($a), abc($b) => 'yes', 19 | default => null 20 | }; 21 | `); 22 | expect(ast).toMatchSnapshot(); 23 | }); 24 | 25 | it("can have multiple values", () => { 26 | const ast = parser.parseEval(` 27 | $test = match(trye) { 28 | 0,1,2,3 => run(), 29 | default => null 30 | }; 31 | `); 32 | expect(ast).toMatchSnapshot(); 33 | }); 34 | it("can have hanging comma", () => { 35 | const ast = parser.parseEval(` 36 | $test = match($test) { 37 | true, => 'ok', 38 | false => throw new Exception('Nope'), 39 | }; 40 | `); 41 | expect(ast).toMatchSnapshot(); 42 | }); 43 | it("does not support older php than 8", () => { 44 | expect(() => { 45 | new parser({ parser: { version: 704 } }).parseEval(` 46 | $test = match($test) { 47 | true => 'ok', 48 | false => 'Nope!', 49 | }; 50 | `); 51 | }).toThrow(SyntaxError); 52 | }); 53 | it("can be nested", () => { 54 | const ast = parser.parseEval(` 55 | $v = match(callMe(1,2,3)) { 56 | null => match($err) { 1 => 'Connect', 2 => 'Auth'}, 57 | match($a) {true => 0, false => -1} => 'Ok' 58 | }; 59 | `); 60 | expect(ast).toMatchSnapshot(); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /test/snapshot/nullsavepropertylookup.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("nullsavepropertylookup", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("$obj?->property;")).toMatchSnapshot(); 6 | }); 7 | it("variable", function () { 8 | expect(parser.parseEval("$obj?->$property;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("$obj?->call();")).toMatchSnapshot(); 12 | }); 13 | it("multiple", function () { 14 | expect( 15 | parser.parseEval("$obj?->property_1?->property_2;"), 16 | ).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/snapshot/number.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test numbers", function () { 4 | it("test common cases", function () { 5 | expect( 6 | parser.parseEval(` 7 | 1234; 8 | $a = -1.5; 9 | $b = 1234; 10 | $c = 9223372036854775807; 11 | $c = 9223372036854775808; 12 | $d = 0x1A; 13 | $d = 0xFF; 14 | $e = 0b1011; 15 | $f = 0123; 16 | $g = 1.2e3; 17 | $h = 7E-10; 18 | `), 19 | ).toMatchSnapshot(); 20 | }); 21 | 22 | it.each([ 23 | ["hexa without hex", "$a = 0xx;"], 24 | ["binary with 2", "$b = 0b2;"], 25 | ["multiple points", "$b = 1.0.5;"], 26 | // @fixme : PHP Parse error: Invalid numeric literal in %s 27 | // ["octal with 9", "$c = 01239;"], 28 | ["exponent with letter", "$d = 7E-a;"], 29 | ["variant (for coverage)", "$d = 7e+a;"], 30 | ["exponent empty", "$e = 7EX;"], 31 | ["underscore #1", "$e = 7__0;"], 32 | ["underscore #2", "$e = 7._0;"], 33 | ["underscore #3", "$e = 7_.0;"], 34 | ["underscore #4", "$e = 7e_0;"], 35 | ["underscore #5", "$e = 7_e0;"], 36 | ])("%s", function (_, code) { 37 | const ast = parser.parseEval(code, { 38 | parser: { 39 | suppressErrors: true, 40 | }, 41 | }); 42 | // expect to fail 43 | expect(ast.errors.length).toBeGreaterThan(0); 44 | // check structure 45 | expect(ast).toMatchSnapshot(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/snapshot/offsetlookup.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("offsetlookup", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('$obj["index"];')).toMatchSnapshot(); 6 | }); 7 | it("variable", function () { 8 | expect(parser.parseEval("$obj[$var];")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("$obj[$var]();")).toMatchSnapshot(); 12 | }); 13 | it("multiple", function () { 14 | expect(parser.parseEval('$obj["first"]["second"];')).toMatchSnapshot(); 15 | }); 16 | it("simple (curly)", function () { 17 | expect(parser.parseEval('$obj{"index"};')).toMatchSnapshot(); 18 | }); 19 | it("variable (curly)", function () { 20 | expect(parser.parseEval("$obj{$var};")).toMatchSnapshot(); 21 | }); 22 | it("call (curly)", function () { 23 | expect(parser.parseEval("$obj{$var}();")).toMatchSnapshot(); 24 | }); 25 | it("multiple (curly)", function () { 26 | expect(parser.parseEval('$obj{"first"}{"second"};')).toMatchSnapshot(); 27 | }); 28 | it("inside propertylookup", function () { 29 | expect( 30 | parser.parseEval(` 31 | $foo->bzr_[1]; 32 | $foo->bzr_['string']; 33 | $foo->bzr_[$baz]; 34 | $foo->bzr_[$baz->foo]; 35 | $foo->bzr_[$var ? 'one' : 'two']; 36 | `), 37 | ).toMatchSnapshot(); 38 | }); 39 | it("inside propertylookup (curly)", function () { 40 | expect( 41 | parser.parseEval(` 42 | $foo->bzr_{1}; 43 | $foo->bzr_{'string'}; 44 | $foo->bzr_{$baz}; 45 | $foo->bzr_{$baz->foo}; 46 | $foo->bzr_{$var ? 'one' : 'two'}; 47 | `), 48 | ).toMatchSnapshot(); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /test/snapshot/parentreference.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("parentreference", function () { 4 | it("variable", function () { 5 | expect(parser.parseEval("parent::$var;")).toMatchSnapshot(); 6 | }); 7 | it("constant", function () { 8 | expect(parser.parseEval("parent::CONSTANT;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("parent::call();")).toMatchSnapshot(); 12 | }); 13 | it("uppercase", function () { 14 | expect(parser.parseEval("PARENT::call();")).toMatchSnapshot(); 15 | }); 16 | it("argument", function () { 17 | expect(parser.parseEval("function foo(parent $arg) {}")).toMatchSnapshot(); 18 | }); 19 | it("argument (uppercase)", function () { 20 | expect(parser.parseEval("function foo(PARENT $arg) {}")).toMatchSnapshot(); 21 | }); 22 | it("return type declarations", function () { 23 | expect(parser.parseEval("function foo($arg): parent {}")).toMatchSnapshot(); 24 | }); 25 | it("return type declarations (uppercase)", function () { 26 | expect(parser.parseEval("function foo($arg): PARENT {}")).toMatchSnapshot(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/snapshot/php5.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test syntax parsing without PHP7 support", function () { 4 | it("special keywords should fail", function () { 5 | const ast = parser.parseEval("class foo { function list() { } }", { 6 | parser: { 7 | version: "5.6", 8 | suppressErrors: true, 9 | }, 10 | }); 11 | expect(ast).toMatchSnapshot(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/snapshot/php73.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test syntax parsing with PHP 73 support", function () { 4 | it("https://wiki.php.net/rfc/list_reference_assignment", function () { 5 | const ast = parser.parseEval( 6 | "[$a, &$b] = $array; list($a, &$b) = $array;", 7 | { 8 | parser: { 9 | version: "7.3", 10 | }, 11 | }, 12 | ); 13 | expect(ast).toMatchSnapshot(); 14 | }); 15 | 16 | it("https://wiki.php.net/rfc/trailing-comma-function-calls", function () { 17 | const ast = parser.parseEval( 18 | ` 19 | $newArray = array_merge( 20 | $arrayOne, 21 | $arrayTwo, 22 | ['foo', 'bar'], 23 | ); 24 | 25 | $foo = new Foo( 26 | 'constructor', 27 | 'bar', 28 | ); 29 | 30 | $foo->bar( 31 | 'method', 32 | 'bar', 33 | ); 34 | 35 | $foo( 36 | 'invoke', 37 | 'bar', 38 | ); 39 | 40 | unset($foo, $bar,); 41 | var_dump(isset($foo, $bar,)); 42 | `, 43 | { 44 | parser: { 45 | version: "7.3", 46 | }, 47 | }, 48 | ); 49 | expect(ast).toMatchSnapshot(); 50 | }); 51 | 52 | it("https://wiki.php.net/rfc/trailing-comma-function-calls#errors", function () { 53 | const ast = parser.parseEval( 54 | ` 55 | # Parse error 56 | function bar($a, $b,) { 57 | // 58 | } 59 | # Parse error 60 | foo(,); 61 | 62 | # Parse error 63 | foo('function', 'bar',,); 64 | # Also parse error 65 | foo(, 'function', 'bar'); 66 | `, 67 | { 68 | parser: { 69 | version: "7.3", 70 | suppressErrors: true, 71 | }, 72 | }, 73 | ); 74 | expect(ast).toMatchSnapshot(); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/snapshot/post.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("post", function () { 4 | it("++", function () { 5 | expect(parser.parseEval("$var++;")).toMatchSnapshot(); 6 | }); 7 | it("--", function () { 8 | expect(parser.parseEval("$var--;")).toMatchSnapshot(); 9 | }); 10 | it("++ and parens", function () { 11 | expect(parser.parseEval("($var++);")).toMatchSnapshot(); 12 | }); 13 | it("-- and parens", function () { 14 | expect(parser.parseEval("($var--);")).toMatchSnapshot(); 15 | }); 16 | it("++ and + unary", function () { 17 | expect(parser.parseEval("+($var++);")).toMatchSnapshot(); 18 | }); 19 | it("++ and - unary", function () { 20 | expect(parser.parseEval("-$var++;")).toMatchSnapshot(); 21 | }); 22 | it("++ and - unary (with parens)", function () { 23 | expect(parser.parseEval("-($var++);")).toMatchSnapshot(); 24 | }); 25 | it("-- and + unary", function () { 26 | expect(parser.parseEval("+$var--;")).toMatchSnapshot(); 27 | }); 28 | it("-- and + unary (with parens)", function () { 29 | expect(parser.parseEval("+($var--);")).toMatchSnapshot(); 30 | }); 31 | it("-- and unary -", function () { 32 | expect(parser.parseEval("-($var--);")).toMatchSnapshot(); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/snapshot/pre.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("pre", function () { 4 | it("++", function () { 5 | expect(parser.parseEval("++$var;")).toMatchSnapshot(); 6 | }); 7 | it("--", function () { 8 | expect(parser.parseEval("--$var;")).toMatchSnapshot(); 9 | }); 10 | it("++ and parens", function () { 11 | expect(parser.parseEval("(++$var);")).toMatchSnapshot(); 12 | }); 13 | it("-- and parens", function () { 14 | expect(parser.parseEval("(--$var);")).toMatchSnapshot(); 15 | }); 16 | it("++ and + unary", function () { 17 | expect(parser.parseEval("+(++$var);")).toMatchSnapshot(); 18 | }); 19 | it("++ and - unary", function () { 20 | expect(parser.parseEval("-++$var;")).toMatchSnapshot(); 21 | }); 22 | it("++ and - unary (with parens)", function () { 23 | expect(parser.parseEval("-(++$var);")).toMatchSnapshot(); 24 | }); 25 | it("-- and + unary", function () { 26 | expect(parser.parseEval("+--$var;")).toMatchSnapshot(); 27 | }); 28 | it("-- and + unary (with parens)", function () { 29 | expect(parser.parseEval("+(--$var);")).toMatchSnapshot(); 30 | }); 31 | it("-- and unary -", function () { 32 | expect(parser.parseEval("-(--$var);")).toMatchSnapshot(); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/snapshot/print.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("print", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('print "string";')).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/snapshot/propertylookup.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("propertylookup", function () { 4 | it("fix 128 - Don't have curly for propertylookup", function () { 5 | expect(parser.parseEval("$this->{foo};$this->bar;")).toMatchSnapshot(); 6 | }); 7 | it("simple", function () { 8 | expect(parser.parseEval("$obj->property;")).toMatchSnapshot(); 9 | }); 10 | it("variable", function () { 11 | expect(parser.parseEval("$obj->$property;")).toMatchSnapshot(); 12 | }); 13 | it("call", function () { 14 | expect(parser.parseEval("$obj->call();")).toMatchSnapshot(); 15 | }); 16 | it("multiple", function () { 17 | expect(parser.parseEval("$obj->property_1->property_2;")).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/snapshot/propertystatement.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("propertystatement", () => { 4 | it("simple", () => { 5 | expect(parser.parseEval("class Foo { public $dsn; }")).toMatchSnapshot(); 6 | }); 7 | it("simple (var)", () => { 8 | expect(parser.parseEval("class Foo { var $dsn; }")).toMatchSnapshot(); 9 | }); 10 | it("multiple", () => { 11 | expect( 12 | parser.parseEval("class Foo { public $dsn, $username, $password; }"), 13 | ).toMatchSnapshot(); 14 | }); 15 | it("multiple (var)", () => { 16 | expect( 17 | parser.parseEval("class Foo { var $dsn, $username, $password; }"), 18 | ).toMatchSnapshot(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/snapshot/return.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("return", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('return "string";')).toMatchSnapshot(); 6 | }); 7 | it("no expression", function () { 8 | expect(parser.parseEval("return;")).toMatchSnapshot(); 9 | }); 10 | it("should fail when no ';' at end", function () { 11 | expect( 12 | parser.parseEval("return", { 13 | parser: { suppressErrors: true }, 14 | }), 15 | ).toMatchSnapshot(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/snapshot/scalar.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test scalar statements", function () { 4 | it.each([ 5 | ["test constants", "$a = foo::ref[-5];"], 6 | ["test constants #2", "$a = Foo;"], 7 | ["test constants #3", "$a = $var::foo;"], 8 | [ 9 | "test dereferencable", 10 | ` 11 | $a = foo::bar()[5]->test; 12 | $b = (new test())->foo(); 13 | $c = (foo())[5]; 14 | $d = (function($a) { return $a * 2; })(5); 15 | `, 16 | ], 17 | ["test dereferencable_scalar", "$var = array(1);"], 18 | ["test dereferencable_scalar #2", "$var = [1];"], 19 | ["test dereferencable_scalar #3", '$var = "test";'], 20 | ["php 8.1 explicit octal", "$var = 0o123 + 0o001_234;"], 21 | ["implicit octal", "$var = 0123;"], 22 | ])("%s", function (_, code) { 23 | expect(parser.parseEval(code)).toMatchSnapshot(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /test/snapshot/selfreference.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("selfreference", function () { 4 | it("variable", function () { 5 | expect(parser.parseEval("self::$var;")).toMatchSnapshot(); 6 | }); 7 | it("constant", function () { 8 | expect(parser.parseEval("self::CONSTANT;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("self::call();")).toMatchSnapshot(); 12 | }); 13 | it("uppercase", function () { 14 | expect(parser.parseEval("SELF::call();")).toMatchSnapshot(); 15 | }); 16 | it("argument", function () { 17 | expect(parser.parseEval("function foo(self $arg) {}")).toMatchSnapshot(); 18 | }); 19 | it("argument (uppercase)", function () { 20 | expect(parser.parseEval("function foo(SELF $arg) {}")).toMatchSnapshot(); 21 | }); 22 | it("return type declarations", function () { 23 | expect(parser.parseEval("function foo($arg): self {}")).toMatchSnapshot(); 24 | }); 25 | it("return type declarations (uppercase)", function () { 26 | expect(parser.parseEval("function foo($arg): SELF {}")).toMatchSnapshot(); 27 | }); 28 | it("return static type declarations", function () { 29 | expect(parser.parseEval("function foo($arg): static {}")).toMatchSnapshot(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/snapshot/silent.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("silent", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("@call();")).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/snapshot/static.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("static", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("static $foo;")).toMatchSnapshot(); 6 | }); 7 | it("assign", function () { 8 | expect(parser.parseEval("static $foo = 1;")).toMatchSnapshot(); 9 | }); 10 | it("multiple", function () { 11 | expect( 12 | parser.parseEval("static $foo = 1, $bar = 2, $baz = 3;"), 13 | ).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/snapshot/staticlookup.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("staticlookup", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("Foo::$var;")).toMatchSnapshot(); 6 | }); 7 | it("simple (2)", function () { 8 | expect(parser.parseEval("$var::$var;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("Foo::call();")).toMatchSnapshot(); 12 | }); 13 | it("call (2)", function () { 14 | expect(parser.parseEval("$var::call();")).toMatchSnapshot(); 15 | }); 16 | it("multiple", function () { 17 | expect(parser.parseEval("$var::$var_1::$var_2;")).toMatchSnapshot(); 18 | }); 19 | it("multiple (2)", function () { 20 | expect(parser.parseEval("Foo::$var_1::$var_2;")).toMatchSnapshot(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/snapshot/staticreference.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("staticreference", function () { 4 | it("variable", function () { 5 | expect(parser.parseEval("static::$var;")).toMatchSnapshot(); 6 | }); 7 | it("constant", function () { 8 | expect(parser.parseEval("static::CONSTANT;")).toMatchSnapshot(); 9 | }); 10 | it("call", function () { 11 | expect(parser.parseEval("static::call();")).toMatchSnapshot(); 12 | }); 13 | it("uppercase", function () { 14 | expect(parser.parseEval("STATIC::call();")).toMatchSnapshot(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/snapshot/throw.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("throw", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval('throw new Exception("Error");')).toMatchSnapshot(); 6 | }); 7 | it("arrow function", function () { 8 | expect( 9 | parser.parseEval('$fn = fn() => throw new Exception("oops");'), 10 | ).toMatchSnapshot(); 11 | }); 12 | it("arrow function in PHP < 8", function () { 13 | expect(() => 14 | parser.parseEval('$fn = fn() => throw new Exception("oops");', { 15 | parser: { version: "7.4" }, 16 | }), 17 | ).toThrow(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/snapshot/token.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test tokens statements", function () { 4 | it("hello world", function () { 5 | const ast = parser.parseCode("Hello ", { 6 | parser: { 7 | debug: false, 8 | extractTokens: true, 9 | }, 10 | }); 11 | expect(ast).toMatchSnapshot(); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/snapshot/trait.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("trait", function () { 4 | it("trait name as identifier", function () { 5 | expect(parser.parseEval("trait A {}")).toMatchSnapshot(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/snapshot/traitprecedence.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("traitprecedence", () => { 4 | it("simple", () => { 5 | expect( 6 | parser.parseEval( 7 | ` 8 | class MyHelloWorld extends Base { 9 | use A, B { 10 | B::smallTalk insteadof A; 11 | A::bigTalk insteadof B; 12 | } 13 | } 14 | `, 15 | ), 16 | ).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/snapshot/unary.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test unary", function () { 4 | it.each([ 5 | ["simple", "!$var;"], 6 | ["number", "-100;"], 7 | ["number (2)", "+100;"], 8 | ["number (3)", "~100;"], 9 | ["number (4)", "!100;"], 10 | ["string", '+"string";'], 11 | ["string (2)", '-"string";'], 12 | ["string (3)", '~"string";'], 13 | ["string (4)", '!"string";'], 14 | ["boolean", "!true;"], 15 | ["multiple", "!!$var;"], 16 | ["multiple", "~~$var;"], 17 | ["multiple (2)", "--$var;"], 18 | ["multiple (3)", "+(+$var);"], 19 | ["multiple (4)", "-(-$var);"], 20 | ["multiple (5)", "!!!!!$var;"], 21 | ["parens", "(!$var);"], 22 | ["parens (2)", "!($var);"], 23 | ["parens (3)", "(-$var);"], 24 | ["parens (4)", "-($var);"], 25 | ["parens (5)", "(+$var);"], 26 | ["parens (6)", "+($var);"], 27 | ["parens (7)", "~($var);"], 28 | ["parens (8)", "(~$var);"], 29 | ["parens (9)", "(-100);"], 30 | ["parens (10)", "-(100);"], 31 | ])("%s", function (_, code) { 32 | expect(parser.parseEval(code)).toMatchSnapshot(); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/snapshot/union.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("Test unions", function () { 4 | it("simple union", function () { 5 | expect(parser.parseEval("function(foo|bar $test) {}")).toMatchSnapshot(); 6 | }); 7 | 8 | it("simple intersection", function () { 9 | expect(parser.parseEval("function(foo&bar $test) {}")).toMatchSnapshot(); 10 | }); 11 | 12 | it("union with reference", function () { 13 | expect(parser.parseEval("function(foo|bar &$test) {}")).toMatchSnapshot(); 14 | }); 15 | 16 | it("intersection with reference", function () { 17 | expect(parser.parseEval("function(foo&bar &$test) {}")).toMatchSnapshot(); 18 | }); 19 | 20 | it("union with variadic", function () { 21 | expect(parser.parseEval("function(foo|bar ...$test) {}")).toMatchSnapshot(); 22 | }); 23 | 24 | it("intersection with variadic", function () { 25 | expect(parser.parseEval("function(foo&bar ...$test) {}")).toMatchSnapshot(); 26 | }); 27 | 28 | it("union with three types", function () { 29 | expect( 30 | parser.parseEval("function(foo|bar|baz $test) {}"), 31 | ).toMatchSnapshot(); 32 | }); 33 | 34 | it("intersection with three types", function () { 35 | expect( 36 | parser.parseEval("function(foo&bar&baz $test) {}"), 37 | ).toMatchSnapshot(); 38 | }); 39 | 40 | it("union mixed with intersection", function () { 41 | const astErr = parser.parseEval("function(foo|bar&baz $test) {}", { 42 | parser: { 43 | version: "8.1", 44 | suppressErrors: true, 45 | }, 46 | }); 47 | 48 | expect(astErr).toMatchSnapshot(); 49 | }); 50 | 51 | it("intersection mixed with union", function () { 52 | const astErr = parser.parseEval("function(foo&bar|baz $test) {}", { 53 | parser: { 54 | version: "8.1", 55 | suppressErrors: true, 56 | }, 57 | }); 58 | 59 | expect(astErr).toMatchSnapshot(); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /test/snapshot/unset.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("unset", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("unset($var);")).toMatchSnapshot(); 6 | }); 7 | it("multiple", function () { 8 | expect(parser.parseEval("unset($var, $var, $var);")).toMatchSnapshot(); 9 | }); 10 | it("trailing comma", function () { 11 | expect(parser.parseEval("unset($foo,);")).toMatchSnapshot(); 12 | }); 13 | it("trailing comma #2", function () { 14 | expect(parser.parseEval("unset($foo, $bar,);")).toMatchSnapshot(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/snapshot/usegroup.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("usegroup", () => { 4 | it("simple", () => { 5 | expect( 6 | parser.parseEval("use My\\Full\\Classname as Another;"), 7 | ).toMatchSnapshot(); 8 | }); 9 | it("multiple", () => { 10 | expect( 11 | parser.parseEval("use My\\Full\\Classname as Another, My\\Full\\NSname;"), 12 | ).toMatchSnapshot(); 13 | }); 14 | it("multiple 2", () => { 15 | expect( 16 | parser.parseEval( 17 | "use My\\Full\\Classname as Another, My\\Full\\NSname, \\Full\\NSname\\With\\Leading\\Backslash;", 18 | ), 19 | ).toMatchSnapshot(); 20 | }); 21 | it("nested", () => { 22 | expect( 23 | parser.parseEval( 24 | "use some\\my_namespace\\{ClassA, ClassB, ClassC as C};", 25 | ), 26 | ).toMatchSnapshot(); 27 | }); 28 | it("nested 2", () => { 29 | expect( 30 | parser.parseEval("use function some\\my_namespace\\{fn_a, fn_b, fn_c};"), 31 | ).toMatchSnapshot(); 32 | }); 33 | it("nested 3", () => { 34 | expect( 35 | parser.parseEval( 36 | "use const some\\my_namespace\\{ConstA, ConstB, ConstC};", 37 | ), 38 | ).toMatchSnapshot(); 39 | }); 40 | it("nested 4", () => { 41 | expect( 42 | parser.parseEval( 43 | `use Vendor\\Package\\SomeNamespace\\{ 44 | SubnamespaceOne\\ClassA, 45 | SubnamespaceOne\\ClassB 46 | };`, 47 | ), 48 | ).toMatchSnapshot(); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /test/snapshot/useitem.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("useitem", () => { 4 | it("simple", () => { 5 | expect(parser.parseEval("use My\\Full\\NSname;")).toMatchSnapshot(); 6 | }); 7 | it("simple 2", () => { 8 | expect(parser.parseEval("use ArrayObject;")).toMatchSnapshot(); 9 | }); 10 | it("with type", () => { 11 | expect( 12 | parser.parseEval("use My\\Full\\Classname as Another;"), 13 | ).toMatchSnapshot(); 14 | }); 15 | it("importing a function", () => { 16 | expect( 17 | parser.parseEval("use function My\\Full\\functionName;"), 18 | ).toMatchSnapshot(); 19 | }); 20 | it("importing a function with type", () => { 21 | expect( 22 | parser.parseEval("use function My\\Full\\functionName as func;"), 23 | ).toMatchSnapshot(); 24 | }); 25 | it("importing a class", () => { 26 | expect( 27 | parser.parseEval("use some\\my_namespace\\ClassC;"), 28 | ).toMatchSnapshot(); 29 | }); 30 | it("importing a class with type", () => { 31 | expect( 32 | parser.parseEval("use some\\my_namespace\\ClassC as C;"), 33 | ).toMatchSnapshot(); 34 | }); 35 | it("importing a constant", () => { 36 | expect(parser.parseEval("use const My\\Full\\CONSTANT;")).toMatchSnapshot(); 37 | }); 38 | it("importing a constant with type", () => { 39 | expect( 40 | parser.parseEval("use const My\\Full\\CONSTANT as MY_CONST;"), 41 | ).toMatchSnapshot(); 42 | }); 43 | it("invalid use", () => { 44 | expect( 45 | parser.parseEval( 46 | `use function $foo; 47 | use const namespace\\{ 48 | FOO, 49 | BAR, 50 | }; 51 | use some\\{ 52 | namespace\\foo, 53 | $error, 54 | function $bar, 55 | };`, 56 | { 57 | parser: { suppressErrors: true }, 58 | }, 59 | ), 60 | ).toMatchSnapshot(); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /test/snapshot/yield.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("yield", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("yield $i;")).toMatchSnapshot(); 6 | }); 7 | it("assign", function () { 8 | expect(parser.parseEval("$data = yield $value;")).toMatchSnapshot(); 9 | }); 10 | it("assign (parens)", function () { 11 | expect(parser.parseEval("$data = (yield $value);")).toMatchSnapshot(); 12 | }); 13 | it("simple (key and value)", function () { 14 | expect(parser.parseEval("yield $id => $fields;")).toMatchSnapshot(); 15 | }); 16 | it("assign (key and value)", function () { 17 | expect( 18 | parser.parseEval("$data = (yield $key => $value);"), 19 | ).toMatchSnapshot(); 20 | }); 21 | it("inside function", function () { 22 | expect(parser.parseEval("function foo() { yield $i; }")).toMatchSnapshot(); 23 | }); 24 | it("expression as generator key", function () { 25 | expect( 26 | parser.parseEval('function foo() { yield "bar {$test}" => 123; }'), 27 | ).toMatchSnapshot(); 28 | }); 29 | it("null", function () { 30 | expect(parser.parseEval("yield;")).toMatchSnapshot(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/snapshot/yieldfrom.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("../main"); 2 | 3 | describe("yieldfrom", function () { 4 | it("simple", function () { 5 | expect(parser.parseEval("yield from from();")).toMatchSnapshot(); 6 | }); 7 | it("array", function () { 8 | expect(parser.parseEval("yield from [3, 4];")).toMatchSnapshot(); 9 | }); 10 | it("new", function () { 11 | expect( 12 | parser.parseEval("yield from new ArrayIterator([5, 6]);"), 13 | ).toMatchSnapshot(); 14 | }); 15 | it("return", function () { 16 | expect(parser.parseEval("return yield from nine_ten();")).toMatchSnapshot(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/version.test.js: -------------------------------------------------------------------------------- 1 | const parser = require("./main"); 2 | 3 | describe("Test versions", function () { 4 | it("unserialize a version string", function () { 5 | const test = parser.create({ 6 | parser: { 7 | version: "7.3", 8 | }, 9 | }); 10 | expect(test.parser.version).toEqual(703); 11 | }); 12 | it("unserialize a version string - with bugfix ignored", function () { 13 | const test = parser.create({ 14 | parser: { 15 | version: "7.3.5", 16 | }, 17 | }); 18 | expect(test.parser.version).toEqual(703); 19 | }); 20 | it("fail to parse array", function () { 21 | expect( 22 | parser.create.bind(null, { 23 | parser: { 24 | version: [701], 25 | }, 26 | }), 27 | ).toThrow(new Error("Expecting a number for version")); 28 | }); 29 | it("fail to parse bad version numbers", function () { 30 | expect( 31 | parser.create.bind(null, { 32 | parser: { 33 | version: "x.y.z", 34 | }, 35 | }), 36 | ).toThrow(new Error("Bad version number : x.y.z")); 37 | }); 38 | it("unhandled version", function () { 39 | expect( 40 | parser.create.bind(null, { 41 | parser: { 42 | version: "4.9", 43 | }, 44 | }), 45 | ).toThrow(new Error("Can only handle versions between 5.x to 8.x")); 46 | expect( 47 | parser.create.bind(null, { 48 | parser: { 49 | version: "9.9", 50 | }, 51 | }), 52 | ).toThrow(new Error("Can only handle versions between 5.x to 8.x")); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /tutorials/Options.md: -------------------------------------------------------------------------------- 1 | # Options 2 | 3 | When you call the parser you can pass options as following : 4 | 5 | ```js 6 | var reader = require('php-parser'); 7 | reader.parseCode('` 41 | * short_tags : handle short opening tag `