[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nquote_type = single\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".eslint-doc-generatorrc.js",
    "content": "/** @type {import('eslint-doc-generator').GenerateOptions} */\nconst config = {\n  configEmoji: [\n    ['jsx-runtime', '🏃'],\n    ['recommended', '☑️'],\n  ],\n  ignoreConfig: ['all', 'flat'],\n  urlConfigs: 'https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs',\n};\n\nmodule.exports = config;\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n\t\"root\": true,\n\t\"extends\": [\"airbnb-base\", \"plugin:eslint-plugin/recommended\"],\n\t\"plugins\": [\"eslint-plugin\"],\n\t\"env\": {\n\t\t\"es6\": true,\n\t\t\"node\": true\n\t},\n\t\"parserOptions\": {\n\t\t\"ecmaVersion\": 6,\n\t\t\"ecmaFeatures\": {\n\t\t\t\"jsx\": true\n\t\t},\n\t\t\"sourceType\": \"script\",\n\t},\n\t\"ignorePatterns\": [\n\t\t\"coverage/\",\n\t\t\".nyc_output/\",\n\t\t\"test-published-types/\",\n\t\t\"tests/fixtures/flat-config/\",\n\t\t\"**/*/*.d.ts\",\n\t],\n\t\"rules\": {\n\t\t\"comma-dangle\": [2, \"always-multiline\"],\n\t\t\"object-shorthand\": [2, \"always\", {\n\t\t\t\"ignoreConstructors\": false,\n\t\t\t\"avoidQuotes\": false, // this is the override vs airbnb\n    }],\n    \"max-len\": [2, 140, {\n      \"ignoreStrings\": true,\n      \"ignoreTemplateLiterals\": true,\n      \"ignoreComments\": true,\n    }],\n    \"consistent-return\": 0,\n\n    \"prefer-destructuring\": [2, { \"array\": false, \"object\": false }, { \"enforceForRenamedProperties\": false }],\n    \"prefer-object-spread\": 0, // until node 8 is required\n    \"prefer-rest-params\": 0, // until node 6 is required\n    \"prefer-spread\": 0, // until node 6 is required\n    \"function-call-argument-newline\": 1, // TODO: enable\n    \"function-paren-newline\": 0,\n    \"no-plusplus\": [2, {\"allowForLoopAfterthoughts\": true}],\n    \"no-param-reassign\": 1,\n    \"no-restricted-syntax\": [2, {\n      \"selector\": \"ObjectPattern\",\n      \"message\": \"Object destructuring is not compatible with Node v4\"\n    }],\n    \"strict\": [2, \"safe\"],\n    \"valid-jsdoc\": [2, {\n      \"requireReturn\": false,\n      \"requireParamDescription\": false,\n      \"requireReturnDescription\": false,\n    }],\n\n    \"eslint-plugin/consistent-output\": 0,\n    \"eslint-plugin/require-meta-docs-description\": [2, { \"pattern\": \"^(Enforce|Require|Disallow)\" }],\n    \"eslint-plugin/require-meta-schema\": 0,\n    \"eslint-plugin/require-meta-type\": 0\n  },\n  \"overrides\": [\n    {\n      \"files\": \"tests/**\",\n      \"rules\": {\n        \"no-template-curly-in-string\": 1,\n      },\n    },\n    {\n      \"files\": \"markdown.config.js\",\n      \"rules\": {\n        \"no-console\": 0,\n      },\n    },\n    {\n      \"files\": \".github/workflows/*.js\",\n      \"parserOptions\": {\n        \"ecmaVersion\": 2019,\n      },\n      \"rules\": {\n        \"camelcase\": 0,\n        \"no-console\": 0,\n        \"no-restricted-syntax\": 0,\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [jsx-eslint, ljharb]\npatreon: # Replace with a single Patreon username\nopen_collective: jsx-eslint # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: npm/eslint-plugin-react\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: File a bug report\ntitle: \"[Bug]: \"\nlabels: [\"bug\", \"triage\"]\nassignees: []\nbody:\n  - type: checkboxes\n    attributes:\n      label: Is there an existing issue for this?\n      description: Please search to see if an issue already exists for the bug you encountered.\n      options:\n      - label: I have searched the existing issues and my issue is unique\n        required: true\n      - label: My issue appears in the command-line and not only in the text editor\n        required: true\n  - type: textarea\n    id: Code\n    attributes:\n      label: Description Overview\n      description: A clear and concise description of bug w/ examples\n      placeholder: |\n        Brief description here\n\n        Show example of your code (as text format), add images/videos/gifs to help explain example\n        and/or Link of repo to where issue is occurring\n\n        What is happening? / What is the error?\n\n        What command(s) did you run to reproduce issue?\n      value: |\n        <!--Brief description-->\n\n\n        <!--Show example of your code (as text format), add images/videos/gifs to help explain example-->\n        <!--and/or Link of repo to where issue is occurring-->\n\n\n        <!--What is happening? / What is the error?-->\n\n\n        <!--What command(s) did you run to reproduce issue?-->\n\n    validations:\n      required: true\n  - type: textarea\n    id: expected_behavior\n    attributes:\n      label: Expected Behavior\n      description: A clear and concise description of what you expected to happen.\n      placeholder: |\n        Brief description here\n\n        Show example of code (as text format), add images/videos/gifs to help explain expected behavior\n      value: |\n        <!--Brief description-->\n\n\n        <!--Show example of code (as text format), add images/videos/gifs to help explain expected behavior-->\n    validations:\n      required: true\n  - type: input\n    id: eslint-plugin-react-version\n    attributes:\n      label: eslint-plugin-react version\n      placeholder: v7.31.11\n    validations:\n      required: true\n  - type: input\n    id: eslint-version\n    attributes:\n      label: eslint version\n      placeholder: v8.28.0\n    validations:\n      required: true\n  - type: input\n    id: node-version\n    attributes:\n      label: node version\n      placeholder: v8.19.2\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/workflows/node-18+.yml",
    "content": "name: 'Tests: node.js (18+)'\n\non: [pull_request, push]\n\njobs:\n  matrix:\n    runs-on: ubuntu-latest\n    outputs:\n      latest: ${{ steps.set-matrix.outputs.requireds }}\n      minors: ${{ steps.set-matrix.outputs.optionals }}\n    steps:\n      - uses: ljharb/actions/node/matrix@main\n        id: set-matrix\n        with:\n          versionsAsRoot: true\n          type: majors\n          preset: '>=18'\n\n  latest:\n    needs: [matrix]\n    name: 'latest majors'\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: ${{ fromJson(needs.matrix.outputs.latest) }}\n        eslint:\n          - 9\n          - 8\n          - 7\n          - 6\n          - 5\n          - 4\n          - 4.14 # last version without messageId\n          - 3\n        babel-eslint:\n          - 10\n          - 9\n          - 8\n        typescript-eslint:\n          - 5\n          - 6\n          - 7\n          - 8\n        exclude:\n          - eslint: 3\n            babel-eslint: 10\n          - eslint: 3\n            typescript-eslint: 5\n          - eslint: 4\n            typescript-eslint: 5\n          - eslint: 4.14\n            typescript-eslint: 5\n          - eslint: 5\n            typescript-eslint: 5\n          - eslint: 3\n            typescript-eslint: 6\n          - eslint: 4\n            typescript-eslint: 6\n          - eslint: 4.14\n            typescript-eslint: 6\n          - eslint: 5\n            typescript-eslint: 6\n          - eslint: 6\n            typescript-eslint: 6\n          - eslint: 9\n            typescript-eslint: 6\n          - eslint: 3\n            typescript-eslint: 7\n          - eslint: 4\n            typescript-eslint: 7\n          - eslint: 4.14\n            typescript-eslint: 7\n          - eslint: 5\n            typescript-eslint: 7\n          - eslint: 6\n            typescript-eslint: 7\n          - eslint: 7\n            typescript-eslint: 7\n          - eslint: 9\n            typescript-eslint: 7\n          - eslint: 3\n            typescript-eslint: 8\n          - eslint: 4\n            typescript-eslint: 8\n          - eslint: 4.14\n            typescript-eslint: 8\n          - eslint: 5\n            typescript-eslint: 8\n          - eslint: 6\n            typescript-eslint: 8\n          - eslint: 7\n            typescript-eslint: 8\n          - eslint: 9\n            typescript-eslint: 5\n          - node-version: 19\n            typescript-eslint: 7\n\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install ${{ matrix.node-version }} && npm install'\n        with:\n          node-version: ${{ matrix.node-version }}\n          after_install: |\n            npm install --no-save \"eslint@${{ matrix.eslint }}\" \"@typescript-eslint/parser@${{ matrix.typescript-eslint == 8 && 8.17 || matrix.typescript-eslint }}\" \"babel-eslint@${{ matrix.babel-eslint }}\"\n        env:\n          NPM_CONFIG_LEGACY_PEER_DEPS: \"${{ matrix.typescript-eslint >= 6 && 'false' || 'true' }}\"\n      - run: npx ls-engines\n      - run: npm run unit-test\n      - uses: codecov/codecov-action@v3.1.5\n\n  node:\n    name: 'node 18+'\n    needs: [latest]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/node-minors.yml",
    "content": "name: 'Tests: node.js (4 - 18)'\n\non: [pull_request, push]\n\njobs:\n  matrix:\n    runs-on: ubuntu-latest\n    outputs:\n      latest: ${{ steps.set-matrix.outputs.requireds }}\n      minors: ${{ steps.set-matrix.outputs.optionals }}\n    steps:\n      - uses: ljharb/actions/node/matrix@main\n        id: set-matrix\n        with:\n          versionsAsRoot: true\n          type: majors\n          preset: '>=4 < 18'\n\n  latest:\n    needs: [matrix]\n    name: 'latest majors'\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version: ${{ fromJson(needs.matrix.outputs.latest) }}\n        eslint:\n          - 8\n          - 7\n          - 6\n          - 5\n          - 4\n          - 4.14 # last version without messageId\n          - 3\n        babel-eslint:\n          - 10\n          - 9\n          - 8\n        exclude:\n          - node-version: 5\n            babel-eslint: 10\n          - node-version: 5\n            babel-eslint: 9\n          - node-version: 4\n            babel-eslint: 10\n          - node-version: 4\n            babel-eslint: 9\n          - node-version: 15\n            eslint: 8\n          - node-version: 13\n            eslint: 8\n          - node-version: 11\n            eslint: 8\n          - node-version: 11\n            eslint: 7\n          - node-version: 10\n            eslint: 8\n          - node-version: 9\n            eslint: 8\n          - node-version: 9\n            eslint: 7\n          - node-version: 8\n            eslint: 8\n          - node-version: 8\n            eslint: 7\n          - node-version: 7\n            eslint: 8\n          - node-version: 7\n            eslint: 7\n          - node-version: 7\n            eslint: 6\n          - node-version: 6\n            eslint: 8\n          - node-version: 6\n            eslint: 7\n          - node-version: 6\n            eslint: 6\n          - node-version: 5\n            eslint: 8\n          - node-version: 5\n            eslint: 7\n          - node-version: 5\n            eslint: 6\n          - node-version: 5\n            eslint: 5\n          - node-version: 4\n            eslint: 8\n          - node-version: 4\n            eslint: 7\n          - node-version: 4\n            eslint: 6\n          - node-version: 4\n            eslint: 5\n\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install ${{ matrix.node-version }} && npm install'\n        with:\n          node-version: ${{ matrix.node-version }}\n          after_install: |\n            npm install --no-save \"eslint@${{ matrix.eslint }}\" \"@typescript-eslint/parser@${{ matrix.node-version >= 18 && matrix.eslint >= 8 && '8.17' || (matrix.node-version >= 16 && matrix.eslint >= 7 && '6' || (matrix.node-version >= 14 && '5' || (matrix.node-version >= 12 && '4' || (matrix.node-version >= 10 && '4.0' || (matrix.node-version >= 8 && '3' || '2'))))) }}\" \"babel-eslint@${{ matrix.babel-eslint }}\"\n          skip-ls-check: ${{ matrix.node-version < 10 && true || false }}\n        env:\n          NPM_CONFIG_LEGACY_PEER_DEPS: \"${{ matrix.node-version >= 16 && matrix.eslint >= 7 && 'false' || 'true' }}\"\n      - run: npx ls-engines\n        if: ${{ matrix.node-version >= 12 }}\n      - run: npm run unit-test\n      - uses: codecov/codecov-action@v3.1.5\n\n  node:\n    name: 'node 4 - 17'\n    needs: [latest]\n    runs-on: ubuntu-latest\n    steps:\n      - run: 'echo tests completed'\n"
  },
  {
    "path": ".github/workflows/node-pretest.yml",
    "content": "name: 'Tests: pretest/posttest'\n\non: [pull_request, push]\n\njobs:\n  pretest:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install lts/* && npm install'\n        with:\n          node-version: 'lts/*'\n      - run: npm run pretest\n\n  posttest:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install lts/* && npm install'\n        with:\n          node-version: 'lts/*'\n        env:\n          NPM_CONFIG_LEGACY_PEER_DEPS: true\n      - run: npx ls-engines\n      - run: echo 'legacy-peer-deps=true' >> .npmrc\n      - run: npm run posttest\n"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: Publish Package to npm\non:\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: \"Tag to publish\"\n        required: true\n\npermissions:\n  contents: read\n\njobs:\n  check-version:\n    runs-on: ubuntu-latest\n    outputs:\n      is-new-version: ${{ steps.cpv.outputs.is-new-version }}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.inputs.tag }}\n\n      - name: Validate semver pattern\n        run: npx semver ${{ inputs.tag }}\n\n      - name: Check package version\n        id: cpv\n        uses: PostHog/check-package-version@v2\n\n      - name: Validate package version\n        uses: actions/github-script@v6\n        with:\n          script: |\n            const isNewVersion = `${{ steps.cpv.outputs.is-new-version }}`;\n            if (isNewVersion === 'true') {\n                console.log(`Version ${context.payload.inputs.tag} has not been published yet`);\n            } else {\n                core.setFailed(`Version ${context.payload.inputs.tag} is already published`);\n            }\n\n  check-status:\n    needs: check-version\n    if: needs.check-version.outputs.is-new-version == 'true'\n    runs-on: ubuntu-latest\n    steps:\n      - name: Verify checks passed\n        uses: actions/github-script@v6\n        with:\n          result-encoding: string\n          retries: 3\n          script: |\n            console.log(process.cwd());\n            const ref = context.payload.inputs.tag;\n\n            console.log(`Checking status checks for ${ref}`);\n\n            const { owner, repo } = context.repo;\n            const { default_branch: branch } = context.payload.repository;\n\n            const branchData = github.rest.repos.getBranch({ owner, repo, branch });\n\n            const { data: { check_suites: checkSuites } } = await github.rest.checks.listSuitesForRef({ owner, repo, ref });\n\n            const pending = checkSuites.filter(({ status }) => status !== 'completed')\n\n            if (pending.length > 0) {\n              core.setFailed(`Some workflows for ${context.payload.inputs.tag} are still in-progress`);\n              pending.forEach(({ pull_requests, ...x }) => {\n                core.debug(JSON.stringify(x));\n              });\n            }\n\n            const result = await Promise.all(\n              (await branchData).data.protection.required_status_checks.checks.map(({ context: check_name }) => (\n                github.rest.checks.listForRef({\n                  owner,\n                  repo,\n                  ref,\n                  check_name,\n                })\n              )),\n            );\n\n            const checkRuns = result.flatMap(({ data: { check_runs } }) => check_runs);\n\n            checkRuns.forEach(({ name, status, conclusion }) => {\n              if (status !== 'completed' || conclusion !== 'success') {\n                console.log(`${name} check failed`);\n                core.setFailed(`Required status check ${name} did not succeed`);\n              }\n              console.log(`${name} check passed`);\n            });\n\n  publish:\n    needs: [check-status]\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      id-token: write\n    steps:\n      - uses: step-security/harden-runner@v2\n        with:\n          egress-policy: block\n          allowed-endpoints: >\n            github.com:443\n            nodejs.org:443\n            prod.api.stepsecurity.io:443\n            registry.npmjs.org:443\n            raw.githubusercontent.com:443\n\n      - uses: actions/checkout@v4\n        with:\n          ref: ${{ github.event.inputs.tag }}\n\n      - uses: ljharb/actions/node/install@main\n        name: \"nvm install lts/* && npm install\"\n        with:\n          node-version: \"lts/*\"\n        env:\n          NPM_CONFIG_LEGACY_PEER_DEPS: true\n\n      - run: echo \"//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}\" >> .npmrc\n\n      - run: npm publish --dry-run\n\n      - uses: step-security/wait-for-secrets@v1\n        id: wait-for-secrets\n        with:\n          slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}\n          secrets: |\n            OTP:\n              name: 'OTP to publish package'\n              description: 'OTP from authenticator app'\n\n      - run: npm publish --access public --otp ${{ steps.wait-for-secrets.outputs.OTP }}\n"
  },
  {
    "path": ".github/workflows/rebase.yml",
    "content": "name: Automatic Rebase\n\non: [pull_request_target]\n\njobs:\n  _:\n    uses: ljharb/actions/.github/workflows/rebase.yml@main\n    secrets:\n      token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    tags:\n      - \"v*.*.*\"\n\njobs:\n  release:\n    if: github.event.repository.fork == false\n\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: write\n\n    steps:\n      - uses: step-security/harden-runner@v2\n        with:\n          allowed-endpoints:\n            api.github.com:443\n            github.com:443\n            raw.githubusercontent.com:443\n            nodejs.org:443\n            registry.npmjs.org:443\n\n      - name: Get version from tag\n        id: tag_name\n        run: echo \"current_version=${GITHUB_REF#refs/tags/v}\" >> \"$GITHUB_OUTPUT\"\n        shell: bash\n\n      - uses: actions/checkout@v4\n\n      - uses: ljharb/actions/node/install@main\n        with:\n          node-version: node\n          skip-install: true\n          skip-ls-check: true\n\n      - uses: mindsers/changelog-reader-action@v2\n        id: changelog_reader\n        with:\n          version: ${{ steps.tag_name.outputs.current_version }}\n\n      - name: Get common links from changelog\n        id: changelog\n        run: |\n          # Parse the changelog for common links\n          _links=\"$(egrep '^\\[.*]:.+' ${GITHUB_WORKSPACE:-.}/CHANGELOG.md | sort -u)\"\n          _links=\"${_links//'%'/'%25'}\"\n          # _links=\"${_links//$'\\n'/'%0A'}\"\n          _links=\"${_links//$'\\r'/'%0D'}\"\n          # Set output 'links' to $_links\n          DELIMITER=$(uuidgen)\n          echo \"links<<${DELIMITER}\" >> \"${GITHUB_OUTPUT}\"\n          echo \"$_links\" >> \"${GITHUB_OUTPUT}\"\n          echo \"${DELIMITER}\" >> \"${GITHUB_OUTPUT}\"\n\n      - name: 'concat data > tmp.md'\n        run: |\n          cat << 'EOF' > tmp.md\n          ${{ steps.changelog_reader.outputs.changes }}\n          ${{ steps.changelog.outputs.links }}\n          EOF\n\n      - run: cat tmp.md\n\n      - id: prune-footnotes\n        run: |\n          DELIMITER=$(uuidgen)\n          echo \"body<<${DELIMITER}\" >> \"${GITHUB_OUTPUT}\"\n          npx gfm-footnotes -i tmp.md >> \"${GITHUB_OUTPUT}\"\n          echo \"${DELIMITER}\" >> \"${GITHUB_OUTPUT}\"\n\n      - uses: softprops/action-gh-release@v2\n        with:\n          body: |\n            ${{ steps.prune-footnotes.outputs.body }}\n"
  },
  {
    "path": ".github/workflows/require-allow-edits.yml",
    "content": "name: Require “Allow Edits”\n\non: [pull_request_target]\n\njobs:\n  _:\n    name: \"Require “Allow Edits”\"\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: ljharb/require-allow-edits@main\n"
  },
  {
    "path": ".github/workflows/smoke-test.yml",
    "content": "name: Smoke test\n\non:\n  schedule:\n    - cron: '0 0 * * SUN'\n  workflow_dispatch:\n\njobs:\n  smoke-test:\n    if: ${{ github.repository == 'jsx-eslint/eslint-plugin-react' || github.event_name == 'workflow_dispatch' }}\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install lts/* && npm install'\n        with:\n          node-version: 'lts/*'\n          skip-ls-check: true\n      - run: |\n          npm link\n          npm link eslint-plugin-react\n      - uses: AriPerkkio/eslint-remote-tester-run-action@v4\n        with:\n          issue-title: 'Results of weekly scheduled smoke test'\n          issue-label: 'smoke-test'\n          eslint-remote-tester-config: test/eslint-remote-tester.config.js\n"
  },
  {
    "path": ".github/workflows/type-check.yml",
    "content": "name: \"Types: check published types\"\n\non: [pull_request, push]\n\npermissions:\n  contents: read\n\njobs:\n  test:\n    name: TS ${{ matrix.ts_version }}, \"${{ matrix.ts_lib }}\"\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        ts_version:\n          # The official ESLint types are not compatible with TS 3.9\n          # - 3.9\n          - '4.0'\n          - 4.1\n          - 4.2\n          - 4.3\n          - 4.4\n          - 4.5\n          - '5.0'\n          - 5.5\n          - 5.6\n        ts_lib:\n          - es2015\n          - es2015,dom\n          - es2020\n          - esnext\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          persist-credentials: false\n          show-progress: false\n\n      - uses: ljharb/actions/node/install@main\n        name: 'nvm install lts/* && npm install'\n        with:\n          node-version: 'lts/*'\n          skip-ls-check: true\n\n      - name: build types\n        run: npm run build-types\n\n      # Pack the lib into a tarball so that when we install the lib later in the\n      # test-published-types directory, it's only install `dependencies` of the\n      # lib.\n      - name: pack the lib\n        run: npm pack --pack-destination /tmp/\n\n      - name: find the packed lib\n        run: echo \"ESLINT_PLUGIN_REACT_PATH=$(ls /tmp/eslint-plugin-react*.tgz | tail -n 1)\" >> $GITHUB_ENV\n\n      - name: show the path to the packed lib\n        run: echo \"$ESLINT_PLUGIN_REACT_PATH\"\n\n      - name: npm install working directory\n        run: npm install\n        working-directory: test-published-types\n\n      - name: install eslint-plugin-react and typescript version ${{ matrix.ts_version }}\n        run: npm install --no-save \"$ESLINT_PLUGIN_REACT_PATH\" typescript@${{ matrix.ts_version }}\n        working-directory: test-published-types\n\n      - name: show installed typescript version\n        run: npm list typescript --depth=0\n        working-directory: test-published-types\n\n      - name: show installed eslint-plugin-react version\n        run: npm list eslint-plugin-react --depth=0\n        working-directory: test-published-types\n\n      - name: check types with lib \"${{ matrix.ts_lib }}\"\n        run: npx tsc --lib ${{ matrix.ts_lib }}\n        working-directory: test-published-types\n"
  },
  {
    "path": ".gitignore",
    "content": "# gitignore\n\nlib-cov\n*.seed\n*.log\n*.csv\n*.dat\n*.out\n*.pid\n*.gz\n*.sublime-project\n*.sublime-workspace\npids\nlogs\nreports\ncoverage\n.nyc_output/\nbuild\nnode_modules\n!tests/**/node_modules\nnpm-debug.log\nsftp-config.json\neslint-remote-tester-results\n\n# Only apps should have lockfiles\nnpm-shrinkwrap≥json\npackage-lock.json\nyarn.lock\n\n.npmignore\n\n/lib/**/*.d.ts\n/lib/**/*.d.ts.map\n!/lib/types.d.ts\n/index.d.ts\n/index.d.ts.map\n"
  },
  {
    "path": ".markdownlint.json",
    "content": "{\n  \"line-length\": false,\n  \"no-inline-html\": false,\n  \"no-hard-tabs\": { \"spaces_per_tab\": 2 },\n  \"ul-style\": { \"style\": \"dash\" }\n}\n"
  },
  {
    "path": ".markdownlintignore",
    "content": "CHANGELOG.md\nLICENSE\nnode_modules\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nThis project adheres to [Semantic Versioning](https://semver.org/).\nThis change log adheres to standards from [Keep a CHANGELOG](https://keepachangelog.com).\n\n## Unreleased\n\n### Added\n* [`async-server-action`]: add rule ([#3729][] @jorgezreik)\n* [`jsx-props-no-multi-spaces`]: improve autofix for multi-line ([#3930][] @justisb)\n* [`jsx-handler-names`]: support namespaced component names ([#3943][] @takuji)\n* [`jsx-no-leaked-render`]: add `ignoreAttributes` option ([#3441][] @aleclarson)\n* [`jsx-sort-props`]: add `sortFirst` option ([#3965][] @loderunner)\n* [`jsx-no-literals`]: add `restrictedAttributes` option ([#3950][] @ushiboy)\n* [`forbid-dom-props`]: Add `disallowedValues` option for forbidden props ([#3877][] @makxca)\n\n### Fixed\n* [`no-unknown-property`]: allow `onLoad` on `body` ([#3923][] @DerekStapleton)\n* [`no-unknown-property`]: allow `closedby` on `dialog` ([#3980][] @ljharb)\n* [`no-unknown-property`]: add `onScrollEnd` and `onScrollEndCapture` events as known properties ([#3958][] @xfeeefeee)\n* Remove extra space from CLI warning ([#3942][] @junaidkbr)\n* [`jsx-key`]: detect missing keys in return statement with ternary operator ([#3928][] @hyeonbinHur)\n* [`jsx-key`]: detect missing keys in logical expressions ([#3986][] @yalperg)\n* [`display-name`]: avoid false positive when React is shadowed ([#3926][] @hyeonbinHur)\n* [`no-unused-prop-types`]: detect used props in nested components ([#3955][] @avaice)\n\n### Changed\n* [Docs] [`no-array-index-key`]: add template literal examples ([#3978][] @akahoshi1421)\n\n[#3986]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3986\n[#3978]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3978\n[#3958]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3958\n[#3980]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3980\n[#3965]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3965\n[#3955]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3955\n[#3950]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3950\n[#3943]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3943\n[#3942]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3942\n[#3930]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3930\n[#3928]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3928\n[#3926]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3926\n[#3923]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3923\n[#3877]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3877\n[#3729]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3729\n[#3441]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3441\n\n## [7.37.5] - 2025.04.03\n\n### Fixed\n* [`no-unknown-property`]: allow shadow root attrs on `<template>` ([#3912][] @ljharb)\n* [`prop-types`]: support `ComponentPropsWithRef` from a namespace import ([#3651][] @corydeppen)\n* [`jsx-no-constructed-context-values`]: detect constructed context values in React 19 `<Context>` usage ([#3910][] @TildaDares)\n* [`no-unknown-property`]: allow `transform-origin` on `rect` ([#3914][] @ljharb)\n\n### Changed\n* [Docs] [`button-has-type`]: clean up phrasing ([#3909][] @hamirmahal)\n\n[7.37.5]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.4...v7.37.5\n[#3914]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3914\n[#3912]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3912\n[#3910]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3910\n[#3909]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3909\n[#3651]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3651\n\n## [7.37.4] - 2025.01.12\n\n### Fixed\n* [`no-unknown-property`]: support `onBeforeToggle`, `popoverTarget`, `popoverTargetAction` attributes ([#3865][] @acusti)\n* [types] fix types of flat configs ([#3874][] @ljharb)\n\n[7.37.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.3...v7.37.4\n[#3874]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3874\n[#3865]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3865\n\n## [7.37.3] - 2024.12.23\n\n### Fixed\n* [`no-danger`]: avoid a crash on a nested component name ([#3833][] @ljharb)\n* [Fix] types: correct generated type declaration ([#3840][] @ocavue)\n* [`no-unknown-property`]: support `precedence` prop in react 19 ([#3829][] @acusti)\n* [`prop-types`]: props missing in validation when using generic types from a namespace import ([#3859][] @rbondoc96)\n\n### Changed\n* [Tests] [`jsx-no-script-url`]: Improve tests ([#3849][] @radu2147)\n* [Docs] fix broken links: [`default-props-match-prop-types`], [`jsx-boolean-value`], [`jsx-curly-brace-presence`], [`jsx-no-bind`], [`no-array-index-key`], [`no-is-mounted`], [`no-render-return-value`], [`require-default-props`] ([#3841][] @bastiendmt)\n\n[7.37.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.2...v7.37.3\n[#3859]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3859\n[#3849]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3849\n[#3841]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3841\n[#3840]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3840\n[#3833]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3833\n[#3829]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3829\n\n## [7.37.2] - 2024.10.22\n\n### Fixed\n* [`destructuring-assignment`]: fix false negative when using `typeof props.a` ([#3835][] @golopot)\n\n### Changed\n* [Refactor] [`destructuring-assignment`]: use `getParentStatelessComponent` ([#3835][] @golopot)\n\n[7.37.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.1...v7.37.2\n[#3835]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3835\n\n## [7.37.1] - 2024.10.01\n\n### Fixed\n* [meta] do not npmignore `d.ts` files ([#3836][] @ljharb)\n\n### Changed\n* [readme] Fix shared settings link ([#3834][] @MgenGlder)\n\n[7.37.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.0...v7.37.1\n[#3836]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3836\n[#3834]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3834\n\n## [7.37.0] - 2024.09.26\n\n### Added\n* add type generation ([#3830][] @voxpelli)\n* [`no-unescaped-entities`]: add suggestions ([#3831][] @StyleShit)\n* [`forbid-component-props`]: add `allowedForPatterns`/`disallowedForPatterns` options ([#3805][] @Efimenko)\n* [`no-unstable-nested-components`]: add `propNamePattern` to support custom render prop naming conventions ([#3826][] @danreeves)\n\n### Changed\n* [readme] flat config example for react 17+ ([#3824][] @GabenGar)\n\n[7.37.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.36.1...v7.37.0\n[#3831]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3831\n[#3830]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3830\n[#3826]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3826\n[#3824]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3824\n[#3805]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3805\n\n## [7.36.1] - 2024.09.12\n\n### Fixed\n* [`no-is-mounted`]: fix logic in method name check ([#3821][] @Mathias-S)\n* [`jsx-no-literals`]: Avoid crashing on valueless boolean props ([#3823][] @reosarevok)\n\n[7.36.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.36.0...v7.36.1\n[#3823]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3823\n[#3821]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3821\n\n## [7.36.0] - 2024.09.12\n\n### Added\n* [`no-string-refs`]: allow this.refs in > 18.3.0 ([#3807][] @henryqdineen)\n* [`jsx-no-literals`] Add `elementOverrides` option and the ability to ignore this rule on specific elements ([#3812][] @Pearce-Ropion)\n* [`forward-ref-uses-ref`]: add rule for checking ref parameter is added ([#3667][] @NotWoods)\n\n### Fixed\n* [`function-component-definition`], [`boolean-prop-naming`], [`jsx-first-prop-new-line`], [`jsx-props-no-multi-spaces`], `propTypes`: use type args ([#3629][] @HenryBrown0)\n* JSX pragma: fail gracefully ([#3632][] @ljharb)\n* [`jsx-props-no-spreading`]: add `explicitSpread` option to schema ([#3799][] @ljharb)\n\n### Changed\n* [Tests] add @typescript-eslint/parser v6 ([#3629][] @HenryBrown0)\n* [Tests] add @typescript-eslint/parser v7 and v8 ([#3629][] @hampustagerud)\n* [Docs] [`no-danger`]: update broken link ([#3817][] @lucasrmendonca)\n* [types] add jsdoc type annotations ([#3731][] @y-hsgw)\n* [Tests] `button-has-type`: add test case with spread ([#3731][] @y-hsgw)\n\n[7.36.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.2...v7.36.0\n[#3799]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3799\n[#3632]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3632\n[#3812]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3812\n[#3731]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3731\n[#3694]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3667\n[#3629]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3629\n[#3817]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3817\n[#3807]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3807\n\n## [7.35.2] - 2024.09.03\n\n### Fixed\n* [`jsx-curly-brace-presence`]: avoid autofixing attributes with double quotes to a double quoted attribute ([#3814][] @ljharb)\n\n[7.35.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.1...v7.35.2\n[#3814]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3814\n\n## [7.35.1] - 2024.09.02\n\n### Fixed\n* [`jsx-curly-brace-presence`]: do not trigger on strings containing a quote character ([#3798][] @akulsr0)\n\n[7.35.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.0...v7.35.1\n[#3798]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3798\n\n## [7.35.0] - 2024.07.19\n\n### Added\n* support eslint v9 ([#3759][] @mdjermanovic)\n* export flat configs from plugin root and fix flat config crash ([#3694][] @bradzacher @mdjermanovic)\n* add [`jsx-props-no-spread-multi`] ([#3724][] @SimonSchick)\n* [`forbid-component-props`]: add `propNamePattern` to allow / disallow prop name patterns ([#3774][] @akulsr0)\n* [`jsx-handler-names`]: support ignoring component names ([#3772][] @akulsr0)\n* version settings: Allow react defaultVersion to be configurable ([#3771][] @onlywei)\n* [`jsx-closing-tag-location`]: add `line-aligned` option ([#3777] @kimtaejin3)\n* [`no-danger`]: add `customComponentNames` option ([#3748][] @akulsr0)\n\n### Fixed\n* [`no-invalid-html-attribute`]: substitute placeholders in suggestion messages ([#3759][] @mdjermanovic)\n* [`sort-prop-types`]: single line type ending without semicolon ([#3784][] @akulsr0)\n* [`require-default-props`]: report when required props have default value ([#3785][] @akulsr0)\n\n### Changed\n* [Refactor] `variableUtil`: Avoid creating a single flat variable scope for each lookup ([#3782][] @DanielRosenwasser)\n\n[7.35.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.4...v7.35.0\n[#3785]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3785\n[#3784]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3784\n[#3782]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3782\n[#3777]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3777\n[#3774]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3774\n[#3772]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3772\n[#3771]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3771\n[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759\n[#3748]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3748\n[#3724]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3724\n[#3694]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3694\n\n## [7.34.4] - 2024.07.13\n\n### Fixed\n\n* [`prop-types`]: fix `className` missing in prop validation false negative ([#3749][] @akulsr0)\n* [`sort-prop-types`]: Check for undefined before accessing `node.typeAnnotation.typeAnnotation` ([#3779][] @tylerlaprade)\n\n[7.34.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.3...v7.34.4\n[#3779]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3779\n[#3749]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3749\n\n## [7.34.3] - 2024.06.18\n\n### Fixed\n* [`prop-types`]: null-check rootNode before calling getScope ([#3762][] @crnhrv)\n* [`boolean-prop-naming`]: avoid a crash with a spread prop ([#3733][] @ljharb)\n* [`jsx-boolean-value`]: `assumeUndefinedIsFalse` with `never` must not allow explicit `true` value ([#3757][] @6uliver)\n* [`no-object-type-as-default-prop`]: enable rule for components with many parameters ([#3768][] @JulienR1)\n* [`jsx-key`]: incorrect behavior for checkKeyMustBeforeSpread with map callbacks ([#3769][] @akulsr0)\n\n[7.34.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.2...v7.34.3\n[#3769]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3769\n[#3768]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3768\n[#3762]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3762\n[#3757]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3757\n[#3733]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3733\n\n## [7.34.2] - 2024.05.24\n\n### Fixed\n* [`boolean-prop-naming`]: avoid a crash with a non-TSTypeReference type ([#3718][] @developer-bandi)\n* [`jsx-no-leaked-render`]: invalid report if left eside is boolean ([#3746][] @akulsr0)\n* [`jsx-closing-bracket-location`]: message shows `{{details}}` when there are no details ([#3759][] @mdjermanovic)\n* [`no-invalid-html-attribute`]: ensure error messages are correct ([#3759][] @mdjermanovic, @ljharb)\n\n### Changed\n * [Refactor] create various eslint utils to fix eslint deprecations ([#3759][] @mdjermanovic, @ljharb)\n\n[7.34.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.1...v7.34.2\n[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759\n[#3746]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3746\n[#3718]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3718\n\n## [7.34.1] - 2024.03.15\n\n### Fixed\n* [`jsx-no-leaked-render`]: prevent wrongly adding parens ([#3700][] @developer-bandi)\n* [`boolean-prop-naming`]: detect TS interfaces ([#3701][] @developer-bandi)\n* [`boolean-prop-naming`]: literalType error fix ([#3704][] @developer-bandi)\n* [`boolean-prop-naming`]: allow TSIntersectionType ([#3705][] @developer-bandi)\n* [`no-unknown-property`]: support `popover`, `popovertarget`, `popovertargetaction` attributes ([#3707][] @ljharb)\n* [`no-unknown-property`]: only match `data-*` attributes containing `-` ([#3713][] @silverwind)\n* [`checked-requires-onchange-or-readonly`]: correct options that were behaving opposite ([#3715][] @jaesoekjjang)\n* [`boolean-prop-naming`]: avoid a crash with a non-TSTypeReference type ([#3718][] @developer-bandi)\n\n### Changed\n* [`boolean-prop-naming`]: improve error message (@ljharb)\n\n[7.34.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.0...v7.34.1\n[#3715]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3715\n[#3713]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3713\n[#3707]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3707\n[#3705]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3705\n[#3704]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3704\n[#3701]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3701\n[#3700]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3700\n\n## [7.34.0] - 2024.03.03\n\n### Added\n* [`sort-prop-types`]: give errors on TS types ([#3615][] @akulsr0)\n* [`no-invalid-html-attribute`]: add support for `apple-touch-startup-image` `rel` attributes in `link` tags ([#3638][] @thomashockaday)\n* [`no-unknown-property`]: add requireDataLowercase option ([#3645][] @HermanBilous)\n* [`no-unknown-property`]: add `displaystyle` on `<math>` ([#3652][] @lounsbrough)\n* [`prefer-read-only-props`], [`prop-types`], component detection: allow components to be async functions ([#3654][] @pnodet)\n* [`no-unknown-property`]: support `onResize` on audio/video tags ([#3662][] @caesar1030)\n* [`jsx-wrap-multilines`]: add `never` option to prohibit wrapping parens on multiline JSX ([#3668][] @reedws)\n* [`jsx-filename-extension`]: add `ignoreFilesWithoutCode` option to allow empty files ([#3674][] @burtek)\n* [`jsx-boolean-value`]: add `assumeUndefinedIsFalse` option ([#3675][] @developer-bandi)\n* `linkAttribute` setting, [`jsx-no-target-blank`]: support multiple properties ([#3673][] @burtek)\n* [`jsx-no-script-url`]: add `includeFromSettings` option to support `linkAttributes` setting ([#3673][] @burtek)\n* [`jsx-one-expression-per-line`]: add `non-jsx` option to allow non-JSX children in one line ([#3677][] @burtek)\n* add [`checked-requires-onchange-or-readonly`] rule ([#3680][] @jaesoekjjang)\n\n### Fixed\n* [`jsx-no-leaked-render`]: preserve RHS parens for multiline jsx elements while fixing ([#3623][] @akulsr0)\n* [`jsx-key`]: detect conditional returns ([#3630][] @yialo)\n* [`jsx-newline`]: prevent a crash when `allowMultilines` ([#3633][] @ljharb)\n* [`no-unknown-property`]: use a better regex to avoid a crash ([#3666][] @ljharb @SCH227)\n* [`prop-types`]: handle nested forwardRef + memo ([#3679][] @developer-bandi)\n* [`no-unknown-property`]: add `fetchPriority` ([#3697][] @SevereCloud)\n* [`forbid-elements`]: prevent a crash on `createElement()` ([#3632][] @ljharb)\n\n### Changed\n* [`jsx-boolean-value`]: make error messages clearer ([#3691][] @developer-bandi)\n* [Refactor] `propTypes`: extract type params to var ([#3634][] @HenryBrown0)\n* [Refactor] [`boolean-prop-naming`]: invert if statement ([#3634][] @HenryBrown0)\n* [Refactor] [`function-component-definition`]: exit early if no type params ([#3634][] @HenryBrown0)\n* [Refactor] [`jsx-props-no-multi-spaces`]: extract type parameters to var ([#3634][] @HenryBrown0)\n* [Docs] [`jsx-key`]: fix correct example ([#3656][] @developer-bandi)\n* [Tests] `jsx-wrap-multilines`: passing tests ([#3545][] @burtek)\n* [Docs] [`iframe-missing-sandbox`]: fix link to iframe attribute on mdn ([#3690][] @nnmrts)\n* [Docs] [`hook-use-state`]: fix an undefined variable ([#3626][] @chentsulin)\n\n[7.34.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.33.2...v7.34.0\n[#3697]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3697\n[#3691]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3691\n[#3690]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3690\n[#3680]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3680\n[#3679]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3679\n[#3677]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3677\n[#3675]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3675\n[#3674]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3674\n[#3673]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3673\n[#3668]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3668\n[#3666]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3666\n[#3662]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3662\n[#3656]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3656\n[#3654]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3654\n[#3652]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3652\n[#3645]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3645\n[#3638]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3638\n[#3634]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3634\n[#3633]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3633\n[#3632]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3632\n[#3630]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3630\n[#3626]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3626\n[#3623]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3623\n[#3615]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3615\n[#3545]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3545\n\n## [7.33.2] - 2023.08.15\n\n### Fixed\n* [`no-deprecated`]: prevent false positive on commonjs import ([#3614][] @akulsr0)\n* [`no-unsafe`]: report on the method instead of the entire component (@ljharb)\n* [`no-deprecated`]: report on the destructured property instead of the entire variable declarator (@ljharb)\n* [`no-deprecated`]: report on the imported specifier instead of the entire import statement (@ljharb)\n* [`no-invalid-html-attribute`]: report more granularly (@ljharb)\n\n[7.33.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.33.1...v7.33.2\n[#3614]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3614\n\n## [7.33.1] - 2023.07.29\n\n### Fixed\n* [`require-default-props`]: fix config schema ([#3605][] @controversial)\n* [`jsx-curly-brace-presence`]: Revert [#3538][] due to issues with intended string type casting usage ([#3611][] @taozhou-glean)\n* [`sort-prop-types`]: ensure sort-prop-types respects noSortAlphabetically ([#3610][] @caesar1030)\n\n[7.33.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.33.0...v7.33.1\n[#3611]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3611\n[#3610]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3610\n[#3605]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3605\n\n## [7.33.0] - 2023.07.19\n\n### Added\n* [`display-name`]: add `checkContextObjects` option ([#3529][] @JulesBlm)\n* [`jsx-first-prop-new-line`]: add `multiprop` option ([#3533][] @haydncomley)\n* [`no-deprecated`]: add React 18 deprecations ([#3548][] @sergei-startsev)\n* [`forbid-component-props`]: add `disallowedFor` option ([#3417][] @jacketwpbb)\n\n### Fixed\n* [`no-array-index-key`]: consider flatMap ([#3530][] @k-yle)\n* [`jsx-curly-brace-presence`]: handle single and only expression template literals ([#3538][] @taozhou-glean)\n* [`no-unknown-property`]: allow `onLoad` on `source` (@ljharb)\n* [`jsx-first-prop-new-line`]: ensure autofix preserves generics in component name ([#3546][] @ljharb)\n* [`no-unknown-property`]: allow `fill` prop on `<symbol>` ([#3555][] @stefanprobst)\n* [`display-name`], [`prop-types`]: when checking for a capitalized name, ignore underscores entirely ([#3560][] @ljharb)\n* [`no-unused-state`]: avoid crashing on a class field function with destructured state ([#3568][] @ljharb)\n* [`no-unused-prop-types`]: allow using spread with object expression in jsx ([#3570][] @akulsr0)\n* Revert \"[`destructuring-assignment`]: Handle destructuring of useContext in SFC\" ([#3583][] [#2797][] @102)\n* [`prefer-read-only-props`]: add TS support ([#3593][] @HenryBrown0)\n\n### Changed\n* [Docs] [`jsx-newline`], [`no-unsafe`], [`static-property-placement`]: Fix code syntax highlighting ([#3563][] @nbsp1221)\n* [readme] resore configuration URL ([#3582][] @gokaygurcan)\n* [Docs] [`jsx-no-bind`]: reword performance rationale ([#3581][] @gpoole)\n- [Docs] [`jsx-first-prop-new-line`]: add missing `multiprop` value ([#3598][] @dzek69)\n\n[7.33.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.32.2...v7.33.0\n[#3598]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3598\n[#3593]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3593\n[#3583]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3583\n[#3582]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3582\n[#3581]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3581\n[#3570]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3570\n[#3568]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3568\n[#3563]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3563\n[#3560]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3560\n[#3555]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3555\n[#3548]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3548\n[#3546]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3546\n[#3538]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3538\n[#3533]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3533\n[#3530]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3530\n[#3529]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3529\n[#3417]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3417\n\n## [7.32.2] - 2023.01.28\n\n### Fixed\n* configs: restore `parserOptions` in legacy configs ([#3523][] @ljharb)\n* [`jsx-no-constructed-context-values`], [`jsx-no-useless-fragment`]: add a rule schema (@ljharb)\n( [`no-unknown-property`]: add `fill` for `<marker>` ([#3525][] @alexey-koran)\n\n[7.32.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.32.1...v7.32.2\n[#3525]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3525\n[#3520]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3523\n\n## [7.32.1] - 2023.01.16\n\n### Fixed\n* prevent circular dependency in index and \"all\" config ([#3519][] @ljharb)\n* [`destructuring-assignment`]: do not force destructuring of optionally chained properties ([#3520][] @ljharb)\n\n[7.32.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.32.0...v7.32.1\n[#3520]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3520\n[#3519]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3519\n\n## [7.32.0] - 2023.01.10\n\n### Added\n* support new config system ([#3429][] @jjangga0214)\n* [`hook-use-state`]: add `allowDestructuredState` option ([#3449][] @ljharb)\n* add [`sort-default-props`] and deprecate [`jsx-sort-default-props`] ([#1861][] @alexzherdev)\n* add [`no-object-type-as-default-prop`] rule ([#2848][] @cyan33 @fengkx)\n\n### Fixed\n* configs: avoid legacy config system error ([#3461][] @ljharb)\n* [`sort-prop-types`]: restore autofixing ([#3452][], [#3471][] @ROSSROSALES)\n* [`no-unknown-property`]: do not check `fbs` elements ([#3494][] @brianogilvie)\n* [`jsx-newline`]: No newline between comments and jsx elements ([#3493][] @justmejulian)\n* [`jsx-no-leaked-render`]: Don't report errors on empty strings if React >= v18 ([#3488][] @himanshu007-creator)\n* [`no-invalid-html-attribute`]: convert autofix to suggestion ([#3474][] @himanshu007-creator @ljharb)\n* [`jsx-no-leaked-render`]: fix removing parentheses for conditionals ([#3502][] @akulsr0)\n* [`jsx-no-leaked-render`]: invalid fixes in coerce mode ([#3511][] @akulsr0)\n* [`destructuring-assignment`]: Handle destructuring of useContext in SFC ([#2797][] @Zinyon @ljharb)\n\n### Changed\n* [Docs] [`jsx-no-leaked-render`]: Remove mentions of empty strings for React 18 ([#3468][] @karlhorky)\n* [Docs] update `eslint-doc-generator` to v1.0.0 ([#3499][] @bmish)\n* [meta] add issue template ([#3483][] @ROSSROSALES)\n* [Docs] Use emoji for jsx-runtime config and config file for eslint-doc-generator ([#3504][] @bmish)\n* [Docs] [`prefer-exact-props`]: fix example flow syntax ([#3510][] @smackfu)\n* [Perf] use `anyOf` instead of `oneOf` (@ljharb @remcohaszing)\n\n[7.32.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.11...v7.32.0\n[#3511]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3511\n[#3510]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3510\n[#3504]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3504\n[#3502]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3502\n[#3499]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3499\n[#3494]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3494\n[#3493]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3493\n[#3488]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3488\n[#3483]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3483\n[#3474]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3474\n[#3471]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3471\n[#3468]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3468\n[#3461]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3461\n[#3452]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3452\n[#3449]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3449\n[#3429]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3429\n[#2848]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2848\n[#2797]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2797\n[#1861]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1861\n\n## [7.31.11] - 2022.11.17\n\n### Fixed\n* [`jsx-no-target-blank`]: allow ternaries with literals ([#3464][] @akulsr0)\n* [`no-unknown-property`]: add `inert` attribute ([#3484][] @ljharb)\n* [`jsx-key`]: detect keys in logical expression and conditional expression ([#3490][] @metreniuk)\n\n### Changed\n* [Perf] component detection: improve performance by avoiding traversing parents unnecessarily ([#3459][] @golopot)\n* [Docs] `forbid-component-props`: inclusive language w/ allowlist ([#3473][] @AndersDJohnson)\n* [Docs] automate doc generation with `eslint-doc-generator` ([#3469][] @bmish)\n\n[7.31.11]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.10...v7.31.11\n[#3490]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3490\n[#3484]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3484\n[#3473]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3473\n[#3469]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3469\n[#3464]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3464\n[#3459]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3459\n\n## [7.31.10] - 2022.10.10\n\n### Fixed\n* [`no-unknown-property`]: allow `allowFullScreen` on `iframe` ([#3455][] @almeidx)\n\n[7.31.10]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.9...v7.31.10\n[#3455]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3455\n\n## [7.31.9] - 2022.10.09\n\n### Fixed\n* [`no-unknown-property`]: add `dialog` attributes ([#3436][] @ljharb)\n* [`no-arrow-function-lifecycle`]: when converting from an arrow, remove the semi and wrapping parens ([#3337][] @ljharb)\n* [`jsx-key`]: Ignore elements inside `React.Children.toArray()` ([#1591][] @silvenon)\n* [`jsx-no-constructed-context-values`]: fix false positive for usage in non-components ([#3448][] @golopot)\n* [`static-property-placement`]: warn on nonstatic expected-statics ([#2581][] @ljharb)\n* [`no-unknown-property`]: properly tag-restrict case-insensitive attributes (@ljharb)\n* [`no-unknown-property`]: allow `webkitDirectory` on `input`, case-insensitive ([#3454][] @ljharb)\n\n### Changed\n* [Docs] [`no-unknown-property`]: fix typo in link ([#3445][] @denkristoffer)\n* [Perf] component detection: improve performance by optimizing getId ([#3451][] @golopot)\n* [Docs] [`no-unstable-nested-components`]: Warn about memoized, nested components ([#3444][] @eps1lon)\n\n[7.31.9]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.8...v7.31.9\n[#3454]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3454\n[#3451]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3451\n[#3448]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3448\n[#3445]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3445\n[#3444]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3444\n[#3436]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3436\n[#3337]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3337\n[#2581]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2581\n[#1591]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1591\n\n## [7.31.8] - 2022.09.08\n\n### Fixed\n* [`no-unknown-property`]: add `viewBox` on `marker` ([#3416][] @ljharb)\n* [`no-unknown-property`]: add `noModule` on `script` ([#3414][] @ljharb)\n* [`no-unknown-property`]: allow `onLoad` on `<object>` ([#3415][] @OleksiiKachan)\n* [`no-multi-comp`]: do not detect a function property returning only null as a component ([#3412][] @ljharb)\n* [`no-unknown-property`]: allow `abbr` on `<th>` and `<td>` ([#3419][] @OleksiiKachan)\n* [`no-unknown-property`]: add `viewBox` for `pattern`, `symbol`, `view` ([#3424][] @MNBuyskih)\n* [`no-unknown-property`]: add `align` on all the tags that support it ([#3425][] @ljharb)\n\n### Changed\n\n* [meta] npmignore markdownlint config ([#3413][] @jorrit)\n\n[7.31.8]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.7...v7.31.8\n[#3425]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3425\n[#3424]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3424\n[#3419]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3419\n[#3416]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3416\n[#3415]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3415\n[#3414]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3414\n[#3413]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3413\n[#3412]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3412\n\n## [7.31.7] - 2022.09.05\n\n### Fixed\n* [`no-unknown-property`]: avoid warning on `fbt` nodes entirely ([#3391][] @ljharb)\n* [`no-unknown-property`]: add `download` property support for `a` and `area` ([#3394][] @HJain13)\n* [`no-unknown-property`]: allow `webkitAllowFullScreen` and `mozAllowFullScreen` ([#3396][] @ljharb)\n* [`no-unknown-property`]: `controlsList`, not `controlList` ([#3397][] @ljharb)\n* [`no-unknown-property`]: add more capture event properties ([#3402][] @sjarva)\n* [`no-unknown-property`]: Add more one word properties found in DefinitelyTyped's react/index.d.ts ([#3402][] @sjarva)\n* [`no-unknown-property`]: Mark onLoad/onError as supported on iframes ([#3398][] @maiis, [#3406][] @akx)\n* [`no-unknown-property`]: allow `imageSrcSet` and `imageSizes` attributes on `<link>` ([#3407][] @terrymun)\n* [`no-unknown-property`]: add `border`; `focusable` on `<svg>` ([#3404][] [#3404][] @ljharb)\n* [`no-unknown-property`]: React lowercases `data-` attrs ([#3395][] @ljharb)\n* [`no-unknown-property`]: add `valign` on table components ([#3389][] @ljharb)\n\n[7.31.7]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.6...v7.31.7\n[#3407]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3407\n[#3406]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3406\n[#3405]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3405\n[#3404]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3404\n[#3402]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3402\n[#3398]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3398\n[#3397]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3397\n[#3396]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3396\n[#3395]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3395\n[#3394]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3394\n[#3391]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3391\n[#3389]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3389\n\n## [7.31.6] - 2022.09.04\n\n### Fixed\n* [`no-unknown-property`]: `onError` and `onLoad` both work on `img` and `script` ([#3388][] @ljharb)\n* [`no-unknown-property`]: data-* attributes can have numbers ([#3390][] @sjarva)\n* [`no-unknown-property`]: add more audio/video attributes ([#3390][] @sjarva)\n* [`no-unknown-property`]: move allowfullscreen to case ignored attributes ([#3390][] @sjarva)\n* [`no-unknown-property`]: fill works on line, mask, and use elements ([#3390][] @sjarva)\n* [`no-unknown-property`]: add onMouseMoveCapture as valid react-specific attribute ([#3390][] @sjarva)\n* [`no-unknown-property`]: make onLoad and onError be accepted on more elements ([#3390][] @sjarva)\n\n### Changed\n\n* [Docs] [`no-unknown-property`]: add a mention about using ignores properties with libraries that add props ([#3390][] @sjarva)\n\n[7.31.6]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.5...v7.31.6\n[#3390]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3390\n[#3388]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3388\n\n## [7.31.5] - 2022.09.03\n\n### Fixed\n* [`no-unknown-property`]: add properties `onToggle`, `fill`, `as`, and pointer events ([#3385][] @sjarva)\n* [`no-unknown-property`]: add `defaultChecked` property ([#3385][] @sjarva)\n* [`no-unknown-property`]: add touch and media event related properties ([#3385][] @sjarva)\n* [`no-unknown-property`]: `children` is always an acceptable prop; iframes have `scrolling`; video has `playsInline` ([#3385][] @ljharb)\n\n[7.31.5]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.4...v7.31.5\n[#3385]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3385\n\n## [7.31.4] - 2022.09.03\n\n### Fixed\n* [`no-unknown-property`]: support `checked` on inputs ([#3383][] @ljharb)\n\n[#3383]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3383\n\n[7.31.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.3...v7.31.4\n\n## [7.31.3] - 2022.09.02\n\n### Fixed\n* [`no-unknown-property`]: add SVG and meta properties ([#3381][] @AhmadMayo)\n\n[7.31.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.2...v7.31.3\n[#3381]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3381\n\n## [7.31.2] - 2022.09.02\n\n### Fixed\n* [`jsx-key`]: avoid a crash with optional chaining ([#3371][] @ljharb)\n* [`jsx-sort-props`]: avoid a crash with spread props ([#3376][] @ljharb)\n* [`no-unknown-property`]: properly recognize valid data- and aria- attributes ([#3377][] @sjarva)\n* [`no-unknown-property`]: properly recognize unknown HTML/DOM attributes ([#3377][] @sjarva)\n\n### Changed\n* [Docs] [`jsx-sort-props`]: replace ref string with ref variable ([#3375][] @Luccasoli)\n* [Refactor] [`no-unknown-property`]: improve jsdoc; extract logic to separate functions ([#3377][] @sjarva)\n* [Refactor] [`no-unknown-property`]: update DOM properties to include also one word properties ([#3377][] @sjarva)\n\n[7.31.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.1...v7.31.2\n[#3377]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3377\n[#3376]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3376\n[#3375]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3375\n[#3371]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3371\n\n## [7.31.1] - 2022.08.26\n\n### Fixed\n* [`jsx-key`]: fix detecting missing key in `Array.from`'s mapping function ([#3369][] @sjarva)\n* [`jsx-no-leaked-render`]: coerce strategy now allows a ternary ([#3370][] @sjarva)\n\n[7.31.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.0...v7.31.1\n[#3370]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3370\n[#3369]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3369\n\n## [7.31.0] - 2022.08.24\n\n### Added\n* [`jsx-newline`]: add `allowMultiline` option when prevent option is true ([#3311][] @TildaDares)\n* [`forbid-dom-props`]: add `disallowedFor` option ([#3338][] @TildaDares)\n\n### Fixed\n* [`jsx-no-literals`]: properly error on children with noAttributeStrings: true ([#3317][] @TildaDares)\n* [`jsx-key`]: catch key errors inside conditional statements ([#3320][] @TildaDares)\n* [`display-name`]: Accept forwardRef and Memo nesting in newer React versions ([#3321][] @TildaDares)\n* [`jsx-key`]: avoid a crash from optional chaining from [#3320][] ([#3327][] @ljharb)\n* [`jsx-key`]: avoid a crash on a non-array node.body from [#3320][] ([#3328][] @ljharb)\n* [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero)\n* [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero)\n* [`require-default-props`]: avoid a crash when function has no props param ([#3350][] @noahnu)\n* [`display-name`], component detection: fix HOF returning null as Components ([#3347][] @jxm-math)\n* [`forbid-prop-types`]: Ignore objects that are not of type React.PropTypes ([#3326][] @TildaDares)\n* [`display-name`], component detection: fix false positive for HOF returning only nulls and literals ([#3305][] @golopot)\n* [`jsx-no-target-blank`]: False negative when rel attribute is assigned using ConditionalExpression ([#3332][] @V2dha)\n* [`jsx-no-leaked-render`]: autofix nested \"&&\" logical expressions ([#3353][] @hduprat)\n* [`jsx-sort-props`]: sorted attributes now respect comments ([#3358][] @ROSSROSALES)\n\n### Changed\n* [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)\n* [Tests] [`jsx-indent`], [`jsx-one-expression-per-line`]: add passing test cases ([#3314][] @ROSSROSALES)\n* [Refactor] `boolean-prop-naming`, `jsx-indent`: avoid assigning to arguments ([#3316][] @caroline223)\n* [Docs] [`sort-comp`]: add class component examples ([#3339][] @maurer2)\n* [Docs] [`jsx-no-useless-fragment`]: add more examples of correct code ([#3349][] @karlhorky)\n* [Docs] [`jsx-boolean-value`]: add jsdoc types for helper functions ([#3344][] @caroline223)\n* [readme] remove dead codeclimate badge, add actions badge (@ljharb)\n* [readme] Remove dead david-dm badge ([#3262][] @ddzz)\n* [Refactor] [`jsx-closing-bracket-location`], [`jsx-no-bind`]: fix eslint issues ([#3351][] @caroline223)\n* [Tests] [`function-component-definition`]: add passing test cases ([#3355][] @TildaDares)\n* [Docs] [`jsx-no-target-blank`]: Fix link to link-type-noreferrer ([#3319][] @Luccasoli)\n* [Docs] document which rules provide suggestions ([#3359][], [#3365][] @bmish)\n* [Docs] Consistent rule descriptions and doc sections ([#3361][] @bmish)\n* [Docs] Standardize deprecated rule notice ([#3364][] @bmish)\n* [Docs] Fix typos ([#3366][] @bmish)\n* [Docs] Add markdownlint for documentation formatting consistency ([#3367][] @bmish)\n* [Docs] Add config notice to rule docs ([#3362][] @bmish)\n\n[7.31.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.30.1...v7.31.0\n[#3367]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3367\n[#3366]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3366\n[#3365]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3365\n[#3364]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3364\n[#3362]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3362\n[#3361]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3361\n[#3359]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3359\n[#3358]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3358\n[#3355]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3355\n[#3353]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3353\n[#3351]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3351\n[#3350]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3350\n[#3349]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3349\n[#3347]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3347\n[#3344]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3344\n[#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339\n[#3338]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3338\n[#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335\n[#3332]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3332\n[#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331\n[#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328\n[#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327\n[#3326]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3326\n[#3321]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3321\n[#3320]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3320\n[#3319]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3319\n[#3317]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3317\n[#3316]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3316\n[#3315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3315\n[#3314]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3314\n[#3311]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3311\n[#3305]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3305\n[#3262]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3262\n\n## [7.30.1] - 2022.06.23\n\n### Fixed\n* [`display-name`]: fix false positive for HOF returning only nulls ([#3291][] @golopot)\n* [`jsx-no-leaked-render`]: avoid unnecessary negation operators and ternary branches deletion ([#3299][] @Belco90)\n* [`display-name`]: fix false positive when using memo ([#3304][] @golopot)\n\n### Changed\n* [Docs] [`jsx-tag-spacing`]: rename option from [#3264][] ([#3294[] @ljharb)\n* [Docs] [`jsx-key`]: split the examples ([#3293][] @ioggstream)\n\n[7.30.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.30.0...v7.30.1\n[#3304]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3304\n[#3299]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3299\n[#3294]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3294\n[#3293]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3293\n[#3291]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3291\n\n## [7.30.0] - 2022.05.18\n\n### Added\n* [`destructuring-assignment`]: add option `destructureInSignature` ([#3235][] @golopot)\n* [`no-unknown-property`]: Allow crossOrigin on image tag (SVG) ([#3251][] @zpao)\n* [`jsx-tag-spacing`]: Add `multiline-always` option ([#3260][], [#3264][] @Nokel81)\n* [`function-component-definition`]: replace `var` by `const` in certain situations ([#3248][] @JohnBerd @SimeonC)\n* add [`jsx-no-leaked-render`] ([#3203][] @Belco90)\n* [`require-default-props`]: add option `functions` ([#3249][] @nix6839)\n* [`jsx-newline`]: Add `allowMultilines` option ([#3311][] @TildaDares)\n\n### Fixed\n* [`hook-use-state`]: Allow UPPERCASE setState setter prefixes ([#3244][] @duncanbeevers)\n* `propTypes`: add `VFC` to react generic type param map ([#3230][] @dlech)\n* [`no-unused-state`]: avoid a crash ([#3258][] @WillyLiaoWH @ljharb)\n* [`jsx-no-useless-fragment`]: use proper apostrophe in error message ([#3266][] @develohpanda)\n* `propTypes`: handle imported types/interface in forwardRef generic ([#3280][] @vedadeepta)\n* [`button-has-type`]: fix exception for `<button type>` ([#3255][] @meowtec)\n* [`no-unstable-nested-components`]: Improve error message and catch React.memo() ([#3247][] @zacharyliu)\n\n### Changed\n* [readme] remove global usage and eslint version from readme ([#3254][] @aladdin-add)\n* [Refactor] fix linter errors ([#3261][] @golopot)\n* [Docs] [`no-unused-prop-types`]: fix syntax errors ([#3259][] @mrdulin)\n* [Refactor] improve performance for detecting function components ([#3265][] @golopot)\n* [Refactor] improve performance for detecting class components ([#3267][] @golopot)\n* [Refactor] [`no-deprecated`]: improve performance ([#3271][] @golopot)\n* [Refactor] [`no-did-mount-set-state`], [`no-did-update-set-state`], [`no-will-update-set-state`]: improve performance ([#3272][] @golopot)\n* [Refactor] improve performance by avoiding unnecessary `Components.detect` ([#3273][] @golopot)\n* [Refactor] add `isParenthesized` AST util ([#3203][] @Belco90)\n* [Docs] `default-props-match-prop-types`, `require-default-props`, `sort-prop-types`: fix typos ([#3279][] @nix6839)\n* [Refactor] improve performance of rule merging ([#3281][] @golopot)\n* [Refactor] improve performance of component detection ([#3276][] @golopot)\n\n[7.30.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.4...v7.30.0\n[#3281]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3281\n[#3280]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3280\n[#3279]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3279\n[#3276]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3276\n[#3273]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3273\n[#3272]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3272\n[#3271]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3271\n[#3267]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3267\n[#3266]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3266\n[#3265]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3265\n[#3264]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3264\n[#3261]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3261\n[#3260]: https://github.jsx-eslintckcr/eslint-plugin-react/pull/3260\n[#3259]: https://githubjsx-eslintickcr/eslint-plugin-react/pull/3259\n[#3258]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3258\n[#3255]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3255\n[#3254]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3254\n[#3251]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3251\n[#3249]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3249\n[#3248]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3248\n[#3247]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3247\n[#3244]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3244\n[#3235]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3235\n[#3230]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3230\n[#3203]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3203\n\n## [7.29.4] - 2022.03.13\n\n### Fixed\n* [`no-unused-state`]: avoid a crash on a class field gDSFP ([#3236][] @ljharb)\n* [`boolean-prop-naming`]: handle React.FC, intersection, union types ([#3241][] @ljharb)\n\n[7.29.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.3...v7.29.4\n[#3241]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3241\n[#3236]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3236\n\n## [7.29.3] - 2022.03.03\n\n### Fixed\n* [`no-unused-state`]: avoid a crash on type-only gDSFP declarations ([#3225][] @ljharb)\n* [`jsx-curly-brace-presence`]: the string \"never\" defaults to `propElementValues` as `ignore` ([#3228][] @ljharb)\n* `propTypes`: add `VFC` to react generic list ([#3230][] @ljharb)\n\n[7.29.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.2...v7.29.3\n[#3230]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3230\n[#3228]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3228\n[#3225]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3225\n\n## [7.29.2] - 2022.02.25\n\n### Fixed\n* [`jsx-curly-brace-presence`]: avoid warning on curlies containing quote characters ([#3214][] @ljharb)\n* [`jsx-indent`]: do not report on non-jsx-returning ternaries that contain null ([#3222][] @ljharb)\n* [`jsx-indent`]: properly report on returned ternaries with jsx ([#3222][] @ljharb)\n* [`no-array-index-key`]: detect named-imported `cloneElement`/`createElement` ([#3213][] @ljharb)\n\n[7.29.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.1...v7.29.2\n[#3222]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3222\n[#3214]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3214\n[#3213]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3213\n\n## [7.29.1] - 2022.02.25\n\n### Fixed\n* [`jsx-key`]: prevent false \"missing array key\" warning ([#3215][] @ljharb)\n* [`jsx-indent`]: avoid checking returns sans jsx ([#3218][] @ljharb)\n* [`jsx-key`]: avoid a crash ([#3220][] @ljharb)\n* version settings: avoid a crash with an invalid version ([#3219][] @ljharb)\n\n[7.29.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.0...v7.29.1\n[#3220]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3220\n[#3219]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3219\n[#3218]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3218\n[#3215]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3215\n\n## [7.29.0] - 2022.02.24\n\n### Added\n* add [`hook-use-state`] rule to enforce symmetric useState hook variable names ([#2921][] @duncanbeevers)\n* [`jsx-no-target-blank`]: Improve fixer with option `allowReferrer` ([#3167][] @apepper)\n* [`jsx-curly-brace-presence`]: add \"propElementValues\" config option ([#3191][] @ljharb)\n* add [`iframe-missing-sandbox`] rule ([#2753][] @tosmolka @ljharb)\n* [`no-did-mount-set-state`], [`no-did-update-set-state`]: no-op with react >= 16.3 ([#1754][] @ljharb)\n* [`jsx-sort-props`]: support multiline prop groups ([#3198][] @duhamelgm)\n* [`jsx-key`]: add `warnDuplicates` option to warn on duplicate jsx keys in an array ([#2614][] @ljharb)\n* [`jsx-sort-props`]: add `locale` option ([#3002][] @ljharb)\n\n### Fixed\n* [`prop-types`], `propTypes`: add support for exported type inference ([#3163][] @vedadeepta)\n* [`no-invalid-html-attribute`]: allow 'shortcut icon' on `link` ([#3174][] @Primajin)\n* [`prefer-exact-props`] improve performance for `Identifier` visitor ([#3190][] @meowtec)\n* `propTypes`: Handle TSTypeReference in no-unused-prop-type ([#3195][] @niik)\n* [`sort-prop-types`]: avoid repeated warnings of the same node/reason ([#519][] @ljharb)\n* [`jsx-indent`]: Fix indent handling for closing parentheses ([#620][] @stefanbuck])\n* [`prop-types`]/`propTypes`: follow a returned identifier to see if it is JSX ([#1046][] @ljharb)\n* [`no-unused-state`]: TS: support `getDerivedStateFromProps` as an arrow function ([#2061][] @ljharb)\n* [`no-array-index-key`]: catch `.toString` and `String()` usage ([#2813][] @RedTn)\n* [`function-component-definition`]: do not break on dollar signs ([#3207][] @ljharb)\n* [`prefer-stateless-function`]: avoid a crash inside `doctrine` ([#2596][] @ljharb)\n* [`prop-types`]: catch infinite loop ([#2861][] @ljharb)\n* [`forbid-prop-types`]: properly report name in error message; check undestructured arguments ([#2945][] @ljharb)\n\n### Changed\n* [readme] change [`jsx-runtime`] link from branch to sha ([#3160][] @tatsushitoji)\n* [Docs] HTTP => HTTPS ([#3133][] @Schweinepriester)\n* [readme] Some grammar fixes ([#3186][] @JJ)\n* [Docs] [`jsx-no-target-blank`]: Improve readme ([#3169][] @apepper)\n* [Docs] [`display-name`]: improve examples ([#3189][] @golopot)\n* [Refactor] [`no-invalid-html-attribute`]: sort HTML_ELEMENTS and messages ([#3182][] @Primajin)\n* [Docs] [`forbid-foreign-prop-types`]: document `allowInPropTypes` option ([#1815][] @ljharb)\n* [Refactor] [`jsx-sort-default-props`]: remove unnecessary code ([#1817][] @ljharb)\n* [Docs] [`jsx-no-target-blank`]: fix syntax highlighting ([#3199][] @shamrin)\n* [Docs] [`jsx-key`]: improve example ([#3202][] @chnakamura)\n* [Refactor] [`jsx-key`]: use more AST selectors (@ljharb)\n\n[7.29.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.28.0...v7.29.0\n[#3207]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3207\n[#3202]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3202\n[#3199]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3199\n[#3198]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3198\n[#3195]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3195\n[#3191]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3191\n[#3190]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3190\n[#3189]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3189\n[#3186]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3186\n[#3182]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3182\n[#3174]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3174\n[#3169]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3169\n[#3167]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3167\n[#3163]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3163\n[#3160]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3160\n[#3133]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3133\n[#3002]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3002\n[#2945]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2945\n[#2921]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2921\n[#2861]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2861\n[#2813]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2813\n[#2753]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2753\n[#2614]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2614\n[#2596]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2596\n[#2061]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2061\n[#1817]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1817\n[#1815]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1815\n[#1754]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1754\n[#1046]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1046\n[#620]: https://github.com/jsx-eslint/eslint-plugin-react/pull/620\n[#519]: https://github.com/jsx-eslint/eslint-plugin-react/issues/519\n\n## [7.28.0] - 2021.12.22\n\n### Added\n* [`function-component-definition`]: support namedComponents option being an array ([#3129][] @petersendidit)\n\n### Fixed\n* [`jsx-indent-props`]: Reset `line.isUsingOperator` correctly after ternary ([#3146][] @tobiaswaltl)\n\n### Changed\n* [Refactor] [`no-arrow-function-lifecycle`], [`no-unused-class-component-methods`]: use report/messages convention (@ljharb)\n* [Tests] component detection: Add testing scaffolding ([#3149][] @duncanbeevers)\n* [New] component detection: track React imports ([#3149][] @duncanbeevers)\n* [New] component detection: add `util.isReactHookCall` ([#3156][] @duncanbeevers)\n\n[7.28.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.27.1...v7.28.0\n[#3156]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3156\n[#3149]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3149\n[#3146]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3146\n[#3129]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3129\n\n## [7.27.1] - 2021.11.18\n\n### Fixed\n* [`no-invalid-html-attribute`]: allow `link` `rel` to have `apple-touch-icon`, `mask-icon` ([#3132][] @ljharb)\n* [`no-unused-class-component-methods`]: add `getChildContext` lifecycle method ([#3136][] @yoyo837)\n* [`prop-types`]: fix false positives on renames in object destructuring ([#3142][] @golopot)\n* [`no-arrow-function-lifecycle`]: fix invalid autofix from a concise arrow method to a regular one ([#3145][] @ljharb)\n* [`display-name`]: avoid false positives on non-creatClass object expressions ([#3144] @ljharb)\n\n### Changed\n* [readme] fix syntax typo ([#3141][] @moselhy)\n\n[7.27.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.27.0...v7.27.1\n[#3145]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3145\n[#3144]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3144\n[#3142]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3142\n[#3141]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3141\n[#3136]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3136\n[#3132]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3132\n\n## [7.27.0] - 2021.11.09\n\n### Added\n* support eslint 8.x ([#3059][] @MichaelDeBoey @ljharb)\n* [`no-unused-class-component-methods`]: Handle unused class component methods ([#2166][] @jakeleventhal @pawelnvk)\n* add [`no-arrow-function-lifecycle`] ([#1980][] @ngtan)\n* add support for `@typescript-eslint/parser` v5 (@ljharb)\n* [`no-invalid-html-attribute`]: add rule ([#2863][] @Nokel81)\n\n### Fixed\n* `propTypes`: add `VoidFunctionComponent` to react generic list ([#3092][] @vedadeepta)\n* [`jsx-fragments`], [`jsx-no-useless-fragment`]: avoid a crash on fragment syntax in `typescript-eslint` parser (@ljharb)\n* [`jsx-props-no-multi-spaces`]: avoid a crash on long member chains in tag names in `typescript-eslint` parser (@ljharb)\n* [`no-unused-prop-types`], `usedPropTypes`: avoid crash with typescript-eslint parser (@ljharb)\n* [`display-name`]: unwrap TS `as` expressions ([#3110][] @ljharb)\n* [`destructuring-assignment`]: detect refs nested in functions ([#3102] @ljharb)\n* [`no-unstable-components`]: improve handling of objects containing render function properties ([#3111] @fizwidget)\n* [`prop-types`], `propTypes`: add forwardRef<>, ForwardRefRenderFunction<> prop-types ([#3112] @vedadeepta)\n* [`no-typos`]: prevent a crash when using private methods (@ljharb)\n* [`destructuring-assignment`], component detection: improve component detection ([#3122] @vedadeepta)\n* [`no-invalid-html-attribute`]: avoid crash on spread props ([#3126] @ljharb)\n\n### Changed\n* [Tests] test on the new babel eslint parser ([#3113] @ljharb)\n* [Docs] [`jsx-no-target-blank`]: adjust options description ([#3124] @gebsh)\n\n[7.27.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.26.1...v7.27.0\n[#3126]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3126\n[#3124]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3124\n[#3122]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3122\n[#3113]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3113\n[#3112]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3112\n[#3111]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3111\n[#3110]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3110\n[#3102]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3102\n[#3092]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3092\n[#3059]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3059\n[#2863]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2863\n[#2166]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2166\n[#1980]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1980\n\n## [7.26.1] - 2021.09.29\n\n### Fixed\n* [`no-namespace`]: fix crash on non-string React.createElement name ([#3082] @ljharb)\n* [`no-namespace`]: avoid crash on non-string createElement values ([#3085] @ljharb)\n* [`jsx-no-target-blank`]: improve error messages ([#3088] @cutiful)\n\n### Changed\n* [Docs] [`jsx-max-props-per-line`]: fix options example ([#3083] @MrRaiter)\n\n[7.26.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.26.0...v7.26.1\n[#3088]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3088\n[#3085]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3085\n[#3083]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3083\n[#3082]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3082\n\n## [7.26.0] - 2021.09.20\n\n### Added\n* add [`no-namespace`] rule ([#2640] @yacinehmito @ljharb)\n* [`jsx-max-props-per-line`]: add `single` and `multi` options ([#3078] @SIL0RAK)\n\n### Fixed\n* [`display-name`]: Get rid of false position on component detection ([#2759] @iiison)\n\n### Changed\n* [`no-access-state-in-setstate`]: passing test for “don't error if it's not a React Component” ([#1873] @kentcdodds)\n\n[7.26.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.25.3...v7.26.0\n[#3078]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3078\n[#2640]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2640\n[#2759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2759\n[#1873]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1873\n\n## [7.25.3] - 2021.09.19\n\n### Fixed\n* [`prop-types`], `propTypes`: bail out unknown generic types inside func params ([#3076] @vedadeepta)\n\n### Changed\n* [readme] Update broken link for configuration files ([#3071] @prateek3255)\n* [Refactor] create/extract `isCreateElement` and `isDestructuredFromPragmaImport` utils (@ljharb)\n\n[7.25.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.25.2...v7.25.3\n[#3076]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3076\n[#3071]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3071\n\n## [7.25.2] - 2021.09.16\n\n### Fixed\n* [`jsx-no-useless-fragments`]: Handle insignificant whitespace correctly when `allowExpressions` is `true` ([#3061][] @benj-dobs)\n* [`prop-types`], `propTypes`: handle implicit `children` prop in react's generic types ([#3064][] @vedadeepta)\n* [`display-name`]: fix arrow function returning result of function call with JSX arguments being interpreted as component ([#3065][] @danielfinke)\n* [`jsx-no-target-blank`]: avoid crash on attr-only href ([#3066][] @ljharb @gaz77a)\n* [`jsx-uses-vars`]: ignore lowercase tag names ([#3070][] @alanorozco)\n\n[7.25.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.25.1...v7.25.2\n[#3070]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3070\n[#3066]: https://github.com/jsx-eslint/eslint-plugin-react/issue/3066\n[#3065]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3065\n[#3064]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3064\n[#3061]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3061\n\n## [7.25.1] - 2021.08.29\n\n### Fixed\n* [`no-this-in-sfc`], component detection: Improve stateless component detection ([#3056][] @Wesitos)\n\n[7.25.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.25.0...v7.25.1\n[#3056]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3056\n\n## [7.25.0] - 2021.08.27\n\n### Added\n* [`jsx-no-useless-fragments`]: add option to allow single expressions in fragments ([#3006][] @mattdarveniza)\n* add [`prefer-exact-props`] rule ([#1547][] @jomasti)\n* [`jsx-no-target-blank`]: add `forms` option ([#1617][] @jaaberg)\n* [`jsx-pascal-case`]: add `allowLeadingUnderscore` option ([#3039][] @pangaeatech)\n* [`no-children-prop`]: Add `allowFunctions` option ([#1903][] @alexzherdev)\n* [`jsx-runtime`]: set `parserOptions.jsxPragma` for `@typescript-eslint/parser` ([bb64df65][] @ljharb)\n\n### Fixed\n* component detection: use `estraverse` to improve component detection ([#2992][] @Wesitos)\n* [`destructuring-assignment`], [`no-multi-comp`], [`no-unstable-nested-components`], component detection: improve component detection ([#3001][] @vedadeepta)\n* [`no-deprecated`]: fix crash on rest elements ([#3016][] @ljharb)\n* [`destructuring-assignment`]: get the contextName correctly ([#3025][] @ohhoney1)\n* [`no-typos`]: prevent crash on styled components and forwardRefs ([#3036][] @ljharb)\n* [`destructuring-assignment`], component detection: handle default exports edge case ([#3038][] @vedadeepta)\n* [`no-typos`]: fix crash on private methods ([#3043][] @ljharb)\n* [`jsx-no-bind`]: handle local function declarations ([#3048][] @p7g)\n* [`prop-types`], `propTypes`: handle React.* TypeScript types ([#3049][] @vedadeepta)\n* [`prop-types`], `propTypes`: add handling for `FC<Props>`, improve tests ([#3051][] @vedadeepta)\n* [`prop-types`], `propTypes`: prevent crash introduced in [#3051][] ([#3053][] @ljharb)\n\n### Changed\n* [Docs] [`jsx-no-bind`]: updates discussion of refs ([#2998][] @dimitropoulos)\n* [Refactor] `utils/Components`: correct spelling and delete unused code ([#3026][] @ohhoney1)\n* [Docs] [`jsx-uses-react`], [`react-in-jsx-scope`]: document [`react/jsx-runtime`] config ([#3018][] @pkuczynski @ljharb)\n* [Docs] [`require-default-props`]: fix small typo ([#2994][] @evsasse)\n* [Tests] add weekly scheduled smoke tests ([#2963][] @AriPerkkio)\n* [Docs] improve instructions for `jsx-runtime` config ([#3052][] @ljharb)\n\n[7.25.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.24.0...v7.25.0\n[bb64df65]: https://github.com/jsx-eslint/eslint-plugin-react/commit/bb64df6505b3e9a01da5b61626ab9f544caea438\n[#3053]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3053\n[#3052]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3052\n[#3051]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3051\n[#3049]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3049\n[#3048]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3048\n[#3043]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3043\n[#3039]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3039\n[#3038]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3038\n[#3036]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3036\n[#3026]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3026\n[#3025]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3025\n[#3018]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3018\n[#3016]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3016\n[#3006]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3006\n[#3001]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3001\n[#2998]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2998\n[#2994]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2994\n[#2992]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2992\n[#2963]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2963\n[#1903]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1903\n[#1617]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1617\n[#1547]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1547\n\n## [7.24.0] - 2021.05.27\n\n### Added\n* component detection: add componentWrapperFunctions setting ([#2713][] @@jzabala @LandonSchropp)\n* [`no-unused-prop-types`]: add ignore option ([#2972][] @grit96)\n* version detection: support recursive processor virtual filename ([#2965][] @JounQin)\n\n### Fixed\n* [`jsx-handler-names`]: properly substitute value into message ([#2975][] @G-Rath)\n* [`jsx-uses-vars`]: ignore namespaces ([#2985][] @remcohaszing)\n* [`jsx-no-undef`]: ignore namespaces ([#2986][] @remcohaszing)\n* [`jsx-child-element-spacing`]: Don't flag whitespace around `<br/>` tags ([#2989][] @pascalpp)\n\n### Changed\n* [Docs] [`jsx-newline`]: Fix minor spelling error on rule name ([#2974][] @DennisSkoko)\n* [Refactor] [`void-dom-elements-no-children`]: improve performance\n* [readme] fix missing trailing commas ([#2980][] @sugardon)\n* [readme] fix broken anchor link ([#2982][] @vzvu3k6k)\n* [Docs] [`jsx-child-element-spacing`]: fixes sentence which ends abruptly ([#2990][] @pascalpp)\n\n[7.24.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.23.2...v7.24.0\n[#2990]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2990\n[#2989]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2989\n[#2986]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2986\n[#2985]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2985\n[#2982]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2982\n[#2980]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2980\n[#2977]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2977\n[#2975]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2975\n[#2974]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2974\n[#2972]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2972\n[#2965]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2965\n[#2713]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2713\n\n## [7.23.2] - 2021.04.08\n\n### Fixed\n* [`jsx-max-depth`]: Prevent getting stuck in circular references ([#2957][] @AriPerkkio)\n* [`jsx-no-target-blank`]: fix handling of `warnOnSpreadAttributes` being false ([#2953][] @Nokel81)\n* [`forbid-dom-props`]: support `JSXNamespacedName` ([#2961][] @mrtnzlml)\n* [`forbid-component-props`]: support `JSXNamespacedName` (@ljharb)\n\n### Changed\n* Fix CHANGELOG.md ([#2950][] @JounQin)\n\n[7.23.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.23.1...v7.23.2\n[#2961]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2961\n[#2953]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2953\n[#2957]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2957\n[#2950]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2950\n\n## [7.23.1] - 2021.03.23\n\n### Fixed\n* version detection: support processor virtual filename ([#2949][] @JounQin)\n\n[7.23.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.23.0...v7.23.1\n[#2949]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2949\n\n## [7.23.0] - 2021.03.22\n\n### Added\n* [`jsx-no-target-blank`]: add fixer ([#2862][] @Nokel81)\n* [`jsx-pascal-case`]: support minimatch `ignore` option ([#2906][] @bcherny)\n* [`jsx-pascal-case`]: support `allowNamespace` option ([#2917][] @kev-y-huang)\n* [`jsx-newline`]: Add prevent option ([#2935][] @jsphstls)\n* [`no-unstable-nested-components`]: Prevent creating unstable components inside components ([#2750][] @AriPerkkio)\n* added `jsx-runtime` config, for the modern JSX runtime transform (@ljharb)\n\n### Fixed\n* [`jsx-no-constructed-context-values`]: avoid a crash with `as X` TS code ([#2894][] @ljharb)\n* [`jsx-no-constructed-context-values`]: avoid a crash with boolean shorthand ([#2895][] @ljharb)\n* [`static-property-placement`]: do not report non-components ([#2893][] @golopot)\n* [`no-array-index-key`]: support optional chaining ([#2897][] @SyMind)\n* [`no-typos`]: avoid a crash on bindingless `prop-types` import; add warning ([#2899][] @ljharb)\n* [`jsx-curly-brace-presence`]: ignore containers with comments ([#2900][] @golopot)\n* [`destructuring-assignment`]: fix a false positive for local prop named `context` in SFC ([#2929][] @SyMind)\n* [`jsx-no-target-blank`]: Allow rel=\"noreferrer\" when `allowReferrer` is true ([#2925][] @edemaine)\n* [`boolean-prop-naming`]: add check for typescript \"boolean\" type ([#2930][] @vedadeepta)\n* version detection: Add tests that verify versioning works for sibling and child projects ([#2943][] @jcrosetto)\n* [`jsx-curly-newline`]: Update error messages ([#2933][] @jbrower2)\n\n### Changed\n* [Docs] [`jsx-no-constructed-context-values`][]: fix invalid example syntax ([#2910][] @kud)\n* [readme] Replace lists of rules with tables in readme ([#2908][] @motato1)\n* [Docs] added missing curly braces ([#2923][] @Muditxofficial)\n\n[7.23.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.22.0...v7.23.0\n[#2943]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2943\n[#2935]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2935\n[#2933]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2933\n[#2930]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2930\n[#2929]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2929\n[#2925]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2925\n[#2923]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2923\n[#2917]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2917\n[#2910]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2910\n[#2908]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2908\n[#2906]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2906\n[#2900]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2900\n[#2899]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2899\n[#2897]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2897\n[#2895]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2895\n[#2894]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2894\n[#2893]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2893\n[#2862]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2862\n[#2750]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2750\n\n## [7.22.0] - 2020.12.29\n\n### Added\n* [`jsx-key`]: added `checkKeyMustBeforeSpread` option for new jsx transform ([#2835][] @morlay)\n* [`jsx-newline`]: add new rule ([#2693][] @jzabala)\n* [`jsx-no-constructed-context-values`]: add new rule which checks when the value passed to a Context Provider will cause needless rerenders ([#2763][] @dylanOshima)\n* [`jsx-indent-props`]: add `ignoreTernaryOperator` option ([#2846][] @SebastianZimmer)\n* [`jsx-no-target-blank`]: Add `warnOnSpreadAttributes` option ([#2855][] @michael-yx-wu)\n\n### Fixed\n* [`display-name`]/component detection: avoid a crash on anonymous components ([#2840][] @ljharb)\n* [`prop-types`]: function in class that returns a component causes false warning in typescript ([#2843][] @SyMind)\n* [`jsx-no-target-blank`]: avoid a crash with a non-string literal ([#2851][] @ljharb)\n* [`jsx-no-script-url`]: avoid crash with boolean `href` ([#2871][] @ljharb, @AriPerkkio)\n* [`no-typos`]: avoid crash with computed method name ([#2870][] @ljharb, @AriPerkkio)\n* [`jsx-max-depth`]: avoid crash with childless jsx child ([#2869][] @ljharb, @AriPerkkio)\n* [`jsx-wrap-multilines`]: fix crash with `declaration`s that are on a new line after `=` ([#2875][] @ljharb)\n* [`no-unknown-property`]: avoid crash with prop named with Object.prototype key ([#2879][] @ljharb, @AriPerkkio)\n* [`prop-types`]: default argument does not count as props-types declaration ([#2877][] @golopot)\n* [`jsx-props-no-multi-spaces`]: fix a false positive for beside comments ([#2878][] @golopot)\n* [`jsx-no-undef`]: handle the TS parser combined with an invalid ecmaVersion ([#2882][] @ljharb)\n* [`no-unused-prop-types`]: apply `skipShapeProps` to exact types ([#2883][] @golopot)\n* [`no-danger-with-children`]/[`style-prop-object`]/[`no-adjacent-inline-elements`]: add category, URL ([#2891][] @thofmann)\n\n### Docs\n* [`no-unused-prop-types`]: Add new example to rule ([#2852][] @thehereward)\n* [`prop-types`]: fix example ([#2881][] @technote-space)\n\n[7.22.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.5...v7.22.0\n[#2891]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2891\n[#2883]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2883\n[#2882]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2882\n[#2881]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2881\n[#2879]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2879\n[#2878]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2878\n[#2877]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2877\n[#2875]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2875\n[#2871]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2871\n[#2870]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2870\n[#2869]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2869\n[#2855]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2855\n[#2852]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2852\n[#2851]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2851\n[#2846]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2846\n[#2843]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2843\n[#2840]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2840\n[#2835]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2835\n[#2763]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2763\n[#2693]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2693\n\n## [7.21.5] - 2020.10.19\n\n### Fixed\n* [`jsx-indent-props`]: Apply indentation when using brackets ([#2826][] @Moong0122)\n* [`jsx-handler-names`]: Skip inline handlers when checkInlineFunction=false ([#2833][] @onigoetz)\n\n### Changed\n* [Tests] `jsx-indent-props`: Add passing test ([#2823][] @Hypnosphi)\n\n[7.21.5]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.4...v7.21.5\n[#2833]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2833\n[#2826]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2826\n[#2823]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2823\n\n## [7.21.4] - 2020.10.09\n\n### Fixed\n* [`no-unused-prop-types`]: Silence false positive on `never` type in TS ([#2815][] @pcorpet)\n* [`jsx-indent-props`]: Apply indentation when operator is used in front of the upper line ([#2808][], [#2820][] @Moong0122)\n* [Deps] update `jsx-ast-utils` ([#2822][] [jsx-eslint/jsx-ast-utils#102][] @ljharb)\n\n[7.21.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.3...v7.21.4\n[#2822]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2822\n[#2820]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2820\n[#2815]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2815\n[#2808]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2808\n[jsx-eslint/jsx-ast-utils#102]: https://github.com/jsx-eslint/jsx-ast-utils/pull/102\n\n## [7.21.3] - 2020.10.02\n\n### Fixed\n* [`prop-types`]: fix Cannot read property 'type' of undefined error when destructured param ([#2807][] @minwe)\n* [`no-typos`]: avoid crash on spread syntax in createReactClass object ([#2816][] @ljharb @Songyu-Wang)\n\n[7.21.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.2...v7.21.3\n[#2816]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2816\n[#2807]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2807\n\n## [7.21.2] - 2020.09.24\n\n### Fixed\n* [`prop-types`]: handle RestElement in destructured param ([#2805][] @hank121314)\n\n[7.21.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.1...v7.21.2\n[#2805]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2805\n\n## [7.21.1] - 2020.09.23\n\n### Fixed\n* [`jsx-handler-names`]: avoid a crash when an inline prop is not a MemberExpression ([#2803][] @willheslam)\n\n[7.21.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.21.0...v7.21.1\n[#2803]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2803\n\n## [7.21.0] - 2020.09.22\n\n### Added\n* [`button-has-type`]: support trivial ternary expressions ([#2748][] @Hypnosphi)\n* [`jsx-handler-names`]: add `checkInlineFunction` option ([#2761][] @dididy)\n* [`jsx-no-literals`]: add `noAttributeStrings` option ([#2782][] @TaLeaMonet)\n* [`prop-types`]: add support for `PropTypes.exact` ([#2740][] @jzabala)\n* [`jsx-filename-extension`]: Add allow option ([#2746][] @remcohaszing)\n\n### Fixed\n* [`function-component-definition`]: ignore object properties ([#2771][] @stefan-wullems)\n* [`forbid-component-props`]: Implemented support for \"namespaced\" components ([#2767][] @mnn)\n* [`prefer-read-only-props`]: support Flow `$ReadOnly` ([#2772][], [#2779][], [#2770][] @karolina-benitez)\n* [`jsx-handler-names`]: handle whitespace ([#2789][] @AriPerkkio)\n* [`prop-types`]: Detect TypeScript types for destructured default prop values ([#2780][] @sunghyunjo)\n* [`jsx-pascal-case`]: Handle single character namespaced component ([#2791][] @daviferreira)\n* [`jsx-closing-bracket-location`]: In `tag-aligned`, made a distinction between tabs and spaces ([#2796][] @Moong0122)\n* [`jsx-handler-names`]: false positive when handler name begins with number ([#1689][] @jsphstls)\n* [`prop-types`]: Detect JSX returned by sequential expression ([#2801][] @mikol)\n* [`jsx-props-no-multi-spaces`]: \"Expected no line gap between\" false positive ([#2792][] @karolina-benitez)\n* [`no-unknown-property`]: check attributes with any input case ([#2790][] @julienw)\n* [`prop-types`]/[`no-unused-prop-types`]: handle CallExpression in ReturnType ([#2802][] @hank121314)\n* [`jsx-uses-react`]: mark fragment variables as used ([#2775][] @remcohaszing)\n* [`no-unused-prop-types`]: improve component declared props detection ([#2755][] @jzabala)\n* [`jsx-props-no-multi-spaces`]: Show error in multi-line props ([#2756][] @iiison)\n\n### Changed\n* [Tests] [`jsx-one-expression-per-line`]: add passing tests ([#2799][] @TaLeaMonet)\n* [Tests] [`prop-types`]: add test ([#2757][] @jzabala)\n\n[7.21.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.6...v7.21.0\n[#2802]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2802\n[#2801]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2801\n[#2799]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2799\n[#2796]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2796\n[#2792]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2792\n[#2791]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2791\n[#2790]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2790\n[#2789]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2789\n[#2782]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2782\n[#2780]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2780\n[#2779]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2779\n[#2775]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2775\n[#2772]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2772\n[#2771]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2771\n[#2770]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2770\n[#2767]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2767\n[#2761]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2761\n[#2757]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2757\n[#2756]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2756\n[#2748]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2748\n[#2746]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2746\n[#2740]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2740\n[#1689]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1689\n\n## [7.20.6] - 2020.08.12\n\n### Fixed\n* [`jsx-curly-brace-presence`]: fix multiline comment case ([#2716][] @ljharb)\n* [`jsx-no-useless-fragment`]: accept fragments with call expressions ([#2744][] @hasparus)\n* [`jsx-no-literals`] with allowStrings doesn't work in props ([#2736][] @karolina-benitez)\n* [`no-find-dom-node`]: Improve error message ([#2741][] @ecraig12345)\n* [`no-typos`]/[`no-unused-prop-types`]/propType detection: Support typescript props interface extension and TSTypeAliasDeclaration ([#2721][] @hank121314)\n* [`no-this-in-sfc`]/component detection: add arrow function to list of allowed position for component ([#2708][] @jzabala)\n* [`no-access-state-in-setstate`]: add check for class component ([#2711][] @jzabala)\n* [`prop-types`]/component detection: avoid a crash when a local `createElement` identifier exists ([#2733][] @ljharb)\n\n### Changed\n* [`no-unused-prop-types`]: add test assigning this.props to a variable\n\n[7.20.6]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.5...v7.20.6\n[#2744]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2744\n[#2741]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2741\n[#2737]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2737\n[#2736]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2736\n[#2733]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2733\n[#2721]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2721\n[#2716]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2716\n[#2711]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2711\n[#2708]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2708\n\n## [7.20.5] - 2020.07.28\n\n### Fixed\n* [`jsx-curly-brace-presence`]: disable disallowed JSX text chars check in props ([#2710][] @jzabala)\n* [`no-unused-state`]: check for class expression ([#2712][] @jzabala)\n* [`prop-types`]: handle anonymous functions ([#2730][], [#2731][] @odinho @wKich @jzabala)\n\n### Docs\n* [Docs] [`no-access-state-in-setstate`]: fix example ([#2724][] @youngjuning)\n\n[7.20.5]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.4...v7.20.5\n[#2731]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2731\n[#2730]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2730\n[#2724]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2724\n[#2712]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2712\n[#2710]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2710\n\n## [7.20.4] - 2020.07.26\n\n### Fixed\n* improve algorithm to check if a variable is coming from the pragma ([#2706][] @jzabala)\n* [`prop-types`]: handle component returning null ([#2696][] @hank121314)\n* [`prop-types`]/[`function-component-definition`]: Add check for first letter capitalization in functional component detection ([#2699][] @jzabala)\n* [`prop-types`]: use variable value in prop type fields defined by variables ([#2704][] @jzabala)\n* [`no-typos`]: warn on a bindingless `react` import\n\n### Changed\n* [Tests] `boolean-prop-naming`: Added test for function invocation of bool ([#2697][] @ajkovar)\n* [Tests] `jsx-curly-brace-presence`, `jsx-no-comment-textnodes`: add passing tests\n* [Refactor] `no-unused-state`: avoid a loop\n\n[7.20.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.3...v7.20.4\n[#2704]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2704\n[#2699]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2699\n[#2697]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2697\n[#2696]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2696\n\n## [7.20.3] - 2020-06-30\n\n### Fixed\n* [`no-unused-prop-types`]/[`prop-types`]: typescript interface support literal type and only FunctionComponent should have propTypes validation ([#2690][] @hank121314)\n* [`no-unused-prop-types`]/TypeScript: avoid crash on indexable interface ([#2687][] @ljharb)\n\n[7.20.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.2...v7.20.3\n[#2690]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2690\n[#2687]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2687\n\n## [7.20.2] - 2020-06-29\n\n### Fixed\n* [`no-unused-prop-types`]: handle optional chaining ([#2679][] @hank121314)\n* [`jsx-pascal-case`]: fix a false positive with \"H1\" ([#2683][] @ljharb)\n* [`jsx-no-useless-fragment`]: avoid a crash when autofixing a self-closing React.Fragment ([#2680][] @ljharb)\n* [`forbid-prop-types`]: avoid crash ([#2682][] @ljharb)\n\n[7.20.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.1...v7.20.2\n[#2683]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2683\n[#2682]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2682\n[#2680]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2680\n[#2679]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2679\n\n## [7.20.1] - 2020-06-28\n\n### Fixed\n* [`forbid-dom-props`], [`function-component-definition`]: fix schema typos ([#2667][] @mflorence99)\n* [`no-unused-prop-types`]: fix with typescript eslint parser ([#2661][] @eltonio450)\n\n### Changed\n* [`forbid-prop-types`]: warn on destructured values as well ([#2676][] @ajkovar)\n* relax JSX pragma regexp ([#2643][] @gfmio)\n* Cache detected React version ([#2673][] @lencioni)\n* [refactor] [`jsx-pascal-case`]: Remove xregexp ([#2636][] @yacinehmito))\n* [Tests] a [`no-typos`] test fails in eslint v7.3 ([#2678][] @toshi-toma)\n* [Deps] update `jsx-ast-utils`, `object.entries`, `resolve`\n* [Dev Deps] update `@types/eslint`, `@types/estree`, `@types/node`, `@typescript-eslint/parser`, `eslint-config-airbnb-base`, `eslint-plugin-eslint-plugin`, `eslint-plugin-import`, `typescript`\n\n[7.20.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.20.0...v7.20.1\n[#2676]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2676\n[#2673]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2673\n[#2667]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2667\n[#2661]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2661\n[#2643]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2643\n[#2636]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2636\n\n## [7.20.0] - 2020-05-12\n\n### Added\n* support eslint v7 ([#2635][] @ljharb, @toshi-toma)\n* [`forbid-component-props`][]/[`forbid-dom-props`][]: Allow a custom message with forbid props ([#2615][] @mtamhankar1)\n* [`jsx-no-literals`][]: add `ignoreProps` option to ignore props validation ([#2146][] @iiison)\n\n### Fixed\n* [`jsx-sort-props`][]: only use localeCompare when case is ignored ([#2556][] @tanmoyopenroot)\n* [`jsx-key`][]: add a failing test case for optional chaining ([#2610][] @JonathanLee-LX)\n* [`no-unused-state`][]: handle optional chaining ([#2588][] @golopot)\n* [`jsx-pascal-case`][]: Do not consider namespaces when checking for DOM ([#2638][] @yacinehmito)\n* [`jsx-curly-spacing`][], [`jsx-no-bind`][], `usedPropTypes` util: avoid node.start and node.end ([25b1936][] @toshi-toma)\n* [`jsx-no-target-blank`][]: allow `no-referrer` without `noopener` by default ([#2043][] @seancrater)\n* [`button-has-type`][]: improve message when non-static value is used ([aecff62][] @golopot)\n* [`no-adjacent-inline-elements`][]: prevent crash on nullish children ([#2621][] @Rogdham)\n* [`prop-types`][]: avoid crash when spreading any type ([#2606][] @golopot))\n* [`require-render-return`][]: add missing \"a\" ([#2604][] @leothorp)\n* [`jsx-no-comment-textnodes`][]: fix for `@typescript-eslint/parser` ([#2601][] @Axnyff)\n* [`displayName`][]: avoid a crash when using React.memo ([#2587][] @golopot)\n\n### Docs\n* Clean up examples in rule docs ([#2546][] @silvenon)\n* [readme] Add Rules of Hooks to Other useful plugins section ([#2633][] @petetnt)\n* [`no-this-in-sfc`][]: backtick `this` ([#2616][] @mrflip)\n* [`function-component-definition`][]: Fix unnamedComponents option examples ([#2608][] @vkrol))\n\n### Changed\n* [Deps] Move \"semver\" to devDependencies ([#2595][] @rajivshah3)\n* [eslint] remove `operator-linebreak` override ([#2578][] @golopot)\n* [Tests] `button-has-type`: ensure no mistakenly allowed identifiers named `button`/`submit`/`reset` ([#2625][] @golopot)\n* [Tests] `displayName`: add a test case ([#2593][] @golopot)\n* [Dev Deps] update `@types/eslint`, `@types/estree`, `@types/node`, `@typescript-eslint/parser`, `coveralls`, `eslint-config-airbnb-base`, `eslint-plugin-import`, `typescript`\n\n[7.20.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.19.0...v7.20.0\n[#2638]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2638\n[#2635]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2635\n[#2633]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2633\n[#2625]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2625\n[#2621]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2621\n[#2616]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2616\n[#2615]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2615\n[#2610]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2610\n[#2608]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2608\n[#2606]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2606\n[#2604]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2604\n[#2601]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2601\n[#2595]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2595\n[#2593]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2593\n[#2588]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2588\n[#2587]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2587\n[#2578]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2578\n[#2556]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2556\n[#2546]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2546\n[#2146]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2146\n[#2043]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2043\n[25b1936]: https://github.com/jsx-eslint/eslint-plugin-react/commit/25b19365e6cc3f188d6a5ed6cecc70fe6f1af7cd\n[aecff62]: https://github.com/jsx-eslint/eslint-plugin-react/commit/aecff625bf0590ed4d80ed6b58b81af11901f5f6\n\n## [7.19.0] - 2020-03-06\n\n### Added\n * [`style-prop-object`][]: Add `allow` option ([#1819][] @hornta)\n * [`jsx-pascal-case`][]: Support unicode characters ([#2557][] @Svish)\n\n### Fixed\n * [`prefer-stateless-function`][]: avoid crash on ts empty constructor ([#2582][] @golopot)\n * [`no-adjacent-inline-elements`][]: avoid a crash ([#2575] @ljharb)\n * [`no-unused-prop-types`][]: Change the reporting to point to a more accurate node ([#2292][] @jseminck)\n * [`self-closing-comp`][]: consider JSXMemberExpression as component too ([#2572][] @Belco90)\n * [`no-unused-prop-types`][]: make `markPropTypesAsUsed` work with `TSEmptyBodyFunctionExpression` AST node ([#2560][] @guillaumewuip)\n * [`displayName`][] (but really, `propTypes` detection): do not crash on empty flow type spreads ([#2570][] @ljharb)\n\n### Changed\n * [readme] Small visual inconsistency ([#2568] @arvigeus)\n * [docs] add `react/` prefix to rule name, for consistency\n * [`no-unescaped-entities`][]: skip test cases that are now parsing errors in acorn-jsx@5.2.0 ([#2583] @golopot)\n\n[7.19.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.18.3...v7.19.0\n[#2583]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2583\n[#2582]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2582\n[#2575]: https://github.com/jsx-eslint/eslint-plugin-react/issue/2575\n[#2572]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2572\n[#2570]: https://github.com/jsx-eslint/eslint-plugin-react/issue/2570\n[#2568]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2568\n[#2560]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2560\n[#2557]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2557\n[#2292]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2292\n[#1819]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1819\n\n## [7.18.3] - 2020-02-02\n\n### Fixed\n * [`jsx-indent`][]: don't check literals not within JSX ([#2564][] @toshi-toma)\n\n[7.18.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.18.2...v7.18.3\n[#2564]: https://github.com/jsx-eslint/eslint-plugin-react/issue/2564\n\n## [7.18.2] - 2020-02-01\n\n### Fixed\n * [`jsx-indent`][]: avoid a crash on non-string literals ([#2561][] @ljharb)\n\n[7.18.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.18.1...v7.18.2\n[#2561]: https://github.com/jsx-eslint/eslint-plugin-react/issue/2561\n\n## [7.18.1] - 2020-02-01\n\n### Fixed\n * [`jsx-indent`][]: Does not check indents for JSXText ([#2542][] @toshi-toma)\n * [`jsx-props-no-spreading`][]: add support for namespaced jsx components ([#2534][] @jonathanpalma)\n * [`jsx-no-target-blank`][]: allow rel to be an expression ([#2544][] @odinho)\n * [`sort-comp`][]: `|` isn’t a valid regex flag; `u` and `s` are (@ljharb)\n\n### Changed\n * [Docs] use `markdown-magic` to automatically sort all rules alphabetically ([#1742][] @ybiquitous)\n * [Docs] [`jsx-props-no-spreading`][]: fix typo to use correct rule ([#2547][] @jonggyun))\n\n[7.18.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.18.0...v7.18.1\n[#2547]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2547\n[#2544]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2544\n[#2542]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2542\n[#2534]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2534\n[#1742]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1742\n\n## [7.18.0] - 2020-01-15\n\n### Added\n * [`require-default-props`][]: add option to ignore functional components ([#2532][] @RedTn)\n * [`function-component-definition`][]: Enforce a specific function type for function components ([#2414][] @Stefanwullems)\n * [`no-adjacent-inline-elements`][]: Prevent adjacent inline elements not separated by whitespace ([#1155][] @SeanHayes)\n * [`jsx-no-script-url`][]: prevent usage of `javascript:` URLs ([#2419][] @sergei-startsev)\n\n### Fixed\n * [`jsx-pascal-case`][]: false negative with namespacing ([#1337][] @mfyuce)\n * [`jsx-curly-brace-presence`][]: Fix `curly-brace-presence` edge cases ([#2523][] @rafbgarcia)\n * [`prop-types`][]: Does not validate missing propTypes for LogicalExpression ([#2533][] @toshi-toma)\n * [`no-unknown-property`][]: allowTransparency does not exist in React >= v16.1 ([#1538][] @dawidvdh)\n * [`jsx-curly-brace-presence`][]: Fix error related to tags line break ([#2521][] @rafbgarcia)\n * [`no-typos`][]: Compilation error when method name is string instead of identifier ([#2514][] @shijistar)\n * [`jsx-curly-brace-presence`][]: allow trailing spaces in TemplateLiteral ([#2507][] @doochik)\n * [`no-unused-prop-types`], [`no-unused-state`]: fix false positives when using TS type assertions ([#2536][] @kdmadej)\n\n### Changed\n * [Docs] [`no-render-return-value`][]: Fix title ([#2540][] @micnic)\n * [Refactor]: remove unused codes in util/propTypes ([#2288][] @golopot)\n * [`no-typos`]: check static lifecycle methods ([#2006][] @bsonntag)\n * [Docs] [`jsx-first-prop-new-line`][]: Fix rule name in \"Rule Options\" section ([#2535][] @barreira)\n * [Tests] [`no-unused-prop-types`][]: Added test cases ([#977][] @dozoisch)\n * [Tests] avoid running tests on pretest job\n * [meta] Move eslint-plugin-eslint-plugin to devDeps ([#2510][] @nstepien)\n * [Deps] update `array-includes`, `object.entries`, `object.fromentries`, `object.values`, `resolve`\n\n[7.18.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.17.0...v7.18.0\n[#2540]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2540\n[#2536]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2536\n[#2535]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2535\n[#2533]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2533\n[#2532]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2532\n[#2523]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2523\n[#2521]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2521\n[#2514]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2514\n[#2510]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2510\n[#2507]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2507\n[#2419]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2419\n[#2414]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2414\n[#2288]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2288\n[#2006]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2006\n[#1538]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1538\n[#1337]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1337\n[#1155]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1155\n[#977]: https://github.com/jsx-eslint/eslint-plugin-react/pull/977\n\n## [7.17.0] - 2019-11-28\n\n### Added\n * [`jsx-no-target-blank`][]: add `allowReferrer` option ([#2478][] @eps1lon)\n * [`jsx-handler-names`][]: add `checkLocalVariables` option ([#2470][] @aub)\n * [`prop-types`][]: Support Flow Type spread ([#2446][] @moroine)\n * [`jsx-props-no-spreading`][]: add `explicitSpread` option to allow explicit spread of props ([#2449][] @pawelnvk)\n * [`jsx-no-target-blank`][]: warn on `target={'_blank'}` expressions ([#2451][] @timkraut)\n * [`function-component-definition`]: Enforce a specific function type for function components ([#2414][] @Stefanwullems)\n\n### Fixed\n * [`sort-prop-types`][], [`jsx-sort-default-props`][]: disable broken autofix ([#2505][] @webOS101)\n * [`no-typos`][]: improve report location ([#2468][] @golopot)\n * [`jsx-no-literals`][]: trim whitespace for `allowedStrings` check ([#2436][] @cainlevy)\n * [`jsx-curly-brace-presence`][]: Fix filter of undefined error with whitespace inside jsx attr curlies ([#2460][] @dustinyoste)\n * [`no-render-return-value`][]: should warn when used in assignment expression ([#2462][] @jichu4n)\n * [`jsx-curly-brace-presence`][]: allow trailing spaces in literal ([#2448][] @doochik)\n\n### Changed\n * [Deps] update `jsx-ast-utils`, `object.fromentries`, `resolve`\n * [eslint] fix func-names and change object-shorthand to 'always' ([#2483][] @golopot)\n * [Docs] `jsx-first-prop-new-line`: Fix documentation formatting ([#2489][] @pjg)\n * [Docs] [`prop-types`][]: Update 'skipUndeclared' in rule options ([#2504][] @cjnickel)\n * [Docs] [`jsx-first-prop-new-line`][]: fix wrong rule name ([#2500][] @zgayjjf)\n * [eslint] enable eslint-plugin-eslint-plugin ([#2469][] @golopot)\n * [Docs] [`jsx-props-no-multi-spaces`][]: suggest using core rule instead ([#2463][] @golopot)\n * [Docs] [`jsx-first-prop-new-line`][]: add rule options ([#2465][] @SerdarMustafa1)\n * [Docs] [`jsx-no-target-blank`][]: Add section about overriding for trusted links ([#2438][] @aschriner)\n * [Docs] fix typo ([#2453][] @cainwatson)\n * [Docs] [`no-unused-prop-types`][]: clean up prose ([#2273][] @coryhouse)\n * [Docs] [`jsx-no-bind`][]: add section about React Hooks ([#2443][] @kdex)\n\n[7.17.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.16.0...v7.17.0\n[#2532]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2532\n[#2505]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2505\n[#2504]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2504\n[#2500]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2500\n[#2489]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2489\n[#2483]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2483\n[#2478]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2478\n[#2470]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2470\n[#2469]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2469\n[#2468]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2468\n[#2465]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2465\n[#2463]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2463\n[#2460]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2460\n[#2453]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2453\n[#2451]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2451\n[#2449]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2449\n[#2448]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2448\n[#2446]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2446\n[#2443]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2443\n[#2438]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2438\n[#2436]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2436\n[#2414]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2414\n[#2273]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2273\n\n## [7.16.0] - 2019-10-04\n\n### Added\n* [`jsx-sort-default-props`][]: make rule fixable ([#2429][] @emroussel)\n\n### Fixed\n* [`jsx-no-useless-fragment`][]: use `array-includes` over `.includes` for back compat (@ljharb)\n* [`jsx-curly-brace-presence`][]: allow necessary white-space literal ([#2437][] @uniqname)\n* [`jsx-curly-brace-presence`][]: warns incorrectly on trailing whitespace ([#2431][] @BC-M)\n* [`no-unused-prop-types`][]: false positive when nested destructuring ([#2428][] @golopot)\n\n[7.16.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.15.1...v7.16.0\n[#2437]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2437\n[#2431]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2431\n[#2429]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2429\n[#2428]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2428\n\n## [7.15.1] - 2019-10-01\n\n### Fixed\n* [`jsx-curly-brace-presence`][]: bail out checks when JSXElements are passed as props ([#2426][] @vedadeepta)\n\n### Changed\n* [Docs] [`prefer-es6-class`][]: Fix typos ([#2425][] @spencerbyw)\n\n[7.15.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.15.0...v7.15.1\n[#2426]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2426\n[#2425]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2425\n\n## [7.15.0] - 2019-09-30\n\n### Added\n* add [`jsx-no-useless-fragment`][] rule ([#2261][] @golopot)\n* [`jsx-handler-name`][]: allow `false` to disable `eventHandlerPrefix`/`eventHandlerPropPrefix` ([#2410][] @tanmoyopenroot)\n* [`sort-comp`][]: add `static-variables` grouping ([#2408][] @vedadeepta)\n* [`jsx-no-literals`][]: Add `allowedStrings` option ([#2380][] @benhollander)\n* [`no-multi-comp`][]: Added handling for `forwardRef` and `memo` wrapping components declared in the same file ([#2184][] @jenil94)\n* [`jsx-pascal-case`][]: `allowAllCaps` option now allows `SCREAMING_SNAKE_CASE` ([#2364][] @TylerR909)\n\n### Fixed\n* [`jsx-indent`][]: Fix false positive when a jsx element is the last statement within a do expression (with tests) ([#2200][] @Kenneth-KT)\n* [`jsx-curly-brace-presence`][]: fix jsx tags in braces ([#2422][] @tanmoyopenroot)\n* [`display-name`][]: Fix false positives ([#2399][] @BPScott)\n* [`jsx-curly-brace-presence`][]: report unnecessary curly braces with children on next line ([#2409][] @vedadeepta)\n* [`no-unused-prop-types`][]: false positive with callback ([#2375][] @golopot)\n* Fix prop-types detection collision on renamed props ([#2383][] @yannickcr)\n* [`jsx-sort-props`][]: use localeCompare rather than comparison operator ([#2391][] @tanmoyopenroot)\n* [`jsx-pascal-case`][]: allow one-letter-named components ([#2395][] @Haegin)\n* [`jsx-wrap-multilines`][]: fix incorrect formatting ([#2392][] @tanmoyopenroot)\n* [`require-optimization`][]: fix when using arrow function in class components ([#2385][] @jenil94)\n* [`no-deprecated`][]: Deprecate cWM/cWRP/cWU lifecycle methods since React 16.9.0 ([#2378][] @meowtec)\n* [`jsx-key`][]: improve docs and confusing error message ([#2367][] @kaykayehnn)\n* Recognize props wrapped in flow $ReadOnly<> utility type ([#2361][] @lukeapage)\n* [`prop-types`][]: false positive with setState updator ([#2359][] @golopot)\n\n### Changed\n* [Docs] [`no-access-state-in-setstate`][]: update grammar ([#2418][] @neaumusic)\n* [`jsx-curly-brace-presence`][], [`jsx-one-expression-per-line`][], [`no-danger-with-children`][]: add `isWhiteSpaces` to `lib/util/jsx` ([#2409][] @vedadeepta)\n\n[7.15.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.14.3...v7.15.0\n[#2422]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2422\n[#2410]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2410\n[#2409]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2409\n[#2408]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2408\n[#2402]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2402\n[#2399]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2399\n[#2395]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2395\n[#2392]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2392\n[#2391]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2391\n[#2385]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2385\n[#2383]: https://github.com/jsx-eslint/eslint-plugin-react/issue/2383\n[#2380]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2380\n[#2378]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2378\n[#2375]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2375\n[#2367]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2367\n[#2364]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2364\n[#2361]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2361\n[#2359]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2359\n[#2261]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2261\n[#2200]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2200\n[#2184]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2184\n\n## [7.14.3] - 2019-07-23\n\n### Fixed\n* Fix [`prop-types`][] to ignore validation when Flow indexers are used ([#2330][] @yannickcr)\n* Fix error being thrown after the first warning when react version cannot be detected ([#2336][] @abhishekdev)\n* Fix component detection when `memo` and `forwardRef` are used together ([#2349][] @yannickcr)\n\n### Changed\n* Documentation improvements (@ljharb, [#2354][] @golopot)\n\n[7.14.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.14.2...v7.14.3\n[#2330]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2330\n[#2336]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2336\n[#2349]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2349\n[#2354]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2354\n\n## [7.14.2] - 2019-06-24\n\n### Fixed\n* Fix [`prop-types`][] crash on for...of destructuring ([#2326][] @yannickcr)\n\n[7.14.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.14.1...v7.14.2\n[#2326]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2326\n\n## [7.14.1] - 2019-06-24\n\n### Fixed\n* Fix [`prop-types`][] crash on multiple destructuring ([#2319][] @golopot)\n\n[7.14.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.14.0...v7.14.1\n[#2319]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2319\n\n## [7.14.0] - 2019-06-23\n\n### Added\n* Add [`jsx-curly-newline`][] rule ([#1493][] @golopot)\n* Add support for nested destructuring to [`prop-types`][] ([#296][] [#1422][] @golopot)\n* Add support for variables defined as props to [`prop-types`][] and [`no-unused-prop-types`][] ([#442][] [#833][] [#1002][] [#1116][] [#1257][] [#1764][] @golopot)\n* Add `checkFragmentShorthand` option to [`jsx-key`][] ([#2316][] @kaykayehnn)\n\n### Fixed\n* Fix [`no-did-mount-set-state`][] and [`no-did-update-set-state`][] to handle cDU and cDM defined as class properties ([#1595][] @jaaberg)\n* Fix [`sort-prop-types`][] cash when a shape PropType is defined in a variable ([#1749][] @alexzherdev)\n* Fix [`no-unused-state`][] false positive when using state of non-lifecycle method ([#2274][] @golopot)\n* Fix [`static-property-placement`][] false positive when accessing static property inside method ([#2283][] @dmason30)\n* Fix [`prop-type`][] detection for annotated props with default value ([#2298][] @yannickcr)\n\n### Changed\n* Add ESLint 6.0.0 as valid peerDependency (@yannickcr)\n* Improve [`no-render-return-value`][] performance ([#2259][] @golopot)\n* Change [`jsx-sort-props`][] to report errors only on the identifier ([#2312][] @MrHen)\n* Change to warn only once if react version cannot be detected ([#2276][] @ljharb)\n* Documentation improvements ([#2263][] @dimitropoulos, [#2262][] @ybiquitous, [#2295][] @battaglr, [#2302][] @Jason-Cooke, [#2303][] @golopot)\n* Code refactoring ([#2265][] [#2267][] [#2286][] [#2294][] @golopot, @ljharb)\n* Tests improvements ([#2304][] [#1047][] @golopot, @yannickcr)\n\n[7.14.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.13.0...v7.14.0\n[#296]: https://github.com/jsx-eslint/eslint-plugin-react/issues/296\n[#442]: https://github.com/jsx-eslint/eslint-plugin-react/issues/442\n[#833]: https://github.com/jsx-eslint/eslint-plugin-react/issues/833\n[#1002]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1002\n[#1047]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1047\n[#1116]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1116\n[#1257]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1257\n[#1422]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1422\n[#1493]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1493\n[#1595]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1595\n[#1749]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1749\n[#1764]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1764\n[#2259]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2259\n[#2262]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2262\n[#2263]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2263\n[#2265]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2265\n[#2267]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2267\n[#2274]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2274\n[#2276]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2276\n[#2283]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2283\n[#2286]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2286\n[#2294]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2294\n[#2295]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2295\n[#2298]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2298\n[#2302]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2302\n[#2303]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2303\n[#2304]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2304\n[#2312]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2312\n[#2316]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2316\n\n## [7.13.0] - 2019-05-03\n\n### Added\n* Make [`jsx-sort-props`][] fully fixable ([#2250][], @guliashvili)\n* [`boolean-prop-naming`][]: add `validateNested` option to validate shape prop names ([#2234][], @pawelnvk)\n* add [`static-property-placement`][] rule ([#2193][], @dmason30)\n* add \"detect\" for flow version ([#2233][], @jedwards1211)\n* [`jsx-indent`][]: Add `indentLogicalExpressions` option ([#2227][], @mdnsk)\n* add [`jsx-props-no-spreading`][] ([#2191][], @ashbhir)\n* [`no-string-refs`][]: Added `noTemplateLiteral` option ([#2167][], @jenil94)\n* add `linkComponents` setting ([#2116][], @gbakernet)\n* [`jsx-no-target-blank`][]: add support for `linkComponents` setting ([#2116][], @gbakernet)\n* Add [`state-in-constructor`][] rule ([#1945][], @lukyth)\n* Add [`prefer-read-only-props`][] rule ([#2110][], @golopot)\n* [`no-unescaped-entities`][]: more friendly error message; add config to adjust ([#2016][], @stevemao)\n\n### Fixed\n* [`jsx-props-no-multi-spaces`][]: support generic components (ts) ([#2256][], @mateuszsokola)\n* [`prop-types`][]: fix case with destructuring and default param ([#2246][], @golopot)\n* [`prefer-stateless-function`][]: Ignoring pure components without props and context usage ([#2238][], @pawelnvk)\n* `propTypes`: resolveSuperParameterPropsType: add null check ([#2232][], @jedwards1211)\n* [`self-closing-comp`][]: stop reporting single-line spaces ([#2210][], @golopot)\n* [`require-render-return`][]: more accurate report location ([#2229][], @golopot)\n* [`sort-prop-types`][]: Fix sorting props with numeric keys ([#2230][], @pawelnvk)\n* [`display-name`][]: fix false negative around nested functions ([#2225][], @dwelle)\n* [`no-unknown-property`][]: fix case like `<Foo.bar>` ([#2207][], @golopot)\n* [`jsx-curly-brace-presence`][]: accept multiline template string ([#2203][], @golopot)\n* [`jsx-one-expression-per-line`][]: fix when using tabs ([#2198][], @Ohar)\n* [`prop-types`][]: Fix false positive on computed member expression ([#2202][], @golopot)\n* [`jsx-sort-default-props`][]: fix case with spread ([#2182][], @VincentLanglet)\n* [`no-this-in-sfc`][]: Fix false positive on SFC defined as object property ([#2147][], @yannickcr)\n* [`sort-comp`][]: correctly recognize instance variables declared without explicit value ([#2183][], @yannickcr)\n* [`no-unused-state`][]: fix set state callback destructing & state use inside callback ([#2151][], @barakyosi)\n* [`no-multi-comp`][]: correctly ignore wrapped stateless components: ([#2145][], @yannickcr)\n* [`display-name`][]: avoid crash on for..of ([#2137][], @ljharb)\n\n### Changed\n* [Docs] [`no-access-state-in-setstate`][]: Use syntax highlighting for examples ([#2160][], @pReya)\n* [Docs] [`jsx-fragments`][]: add \"fixable\" note ([#2143][], @joshunger)\n* [Docs] Added shared settings info, React version default note ([#2180][], @samsch)\n* [Tests] [`jsx-curly-spacing`][]: add regression test case ([#2206][], @ColCh)\n\n[7.13.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.12.4...v7.13.0\n[#2256]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2256\n[#2250]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2250\n[#2246]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2246\n[#2238]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2238\n[#2234]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2234\n[#2233]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2233\n[#2232]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2232\n[#2230]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2230\n[#2229]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2229\n[#2227]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2227\n[#2225]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2225\n[#2210]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2210\n[#2207]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2207\n[#2206]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2206\n[#2203]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2203\n[#2202]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2202\n[#2198]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2198\n[#2193]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2193\n[#2191]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2191\n[#2183]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2183\n[#2182]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2182\n[#2180]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2180\n[#2167]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2167\n[#2147]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2147\n[#2145]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2145\n[#2143]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2143\n[#2137]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2137\n[#2116]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2116\n[#2110]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2110\n[#2016]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2016\n[#1945]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1945\n\n## [7.12.4] - 2019-01-16\n\n### Fixed\n* [`no-unused-prop-types`][]: avoid a crash ([#2131][], @ljharb)\n* [`prop-types`][]: avoid further crashes from nonexistent nodes in unusedPropTypes ([#2127][], @ljharb)\n* [`prop-types`][]: Read name of callee object ([#2125][], @CrOrc)\n* [`prop-types`][]: Ignore reassignments when matching props declarations with components ([#2051][], [#1957][], @yannickcr)\n* [`prop-types`][], [`no-unused-prop-types`][], [`require-default-props`][]: Detect components with return statement in switch/case ([#2118][], @yannickcr)\n\n### Changed\n* [`prop-types`][], [`no-typos`][]: add passing test cases ([#2123][], [#2128][], [#2136][], [#2134][], @ljharb)\n\n[7.12.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.12.3...v7.12.4\n[#2136]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2136\n[#2134]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2134\n[#2131]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2131\n[#2128]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2128\n[#2127]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2127\n[#2125]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2125\n[#2123]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2123\n[#2118]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2118\n[#2051]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2051\n[#1957]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1957\n\n## [7.12.3] - 2019-01-04\n\n### Fixed\n* [`jsx-indent`][]: Prevent crash on valueless props ([#2120][], @jomasti)\n* [`jsx-fragments`][]: avoid crashing on self-closing fragments ([#2113][], @alexzherdev)\n* [`no-unused-prop-types`][]: Fix propType detection inside class bodies ([#2115][], @drx)\n* [`no-unused-prop-types`][]: fix issue with propTypes misclassifying props ([#2111][], @drx)\n* [`display-name`][]: fix false positive for `React.memo` ([#2109][], @jomasti)\n\n### Changed\n* [Docs] add a missing comma in the JSON settings ([#2117][], @haideralsh)\n* [Docs] update README to document React version detection ([#2114][], @mohsinulhaq)\n\n[7.12.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.12.2...v7.12.3\n[#2120]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2120\n[#2117]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2117\n[#2115]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2115\n[#2114]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2114\n[#2113]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2113\n[#2111]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2111\n[#2109]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2109\n\n## [7.12.2] - 2019-01-02\n\n### Fixed\n* [`prop-types`][]: avoid crash on used prevProps ([#2095][], @ljharb)\n* Version warning: Link does not end with '.' ([#2103][], @yoyo837))\n* [`forbid-prop-types`][]: fix crash with propWrapper check on MemberExpressions ([#2104][], @ljharb)\n\n[7.12.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.12.1...v7.12.2\n[#2104]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2104\n[#2103]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2103\n[#2095]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2095\n\n## [7.12.1] - 2019-01-01\n\n### Fixed\n* [`no-unused-state`][]: Fix crash with class fields ([#2098][], @jomasti)\n* [`prop-types`][]: Fix false positives inside lifecycle methods ([#2099][], @jomasti)\n* [`jsx-max-depth`][]: avoid a crash ([#2102][], @ljharb)\n* [`jsx-wrap-multilines`][]: avoid crash when no trailing newline ([#2100][], @ljharb)\n\n### Changed\n* Fix CHANGELOG.md ([#2097][], @alexzherdev)\n\n[7.12.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.12.0...v7.12.1\n[#2102]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2102\n[#2100]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2100\n[#2099]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2099\n[#2098]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2098\n[#2097]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2097\n\n## [7.12.0] - 2018-12-27\n\n### Added\n* [`no-typos`]: Support createClass ([#1828][], @alexzherdev)\n* Support detecting React.forwardRef/React.memo ([#2089][], @jomasti)\n* [`jsx-indent`][]: add `checkAttributes` option for JSX attribute indentation ([#2086][], @jomasti)\n* Change allowed `propWrapperFunctions` setting values ([#2065][], @jomasti)\n* add [`jsx-fragments`][] rule to enforce fragment syntax ([#1994][], @alexzherdev)\n* Support \"detect\" option for React version setting ([#1978][], @alexzherdev)\n* Support shorthand fragment syntax in many rules ([#1956][], @alexzherdev)\n* [`jsx-no-literals`][]: print node value in warning message ([#2008][], @jlgonzalezdev)\n\n### Fixed\n* [`jsx-max-depth`][]: Fix depth of JSX siblings in a JSXEpressionContainer ([#1824][], @alexzherdev)\n* [`no-array-index-key`][]: fix in React.Children methods ([#2085][], @himynameisdave)\n* [`no-unused-state`][]: handle functional setState ([#2084][], @jomasti)\n* version errors should log to stderr, not stdout ([#2082][], @ljharb)\n* [`no-deprecated`][]: Disable legacy lifecycle methods linting for now ([#2069][], @sergei-startsev)\n* ensure that react and flow versions can be numbers ([#2056][], @ljharb)\n* [`forbid-foreign-prop-types`][]: ensure `allowInPropTypes` option applies to class fields ([#2040][], @Sheile)\n* [`jsx-wrap-multilines`][]: catch single missing newlines ([#1984][], @MrHen)\n* [`jsx-first-prop-new-line`][]: Fix for parsers (like TypeScript) ([#2026][], @HauptmannEck)\n* [`sort-comp`][]: Fix fixer in case of more than 10 props ([#2012][], @tihonove)\n* [`no-unused-state`][] Don't depend on state parameter name ([#1829][], @alexzherdev)\n* [`no-this-in-sfc`][] fix for class properties ([#1995][], @sergei-startsev)\n* [`no-this-in-sfc`][] fix rule behavior for arrow functions inside a class field ([#1989][], @sergei-startsev)\n* [`destructuring-assignment`][]: handle nested props usage ([#1983][], @alexzherdev)\n* [`sort-prop-types`][]: fix string property order ([#1977][], @metreniuk)\n* [`jsx-no-target-blank`][]: don’t crash when there’s no value ([#1949][], @ljharb)\n* [`prop-types`][], [`no-unused-prop-types`][]: better handle object spread ([#1939][], @alexzherdev)\n\n### Changed\n* [`jsx-fragments`][]: improve message text ([#2032][], @alexzherdev)\n* [`no-unsafe`][]: handle all unsafe life-cycle methods ([#2075][], @sergei-startsev)\n* [`require-default-props`][]: Change error message naming from singular defaultProp to plural defaultProps ([#2064][], @jseminck)\n* [Refactor] Extract used `propTypes` detection ([#1946][], @alexzherdev)\n* [Refactor] Extract `defaultProps` detection ([#1942][], @alexzherdev)\n* [Refactor] Extract required `propTypes` detection ([#2001][], @alexzherdev)\n* [Docs] [`no-did-mount-set-state`][], [`no-did-update-set-state`][], [`no-will-update-set-state`][]: fix docs URLs ([#2090][], @JBallin)\n* [Docs] Remove statement on GC in jsx-no-bind ([#2067][], @rickhanlonii)\n* [Docs] [`jsx-sort-props`][]: Fix small mistake ([#2044][], @dimitarnestorov)\n* [Docs] [`no-unescaped-entities`][]: add more escape examples ([#2015][], @stevemao)\n* [Docs] [`display-name`][]: mention default `ignoreTranspilerName` value ([#2002][], @OliverJAsh)\n* [Docs] [`jsx-no-target-blank`][]: Add full example ([#1988][], @atomcorp)\n* [Docs] Update [`jsx-no-target-blank`][].md ([#1953][], @brunocoelho)\n* [Changelog] fix \"Ignore class properties\" contributor ([#1941][], @alexzherdev)\n* [Tests] Remove redundant `require('babel-eslint')` from tests ([#2004][], @sergei-startsev)\n* [Tests] [`prop-types`][]: Add tests for prop-types destructuring ([#2029][], @sstern6)\n* [Tests] [`display-name`][]: add false positive component detection for destructured createElement ([#1098][], @arian)\n\n[7.12.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.11.1...v7.12.0\n[#2090]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2090\n[#2089]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2089\n[#2086]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2086\n[#2085]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2085\n[#2084]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2084\n[#2082]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2082\n[#2075]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2075\n[#2069]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2069\n[#2067]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2067\n[#2065]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2065\n[#2064]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2064\n[#2056]: https://github.com/jsx-eslint/eslint-plugin-react/issues/2056\n[#2044]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2044\n[#2040]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2040\n[#2032]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2032\n[#2029]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2029\n[#2026]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2026\n[#2015]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2015\n[#2012]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2012\n[#2008]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2008\n[#2004]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2004\n[#2002]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2002\n[#2001]: https://github.com/jsx-eslint/eslint-plugin-react/pull/2001\n[#1995]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1995\n[#1994]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1994\n[#1989]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1989\n[#1988]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1988\n[#1984]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1984\n[#1983]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1983\n[#1978]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1978\n[#1977]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1977\n[#1956]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1956\n[#1953]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1953\n[#1949]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1949\n[#1946]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1946\n[#1942]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1942\n[#1941]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1941\n[#1939]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1939\n[#1829]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1829\n[#1828]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1828\n[#1824]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1824\n[#1098]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1098\n\n## [7.11.1] - 2018-08-14\n### Fixed\n* stop crashing when assigning to propTypes ([#1932][], @alexzherdev)\n\n### Changed\n* Fix changelog links ([#1926][], @ferhatelmas)\n* Fix changelog links ([#1929][], @alexzherdev)\n\n[7.11.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.11.0...v7.11.1\n[#1932]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1932\n[#1929]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1929\n[#1926]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1926\n\n## [7.11.0] - 2018-08-13\n### Added\n* [`jsx-one-expression-per-line`][]: add \"allow\" option ([#1924][], @alexzherdev)\n* [`sort-prop-types`][]: add autofix ([#1891][], @finnp)\n* [`jsx-no-bind`][]: Add ignoreDOMComponents option ([#1868][], @alexzherdev)\n* Output a warning if React version is missing in settings ([#1857][], @alexzherdev)\n\n### Fixed\n* [`destructuring-assignment`][]: Ignore class properties ([#1909][], @alexandernanberg)\n* [`destructuring-assignment`][], component detection: ignore components with confidence = 0 ([#1907][], @alexzherdev)\n* [`boolean-prop-naming`][]: Handle inline Flow type ([#1905][], @alexzherdev)\n* [`jsx-props-no-multi-spaces`][]: Handle member expressions ([#1890][], @alexzherdev)\n* [`sort-comp`][]: Allow methods to belong to any matching group ([#1858][], @nosilleg)\n* [`jsx-sort-props`][]: Fix `reservedFirst` ([#1883][], @fleischie)\n* [`prop-types`][]: (flow) Stop crashing on undefined or null properties ([#1860][], @nicholas-l)\n* [`no-unknown-property`][]: Make attribute \"charset\" valid ([#1863][], @silvenon)\n* [`no-deprecated`][]: report identifier AST node instead of the class node ([#1854][], @jsnajdr)\n* [`button-has-type`][]: Account for pragma ([#1851][], @alexzherdev)\n* [`button-has-type`][]: improve error message when an identifier is used as the value ([#1874][], @ljharb)\n* support JSXText nodes alongside Literal nodes (@ljharb)\n\n### Changed\n* Extract propTypes detection code ([#1911][], @alexzherdev)\n* Fix broken links in changelog ([#1849][], @alexzherdev)\n* [`no-unused-state`][]: combine spread visitors (@ljharb)\n* [`jsx-one-expression-per-line`][]: Fix JSX Syntax in docs ([#1867][], @peter-mouland)\n* [`jsx-max-depth`][], [`jsx-sort-default-props`][]: add missing docs urls ([#1880][], @flyerhzm)\n* [`jsx-indent`][]: add test cases ([#1892][], @alexzherdev)\n* [`prop-types`][]: add test cases ([#1898][], @alexzherdev)\n* Add a helper function for determining function-like expressions ([#1914][], @alexzherdev)\n* [`jsx-props-no-multi-spaces`][]: update docs ([#1918][], @BenRichter)\n\n[7.11.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.10.0...v7.11.0\n[#1924]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1924\n[#1918]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1918\n[#1914]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1914\n[#1911]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1911\n[#1909]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1909\n[#1907]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1907\n[#1905]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1905\n[#1898]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1898\n[#1892]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1892\n[#1891]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1891\n[#1890]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1890\n[#1883]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1883\n[#1880]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1880\n[#1874]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1874\n[#1868]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1868\n[#1867]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1867\n[#1863]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1863\n[#1860]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1860\n[#1858]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1858\n[#1857]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1857\n[#1854]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1854\n[#1851]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1851\n[#1849]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1849\n\n## [7.10.0] - 2018-06-24\n### Added\n* Allow eslint ^5 ([#1843][] @papandreou, @ljharb)\n* [`no-unsafe`][] rule ([#1831][], [#1830][] @sergei-startsev)\n* [`no-will-update-set-state`][]: Account for `UNSAFE_` methods ([#1845][], [#1844][] @alexzherdev)\n\n### Fixed\n* [`no-typos`][]: Fix static propTypes handling ([#1827][], [#1677][] @alexzherdev)\n* [`destructuring-assignment`][]: Allow LHS ([#1825][], [#1728][] @alexzherdev)\n* [`no-unused-prop-types`][]: Fix crash when encountering mixed union and intersection flow types ([#1806][] @yannickcr)\n\n### Changed\n* Typo fixes in [`jsx-no-target-blank`][] ([#1805][] @ferhatelmas))\n\n[7.10.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.9.1...v7.10.0\n[#1845]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1845\n[#1844]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1844\n[#1843]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1843\n[#1831]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1831\n[#1830]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1830\n[#1827]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1827\n[#1825]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1825\n[#1806]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1806\n[#1805]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1805\n[#1728]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1728\n[#1677]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1677\n\n## [7.9.1] - 2018-06-03\n* Nothing was fixed; this is a republish with some updated deps. ([#1804][] @ljharb)\n\n[7.9.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.9.0...v7.9.1\n[#1804]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1804\n\n## [7.9.0] - 2018-06-03\n### Added\n* Add [`jsx-props-no-multi-spaces`][] rule ([#1755][] @ThiefMaster)\n* Add `first` option to [`jsx-indent-props`][] ([#398][] @ThiefMaster)\n* Add `enforceDynamicLinks` option to [`jsx-no-target-blank`][] ([#1737][] @kenearley)\n\n### Fixed\n* Fix static lifecycle methods validation in [`sort-comp`][] ([#1793][] @lynxtaa)\n* Fix crash in [`no-typos`][] when encountering anonymous react imports ([#1796][] @jsg2021)\n* Fix ESLint 3 support ([#1779][])\n\n### Changed\n* Documentation improvements ([#1794][] @lencioni)\n* Update Travis CI configuration to test on multiple ESLint verions\n\n[7.9.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.8.2...v7.9.0\n[#1755]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1755\n[#398]: https://github.com/jsx-eslint/eslint-plugin-react/issues/398\n[#1737]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1737\n[#1793]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1793\n[#1796]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1796\n[#1779]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1779\n[#1794]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1794\n\n## [7.8.2] - 2018-05-13\n### Fixed\n* Fix crash in [`boolean-prop-naming`][] when encountering a required shape prop type ([#1791][] @pcorpet)\n\n[7.8.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.8.1...v7.8.2\n[#1791]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1791\n\n## [7.8.1] - 2018-05-12\n### Fixed\n* Fix crash in [`no-deprecated`][] when encountering a class constructor ([#1785][] @taddei)\n\n[7.8.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.8.0...v7.8.1\n[#1785]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1785\n\n## [7.8.0] - 2018-05-11\n### Added\n* Add support for fragments to [`react-in-jsx-scope`][] ([#1758][])\n* Add support for Flow generic PropType to [`require-default-props`][] ([#1724][] @Miziak)\n* Add component whitelist option to [`forbid-component-props`][] ([#1732][] @ThiefMaster)\n* Add support for React 16.3 lifecycle methods to [`no-unused-prop-types`][] ([#1681][] @bvaughn)\n* Add support for React 16.3 lifecycle methods to [`sort-comp`][] ([#1767][] @joe-denea)\n* Add support for React 16.3 lifecycle methods to [`no-typos`][]\n* Add support for `prevState` and `nextState` to [`no-unused-state`][] ([#1759][])\n* Add warnings for `componentWillMount`, `componentWillReceiveProps` and `componentWillUpdate` lifecycle methods in [`no-deprecated`][] ([#1750][] @sergei-startsev)\n\n### Fixed\n* Fix [`no-typos`][] false positive on custom `PropType` classes ([#1389][] @brettdh)\n* Fix [`boolean-prop-naming`][] to handle required props ([#1389][] @louisscruz)\n* Fix [`jsx-curly-brace-presence`][] to allow whitespace JSX container ([#1717][] @sharmilajesupaul)\n* Fix [`jsx-no-bind`][] to handle ternary conditions ([#1722][] @gwenaellarmet)\n\n### Changed\n* Documentation improvements ([#1699][] @ronanmathew, [#1743][] @ybiquitous, [#1753][] @awthwathje, [#1783][] @chentsulin, [#1703][] @ferhatelmas)\n\n[7.8.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.7.0...v7.8.0\n[#1758]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1758\n[#1724]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1724\n[#1732]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1732\n[#1681]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1681\n[#1767]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1767\n[#1759]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1759\n[#1750]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1750\n[#1389]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1389\n[#1717]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1717\n[#1722]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1722\n[#1699]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1699\n[#1743]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1743\n[#1753]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1753\n[#1783]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1783\n[#1703]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1703\n\n## [7.7.0] - 2018-02-19\n### Added\n* [`forbid-foreign-prop-types`][]: add `allowInPropTypes` option ([#1655][] @iansu)\n* Add [`jsx-max-depth`][] rule ([#1260][] @chriswong)\n\n### Fixed\n* [`no-access-state-in-setstate`][]: Exclude references to this.state in setState callback ([#1610][] @pfhayes)\n* [`no-danger-with-children`][]: prevent infinite loop ([#1571][] @ljharb)\n* [`sort-prop-types`][]: Fix sortShapeProp when shape is not an object literal ([#1669][] @justinanastos)\n* [`jsx-child-element-spacing`][]: fix error location ([#1666][] @pfhayes)\n* [`no-unused-prop-types`][]: fix for createClass ([#1675][] @yuri-sakharov)\n* [`prop-types`][]: include nextProps checking in shouldComponentUpdate ([#1690][] @amerryma)\n* [`jsx-curly-spacing`][]: refactor to fix start and end-braces in a single pass ([#1414][] @s-h-a-d-o-w)\n\n### Changed\n* [`jsx-child-element-spacing`][]: add missing docs ([#1665][] @pfhayes); fix docs ([#1670][] @SammyM)\n\n[7.7.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.6.1...v7.7.0\n[#1690]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1690\n[#1675]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1675\n[#1670]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1670\n[#1669]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1669\n[#1666]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1666\n[#1665]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1665\n[#1655]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1655\n[#1610]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1610\n[#1414]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1414\n[#1260]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1260\n[#1571]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1571\n\n## [7.6.1] - 2018-01-28\n### Fixed\n* Flow: fix crash in [`prop-types`][] with recursive type annotations ([#1653][] @jetpacmonkey)\n* Fix [`no-unknown-property`][] to properly recognize `crossOrigin` instead of `crossorigin`, and allow it on `link` tags. ([#1659][] @jzDev)\n* Fix [`no-access-state-in-setstate`][] to handle object spread ([#1657][] @ljharb)\n\n[7.6.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.6.0...v7.6.1\n[#1659]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1659\n[#1657]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1657\n[#1653]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1653\n\n## [7.6.0] - 2018-01-25\n### Added\n* Add [`forbid-dom-props`][] rule ([#1562][] @davazp)\n* Add [`jsx-child-element-spacing`][] rule ([#1515][] @pfhayes)\n* Add [`no-this-in-sfc`][] rule ([#1435][] @jomasti)\n* Add [`jsx-sort-default-props`][] rule ([#281][] @b0gok)\n* Add `message` option to [`boolean-prop-naming`][] ([#1588][] @louisscruz)\n* Add `beforeClosing` option to [`jsx-tag-spacing`][] ([#1396][] @cjskillingstad)\n* Add `instance-methods` and `instance-variables` to [`sort-comp`][] ([#599][] @RDGthree)\n* Add `propWrapperFunctions` support for [`boolean-prop-naming`][] ([#1478][] @jomasti)\n* Add warning for `React.addons.TestUtils` in [`no-deprecated`][] ([#1644][] @nirnaor)\n* Add URL to rule documentation to the rules metadata ([#1635][] @Arcanemagus)\n\n### Fixed\n* Fix crashes in [`no-access-state-in-setstate`][] ([#1559][] @jomasti, [#1611][] @pfhayes)\n* Fix crash in [`require-optimization`][] when encountering arrays with empty items as values in object ([#1621][] @kamataryo)\n* Fix crash in [`no-unused-prop-types`][] when passing an empty function as a PropType ([#1542][] [#1581][] @kevinzwhuang)\n* Fix crash in [`no-typos`][] when using `PropType.shape` without arguments ([#1471][] @mrichmond)\n* Fix crash when using Unions in flow propTypes ([#1468][] @justinanastos)\n* Fix missing meta in [`jsx-tag-spacing`][] ([#1650][] @flyerhzm)\n* Fix [`no-unused-state`][] to detect usage of `this.state` as an object ([#1572][])\n* Fix [`no-access-state-in-setstate`][] to detect when the `state` variable is destructured from `this.state` ([#1597][] @jaaberg)\n* Fix [`jsx-no-literals`][] to correctly find string literals part of BinaryExpressions ([#1511][] @jaaberg)\n* Fix [`no-typos`][] false positive on custom propTypes with isRequired ([#1607][] @lfades)\n* Fix [`prop-types`][] to check for `nextProps` in `componentWillReceiveProps` ([#1636][] @xjmdoo)\n* Fix [`no-unknown-property`][] to not pascal-casing `crossorigin` attribute and only allow it on script/img/video ([#1642][] @ljharb)\n\n### Changed\n* Improve [`jsx-wrap-multilines`][] auto fix ([#1576][] @sharmilajesupaul)\n* Export `defaultConfig` from [`sort-comp`][] rule for programmatic use ([#1578][] @Andarist)\n* Documentation improvements ([#1552][] @TSMMark, [#1566][] @lukeapage, [#1624][] @alexilyaev, @ljharb)\n* Update dependencies (@ljharb)\n\n[7.6.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.5.1...v7.6.0\n[#1562]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1562\n[#1515]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1515\n[#1435]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1435\n[#281]: https://github.com/jsx-eslint/eslint-plugin-react/issues/281\n[#1588]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1588\n[#1396]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1396\n[#599]: https://github.com/jsx-eslint/eslint-plugin-react/issues/599\n[#1478]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1478\n[#1644]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1644\n[#1635]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1635\n[#1559]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1559\n[#1611]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1611\n[#1621]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1621\n[#1542]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1542\n[#1581]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1581\n[#1471]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1471\n[#1468]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1468\n[#1650]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1650\n[#1572]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1572\n[#1597]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1597\n[#1511]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1511\n[#1607]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1607\n[#1636]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1636\n[#1642]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1642\n[#1576]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1576\n[#1578]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1578\n[#1552]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1552\n[#1566]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1566\n[#1624]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1624\n\n## [7.5.1] - 2017-11-19\n### Fixed\n* Fix [`jsx-no-bind`][] crash ([#1543][] @jomasti)\n* Fix [`no-unused-prop-types`][] crash ([#1542][] @jomasti)\n\n### Changed\n* Documentation improvements ([#1546][] @jseminck)\n\n[7.5.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.5.0...v7.5.1\n[#1543]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1543\n[#1542]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1542\n[#1546]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1546\n\n## [7.5.0] - 2017-11-18\n### Added\n* Add [`jsx-one-expression-per-line`][] rule ([#1497][] @TSMMark)\n* Add [`destructuring-assignment`][] rule ([#1462][] @DianaSuvorova)\n* Add [`no-access-state-in-setstate`][] rule ([#1374][] @jaaberg)\n* Add [`button-has-type`][] rule ([#1525][] @Hypnosphi)\n* Add warnings for `React.DOM` factories in [`no-deprecated`][] ([#1530][] @backjo)\n* Add `sortShapeProp` option to [`sort-prop-types`][] ([#1476][] @jomasti)\n* Add `parens-new-line` option to [`jsx-wrap-multilines`][] ([#1475][] @jomasti)\n* Add `checkContextTypes` and `checkChildContextTypes` options to [`forbid-prop-types`][] ([#1533][] @jomasti)\n* Add `forbidDefaultForRequired ` option to [`require-default-props`][] ([#1524][] @jomasti)\n* Add new nodes support to [`jsx-wrap-multilines`][] ([#1384][] @evgeny-petukhov)\n\n### Fixed\n* Fix [`jsx-curly-brace-presence`][] auto fix by bailing out when some chars exist ([#1479][] [#1449][] @jackyho112)\n* Fix [`boolean-prop-naming`][] crash with Object spread ([#1485][] @track0x1)\n* Fix [`no-unused-state`][] to correctly handle arrow function class method ([#1363][] @jackyho112)\n* Fix incompatibility with [`typescript-eslint-parser`](https://github.com/eslint/typescript-eslint-parser) ([#1496][] @timothykang)\n* Fix [`jsx-no-bind`][] to only warn for props and account for variable declaration ([#1444][] [#1395][] [#1417][] @jackyho112)\n* Fix [`no-unused-prop-types`][] to handle props usage in custom prop validators ([#1518][] @petersendidit)\n* Fix [`prefer-stateless-function`][] to account for `contextTypes` and `defaultProps` ([#1521][] @jomasti)\n* Fix [`jsx-no-comment-textnodes`][] to not warn when using two slashes via html entities at the beginning of a literal ([#1517][] @jomasti)\n* Fix [`default-props-match-prop-types`][] crash ([#1499][] @jomasti)\n* Fix [`no-unused-prop-types`][] to handle props used in the `setState` update callback ([#1507][] @petersendidit)\n* Fix alignment bug in [`jsx-indent`][] ([#1246][] @jseminck)\n\n### Changed\n* Documentation improvements ([#1438][] @jseminck, [#1464][] @AlaaAttya, [#1494][] @piperchester, [#1467][] @felicio, [#1512][] @adam-golab)\n* Code refactoring ([#1423][] [#1398][] @jseminck, [#1500][] [#1514][] @Aladdin-ADD, [#1502][] @SimenB, [#1508][] [#1526][] @jomasti, @ljharb)\n* Update dependencies ([#1450][] @leebyron, @ljharb)\n\n[7.5.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.4.0...v7.5.0\n[#1497]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1497\n[#1462]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1462\n[#1374]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1374\n[#1525]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1525\n[#1530]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1530\n[#1476]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1476\n[#1475]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1475\n[#1533]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1533\n[#1524]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1524\n[#1384]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1384\n[#1479]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1479\n[#1449]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1449\n[#1485]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1485\n[#1363]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1363\n[#1496]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1496\n[#1444]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1444\n[#1395]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1395\n[#1417]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1417\n[#1518]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1518\n[#1521]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1521\n[#1517]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1517\n[#1499]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1499\n[#1507]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1507\n[#1246]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1246\n[#1438]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1438\n[#1464]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1464\n[#1494]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1494\n[#1467]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1467\n[#1512]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1512\n[#1423]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1423\n[#1500]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1500\n[#1514]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1514\n[#1502]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1502\n[#1508]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1508\n[#1526]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1526\n[#1398]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1398\n[#1450]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1450\n\n## [7.4.0] - 2017-09-24\n### Added\n* Add Flow 0.53 support ([#1376][] @jseminck)\n* Add [`jsx-curly-brace-presence`][] rule ([#1310][] @jackyho112)\n* Add support for Flow IntersectionTypeAnnotation to [`prop-types`][] and [`no-unused-prop-types`][] ([#1364][] [#1323][] @jseminck)\n* Add support for Flow TypedArgument to [`no-unused-prop-types`][] ([#1412][] @jseminck)\n* Add support for Flow ClassExpressions to [`prop-types`][] ([#1400][] @jseminck)\n* Add support for Flow read-only props to [`no-unused-prop-types`][] ([#1388][] @jseminck)\n* Add more tests for [`prop-types`][] and [`no-unused-prop-types`][] ([#1381][] @DianaSuvorova)\n* Add support for increment and decrement operations to [`no-direct-mutation-state`][] ([#1386][] @zpao)\n\n### Fixed\n* Fix [`no-unused-state`][] to ignore computed property keys ([#1361][] @jackyho112)\n* Fix [`no-typos`][] crash ([#1406][] @jseminck)\n* Fix [`boolean-prop-naming`][] crash ([#1409][] @EvHaus)\n* Fix [`prop-types`][] and [`no-unused-prop-types`][] crash with IntersectionTypeAnnotation ([#1413][] @jseminck)\n\n### Changed\n* Documentation improvements ([#1392][] @xcatliu, [#1403][] @piperchester, [#1432][] @jneuendorf)\n\n[7.4.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.3.0...v7.4.0\n[#1376]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1376\n[#1310]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1310\n[#1364]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1364\n[#1323]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1323\n[#1412]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1412\n[#1400]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1400\n[#1388]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1388\n[#1381]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1381\n[#1361]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1361\n[#1406]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1406\n[#1409]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1409\n[#1392]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1392\n[#1403]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1403\n[#1386]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1386\n[#1413]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1413\n[#1432]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1432\n\n## [7.3.0] - 2017-08-21\n### Added\n* Add checks for `propTypes`, `contextTypes` and `childContextTypes` to [`no-typos`][] ([#213][] @DianaSuvorova)\n\n### Fixed\n* Fix [`boolean-prop-naming`][] crash ([#1369][] @EvHaus)\n* Fix [`no-typos`][] crash ([#1353][] @jseminck)\n* Fix [`require-default-props`][] stopping when it finds a component without props ([#1380][] @brgibson)\n* Fix [`no-direct-mutation-state`][] detection with nested components ([#1382][])\n\n### Changed\n* Documentation improvements ([#1383][] @mjomble)\n\n[7.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.2.1...v7.3.0\n[#213]: https://github.com/jsx-eslint/eslint-plugin-react/issues/213\n[#1369]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1369\n[#1353]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1353\n[#1380]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1380\n[#1382]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1382\n[#1383]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1383\n\n## [7.2.1] - 2017-08-14\n### Fixed\n* Fix [`forbid-prop-types`][] crash on identifiers ([#1352][] @ljharb)\n* Fix [`boolean-prop-naming`][] crash with propTypes wrapper ([#1354][] @dustinsoftware)\n* Fix [`prop-types`][] false positive with local variable `props` ([#1288][] @DianaSuvorova)\n* Fix wrapped propTypes detection ([#1366][])\n\n### Changed\n* Documentation improvements ([#1123][] @penx)\n\n[7.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.2.0...v7.2.1\n[#1352]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1352\n[#1354]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1354\n[#1288]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1288\n[#1366]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1366\n[#1123]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1123\n\n## [7.2.0] - 2017-08-09\n### Added\n* Add [`no-unused-state`][] rule ([#1103][] @wbinnssmith)\n* Add [`boolean-prop-naming`][] rule ([#1264][] @EvHaus)\n* Add [`no-typos`][] rule ([#1189][] @jseminck, [#1294][] @haridusenadeera)\n* Add auto fix for [`jsx-sort-props`][] ([#1273][] @Overload119)\n* Add `getters` and `setters` groups to [`sort-comp`][] ([#100][] @RDGthree)\n* Add `noStrings` option to [`jsx-no-literals`][] ([#1202][] @deecewan)\n* Add inverse option for `always`/`never` to [`jsx-boolean-value`][] ([#1249][] @ljharb)\n\n### Fixed\n* Fix [`no-direct-mutation-state`][] to disallow `this.state` mutation in constructor ([#832][] @burabure)\n* Fix [`jsx-no-target-blank`][] crash on empty `rel` attribute ([#1269][] @dustinsoftware)\n* Fix [`sort-comp`][] component detection with `ClassExpression` ([#1076][] @webOS101)\n* Fix [`no-unused-prop-types`][] detection with async class properties and methods ([#1053][] @benstepp)\n* Fix [`void-dom-elements-no-children`][] crash ([#1226][] @kokobeware)\n* Fix [`no-danger-with-children`][] to ignore line breaks ([#1262][])\n* Fix [`no-danger-with-children`][] crash with undefined ([#1287][])\n* Fix [`jsx-no-target-blank`][] crash ([#1296][] @jseminck)\n* Fix [`no-unused-prop-types`][] to no longer ignore components with no used props ([#1303][] @DianaSuvorova)\n* Fix [`jsx-no-duplicate-props`][] crash ([#969][] @marcelmokos)\n* Fix [`jsx-no-literals`][] false positives ([#1301][] @davidyorr)\n* Fix [`no-find-dom-node`][] detection with named imports ([#785][] @Hypnosphi)\n* Fix proTypes-related rules detection with wrapped propTypes ([#1266][] @dustinsoftware)\n* Fix [`no-unused-prop-types`][] detection with propTypes wrapped in a function ([#1253][] @dustinsoftware)\n* Fix [`no-unused-prop-types`][] detection with destructured use of properties ([#816][] @DianaSuvorova)\n* Fix [`no-unused-prop-types`][] detection with inline functions ([#1309][] @DianaSuvorova)\n* Fix [`no-unused-prop-types`][] `skipShapeProps` option with Flow annotations ([#1335][] @DianaSuvorova)\n* Fix [`jsx-curly-spacing`][] schema incompatibility with ESLint 4.2.0 ([#1290][] @jseminck)\n\n### Changed\n* Documentation improvements ([#1261][] @mminer, [#1005][] @yooungt13, [#1289][] @konekoya, [#1308][] @xcatliu, [#1306][] @egberts, [#1329][] [#1344][] @DianaSuvorova)\n* ES6-ify codebase ([#1274][] [#1277][] [#1281][] @dfilipidisz)\n* Code refactoring (@ljharb)\n* Update Travis CI and AppVeyor CI configurations (@lencioni)\n\n[7.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.1.0...v7.2.0\n[#1103]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1103\n[#1273]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1273\n[#1264]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1264\n[#1189]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1189\n[#1294]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1294\n[#100]: https://github.com/jsx-eslint/eslint-plugin-react/issues/100\n[#1202]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1202\n[#1249]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1249\n[#832]: https://github.com/jsx-eslint/eslint-plugin-react/issues/832\n[#1269]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1269\n[#1076]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1076\n[#1053]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1053\n[#1226]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1226\n[#1262]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1262\n[#1287]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1287\n[#1296]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1296\n[#1303]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1303\n[#969]: https://github.com/jsx-eslint/eslint-plugin-react/issues/969\n[#1301]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1301\n[#785]: https://github.com/jsx-eslint/eslint-plugin-react/issues/785\n[#1266]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1266\n[#1253]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1253\n[#816]: https://github.com/jsx-eslint/eslint-plugin-react/issues/816\n[#1309]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1309\n[#1261]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1261\n[#1005]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1005\n[#1289]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1289\n[#1308]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1308\n[#1306]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1306\n[#1329]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1329\n[#1274]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1274\n[#1277]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1277\n[#1281]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1281\n[#1335]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1335\n[#1344]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1344\n[#1290]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1290\n\n## [7.1.0] - 2017-06-13\n### Added\n* Add [`default-props-match-prop-types`][] rule ([#1022][] @webOS101)\n* Add [`no-redundant-should-component-update`][] rule ([#985][] @jomasti)\n* Add [`jsx-closing-tag-location`][] rule ([#1206][] @rsolomon)\n* Add auto fix for [`jsx-max-props-per-line`][] ([#949][] @snowypowers)\n* Add support for lifecycle methods with `nextProps`/`prevProps` in [`no-unused-prop-types`][] ([#1213][] @jseminck)\n* Add Flow SuperTypeParameters support to [`prop-types`][] ([#1236][] @gpeal)\n* Add `children` option to [`jsx-curly-spacing`][] ([#857][] @fatfisz)\n\n### Fixed\n* Fix [`prefer-stateless-function`][] `ignorePureComponents` option when using class expressions ([#1122][] @dreid)\n* Fix [`void-dom-elements-no-children`][] crash ([#1195][] @oliviertassinari)\n* Fix [`require-default-props`][] quoted `defaultProps` detection ([#1201][])\n* Fix [`jsx-sort-props`][] bug with `ignoreCase` and `callbacksLast` options set to `true` ([#1175][] @jseminck)\n* Fix [`no-unused-prop-types`][] false positive ([#1183][] [#1135][] @jseminck)\n* Fix [`jsx-no-target-blank`][] to not issue errors for non-external URLs ([#1216][] @gfx)\n* Fix [`prop-types`][] quoted Flow types detection ([#1132][] @ethanjgoldberg)\n* Fix [`no-array-index-key`][] crash with `key` without value ([#1242][] @jseminck)\n\n### Changed\n* Set ESLint 4.0.0 as valid peerDependency\n* Dead code removal ([#1227][] @jseminck)\n* Update dependencies (@ljharb)\n* Documentation improvements ([#1071][] @adnasa, [#1199][] @preco21, [#1222][] @alexilyaev, [#1231][] @vonovak, [#1239][] @webOS101, [#1241][] @102)\n\n[7.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.0.1...v7.1.0\n[#1022]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1022\n[#949]: https://github.com/jsx-eslint/eslint-plugin-react/pull/949\n[#985]: https://github.com/jsx-eslint/eslint-plugin-react/issues/985\n[#1213]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1213\n[#1236]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1236\n[#1206]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1206\n[#857]: https://github.com/jsx-eslint/eslint-plugin-react/issues/857\n[#1122]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1122\n[#1195]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1195\n[#1201]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1201\n[#1175]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1175\n[#1183]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1183\n[#1135]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1135\n[#1216]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1216\n[#1132]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1132\n[#1242]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1242\n[#1227]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1227\n[#1071]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1071\n[#1199]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1199\n[#1222]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1222\n[#1231]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1231\n[#1239]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1239\n[#1241]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1241\n\n## [7.0.1] - 2017-05-13\n### Fixed\n* Fix [`jsx-curly-spacing`][] `allowMultiline` option being undefined in some cases ([#1179][] @fatfisz)\n* Fix [`jsx-curly-spacing`][] newline with object literals bug ([#1180][] @fatfisz)\n* Fix [`prop-types`][] to not mark class static function as valid propTypes definition ([#1174][])\n* Fix [`prop-types`][] crash with Flow spread operator ([#1178][])\n* Fix [`void-dom-elements-no-children`][] crash on faulty `createElement` detection ([#1101][])\n* Fix [`require-default-props`][] error message for quoted props ([#1161][])\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#1173][] @luftywiranda13, [#1192][] @markus-willems)\n\n[7.0.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.0.0...v7.0.1\n[#1179]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1179\n[#1180]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1180\n[#1174]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1174\n[#1178]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1178\n[#1101]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1101\n[#1161]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1161\n[#1173]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1173\n[#1192]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1192\n\n## [7.0.0] - 2017-05-06\n### Added\n* Add [`no-will-update-set-state`][] rule ([#1139][] @ManThursday)\n* Add import and destructuring support to [`no-deprecated`][]\n* Add `reservedFirst` option to [`jsx-sort-props`][] ([#1134][] @MatthewHerbst)\n\n### Breaking\n* Update rules for React 15.5.0:\n  * Add warnings for `React.PropTypes` and `React.createClass` in [`no-deprecated`][] ([#1148][] @Calyhre)\n  * Update `createClass` component factory to `createReactClass`. This is used for React component detection, if you still using `React.createClass` use the [shared settings](README.md#configuration) to specify `createClass` as component factory\n* Drop Node.js < 4 support ([#1038][] @ljharb)\n* Add [`no-danger-with-children`][] rule to recommended rules ([#748][] @ljharb)\n* Add [`no-string-refs`][] rule to recommended rules ([#749][] @ljharb)\n* Add [`jsx-key`][] rule to recommended rules ([#750][] @ljharb)\n* Add [`jsx-no-comment-textnodes`][] rule to recommended rules ([#751][] @ljharb)\n* Add [`jsx-no-target-blank`][] rule to recommended rules ([#752][] @ljharb)\n* Add [`no-unescaped-entities`][] rule to recommended rules ([#841][] @ljharb)\n* Add [`no-children-prop`][] rule to recommended rules ([#842][] @ljharb)\n* Remove deprecated [`wrap-multilines`][] rule, use [`jsx-wrap-multilines`][] instead\n* Remove deprecated [`no-comment-textnodes`][] rule, use [`jsx-no-comment-textnodes`][] instead\n* Remove deprecated [`require-extension`][] rule, use the [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) [`extensions`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md) rule instead\n* Deprecate [`jsx-space-before-closing`][] rule, use the [`jsx-tag-spacing`][] rule instead. [`jsx-space-before-closing`][] still works but will trigger a warning ([#1070][] @afairb)\n* [`jsx-first-prop-new-line`][] default is now `multiline-multiprop` ([#802][] @kokarn)\n* [`jsx-wrap-multilines`][] now checks arrow functions without block body. It can be deactivated in [rule options](docs/rules/jsx-wrap-multilines.md#rule-details) ([#790][] @ColCh)\n* [`jsx-no-undef`][] will not check the global scope by default. You can force it with the [`allowGlobals`](docs/rules/jsx-no-undef.md#allowglobals) option ([#1013][] @jomasti)\n\n### Fixed\n* Fix [`no-unused-prop-types`][] false positive with `nextProps` ([#1079][] @Kerumen)\n* Fix [`prefer-stateless-function`][] to not warn on classes with decorators ([#1034][] @benstepp)\n\n### Changed\n* Update dependencies ([#1119][] @danez)\n* Documentation improvements ([#1121][] @omerzach, [#1130][] @dreid, [#1131][] @shoesandsocks, [#1149][] @Adzz, [#1151][] @MatthewHerbst, [#1167][] @Slumber86)\n\n[7.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.10.3...v7.0.0\n[#1134]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1134\n[#1038]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1038\n[#802]: https://github.com/jsx-eslint/eslint-plugin-react/pull/802\n[#790]: https://github.com/jsx-eslint/eslint-plugin-react/issues/790\n[#1013]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1013\n[#1070]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1070\n[#748]: https://github.com/jsx-eslint/eslint-plugin-react/issues/748\n[#749]: https://github.com/jsx-eslint/eslint-plugin-react/issues/749\n[#750]: https://github.com/jsx-eslint/eslint-plugin-react/issues/750\n[#751]: https://github.com/jsx-eslint/eslint-plugin-react/issues/751\n[#752]: https://github.com/jsx-eslint/eslint-plugin-react/issues/752\n[#841]: https://github.com/jsx-eslint/eslint-plugin-react/issues/841\n[#842]: https://github.com/jsx-eslint/eslint-plugin-react/issues/842\n[#1139]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1139\n[#1148]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1148\n[#1079]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1079\n[#1034]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1034\n[#1119]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1119\n[#1121]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1121\n[#1130]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1130\n[#1131]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1131\n[#1149]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1149\n[#1151]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1151\n[#1167]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1167\n\n## [6.10.3] - 2017-03-20\n### Fixed\n* Revert [#1057][] due to issues with [`jsx-indent`][] ([#1117][])\n\n[6.10.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.10.2...v6.10.3\n\n## [6.10.2] - 2017-03-19\n### Fixed\n* Fix [`jsx-indent`][] indentation calculation with nested JSX ([#1117][])\n\n[6.10.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.10.1...v6.10.2\n[#1117]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1117\n\n## [6.10.1] - 2017-03-19\n### Fixed\n* Fix [`jsx-indent`][] auto fix with tabs ([#1057][] @kentcdodds @webOS101)\n* Fix [`jsx-indent`][] crash ([#1061][] @iancmyers)\n* Fix [`void-dom-elements-no-children`][] crash and fix it to only checks for a createElement call from\nReact ([#1073][] @jomasti)\n* Fix component detection that caused a false positive in [`no-multi-comp`][] ([#1088][] @benstepp)\n\n[6.10.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.10.0...v6.10.1\n[#1057]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1057\n[#1061]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1061\n[#1073]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1073\n[#1088]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1088\n\n## [6.10.0] - 2017-02-16\n### Added\n* Add [`forbid-foreign-prop-types`][] rule ([#696][] @iancmyers)\n* Add [`void-dom-elements-no-children`][] rule ([#709][] @lencioni)\n* Add [`forbid-elements`][] rule ([#887][] @kentor)\n* Add `noSortAlphabetically` option to [`jsx-sort-props`][] ([#541][] [#786][] @markus101)\n* Add `when` option to [`jsx-max-props-per-line`][] ([#878][] @kentor)\n* Add support for `nextProps` to [`prop-types`][] ([#814][])\n\n### Fixed\n* Fix [`require-default-props`][] crash ([#1029][])\n* Fix [`require-default-props`][] rule when using Flow type from assignment ([#1043][] @wyze @CarlRosell)\n* Fix [`style-prop-object`][] to not warn with explicit `null` or `undefined` ([#812][] @ljharb)\n* Fix [`no-unused-prop-types`][] props detection in stateless components ([#885][] @BarryThePenguin)\n* Fix [`display-name`] false positive with `document.createElement` ([#996][] @jomasti)\n* Fix ESLint 2 compatibility (@ljharb)\n\n### Changed\n* Tests improvements (@ljharb)\n* Documentation improvements ([#958][] @Jorundur, [#1010][] @amilajack, [#1041][] @EvNaverniouk, [#1050][] @lencioni, [#1062][] @dguo)\n\n[6.10.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.9.0...v6.10.0\n[#696]: https://github.com/jsx-eslint/eslint-plugin-react/issues/696\n[#709]: https://github.com/jsx-eslint/eslint-plugin-react/issues/709\n[#887]: https://github.com/jsx-eslint/eslint-plugin-react/issues/887\n[#541]: https://github.com/jsx-eslint/eslint-plugin-react/issues/541\n[#786]: https://github.com/jsx-eslint/eslint-plugin-react/issues/786\n[#878]: https://github.com/jsx-eslint/eslint-plugin-react/issues/878\n[#814]: https://github.com/jsx-eslint/eslint-plugin-react/issues/814\n[#1029]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1029\n[#1043]: https://github.com/jsx-eslint/eslint-plugin-react/issues/1043\n[#812]: https://github.com/jsx-eslint/eslint-plugin-react/issues/812\n[#885]: https://github.com/jsx-eslint/eslint-plugin-react/issues/885\n[#996]: https://github.com/jsx-eslint/eslint-plugin-react/issues/996\n[#958]: https://github.com/jsx-eslint/eslint-plugin-react/pull/958\n[#1010]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1010\n[#1041]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1041\n[#1050]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1050\n[#1062]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1062\n\n## [6.9.0] - 2017-01-08\n### Added\n* Add support for variable reference to [`sort-prop-types`][] ([#622][])\n\n### Fixed\n* Fix Node.js 0.10 support ([#1000][] @ljharb)\n* Fix [`prop-types`][] to correctly assign props to components ([#991][])\n\n### Changed\n* Documentation improvements ([#995][] @rutsky)\n\n[6.9.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.8.0...v6.9.0\n[#622]: https://github.com/jsx-eslint/eslint-plugin-react/issues/622\n[#1000]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1000\n[#991]: https://github.com/jsx-eslint/eslint-plugin-react/issues/991\n[#995]: https://github.com/jsx-eslint/eslint-plugin-react/pull/995\n\n## [6.8.0] - 2016-12-05\n### Added\n* Add [`no-array-index-key`][] rule ([#978][] @lencioni)\n* Add [`require-default-props`][] rule ([#528][]  @vitorbal)\n* Add support for flow variance syntax to [`prop-types`][] ([#961][] @ajhyndman)\n\n### Fixed\n* Fix [`jsx-indent`][] with multiline jsx in ternaries ([#966][])\n* Fix component detection to ignore async functions ([#989][] @taion)\n* Fix [`jsx-curly-spacing`][] autofix to not delete comments ([#648][])\n* Fix auto-enabling of `eslint-plugin-react` in exported configurations ([#984][] @jamischarles)\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#960][] @evilebottnawi, [#973][] @JamesWatling, [#982][] @captbaritone)\n\n[6.8.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.7.1...v6.8.0\n[#978]: https://github.com/jsx-eslint/eslint-plugin-react/pull/978\n[#528]: https://github.com/jsx-eslint/eslint-plugin-react/issues/528\n[#961]: https://github.com/jsx-eslint/eslint-plugin-react/issues/961\n[#966]: https://github.com/jsx-eslint/eslint-plugin-react/issues/966\n[#989]: https://github.com/jsx-eslint/eslint-plugin-react/pull/989\n[#648]: https://github.com/jsx-eslint/eslint-plugin-react/issues/648\n[#984]: https://github.com/jsx-eslint/eslint-plugin-react/pull/984\n[#960]: https://github.com/jsx-eslint/eslint-plugin-react/pull/960\n[#973]: https://github.com/jsx-eslint/eslint-plugin-react/pull/973\n[#982]: https://github.com/jsx-eslint/eslint-plugin-react/pull/982\n\n## [6.7.1] - 2016-11-15\n### Fixed\n* Fix [`jsx-tag-spacing`][] crash when options object isn't passed ([#955][] @daltones)\n\n[6.7.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.7.0...v6.7.1\n[#955]: https://github.com/jsx-eslint/eslint-plugin-react/issues/955\n\n## [6.7.0] - 2016-11-14\n### Added\n* Add [`jsx-tag-spacing`][] rule ([#693][] @Kovensky)\n\n### Fixed\n* Fix [`jsx-indent`][] for parenthesized ternaries ([#945][] @voxpelli)\n* Fix [`jsx-indent`][] for multiline ternaries\n* Fix [`jsx-indent`][] for arrays in jsx ([#947][])\n* Fix [`no-danger-with-children`][] crash with spread on global variables ([#921][])\n* Fix [`jsx-wrap-multilines`][] ternaries handling ([#916][])\n\n### Changed\n* Enable [`no-unused-prop-types`][] `skipShapeProps` option by default to limit false positive ([#953][] @everdimension)\n\n[6.7.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.6.0...v6.7.0\n[#693]: https://github.com/jsx-eslint/eslint-plugin-react/issues/693\n[#945]: https://github.com/jsx-eslint/eslint-plugin-react/issues/945\n[#947]: https://github.com/jsx-eslint/eslint-plugin-react/issues/947\n[#921]: https://github.com/jsx-eslint/eslint-plugin-react/issues/921\n[#916]: https://github.com/jsx-eslint/eslint-plugin-react/issues/916\n[#953]: https://github.com/jsx-eslint/eslint-plugin-react/pull/953\n\n## [6.6.0] - 2016-11-06\n### Added\n* Add [`jsx-first-prop-new-line`][] auto fix ([#886][] @snowypowers)\n\n### Fixed\n* Fix [`no-unused-prop-types`][] crash with destructured prop-types ([#938][])\n* Fix [`jsx-indent`][] in multi-line conditional expressions ([#901][], [#907][])\n* Fix [`sort-comp`][] bad error message if 2 methods in the same group must be moved ([#507][])\n\n### Changed\n* Documentation improvements ([#941][] @pwmckenna)\n\n[6.6.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.5.0...v6.6.0\n[#886]: https://github.com/jsx-eslint/eslint-plugin-react/pull/886\n[#938]: https://github.com/jsx-eslint/eslint-plugin-react/issues/938\n[#901]: https://github.com/jsx-eslint/eslint-plugin-react/issues/901\n[#907]: https://github.com/jsx-eslint/eslint-plugin-react/issues/907\n[#507]: https://github.com/jsx-eslint/eslint-plugin-react/issues/507\n[#941]: https://github.com/jsx-eslint/eslint-plugin-react/pull/941\n\n## [6.5.0] - 2016-11-01\n### Added\n* Add tab support to [`jsx-closing-bracket-location`][] auto fixer ([#909][] @arperry)\n* Add tab and space support to [`jsx-indent`][] auto fixer ([#608][] @jayphelps)\n* Add `multiline-multiprop` option to [`jsx-first-prop-new-line`][] ([#883][] @kentor)\n\n### Fixed\n* Fix [`forbid-component-props`][] crash with self reference JSX element ([#839][] @xeodou)\n* Fix [`jsx-indent`][] to ignore lines starting by literals ([#900][])\n* Fix [`no-set-state`][] to correctly detect `setState` in arrow functions ([#931][])\n\n### Changed\n* Update dependencies\n* Add `deprecated` metadata to deprecated rules ([#911][] @randycoulman)\n* Auto-enable `eslint-plugin-react` in exported configurations ([#925][] @MoOx)\n* Documentation improvements ([#910][] @Wilfred, [#932][] @gnarf)\n\n[6.5.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.4.1...v6.5.0\n[#909]: https://github.com/jsx-eslint/eslint-plugin-react/pull/909\n[#608]: https://github.com/jsx-eslint/eslint-plugin-react/pull/608\n[#883]: https://github.com/jsx-eslint/eslint-plugin-react/pull/883\n[#839]: https://github.com/jsx-eslint/eslint-plugin-react/pull/839\n[#900]: https://github.com/jsx-eslint/eslint-plugin-react/issues/900\n[#931]: https://github.com/jsx-eslint/eslint-plugin-react/issues/931\n[#911]: https://github.com/jsx-eslint/eslint-plugin-react/pull/911\n[#925]: https://github.com/jsx-eslint/eslint-plugin-react/pull/925\n[#910]: https://github.com/jsx-eslint/eslint-plugin-react/pull/910\n[#932]: https://github.com/jsx-eslint/eslint-plugin-react/pull/932\n\n## [6.4.1] - 2016-10-10\n### Fixed\n* Fix [`jsx-indent`][] for arrays ([#897][], [#898][])\n* Fix [`jsx-indent`][] to allow multi-line logical expressions with one level of indent ([#896][])\n\n[6.4.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.4.0...v6.4.1\n[#897]: https://github.com/jsx-eslint/eslint-plugin-react/issues/897\n[#898]: https://github.com/jsx-eslint/eslint-plugin-react/issues/898\n[#896]: https://github.com/jsx-eslint/eslint-plugin-react/pull/896\n\n## [6.4.0] - 2016-10-09\n### Added\n* Add `skipUndeclared` option to [`prop-types`][] ([#846][] @pfhayes)\n\n### Fixed\n* Fix [`jsx-no-bind`][] crash on arrow functions ([#854][])\n* Fix [`display-name`][] false negative on es6-style method in `React.createClass` ([#852][])\n* Fix [`prefer-stateless-function`][] to allow components with `childContextTypes` ([#853][])\n* Fix [`no-children-prop`][] spread support ([#862][] @randycoulman)\n* Fix [`no-unused-prop-types`][] to ignore validation when spread is used ([#840][])\n* Fix [`jsx-closing-bracket-location`][] for multi-line prop ([#889][])\n* Fix [`jsx-indent`][] in multi-line function calls ([#895][])\n* Fix [`jsx-indent`][] in multi-line logical expressions ([#540][])\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#860][] @fson, [#863][] @corydolphin, [#830][] @eelyafi, [#876][] @manovotny, [#877][] @gaearon)\n\n[6.4.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.3.0...v6.4.0\n[#846]: https://github.com/jsx-eslint/eslint-plugin-react/pull/846\n[#854]: https://github.com/jsx-eslint/eslint-plugin-react/issues/854\n[#852]: https://github.com/jsx-eslint/eslint-plugin-react/issues/852\n[#853]: https://github.com/jsx-eslint/eslint-plugin-react/issues/853\n[#862]: https://github.com/jsx-eslint/eslint-plugin-react/pull/862\n[#840]: https://github.com/jsx-eslint/eslint-plugin-react/issues/840\n[#889]: https://github.com/jsx-eslint/eslint-plugin-react/issues/889\n[#895]: https://github.com/jsx-eslint/eslint-plugin-react/issues/895\n[#540]: https://github.com/jsx-eslint/eslint-plugin-react/issues/540\n[#860]: https://github.com/jsx-eslint/eslint-plugin-react/pull/860\n[#863]: https://github.com/jsx-eslint/eslint-plugin-react/pull/863\n[#830]: https://github.com/jsx-eslint/eslint-plugin-react/pull/830\n[#876]: https://github.com/jsx-eslint/eslint-plugin-react/pull/876\n[#877]: https://github.com/jsx-eslint/eslint-plugin-react/pull/877\n\n## [6.3.0] - 2016-09-20\n### Added\n* Add [`no-children-prop`][] rule ([#720][] @benstepp)\n* Add [`no-unescaped-entities`][] rule ([#681][] @pfhayes)\n* Add JSXExpressionContainer support to [`jsx-indent`][] rule ([#838][] @eelyafi)\n\n### Fixed\n* Fix [`style-prop-object`][] crash ([#834][])\n* Fix [`style-prop-object`][] false positive on computed properties ([#820][])\n* Fix [`style-prop-object`][] to deal with null and spread props that can't be resolved ([#809][] [#812][] @petersendidit)\n\n[6.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.2.2...v6.3.0\n[#720]: https://github.com/jsx-eslint/eslint-plugin-react/issues/720\n[#681]: https://github.com/jsx-eslint/eslint-plugin-react/pull/681\n[#838]: https://github.com/jsx-eslint/eslint-plugin-react/pull/838\n[#834]: https://github.com/jsx-eslint/eslint-plugin-react/issues/834\n[#820]: https://github.com/jsx-eslint/eslint-plugin-react/issues/820\n[#809]: https://github.com/jsx-eslint/eslint-plugin-react/issues/809\n[#812]: https://github.com/jsx-eslint/eslint-plugin-react/issues/812\n\n## [6.2.2] - 2016-09-15\n### Fixed\n* Fix [`no-unused-prop-types`][] crash ([#825][] @EvNaverniouk)\n* Fix [`jsx-no-target-blank`][] crash ([#821][])\n\n[6.2.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.2.1...v6.2.2\n[#821]: https://github.com/jsx-eslint/eslint-plugin-react/issues/821\n[#825]: https://github.com/jsx-eslint/eslint-plugin-react/pull/825\n\n## [6.2.1] - 2016-09-13\n### Fixed\n* Fix false positive in [`no-unused-prop-types`][] ([#792][] @EvNaverniouk)\n* Fix [`jsx-no-target-blank`][] to target only anchor elements ([#793][] @aduth)\n* Fix [`jsx-no-target-blank`][] to be case insensitive [#796][] @dmnd)\n* Fix [`jsx-uses-vars`][] shadowed variables handling ([#799][])\n\n### Changed\n* Update dependencies\n* Documentation improvements (@ljharb, [#794][] @dougshamoo, [#813][] @AndiDog, [#815][] @chris-vaszauskas)\n\n[6.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.2.0...v6.2.1\n[#792]: https://github.com/jsx-eslint/eslint-plugin-react/pull/792\n[#793]: https://github.com/jsx-eslint/eslint-plugin-react/pull/793\n[#794]: https://github.com/jsx-eslint/eslint-plugin-react/pull/794\n[#796]: https://github.com/jsx-eslint/eslint-plugin-react/pull/796\n[#799]: https://github.com/jsx-eslint/eslint-plugin-react/issues/799\n[#813]: https://github.com/jsx-eslint/eslint-plugin-react/pull/813\n[#815]: https://github.com/jsx-eslint/eslint-plugin-react/pull/815\n\n## [6.2.0] - 2016-08-28\n### Added\n* Add [`no-unused-prop-types`][] rule ([#226][] @EvNaverniouk)\n* Add [`style-prop-object`][] rule ([#715][] @petersendidit)\n* Add auto fix for [`self-closing-comp`][] ([#770][] @pl12133)\n* Add support for `typeAnnotations` in [`sort-comp`][] ([#235][] @dozoisch)\n* Add support for `PureComponent` in [`prefer-stateless-function`][] ([#781][] @tiemevanveen)\n\n### Fixed\n* Fix [`jsx-uses-vars`][] to work better with [`prefer-const`](https://eslint.org/docs/rules/prefer-const). You'll need to upgrade to ESLint 3.4.0 to completely fix the compatibility issue ([#716][])\n* Fix [`require-render-return`][] crash ([#784][])\n* Fix related components detection in [`prop-types`][] ([#735][])\n* Fix component detection to ignore functions expression without a parent component\n\n### Changed\n* Update dependencies\n* Documentation improvements (@lencioni)\n\n[6.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.1.2...v6.2.0\n[#226]: https://github.com/jsx-eslint/eslint-plugin-react/issues/226\n[#715]: https://github.com/jsx-eslint/eslint-plugin-react/issues/715\n[#770]: https://github.com/jsx-eslint/eslint-plugin-react/pull/770\n[#235]: https://github.com/jsx-eslint/eslint-plugin-react/issues/235\n[#781]: https://github.com/jsx-eslint/eslint-plugin-react/pull/781\n[#716]: https://github.com/jsx-eslint/eslint-plugin-react/issues/716\n[#784]: https://github.com/jsx-eslint/eslint-plugin-react/issues/784\n[#735]: https://github.com/jsx-eslint/eslint-plugin-react/issues/735\n\n## [6.1.2] - 2016-08-17\n### Fixed\n* Fix nested spread handling in [`no-danger-with-children`][] ([#771][] @petersendidit)\n\n### Changed\n* Documentation improvements\n\n[6.1.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.1.1...v6.1.2\n[#771]: https://github.com/jsx-eslint/eslint-plugin-react/issues/771\n\n## [6.1.1] - 2016-08-16\n### Fixed\n* Fix [`prop-types`][] on annotated components ([#766][])\n* Fix [`no-danger-with-children`][] spread support ([#767][] @petersendidit)\n\n### Changed\n* Documentation improvements ([#769][] @daltones)\n\n[6.1.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.1.0...v6.1.1\n[#766]: https://github.com/jsx-eslint/eslint-plugin-react/issues/766\n[#767]: https://github.com/jsx-eslint/eslint-plugin-react/issues/767\n[#769]: https://github.com/jsx-eslint/eslint-plugin-react/pull/769\n\n## [6.1.0] - 2016-08-14\n### Added\n* Add `React.PureComponent` support ([#737][])\n* Add [`forbid-component-props`][] rule ([#314][] @lencioni)\n* Add [`no-danger-with-children`][] rule ([#710][] @petersendidit)\n* Add pragma for `createClass` factory method ([#725][] @zurawiki)\n\n### Fixed\n* Fix Node.js 0.10 support ([#746][])\n* Fix [`prop-types`][] on annotated components ([#729][])\n* Fix [`require-optimization`][] test for function declaration ([#744][] @Tom910)\n* Fix [`jsx-uses-vars`][] to handle nested object properties ([#761][] @yayalice)\n* Fix rules metadata\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#759][] @embrown, [#703][] [#753][] @lencioni, [#739][] @ljharb, [#731][] @wKich, [#745][] @petersendidit, [#659][] @dguo)\n\n[6.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v6.0.0...v6.1.0\n[#737]: https://github.com/jsx-eslint/eslint-plugin-react/issues/737\n[#710]: https://github.com/jsx-eslint/eslint-plugin-react/issues/710\n[#725]: https://github.com/jsx-eslint/eslint-plugin-react/pull/725\n[#746]: https://github.com/jsx-eslint/eslint-plugin-react/issues/746\n[#729]: https://github.com/jsx-eslint/eslint-plugin-react/issues/729\n[#744]: https://github.com/jsx-eslint/eslint-plugin-react/pull/744\n[#761]: https://github.com/jsx-eslint/eslint-plugin-react/pull/761\n[#759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/759\n[#703]: https://github.com/jsx-eslint/eslint-plugin-react/pull/703\n[#753]: https://github.com/jsx-eslint/eslint-plugin-react/pull/753\n[#739]: https://github.com/jsx-eslint/eslint-plugin-react/issues/739\n[#731]: https://github.com/jsx-eslint/eslint-plugin-react/pull/731\n[#745]: https://github.com/jsx-eslint/eslint-plugin-react/pull/745\n[#659]: https://github.com/jsx-eslint/eslint-plugin-react/pull/659\n[#314]: https://github.com/jsx-eslint/eslint-plugin-react/pull/314\n\n## [6.0.0] - 2016-08-01\n### Added\n* Add an `all` shareable configuration with all rules enabled ([#674][] @pfhayes)\n* Add [`no-find-dom-node`][] rule ([#678][])\n* Add `shorthandLast` option to [`jsx-sort-props`][] ([#391][] @mathieumg)\n* Add `allowDecorators` option to [`require-optimization`][] ([#669][] @Tom910)\n\n### Breaking\n* Deprecate [`require-extension`][] rule, use the [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) [`extensions`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md) rule instead. [`require-extension`][] still works but will trigger a warning\n* Enable `allow-in-func` mode by default in [`no-did-mount-set-state`][] and [`no-did-update-set-state`][] rules ([#702][] @lencioni)\n* Enable html tags check by default in `self-closing-comp`\n* Remove `pragma` option from `jsx-uses-react`, use the [shared settings](README.md#configuration) to specify a custom pragma ([#700][] @lencioni)\n* Remove `react` option from [`no-deprecated`][] rule, use the [shared settings](README.md#configuration) to specify the React version ([#700][] @lencioni)\n* Add [`require-render-return`][] rule to recommended rules\n* Remove [`no-danger`][] from recommended rules ([#636][] @mjackson)\n* Remove [`no-did-mount-set-state`][] and [`no-did-update-set-state`][] from recommended rules ([#596][])\n* Remove deprecated [`jsx-sort-prop-types`][] rule, use [`sort-prop-types`][] instead ([#549][] @lencioni)\n* Rename [`no-comment-textnodes`][] to [`jsx-no-comment-textnodes`][]. [`no-comment-textnodes`][] still works but will trigger a warning ([#668][] @lencioni)\n* Rename [`wrap-multilines`][] to [`jsx-wrap-multilines`][]. [`wrap-multilines`][] still works but will trigger a warning ([#668][] @lencioni)\n* Add ESLint as peerDependency ([#657][] @jokeyrhyme)\n* Add Node.js 0.10 as minimum required version ([#657][] @jokeyrhyme)\n\n### Fixed\n* Fix [`jsx-handler-names`][] incorrectly flagging `only` ([#571][] @lencioni)\n* Fix spread props cash in [`jsx-no-target-blank`][] ([#679][] @randycoulman)\n* Fix [`require-optimization`][] warning on stateless components ([#687][])\n* Fix [`jsx-uses-vars`][] that incorrectly marked some variables as used ([#694][] @lencioni)\n* Fix [`no-unknown-property`][] check on SVG attributes ([#718][])\n* Fix [`jsx-no-bind`][] reporting errors on render functions that don't return JSX ([#663][] @petersendidit)\n* Fix [`jsx-closing-bracket-location`][] autofix when `location` is set to `props-aligned` ([#684][] @pfhayes)\n* Fix [`prop-types`][] for destructured arguments being assigned to the parent stateless component in some cases ([#698][])\n* Fix [`prop-types`][] for JSX return being assigned to the parent function in some cases ([#504][])\n* Fix [`jsx-curly-spacing`][] for reporting on JSX content by mistake ([#671][])\n* Fix [`prop-types`][] crash when accessing constructor on props ([#654][])\n* Fix [`jsx-filename-extension`][] to not check filenames on text input ([#662][] @ljharb)\n* Fix [`jsx-no-comment-textnodes`][] incorrectly catching urls ([#664][] @petersendidit)\n\n### Changed\n* Only report [`jsx-filename-extension`][] warning once per file ([#660][] @mathieumg)\n* Update SVG and DOM attribute list for `no-unknown-property`\n* Update rules to use the new ESLint rule format ([#661][] @petersendidit)\n* Update dependencies\n* Documentation improvements ([#724][] @lencioni)\n* Update Travis CI and AppVeyor CI configurations (@ljharb)\n\n[6.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.2.2...v6.0.0\n[#571]: https://github.com/jsx-eslint/eslint-plugin-react/issues/571\n[#728]: https://github.com/jsx-eslint/eslint-plugin-react/pull/728\n[#679]: https://github.com/jsx-eslint/eslint-plugin-react/pull/679\n[#687]: https://github.com/jsx-eslint/eslint-plugin-react/issues/687\n[#694]: https://github.com/jsx-eslint/eslint-plugin-react/issues/694\n[#718]: https://github.com/jsx-eslint/eslint-plugin-react/issues/718\n[#723]: https://github.com/jsx-eslint/eslint-plugin-react/pull/723\n[#702]: https://github.com/jsx-eslint/eslint-plugin-react/pull/702\n[#700]: https://github.com/jsx-eslint/eslint-plugin-react/pull/700\n[#636]: https://github.com/jsx-eslint/eslint-plugin-react/pull/636\n[#596]: https://github.com/jsx-eslint/eslint-plugin-react/issues/596\n[#661]: https://github.com/jsx-eslint/eslint-plugin-react/issues/661\n[#724]: https://github.com/jsx-eslint/eslint-plugin-react/pull/724\n[#674]: https://github.com/jsx-eslint/eslint-plugin-react/issues/674\n[#678]: https://github.com/jsx-eslint/eslint-plugin-react/issues/678\n[#391]: https://github.com/jsx-eslint/eslint-plugin-react/issues/391\n[#669]: https://github.com/jsx-eslint/eslint-plugin-react/pull/669\n[#663]: https://github.com/jsx-eslint/eslint-plugin-react/issues/663\n[#684]: https://github.com/jsx-eslint/eslint-plugin-react/pull/684\n[#698]: https://github.com/jsx-eslint/eslint-plugin-react/issues/698\n[#504]: https://github.com/jsx-eslint/eslint-plugin-react/issues/504\n[#671]: https://github.com/jsx-eslint/eslint-plugin-react/issues/671\n[#549]: https://github.com/jsx-eslint/eslint-plugin-react/issues/549\n[#668]: https://github.com/jsx-eslint/eslint-plugin-react/issues/668\n[#660]: https://github.com/jsx-eslint/eslint-plugin-react/pull/660\n[#654]: https://github.com/jsx-eslint/eslint-plugin-react/issues/654\n[#662]: https://github.com/jsx-eslint/eslint-plugin-react/issues/662\n[#664]: https://github.com/jsx-eslint/eslint-plugin-react/issues/664\n[#657]: https://github.com/jsx-eslint/eslint-plugin-react/pull/657\n\n## [5.2.2] - 2016-06-17\n### Fixed\n* Fix [`jsx-no-bind`][] crash ([#641][])\n\n[5.2.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.2.1...v5.2.2\n[#641]: https://github.com/jsx-eslint/eslint-plugin-react/issues/641\n\n## [5.2.1] - 2016-06-17\n### Fixed\n* Fix [`jsx-pascal-case`][] for namespaced components ([#637][] @evcohen)\n\n[5.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.2.0...v5.2.1\n[#637]: https://github.com/jsx-eslint/eslint-plugin-react/issues/637\n\n## [5.2.0] - 2016-06-17\n### Added\n* Add [`require-optimization`][] rule ([#240][] @EvNaverniouk)\n* Add [`jsx-filename-extension`][] rule  ([#495][] @lencioni)\n* Add [`no-render-return-value`][] rule ([#531][] @iamdustan)\n* Add [`no-comment-textnodes`][] rule ([#616][] @benvinegar)\n* Add `objectLiterals` option to [`jsx-curly-spacing`][] ([#388][], [#211][] @casesandberg @ljharb)\n* Add option to [`self-closing-comp`][] to check html tags ([#572][] @gitim)\n* Add `ignore` option to [`no-unknown-property`][] rule ([#631][] @insin)\n* Add support for ES7 bind operator to [`jsx-handler-names`][] ([#630][])\n* Add support for explicit declaration that class extends React.Component ([#68][] @gausie)\n\n### Fixed\n* Fix [`jsx-closing-bracket-location`][] multiline prop support ([#493][] @tuures)\n* Fix [`prop-types`][] for props that where not assigned to the right component ([#591][])\n* Fix [`display-name`][] when JSON style is used for defining components ([#590][] @gitim)\n* Fix [`jsx-no-bind`][] for bind detection in render when assigned to a variable ([#474][] @petersendidit)\n* Fix [`jsx-curly-spacing`][] for spread operator ([#606][] @gitim)\n* Fix [`sort-comp`][] crash on spread operator ([#624][])\n* Fix [`prop-types`][] crash when destructuring props with spread only\n\n### Changed\n* Update dependencies\n* Add [doctrine](https://github.com/eslint/doctrine) as a dependency ([#68][] @gausie)\n* Add [jsx-ast-utils](https://github.com/evcohen/jsx-ast-utils) as a dependency ([#634][] @evcohen)\n* Documentation improvements ([#594][] @lencioni, [#598][] @mLuby, [#633][] @appsforartists)\n\n[5.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.1.1...v5.2.0\n[#68]: https://github.com/jsx-eslint/eslint-plugin-react/issues/68\n[#211]: https://github.com/jsx-eslint/eslint-plugin-react/issues/211\n[#240]: https://github.com/jsx-eslint/eslint-plugin-react/issues/240\n[#388]: https://github.com/jsx-eslint/eslint-plugin-react/issues/388\n[#474]: https://github.com/jsx-eslint/eslint-plugin-react/issues/474\n[#493]: https://github.com/jsx-eslint/eslint-plugin-react/pull/493\n[#495]: https://github.com/jsx-eslint/eslint-plugin-react/issues/495\n[#531]: https://github.com/jsx-eslint/eslint-plugin-react/issues/531\n[#572]: https://github.com/jsx-eslint/eslint-plugin-react/issues/572\n[#590]: https://github.com/jsx-eslint/eslint-plugin-react/issues/590\n[#591]: https://github.com/jsx-eslint/eslint-plugin-react/issues/591\n[#594]: https://github.com/jsx-eslint/eslint-plugin-react/pull/594\n[#598]: https://github.com/jsx-eslint/eslint-plugin-react/pull/598\n[#606]: https://github.com/jsx-eslint/eslint-plugin-react/issues/606\n[#616]: https://github.com/jsx-eslint/eslint-plugin-react/pull/616\n[#624]: https://github.com/jsx-eslint/eslint-plugin-react/issues/624\n[#630]: https://github.com/jsx-eslint/eslint-plugin-react/issues/630\n[#631]: https://github.com/jsx-eslint/eslint-plugin-react/pull/631\n[#633]: https://github.com/jsx-eslint/eslint-plugin-react/pull/633\n[#634]: https://github.com/jsx-eslint/eslint-plugin-react/pull/634\n\n## [5.1.1] - 2016-05-10\n### Fixed\n* Fix [`require-render-return`][] crash ([#589][])\n\n[5.1.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.1.0...v5.1.1\n[#589]: https://github.com/jsx-eslint/eslint-plugin-react/issues/589\n\n## [5.1.0] - 2016-05-10\n### Added\n* Add [`jsx-no-target-blank`][] rule ([#582][] @Gasparila)\n* Add `allowAllCaps` and `ignore` options to [`jsx-pascal-case`][] ([#575][])\n* Add class properties support to [`require-render-return`][] ([#564][])\n\n### Fixed\n* Fix [`jsx-closing-bracket-location`][] fixer ([#533][] @dtinth)\n* Fix [`require-render-return`][] to only check valid render methods ([#563][])\n* Fix detection to allow simple `this` usage in fonctional components ([#576][])\n* Fix [`forbid-prop-types`][] crash ([#579][])\n* Fix comment handling in [`jsx-curly-spacing`][] ([#584][])\n\n### Changed\n* Update dependencies\n* Documentation improvements (@coryhouse, [#581][] @scurker, [#588][])\n\n[5.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.0.1...v5.1.0\n[#582]: https://github.com/jsx-eslint/eslint-plugin-react/pull/582\n[#575]: https://github.com/jsx-eslint/eslint-plugin-react/issues/575\n[#564]: https://github.com/jsx-eslint/eslint-plugin-react/issues/564\n[#533]: https://github.com/jsx-eslint/eslint-plugin-react/issues/533\n[#563]: https://github.com/jsx-eslint/eslint-plugin-react/issues/563\n[#576]: https://github.com/jsx-eslint/eslint-plugin-react/issues/576\n[#579]: https://github.com/jsx-eslint/eslint-plugin-react/issues/579\n[#584]: https://github.com/jsx-eslint/eslint-plugin-react/pull/584\n[#559]: https://github.com/jsx-eslint/eslint-plugin-react/pull/559\n[#581]: https://github.com/jsx-eslint/eslint-plugin-react/pull/581\n[#588]: https://github.com/jsx-eslint/eslint-plugin-react/issues/588\n\n## [5.0.1] - 2016-04-18\n### Fixed\n* Fix [`require-render-return`][] to not check stateless functions ([#550][])\n\n[5.0.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v5.0.0...v5.0.1\n[#550]: https://github.com/jsx-eslint/eslint-plugin-react/issues/550\n\n## [5.0.0] - 2016-04-17\n### Added\n* Add [`jsx-first-prop-new-line`][] rule ([#410][] @jseminck)\n\n### Breaking\n* Update rules for React 15:\n  * Add warnings for `LinkedStateMixin`, `ReactPerf.printDOM` and `ReactPerf.getMeasurementsSummaryMap` in `no-deprecated`\n  * Allow stateless components to return `null` in [`prefer-stateless-function`][]\n  * Remove SVG attributes warnings ([#490][])\n\nIf you're still not using React 15 you can keep the old behavior by setting the React version to `0.14` in the [shared settings](README.md#configuration).\n\n### Fixed\n* Rewrite [`require-render-return`][] rule ([#542][], [#543][])\n* Fix [`prefer-stateless-function`][] crash ([#544][])\n* Fix external propTypes handling ([#545][])\n* Do not mark inline functions in JSX as components ([#546][])\n\n### Changed\n* Update dependencies\n* Documentation improvements\n\n[5.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.3.0...v5.0.0\n[#410]: https://github.com/jsx-eslint/eslint-plugin-react/issues/410\n[#490]: https://github.com/jsx-eslint/eslint-plugin-react/issues/490\n[#542]: https://github.com/jsx-eslint/eslint-plugin-react/issues/542\n[#543]: https://github.com/jsx-eslint/eslint-plugin-react/issues/543\n[#544]: https://github.com/jsx-eslint/eslint-plugin-react/issues/544\n[#545]: https://github.com/jsx-eslint/eslint-plugin-react/issues/545\n[#546]: https://github.com/jsx-eslint/eslint-plugin-react/issues/546\n\n## [4.3.0] - 2016-04-07\n### Added\n* Add [`require-render-return`][] rule ([#482][] @shmuga)\n* Add auto fix for [`jsx-equals-spacing`][] ([#506][] @peet)\n* Add auto fix for [`jsx-closing-bracket-location`][] ([#511][] @KevinGrandon)\n\n### Fixed\n* Fix [`prefer-stateless-function`][] for conditional JSX ([#516][])\n* Fix [`jsx-pascal-case`][] to support single letter component names ([#505][] @dthielman)\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#509][] @coryhouse, [#526][] @ahoym)\n\n[4.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.2.3...v4.3.0\n[#482]: https://github.com/jsx-eslint/eslint-plugin-react/issues/482\n[#506]: https://github.com/jsx-eslint/eslint-plugin-react/pull/506\n[#511]: https://github.com/jsx-eslint/eslint-plugin-react/pull/511\n[#516]: https://github.com/jsx-eslint/eslint-plugin-react/issues/516\n[#505]: https://github.com/jsx-eslint/eslint-plugin-react/issues/505\n[#509]: https://github.com/jsx-eslint/eslint-plugin-react/pull/509\n[#526]: https://github.com/jsx-eslint/eslint-plugin-react/pull/526\n\n## [4.2.3] - 2016-03-15\n### Fixed\n* Fix class properties retrieval in [`prefer-stateless-function`][] ([#499][])\n\n[4.2.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.2.2...v4.2.3\n[#499]: https://github.com/jsx-eslint/eslint-plugin-react/issues/499\n\n## [4.2.2] - 2016-03-14\n### Fixed\n* Rewrite [`prefer-stateless-function`][] rule ([#491][])\n* Fix [`self-closing-comp`][] to treat non-breaking spaces as content ([#496][])\n* Fix detection for direct props in [`prop-types`][] ([#497][])\n* Fix annotated function detection in [`prop-types`][] ([#498][])\n* Fix `this` usage in [`jsx-no-undef`][] ([#489][])\n\n### Changed\n* Update dependencies\n* Add shared setting for React version\n\n[4.2.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.2.1...v4.2.2\n[#491]: https://github.com/jsx-eslint/eslint-plugin-react/issues/491\n[#496]: https://github.com/jsx-eslint/eslint-plugin-react/issues/496\n[#497]: https://github.com/jsx-eslint/eslint-plugin-react/issues/497\n[#498]: https://github.com/jsx-eslint/eslint-plugin-react/issues/498\n[#489]: https://github.com/jsx-eslint/eslint-plugin-react/issues/489\n\n## [4.2.1] - 2016-03-08\n### Fixed\n* Fix [`sort-prop-types`][] crash with spread operator ([#478][])\n* Fix stateless components detection when conditionally returning JSX ([#486][])\n* Fix case where props were not assigned to the right component ([#485][])\n* Fix missing `getChildContext` lifecycle method in [`prefer-stateless-function`][] ([#492][])\n\n[4.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.2.0...v4.2.1\n[#478]: https://github.com/jsx-eslint/eslint-plugin-react/issues/478\n[#486]: https://github.com/jsx-eslint/eslint-plugin-react/issues/486\n[#485]: https://github.com/jsx-eslint/eslint-plugin-react/issues/485\n[#492]: https://github.com/jsx-eslint/eslint-plugin-react/issues/492\n\n## [4.2.0] - 2016-03-05\n### Added\n* Add support for Flow annotations on stateless components ([#467][])\n* Add [`prefer-stateless-function`][] rule ([#214][])\n* Add auto fix for [`jsx-indent-props`][] ([#483][] @shioju)\n\n### Fixed\n* Fix [`jsx-no-undef`][] crash on objects ([#469][])\n* Fix propTypes detection when declared before the component ([#472][])\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#464][] @alex-tan, [#466][] @awong-dev, [#470][] @Gpx; [#462][] @thaggie)\n\n[4.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.1.0...v4.2.0\n[#467]: https://github.com/jsx-eslint/eslint-plugin-react/issues/467\n[#214]: https://github.com/jsx-eslint/eslint-plugin-react/issues/214\n[#483]: https://github.com/jsx-eslint/eslint-plugin-react/pull/483\n[#469]: https://github.com/jsx-eslint/eslint-plugin-react/issues/469\n[#472]: https://github.com/jsx-eslint/eslint-plugin-react/issues/472\n[#464]: https://github.com/jsx-eslint/eslint-plugin-react/pull/464\n[#466]: https://github.com/jsx-eslint/eslint-plugin-react/pull/466\n[#470]: https://github.com/jsx-eslint/eslint-plugin-react/pull/470\n[#462]: https://github.com/jsx-eslint/eslint-plugin-react/pull/462\n\n## [4.1.0] - 2016-02-23\n### Added\n* Add component detection for class expressions\n* Add displayName detection for class expressions in [`display-name`][] ([#419][])\n\n### Fixed\n* Fix used props detection in components for which we are not confident in [`prop-types`][] ([#420][])\n* Fix false positive in [`jsx-key`][] ([#456][] @jkimbo)\n\n### Changed\n* Documentation improvements ([#457][] @wyze)\n\n[4.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v4.0.0...v4.1.0\n[#419]: https://github.com/jsx-eslint/eslint-plugin-react/issues/419\n[#420]: https://github.com/jsx-eslint/eslint-plugin-react/issues/420\n[#456]: https://github.com/jsx-eslint/eslint-plugin-react/pull/456\n[#457]: https://github.com/jsx-eslint/eslint-plugin-react/pull/457\n\n## [4.0.0] - 2016-02-19\n### Added\n* Add [`jsx-space-before-closing`][] rule ([#244][] @ryym)\n* Add support for destructing in function signatures to [`prop-types`][] ([#354][] @lencioni)\n\n### Breaking\n* Add support for static methods to `sort-comp`. Static methods must now be declared first, see [rule documentation](docs/rules/sort-comp.md) ([#128][] @lencioni)\n* Add shareable config in place of default configuration. [`jsx-uses-vars`][] is not enabled by default anymore, see [documentation](README.md#recommended-configuration) ([#192][])\n* Rename `jsx-sort-prop-types` to [`sort-prop-types`][]. `jsx-sort-prop-types` still works but will trigger a warning ([#87][] @lencioni)\n* Remove deprecated `jsx-quotes` rule ([#433][] @lencioni)\n* [`display-name`][] now accept the transpiler name by default. You can use the `ignoreTranspilerName` option to get the old behavior, see [rule documentation](docs/rules/display-name.md#ignoretranspilername) ([#440][] @lencioni)\n\n### Fixed\n* Only ignore lowercase JSXIdentifier in [`jsx-no-undef`][] ([#435][])\n* Fix [`jsx-handler-names`][] regex ([#425][])\n* Fix destructured props detection in [`prop-types`][] ([#443][])\n\n### Changed\n* Update dependencies ([#426][] @quentin-)\n* Documentation improvements ([#414][] @vkrol, [#370][] @tmcw, [#441][] [#429][] @lencioni, [#432][] @note89, [#438][] @jmann6)\n\n[4.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.16.1...v4.0.0\n[#244]: https://github.com/jsx-eslint/eslint-plugin-react/issues/244\n[#354]: https://github.com/jsx-eslint/eslint-plugin-react/issues/354\n[#128]: https://github.com/jsx-eslint/eslint-plugin-react/issues/128\n[#192]: https://github.com/jsx-eslint/eslint-plugin-react/issues/192\n[#87]: https://github.com/jsx-eslint/eslint-plugin-react/issues/87\n[#440]: https://github.com/jsx-eslint/eslint-plugin-react/pull/440\n[#435]: https://github.com/jsx-eslint/eslint-plugin-react/issues/435\n[#425]: https://github.com/jsx-eslint/eslint-plugin-react/issues/425\n[#443]: https://github.com/jsx-eslint/eslint-plugin-react/issues/443\n[#426]: https://github.com/jsx-eslint/eslint-plugin-react/pull/426\n[#414]: https://github.com/jsx-eslint/eslint-plugin-react/pull/414\n[#370]: https://github.com/jsx-eslint/eslint-plugin-react/pull/370\n[#441]: https://github.com/jsx-eslint/eslint-plugin-react/pull/441\n[#429]: https://github.com/jsx-eslint/eslint-plugin-react/pull/429\n[#432]: https://github.com/jsx-eslint/eslint-plugin-react/pull/432\n[#438]: https://github.com/jsx-eslint/eslint-plugin-react/pull/438\n[#433]: https://github.com/jsx-eslint/eslint-plugin-react/pull/433\n\n## [3.16.1] - 2016-01-24\n### Fixed\n* Fix [`jsx-sort-prop-types`][] issue with custom propTypes ([#408][] @alitaheri)\n\n[3.16.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.16.0...v3.16.1\n[#408]: https://github.com/jsx-eslint/eslint-plugin-react/issues/408\n\n## [3.16.0] - 2016-01-24\n### Added\n* Add [`jsx-equals-spacing`][] rule ([#394][] @ryym)\n* Add auto fix for `wrap-multiline`\n* Add auto fix for `jsx-boolean-value`\n* Add auto fix for `no-unknown-property`\n* Add auto fix for [`jsx-curly-spacing`][] ([#407][] @ewendel)\n* Add `requiredFirst` option to [`jsx-sort-prop-types`][] ([#392][] @chrislaskey)\n* Add `ignoreRefs` option to [`jsx-no-bind`][] ([#330][] @silvenon)\n\n### Fixed\n* Ignore `ref` in [`jsx-handler-names`][] (again) ([#396][])\n\n### Changed\n* Update dependencies\n\n[3.16.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.15.0...v3.16.0\n[#394]: https://github.com/jsx-eslint/eslint-plugin-react/issues/394\n[#407]: https://github.com/jsx-eslint/eslint-plugin-react/pull/407\n[#392]: https://github.com/jsx-eslint/eslint-plugin-react/pull/392\n[#330]: https://github.com/jsx-eslint/eslint-plugin-react/issues/330\n[#396]: https://github.com/jsx-eslint/eslint-plugin-react/issues/396\n\n## [3.15.0] - 2016-01-12\n### Added\n* Add support for flow annotations to [`prop-types`][] ([#382][] @phpnode)\n\n### Fixed\n* Fix [`prop-types`][] crash when initializing class variable with an empty object ([#383][])\n* Fix [`prop-types`][] crash when propTypes are using the spread operator ([#389][])\n\n### Changed\n* Improve [`sort-comp`][] error messages ([#372][] @SystemParadox)\n* Update dependencies\n\n[3.15.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.14.0...v3.15.0\n[#382]: https://github.com/jsx-eslint/eslint-plugin-react/pull/382\n[#383]: https://github.com/jsx-eslint/eslint-plugin-react/issues/383\n[#389]: https://github.com/jsx-eslint/eslint-plugin-react/issues/389\n[#372]: https://github.com/jsx-eslint/eslint-plugin-react/pull/372\n\n## [3.14.0] - 2016-01-05\n### Added\n* Add [`jsx-indent`][] rule ([#342][])\n* Add shared setting for pragma configuration ([#228][] @NickStefan)\n\n### Fixed\n* Fix crash in [`jsx-key`][] ([#380][] @nfcampos)\n* Fix crash in [`forbid-prop-types`][] ([#377][] @nfcampos)\n* Ignore `ref` in [`jsx-handler-names`][] ([#375][])\n\n### Changed\n* Add AppVeyor CI to run tests on a Windows platform\n* Add [`sort-comp`][] codemod to [`sort-comp`][] documentation ([#381][] @turadg)\n\n[3.14.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.13.1...v3.14.0\n[#342]: https://github.com/jsx-eslint/eslint-plugin-react/issues/342\n[#228]: https://github.com/jsx-eslint/eslint-plugin-react/issues/228\n[#380]: https://github.com/jsx-eslint/eslint-plugin-react/pull/380\n[#377]: https://github.com/jsx-eslint/eslint-plugin-react/pull/377\n[#375]: https://github.com/jsx-eslint/eslint-plugin-react/issues/375\n[#381]: https://github.com/jsx-eslint/eslint-plugin-react/pull/381\n\n## [3.13.1] - 2015-12-26\n### Fixed\n* Fix crash in [`jsx-key`][] ([#373][] @lukekarrys)\n\n[3.13.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.13.0...v3.13.1\n[#373]: https://github.com/jsx-eslint/eslint-plugin-react/issues/373\n\n## [3.13.0] - 2015-12-24\n### Added\n* Add [`no-string-refs`][] rule ([#341][] @Intellicode)\n* Add support for propTypes assigned via a variable in [`prop-types`][] ([#355][])\n\n### Fixed\n* Fix `never` option in [`prefer-es6-class`][]\n* Fix [`jsx-key`][] false-positives ([#320][] @silvenon)\n\n### Changed\n* Documentation improvements ([#368][] @lencioni, [#370][] @tmcw, [#371][])\n* Update dependencies\n\n[3.13.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.12.0...v3.13.0\n[#341]: https://github.com/jsx-eslint/eslint-plugin-react/issues/341\n[#355]: https://github.com/jsx-eslint/eslint-plugin-react/issues/355\n[#320]: https://github.com/jsx-eslint/eslint-plugin-react/issues/320\n\n[#368]: https://github.com/jsx-eslint/eslint-plugin-react/pull/368\n[#370]: https://github.com/jsx-eslint/eslint-plugin-react/pull/370\n[#371]: https://github.com/jsx-eslint/eslint-plugin-react/issues/371\n\n## [3.12.0] - 2015-12-20\n### Added\n* Add [`no-deprecated`][] rule ([#356][] @graue)\n* Add [`no-is-mounted`][] rule ([#37][] @lencioni)\n* Add `never` option to [`prefer-es6-class`][] rule ([#359][] @pwmckenna)\n\n### Fixed\n* Fix [`jsx-pascal-case`][] to stop checking lower cased components ([#329][])\n* Fix crash in component detection class ([#364][])\n\n### Changed\n* Add link to [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native) in Readme\n* Update dependencies\n\n[3.12.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.11.3...v3.12.0\n[#356]: https://github.com/jsx-eslint/eslint-plugin-react/pull/356\n[#37]: https://github.com/jsx-eslint/eslint-plugin-react/issues/37\n[#359]: https://github.com/jsx-eslint/eslint-plugin-react/pull/359\n[#329]: https://github.com/jsx-eslint/eslint-plugin-react/issues/329\n[#364]: https://github.com/jsx-eslint/eslint-plugin-react/issues/364\n\n## [3.11.3] - 2015-12-05\n### Fixed\n* Fix crash in [`prop-types`][] when reassigning props ([#345][])\n* Fix [`jsx-handler-names`][] for stateless components ([#346][])\n\n### Changed\n* Update [`jsx-handler-names`][] error messages to be less specific ([#348][] @jakemmarsh)\n\n[3.11.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.11.2...v3.11.3\n[#345]: https://github.com/jsx-eslint/eslint-plugin-react/issues/345\n[#346]: https://github.com/jsx-eslint/eslint-plugin-react/issues/346\n[#348]: https://github.com/jsx-eslint/eslint-plugin-react/pull/348\n\n## [3.11.2] - 2015-12-01\n### Fixed\n* Allow numbers in [`jsx-pascal-case`][] ([#339][])\n* Fix [`jsx-handler-names`][] crash with arrays ([#340][])\n\n### Changed\n* Add `allow-in-func` option to [`no-did-update-set-state`][] documentation\n\n[3.11.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.11.1...v3.11.2\n[#339]: https://github.com/jsx-eslint/eslint-plugin-react/issues/339\n[#340]: https://github.com/jsx-eslint/eslint-plugin-react/issues/340\n\n## [3.11.1] - 2015-11-29\n### Fixed\n* Fix SVG attributes support for [`no-unknown-property`][] ([#338][])\n\n[3.11.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.11.0...v3.11.1\n[#338]: https://github.com/jsx-eslint/eslint-plugin-react/issues/338\n\n## [3.11.0] - 2015-11-29\n### Added\n* Add [`jsx-handler-names`][] rule ([#315][] @jakemmarsh)\n* Add SVG attributes support to [`no-unknown-property`][] ([#318][])\n* Add shorthandFirst option to [`jsx-sort-props`][] ([#336][] @lucasmotta)\n\n### Fixed\n* Fix destructured props detection in stateless components ([#326][])\n* Fix props validation for nested stateless components ([#331][])\n* Fix [`require-extension`][] to ignore extension if it's part of the package name ([#319][])\n\n### Changed\n* Allow consecutive uppercase letters in [`jsx-pascal-case`][] ([#328][] @lencioni)\n* Update dependencies\n\n[3.11.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.10.0...v3.11.0\n[#315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/315\n[#318]: https://github.com/jsx-eslint/eslint-plugin-react/issues/318\n[#336]: https://github.com/jsx-eslint/eslint-plugin-react/pull/336\n[#326]: https://github.com/jsx-eslint/eslint-plugin-react/issues/326\n[#331]: https://github.com/jsx-eslint/eslint-plugin-react/issues/331\n[#319]: https://github.com/jsx-eslint/eslint-plugin-react/issues/319\n[#328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/328\n\n## [3.10.0] - 2015-11-21\n### Added\n* Add [`jsx-pascal-case`][] rule ([#306][] @jakemmarsh)\n\n### Fixed\n* Fix crash on incomplete class property declaration ([#317][] @dapetcu21)\n* Fix crash with ESLint 1.10.0 ([#323][] @lukekarrys)\n\n[3.10.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.9.0...v3.10.0\n[#306]: https://github.com/jsx-eslint/eslint-plugin-react/pull/306\n[#317]: https://github.com/jsx-eslint/eslint-plugin-react/issues/317\n[#323]: https://github.com/jsx-eslint/eslint-plugin-react/issues/323\n\n## [3.9.0] - 2015-11-17\n### Added\n* Add [`jsx-key`][] rule ([#293][] @benmosher)\n* Add `allow-in-func` option to [`no-did-update-set-state`][] ([#300][])\n* Add option to only enforce [`jsx-closing-bracket-location`][] rule to one type of tag (nonEmpty or selfClosing) ([#307][])\n\n### Fixed\n* Fix crash when destructuring with only the rest spread ([#269][])\n* Fix variables detection when searching for related components ([#303][])\n* Fix [`no-unknown-property`][] to not check custom elements ([#308][] @zertosh)\n\n### Changed\n* Improve [`jsx-closing-bracket-location`][] error message ([#301][] @alopatin)\n* Update dependencies\n\n[3.9.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.8.0...v3.9.0\n[#293]: https://github.com/jsx-eslint/eslint-plugin-react/pull/293\n[#300]: https://github.com/jsx-eslint/eslint-plugin-react/issues/300\n[#307]: https://github.com/jsx-eslint/eslint-plugin-react/issues/307\n[#269]: https://github.com/jsx-eslint/eslint-plugin-react/issues/269\n[#303]: https://github.com/jsx-eslint/eslint-plugin-react/issues/303\n[#308]: https://github.com/jsx-eslint/eslint-plugin-react/pull/308\n[#301]: https://github.com/jsx-eslint/eslint-plugin-react/pull/301\n\n## [3.8.0] - 2015-11-07\n### Added\n* Add ignoreStateless option to [`no-multi-comp`][] ([#290][])\n\n### Fixed\n* Fix classes with properties to always be marked as components ([#291][])\n* Fix ES5 class detection when using `createClass` by itself ([#297][])\n* Fix direct props detection ([#298][])\n* Ignore functions containing the keyword `this` during component detection\n\n[3.8.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.7.1...v3.8.0\n[#290]: https://github.com/jsx-eslint/eslint-plugin-react/issues/290\n[#291]: https://github.com/jsx-eslint/eslint-plugin-react/issues/291\n[#297]: https://github.com/jsx-eslint/eslint-plugin-react/issues/297\n[#298]: https://github.com/jsx-eslint/eslint-plugin-react/issues/298\n\n## [3.7.1] - 2015-11-05\n### Fixed\n* Fix [`sort-comp`][] crash on stateless components ([#285][])\n* Fix crash in ES5 components detection ([#286][])\n* Fix ES5 components detection from nested functions ([#287][])\n\n[3.7.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.7.0...v3.7.1\n[#285]: https://github.com/jsx-eslint/eslint-plugin-react/issues/285\n[#286]: https://github.com/jsx-eslint/eslint-plugin-react/issues/286\n[#287]: https://github.com/jsx-eslint/eslint-plugin-react/issues/287\n\n## [3.7.0] - 2015-11-05\n### Added\n* Add [`jsx-no-bind`][] rule ([#184][] @Daniel15)\n* Add line-aligned option to [`jsx-closing-bracket-location`][] ([#243][] @alopatin)\n\n### Fixed\n* Fix a lot of issues about components detection, mostly related to stateless components ([#264][], [#267][], [#268][], [#276][], [#277][], [#280][])\n\n### Changed\n* Update dependencies\n\n[3.7.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.6.3...v3.7.0\n[#184]: https://github.com/jsx-eslint/eslint-plugin-react/issues/184\n[#243]: https://github.com/jsx-eslint/eslint-plugin-react/issues/243\n[#264]: https://github.com/jsx-eslint/eslint-plugin-react/issues/264\n[#267]: https://github.com/jsx-eslint/eslint-plugin-react/issues/267\n[#268]: https://github.com/jsx-eslint/eslint-plugin-react/issues/268\n[#276]: https://github.com/jsx-eslint/eslint-plugin-react/issues/276\n[#277]: https://github.com/jsx-eslint/eslint-plugin-react/issues/277\n[#280]: https://github.com/jsx-eslint/eslint-plugin-react/issues/280\n\n## [3.6.3] - 2015-10-20\n### Fixed\n* Fix [`display-name`][] for stateless components ([#256][])\n* Fix [`prop-types`][] props validation in constructor ([#259][])\n* Fix typo in README ([#261][] @chiedojohn)\n\n[3.6.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.6.2...v3.6.3\n[#256]: https://github.com/jsx-eslint/eslint-plugin-react/issues/256\n[#259]: https://github.com/jsx-eslint/eslint-plugin-react/issues/259\n[#261]: https://github.com/jsx-eslint/eslint-plugin-react/pull/261\n\n## [3.6.2] - 2015-10-18\n### Fixed\n* Fix wrong prop-types detection ([#255][])\n\n[3.6.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.6.1...v3.6.2\n[#255]: https://github.com/jsx-eslint/eslint-plugin-react/issues/255\n\n## [3.6.1] - 2015-10-18\n### Fixed\n* Fix props validation in constructor ([#254][])\n\n[3.6.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.6.0...v3.6.1\n[#254]: https://github.com/jsx-eslint/eslint-plugin-react/issues/254\n\n## [3.6.0] - 2015-10-18\n### Added\n* Add support for stateless function components to [`display-name`][] and [`prop-types`][] ([#237][])\n* Add callbacksLast option to [`jsx-sort-props`][] and [`jsx-sort-prop-types`][] ([#242][] @Daniel15)\n* Add [`prefer-es6-class`][] rule ([#247][] @hamiltondanielb)\n\n### Fixed\n* Fix [`forbid-prop-types`][] crash with destructured PropTypes ([#230][] @epmatsw)\n* Fix [`forbid-prop-types`][] to do not modify AST directly ([#249][] @rhysd)\n* Fix [`prop-types`][] crash with empty destructuring ([#251][])\n* Fix [`prop-types`][] to not validate computed keys in destructuring ([#236][])\n\n### Changed\n* Update dependencies\n* Improve components detection ([#233][])\n* Documentation improvements ([#248][] @dguo)\n\n[3.6.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.5.1...v3.6.0\n[#237]: https://github.com/jsx-eslint/eslint-plugin-react/issues/237\n[#242]: https://github.com/jsx-eslint/eslint-plugin-react/pull/242\n[#247]: https://github.com/jsx-eslint/eslint-plugin-react/issues/247\n[#230]: https://github.com/jsx-eslint/eslint-plugin-react/issues/230\n[#249]: https://github.com/jsx-eslint/eslint-plugin-react/issues/249\n[#251]: https://github.com/jsx-eslint/eslint-plugin-react/issues/251\n[#236]: https://github.com/jsx-eslint/eslint-plugin-react/issues/236\n[#233]: https://github.com/jsx-eslint/eslint-plugin-react/issues/233\n[#248]: https://github.com/jsx-eslint/eslint-plugin-react/pull/248\n\n## [3.5.1] - 2015-10-01\n### Fixed\n* Fix [`no-direct-mutation-state`][] to report only in React components ([#229][])\n* Fix [`forbid-prop-types`][] for arrayOf and instanceOf ([#230][])\n\n### Changed\n* Documentation improvements ([#232][] @edge)\n\n[3.5.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.5.0...v3.5.1\n[#229]: https://github.com/jsx-eslint/eslint-plugin-react/issues/229\n[#230]: https://github.com/jsx-eslint/eslint-plugin-react/issues/230\n[#232]: https://github.com/jsx-eslint/eslint-plugin-react/pull/232\n\n## [3.5.0] - 2015-09-28\n### Added\n* Add [`no-direct-mutation-state`][] rule ([#133][], [#201][] @petersendidit)\n* Add [`forbid-prop-types`][] rule ([#215][] @pwmckenna)\n\n### Fixed\n* Fix no-did-mount/update-set-state rules, these rules were not working on ES6 classes\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#222][] @Andersos)\n\n[3.5.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.4.2...v3.5.0\n[#133]: https://github.com/jsx-eslint/eslint-plugin-react/issues/133\n[#201]: https://github.com/jsx-eslint/eslint-plugin-react/issues/201\n[#215]: https://github.com/jsx-eslint/eslint-plugin-react/issues/215\n[#222]: https://github.com/jsx-eslint/eslint-plugin-react/pull/222\n\n## [3.4.2] - 2015-09-18\n### Fixed\n* Only display the `jsx-quotes` deprecation warning with the default formatter ([#221][])\n\n[3.4.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.4.1...v3.4.2\n[#221]: https://github.com/jsx-eslint/eslint-plugin-react/issues/221\n\n## [3.4.1] - 2015-09-17\n### Fixed\n* Fix `jsx-quotes` rule deprecation message ([#220][])\n\n[3.4.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.4.0...v3.4.1\n[#220]: https://github.com/jsx-eslint/eslint-plugin-react/issues/220\n\n## [3.4.0] - 2015-09-16\n### Added\n* Add namespaced JSX support to [`jsx-no-undef`][] ([#219][] @zertosh)\n* Add option to [`jsx-closing-bracket-location`][] to configure different styles for self-closing and non-empty tags ([#208][] @evocateur)\n\n### Deprecated\n* Deprecate `jsx-quotes` rule, will now trigger a warning if used ([#217][])\n\n[3.4.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.3.2...v3.4.0\n[#219]: https://github.com/jsx-eslint/eslint-plugin-react/pull/219\n[#208]: https://github.com/jsx-eslint/eslint-plugin-react/pull/208\n[#217]: https://github.com/jsx-eslint/eslint-plugin-react/issues/217\n\n## [3.3.2] - 2015-09-10\n### Changed\n* Add `state` in lifecycle methods for [`sort-comp`][] rule ([#197][] @mathieudutour)\n* Treat component with render which returns `createElement` as valid ([#206][] @epmatsw)\n\n### Fixed\n* Fix allowed methods on arrayOf in [`prop-types`][] ([#146][])\n* Fix default configuration for [`jsx-boolean-value`][] ([#210][])\n\n[3.3.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.3.1...v3.3.2\n[#146]: https://github.com/jsx-eslint/eslint-plugin-react/issues/146\n[#197]: https://github.com/jsx-eslint/eslint-plugin-react/pull/197\n[#206]: https://github.com/jsx-eslint/eslint-plugin-react/pull/206\n[#210]: https://github.com/jsx-eslint/eslint-plugin-react/issues/210\n\n## [3.3.1] - 2015-09-01\n### Changed\n* Update dependencies\n* Update changelog to follow the Keep a CHANGELOG standards\n* Documentation improvements ([#198][] @lencioni)\n\n### Fixed\n* Fix [`jsx-closing-bracket-location`][] for multiline props ([#199][])\n\n[3.3.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.3.0...v3.3.1\n[#198]: https://github.com/jsx-eslint/eslint-plugin-react/pull/198\n[#199]: https://github.com/jsx-eslint/eslint-plugin-react/issues/199\n\n## [3.3.0] - 2015-08-26\n### Added\n* Add [`jsx-indent-props`][] rule ([#15][], [#181][])\n* Add `no-set-state rule` ([#197][] @markdalgleish)\n* Add [`jsx-closing-bracket-location`][] rule ([#14][], [#64][])\n\n### Changed\n* Update dependencies\n\n### Fixed\n* Fix crash on propTypes declarations with an empty body ([#193][] @mattyod)\n\n[3.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.2.3...v3.3.0\n[#15]: https://github.com/jsx-eslint/eslint-plugin-react/issues/15\n[#181]: https://github.com/jsx-eslint/eslint-plugin-react/issues/181\n[#197]: https://github.com/jsx-eslint/eslint-plugin-react/pull/197\n[#14]: https://github.com/jsx-eslint/eslint-plugin-react/issues/14\n[#64]: https://github.com/jsx-eslint/eslint-plugin-react/issues/64\n[#193]: https://github.com/jsx-eslint/eslint-plugin-react/pull/193\n\n## [3.2.3] - 2015-08-16\n### Changed\n* Update dependencies\n\n### Fixed\n* Fix object rest/spread handling ([#187][] @xjamundx, [#189][] @Morantron)\n\n[3.2.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.2.2...v3.2.3\n[#187]: https://github.com/jsx-eslint/eslint-plugin-react/pull/187\n[#189]: https://github.com/jsx-eslint/eslint-plugin-react/pull/189\n\n## [3.2.2] - 2015-08-11\n### Changed\n* Remove peerDependencies ([#178][])\n\n[3.2.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.2.1...v3.2.2\n[#178]: https://github.com/jsx-eslint/eslint-plugin-react/issues/178\n\n## [3.2.1] - 2015-08-08\n### Fixed\n* Fix crash when propTypes don't have any parent ([#182][])\n* Fix jsx-no-literals reporting errors outside JSX ([#183][] @CalebMorris)\n\n[3.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.2.0...v3.2.1\n[#182]: https://github.com/jsx-eslint/eslint-plugin-react/issues/182\n[#183]: https://github.com/jsx-eslint/eslint-plugin-react/pull/183\n\n## [3.2.0] - 2015-08-04\n### Added\n* Add [`jsx-max-props-per-line`][] rule ([#13][])\n* Add [`jsx-no-literals`][] rule ([#176][] @CalebMorris)\n\n### Changed\n* Update dependencies\n\n### Fixed\n* Fix object access in [`jsx-no-undef`][] ([#172][])\n\n[3.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.1.0...v3.2.0\n[#13]: https://github.com/jsx-eslint/eslint-plugin-react/issues/13\n[#176]: https://github.com/jsx-eslint/eslint-plugin-react/pull/176\n[#172]: https://github.com/jsx-eslint/eslint-plugin-react/issues/172\n\n## [3.1.0] - 2015-07-28\n### Added\n* Add event handlers to [`no-unknown-property`][] ([#164][] @mkenyon)\n* Add customValidators option to [`prop-types`][] ([#145][] @CalebMorris)\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#167][] @ngbrown)\n\n### Fixed\n* Fix comment handling in [`jsx-curly-spacing`][] ([#165][])\n\n[3.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v3.0.0...v3.1.0\n[#164]: https://github.com/jsx-eslint/eslint-plugin-react/pull/164\n[#145]: https://github.com/jsx-eslint/eslint-plugin-react/issues/145\n[#165]: https://github.com/jsx-eslint/eslint-plugin-react/issues/165\n[#167]: https://github.com/jsx-eslint/eslint-plugin-react/pull/167\n\n## [3.0.0] - 2015-07-21\n### Added\n* Add jsx-no-duplicate-props rule ([#161][] @hummlas)\n* Add allowMultiline option to the [`jsx-curly-spacing`][] rule ([#156][] @mathieumg)\n\n### Breaking\n* In [`jsx-curly-spacing`][] braces spanning multiple lines are now allowed with `never` option ([#156][] @mathieumg)\n\n### Fixed\n* Fix multiple var and destructuring handling in [`prop-types`][] ([#159][])\n* Fix crash when retrieving propType name ([#163][])\n\n[3.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.7.1...v3.0.0\n[#161]: https://github.com/jsx-eslint/eslint-plugin-react/pull/161\n[#156]: https://github.com/jsx-eslint/eslint-plugin-react/pull/156\n[#159]: https://github.com/jsx-eslint/eslint-plugin-react/issues/159\n[#163]: https://github.com/jsx-eslint/eslint-plugin-react/issues/163\n\n## [2.7.1] - 2015-07-16\n### Changed\n* Update peerDependencies requirements ([#154][])\n* Update codebase for ESLint v1.0.0\n* Change oneOfType to actually keep the child types ([#148][] @CalebMorris)\n* Documentation improvements ([#147][] @lencioni)\n\n[2.7.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.7.0...v2.7.1\n[#154]: https://github.com/jsx-eslint/eslint-plugin-react/issues/154\n[#148]: https://github.com/jsx-eslint/eslint-plugin-react/issues/148\n[#147]: https://github.com/jsx-eslint/eslint-plugin-react/pull/147\n\n## [2.7.0] - 2015-07-11\n### Added\n* Add [`no-danger`][] rule ([#138][] @scothis)\n* Add [`jsx-curly-spacing`][] rule ([#142][])\n\n### Fixed\n* Fix properties limitations on propTypes ([#139][])\n* Fix component detection ([#144][])\n\n[2.7.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.6.4...v2.7.0\n[#138]: https://github.com/jsx-eslint/eslint-plugin-react/pull/138\n[#142]: https://github.com/jsx-eslint/eslint-plugin-react/issues/142\n[#139]: https://github.com/jsx-eslint/eslint-plugin-react/issues/139\n[#144]: https://github.com/jsx-eslint/eslint-plugin-react/issues/144\n\n## [2.6.4] - 2015-07-02\n### Fixed\n* Fix simple destructuring handling ([#137][])\n\n[2.6.4]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.6.3...v2.6.4\n[#137]: https://github.com/jsx-eslint/eslint-plugin-react/issues/137\n\n## [2.6.3] - 2015-06-30\n### Fixed\n* Fix ignore option for [`prop-types`][] rule ([#135][])\n* Fix nested props destructuring ([#136][])\n\n[2.6.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.6.2...v2.6.3\n[#135]: https://github.com/jsx-eslint/eslint-plugin-react/issues/135\n[#136]: https://github.com/jsx-eslint/eslint-plugin-react/issues/136\n\n## [2.6.2] - 2015-06-28\n### Fixed\n* Fix props validation when using a prop as an object key ([#132][])\n\n[2.6.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.6.1...v2.6.2\n[#132]: https://github.com/jsx-eslint/eslint-plugin-react/issues/132\n\n## [2.6.1] - 2015-06-28\n### Fixed\n* Fix crash in [`prop-types`][] when encountering an empty variable declaration ([#130][])\n\n[2.6.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.6.0...v2.6.1\n[#130]: https://github.com/jsx-eslint/eslint-plugin-react/issues/130\n\n## [2.6.0] - 2015-06-28\n### Added\n* Add support for nested propTypes ([#62][] [#105][] @Cellule)\n* Add [`require-extension`][] rule ([#117][] @scothis)\n* Add support for computed string format in [`prop-types`][] ([#127][] @Cellule)\n* Add ES6 methods to [`sort-comp`][] default configuration ([#97][] [#122][])\n* Add support for props destructuring directly on the this keyword\n* Add `acceptTranspilerName` option to [`display-name`][] rule ([#75][])\n* Add schema to validate rules options\n\n### Changed\n* Update dependencies\n\n### Fixed\n* Fix test command for Windows ([#114][] @Cellule)\n* Fix detection of missing displayName and propTypes when `ecmaFeatures.jsx` is false ([#119][] @rpl)\n* Fix propTypes destructuring with properties as string ([#118][] @Cellule)\n* Fix [`jsx-sort-prop-types`][] support for keys as string ([#123][] @Cellule)\n* Fix crash if a ClassProperty has only one token ([#125][])\n* Fix invalid class property handling in [`jsx-sort-prop-types`][] ([#129][])\n\n[2.6.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.5.2...v2.6.0\n[#62]: https://github.com/jsx-eslint/eslint-plugin-react/issues/62\n[#105]: https://github.com/jsx-eslint/eslint-plugin-react/issues/105\n[#114]: https://github.com/jsx-eslint/eslint-plugin-react/pull/114\n[#117]: https://github.com/jsx-eslint/eslint-plugin-react/pull/117\n[#119]: https://github.com/jsx-eslint/eslint-plugin-react/pull/119\n[#118]: https://github.com/jsx-eslint/eslint-plugin-react/issues/118\n[#123]: https://github.com/jsx-eslint/eslint-plugin-react/pull/123\n[#125]: https://github.com/jsx-eslint/eslint-plugin-react/issues/125\n[#127]: https://github.com/jsx-eslint/eslint-plugin-react/pull/127\n[#97]: https://github.com/jsx-eslint/eslint-plugin-react/issues/97\n[#122]: https://github.com/jsx-eslint/eslint-plugin-react/issues/122\n[#129]: https://github.com/jsx-eslint/eslint-plugin-react/issues/129\n[#75]: https://github.com/jsx-eslint/eslint-plugin-react/issues/75\n\n## [2.5.2] - 2015-06-14\n### Fixed\n* Fix regression in [`jsx-uses-vars`][] with `babel-eslint` ([#110][])\n\n[2.5.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.5.1...v2.5.2\n[#110]: https://github.com/jsx-eslint/eslint-plugin-react/issues/110\n\n## [2.5.1] - 2015-06-14\n### Changed\n* Update dependencies\n* Documentation improvements ([#99][] @morenoh149)\n\n### Fixed\n* Fix [`prop-types`][] crash when propTypes definition is invalid ([#95][])\n* Fix [`jsx-uses-vars`][] for ES6 classes ([#96][])\n* Fix hasOwnProperty that is taken for a prop ([#102][])\n\n[2.5.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.5.0...v2.5.1\n[#95]: https://github.com/jsx-eslint/eslint-plugin-react/issues/95\n[#96]: https://github.com/jsx-eslint/eslint-plugin-react/issues/96\n[#102]: https://github.com/jsx-eslint/eslint-plugin-react/issues/102\n[#99]: https://github.com/jsx-eslint/eslint-plugin-react/pull/99\n\n## [2.5.0] - 2015-06-04\n### Added\n* Add option to make [`wrap-multilines`][] more granular ([#94][] @PiPeep)\n\n### Changed\n* Update dependencies\n* Documentation improvements ([#92][] [#93][] @lencioni)\n\n[2.5.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.4.0...v2.5.0\n[#94]: https://github.com/jsx-eslint/eslint-plugin-react/pull/94\n[#92]: https://github.com/jsx-eslint/eslint-plugin-react/pull/92\n[#93]: https://github.com/jsx-eslint/eslint-plugin-react/pull/93\n\n## [2.4.0] - 2015-05-30\n### Added\n* Add pragma option to [`jsx-uses-react`][] ([#82][] @dominicbarnes)\n* Add context props to [`sort-comp`][] ([#89][] @zertosh)\n\n### Changed\n* Update dependencies\n* Documentation improvement ([#91][] @matthewwithanm)\n\n### Fixed\n* Fix itemID in [`no-unknown-property`][] rule ([#85][] @cody)\n* Fix license field in package.json ([#90][] @zertosh)\n* Fix usage of contructor in [`sort-comp`][] options ([#88][])\n\n[2.4.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.3.0...v2.4.0\n[#82]: https://github.com/jsx-eslint/eslint-plugin-react/pull/82\n[#89]: https://github.com/jsx-eslint/eslint-plugin-react/pull/89\n[#85]: https://github.com/jsx-eslint/eslint-plugin-react/pull/85\n[#90]: https://github.com/jsx-eslint/eslint-plugin-react/pull/90\n[#88]: https://github.com/jsx-eslint/eslint-plugin-react/issues/88\n[#91]: https://github.com/jsx-eslint/eslint-plugin-react/pull/91\n\n## [2.3.0] - 2015-05-14\n### Added\n* Add [`sort-comp`][] rule ([#39][])\n* Add `allow-in-func` option to [`no-did-mount-set-state`][] ([#56][])\n\n### Changed\n* Update dependencies\n* Improve errors locations for `prop-types`\n\n### Fixed\n* Fix quoted propTypes in ES6 ([#77][])\n\n[2.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.2.0...v2.3.0\n[#39]: https://github.com/jsx-eslint/eslint-plugin-react/issues/39\n[#77]: https://github.com/jsx-eslint/eslint-plugin-react/issues/77\n[#56]: https://github.com/jsx-eslint/eslint-plugin-react/issues/56\n\n## [2.2.0] - 2015-04-22\n### Added\n* Add [`jsx-sort-prop-types`][] rule ([#38][] @AlexKVal)\n\n### Changed\n* Documentation improvements ([#71][] @AlexKVal)\n\n### Fixed\n* Fix variables marked as used when a prop has the same name ([#69][] @burnnat)\n\n[2.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.1.1...v2.2.0\n[#38]: https://github.com/jsx-eslint/eslint-plugin-react/issues/38\n[#69]: https://github.com/jsx-eslint/eslint-plugin-react/pull/69\n[#71]: https://github.com/jsx-eslint/eslint-plugin-react/pull/71\n\n## [2.1.1] - 2015-04-17\n### Added\n* Add support for classes static properties ([#43][])\n* Add tests for the `babel-eslint` parser\n* Add ESLint as peerDependency ([#63][] @AlexKVal)\n\n### Changed\n* Documentation improvements ([#55][] @AlexKVal, [#60][] @chriscalo)\n\n[2.1.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.1.0...v2.1.1\n[#43]: https://github.com/jsx-eslint/eslint-plugin-react/issues/43\n[#63]: https://github.com/jsx-eslint/eslint-plugin-react/pull/63\n[#55]: https://github.com/jsx-eslint/eslint-plugin-react/pull/55\n[#60]: https://github.com/jsx-eslint/eslint-plugin-react/pull/60\n\n## [2.1.0] - 2015-04-06\n### Added\n* Add [`jsx-boolean-value`][] rule ([#11][])\n* Add support for static methods in [`display-name`][] and [`prop-types`][] ([#48][])\n\n### Changed\n* Update [`jsx-sort-props`][] to reset the alphabetical verification on spread ([#47][] @zertosh)\n* Update [`jsx-uses-vars`][] to be enabled by default ([#49][] @banderson)\n\n### Fixed\n* Fix describing comment for hasSpreadOperator() method ([#53][] @AlexKVal)\n\n[2.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.0.2...v2.1.0\n[#47]: https://github.com/jsx-eslint/eslint-plugin-react/pull/47\n[#49]: https://github.com/jsx-eslint/eslint-plugin-react/pull/49\n[#11]: https://github.com/jsx-eslint/eslint-plugin-react/issues/11\n[#48]: https://github.com/jsx-eslint/eslint-plugin-react/issues/48\n[#53]: https://github.com/jsx-eslint/eslint-plugin-react/pull/53\n\n## [2.0.2] - 2015-03-31\n### Fixed\n* Fix ignore rest spread when destructuring props ([#46][])\n* Fix component detection in [`prop-types`][] and [`display-name`][] ([#45][])\n* Fix spread handling in [`jsx-sort-props`][] ([#42][] @zertosh)\n\n[2.0.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.0.1...v2.0.2\n[#46]: https://github.com/jsx-eslint/eslint-plugin-react/issues/46\n[#45]: https://github.com/jsx-eslint/eslint-plugin-react/issues/45\n[#42]: https://github.com/jsx-eslint/eslint-plugin-react/pull/42\n\n## [2.0.1] - 2015-03-30\n### Fixed\n* Fix props detection when used in an object ([#41][])\n\n[2.0.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v2.0.0...v2.0.1\n[#41]: https://github.com/jsx-eslint/eslint-plugin-react/issues/41\n\n## [2.0.0] - 2015-03-29\n### Added\n* Add [`jsx-sort-props`][] rule ([#16][])\n* Add [`no-unknown-property`][] rule ([#28][])\n* Add ignore option to [`prop-types`][] rule\n\n### Changed\n* Update dependencies\n\n### Breaking\n* In [`prop-types`][] the children prop is no longer ignored\n\n### Fixed\n* Fix components are now detected when using ES6 classes ([#24][])\n* Fix [`prop-types`][] now return the right line/column ([#33][])\n* Fix props are now detected when destructuring ([#27][])\n* Fix only check for computed property names in [`prop-types`][] ([#36][] @burnnat)\n\n[2.0.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.6.1...v2.0.0\n[#16]: https://github.com/jsx-eslint/eslint-plugin-react/issues/16\n[#28]: https://github.com/jsx-eslint/eslint-plugin-react/issues/28\n[#24]: https://github.com/jsx-eslint/eslint-plugin-react/issues/24\n[#33]: https://github.com/jsx-eslint/eslint-plugin-react/issues/33\n[#27]: https://github.com/jsx-eslint/eslint-plugin-react/issues/27\n[#36]: https://github.com/jsx-eslint/eslint-plugin-react/pull/36\n\n## [1.6.1] - 2015-03-25\n### Changed\n* Update `jsx-quotes` documentation\n\n### Fixed\n* Fix [`jsx-no-undef`][] with `babel-eslint` ([#30][])\n* Fix `jsx-quotes` on Literal childs ([#29][])\n\n[1.6.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.6.0...v1.6.1\n[#30]: https://github.com/jsx-eslint/eslint-plugin-react/issues/30\n[#29]: https://github.com/jsx-eslint/eslint-plugin-react/issues/29\n\n## [1.6.0] - 2015-03-22\n### Added\n* Add [`jsx-no-undef`][] rule\n* Add `jsx-quotes` rule ([#12][])\n* Add `@jsx` pragma support ([#23][])\n\n### Changed\n* Allow `this.getState` references (not calls) in lifecycle methods ([#22][] @benmosher)\n* Update dependencies\n\n### Fixed\n* Fix [`react-in-jsx-scope`][] in Node.js env\n* Fix usage of propTypes with an external object ([#9][])\n\n[1.6.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.5.0...v1.6.0\n[#12]: https://github.com/jsx-eslint/eslint-plugin-react/issues/12\n[#23]: https://github.com/jsx-eslint/eslint-plugin-react/issues/23\n[#9]: https://github.com/jsx-eslint/eslint-plugin-react/issues/9\n[#22]: https://github.com/jsx-eslint/eslint-plugin-react/pull/22\n\n## [1.5.0] - 2015-03-14\n### Added\n* Add [`jsx-uses-vars`][] rule\n\n### Fixed\n* Fix [`jsx-uses-react`][] for ESLint 0.17.0\n\n[1.5.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.4.1...v1.5.0\n\n## [1.4.1] - 2015-03-03\n### Fixed\n* Fix `this.props.children` marked as missing in props validation ([#7][])\n* Fix usage of `this.props` without property ([#8][])\n\n[1.4.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.4.0...v1.4.1\n[#7]: https://github.com/jsx-eslint/eslint-plugin-react/issues/7\n[#8]: https://github.com/jsx-eslint/eslint-plugin-react/issues/8\n\n## [1.4.0] - 2015-02-24\n### Added\n* Add [`react-in-jsx-scope`][] rule ([#5][] @glenjamin)\n* Add [`jsx-uses-react`][] rule ([#6][] @glenjamin)\n\n### Changed\n* Update [`prop-types`][] to check props usage insead of propTypes presence ([#4][])\n\n[1.4.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.3.0...v1.4.0\n[#4]: https://github.com/jsx-eslint/eslint-plugin-react/issues/4\n[#5]: https://github.com/jsx-eslint/eslint-plugin-react/pull/5\n[#6]: https://github.com/jsx-eslint/eslint-plugin-react/pull/6\n\n## [1.3.0] - 2015-02-24\n### Added\n* Add [`no-did-mount-set-state`][] rule\n* Add [`no-did-update-set-state`][] rule\n\n### Changed\n* Update dependencies\n\n[1.3.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.2.2...v1.3.0\n\n## [1.2.2] - 2015-02-09\n### Changed\n* Update dependencies\n\n### Fixed\n* Fix childs detection in [`self-closing-comp`][] ([#3][])\n\n[1.2.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.2.1...v1.2.2\n[#3]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3\n\n## [1.2.1] - 2015-01-29\n### Changed\n* Update Readme\n* Update dependencies\n* Update [`wrap-multilines`][] and [`self-closing-comp`][] rules for ESLint 0.13.0\n\n[1.2.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.2.0...v1.2.1\n\n## [1.2.0] - 2014-12-29\n### Added\n* Add [`self-closing-comp`][] rule\n\n### Fixed\n* Fix [`display-name`][] and [`prop-types`][] rules\n\n[1.2.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.1.0...v1.2.0\n\n## [1.1.0] - 2014-12-28\n### Added\n * Add [`display-name`][] rule\n * Add [`wrap-multilines`][] rule\n * Add rules documentation\n * Add rules tests\n\n[1.1.0]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v1.0.0...v1.1.0\n\n## 1.0.0 - 2014-12-16\n### Added\n * First revision\n\n[`react/jsx-runtime`]: https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/index.js#L163-L176\n\n[`boolean-prop-naming`]: docs/rules/boolean-prop-naming.md\n[`button-has-type`]: docs/rules/button-has-type.md\n[`checked-requires-onchange-or-readonly`]: docs/rules/checked-requires-onchange-or-readonly.md\n[`default-props-match-prop-types`]: docs/rules/default-props-match-prop-types.md\n[`destructuring-assignment`]: docs/rules/destructuring-assignment.md\n[`display-name`]: docs/rules/display-name.md\n[`forbid-component-props`]: docs/rules/forbid-component-props.md\n[`forbid-dom-props`]: docs/rules/forbid-dom-props.md\n[`forbid-elements`]: docs/rules/forbid-elements.md\n[`forbid-foreign-prop-types`]: docs/rules/forbid-foreign-prop-types.md\n[`forbid-prop-types`]: docs/rules/forbid-prop-types.md\n[`forward-ref-uses-ref`]: docs/rules/forward-ref-uses-ref.md\n[`function-component-definition`]: docs/rules/function-component-definition.md\n[`hook-use-state`]: docs/rules/hook-use-state.md\n[`iframe-missing-sandbox`]: docs/rules/iframe-missing-sandbox.md\n[`jsx-boolean-value`]: docs/rules/jsx-boolean-value.md\n[`jsx-child-element-spacing`]: docs/rules/jsx-child-element-spacing.md\n[`jsx-closing-bracket-location`]: docs/rules/jsx-closing-bracket-location.md\n[`jsx-closing-tag-location`]: docs/rules/jsx-closing-tag-location.md\n[`jsx-curly-brace-presence`]: docs/rules/jsx-curly-brace-presence.md\n[`jsx-curly-newline`]: docs/rules/jsx-curly-newline.md\n[`jsx-curly-spacing`]: docs/rules/jsx-curly-spacing.md\n[`jsx-equals-spacing`]: docs/rules/jsx-equals-spacing.md\n[`jsx-filename-extension`]: docs/rules/jsx-filename-extension.md\n[`jsx-first-prop-new-line`]: docs/rules/jsx-first-prop-new-line.md\n[`jsx-fragments`]: docs/rules/jsx-fragments.md\n[`jsx-handler-names`]: docs/rules/jsx-handler-names.md\n[`jsx-indent-props`]: docs/rules/jsx-indent-props.md\n[`jsx-indent`]: docs/rules/jsx-indent.md\n[`jsx-key`]: docs/rules/jsx-key.md\n[`jsx-max-depth`]: docs/rules/jsx-max-depth.md\n[`jsx-max-props-per-line`]: docs/rules/jsx-max-props-per-line.md\n[`jsx-newline`]: docs/rules/jsx-newline.md\n[`jsx-no-bind`]: docs/rules/jsx-no-bind.md\n[`jsx-no-comment-textnodes`]: docs/rules/jsx-no-comment-textnodes.md\n[`jsx-no-constructed-context-values`]: docs/rules/jsx-no-constructed-context-values.md\n[`jsx-no-duplicate-props`]: docs/rules/jsx-no-duplicate-props.md\n[`jsx-no-leaked-render`]: docs/rules/jsx-no-leaked-render.md\n[`jsx-no-literals`]: docs/rules/jsx-no-literals.md\n[`jsx-no-script-url`]: docs/rules/jsx-no-script-url.md\n[`jsx-no-target-blank`]: docs/rules/jsx-no-target-blank.md\n[`jsx-no-undef`]: docs/rules/jsx-no-undef.md\n[`jsx-no-useless-fragment`]: docs/rules/jsx-no-useless-fragment.md\n[`jsx-one-expression-per-line`]: docs/rules/jsx-one-expression-per-line.md\n[`jsx-pascal-case`]: docs/rules/jsx-pascal-case.md\n[`jsx-props-no-multi-spaces`]: docs/rules/jsx-props-no-multi-spaces.md\n[`jsx-props-no-spread-multi`]: docs/rules/jsx-props-no-spread-multi.md\n[`jsx-props-no-spreading`]: docs/rules/jsx-props-no-spreading.md\n[`jsx-props-no-spreading`]: docs/rules/jsx-props-no-spreading.md\n[`jsx-sort-default-props`]: docs/rules/jsx-sort-default-props.md\n[`jsx-sort-prop-types`]: docs/rules/sort-prop-types.md\n[`jsx-sort-props`]: docs/rules/jsx-sort-props.md\n[`jsx-space-before-closing`]: docs/rules/jsx-space-before-closing.md\n[`jsx-tag-spacing`]: docs/rules/jsx-tag-spacing.md\n[`jsx-uses-react`]: docs/rules/jsx-uses-react.md\n[`jsx-uses-vars`]: docs/rules/jsx-uses-vars.md\n[`jsx-wrap-multilines`]: docs/rules/jsx-wrap-multilines.md\n[`no-access-state-in-setstate`]: docs/rules/no-access-state-in-setstate.md\n[`no-adjacent-inline-elements`]: docs/rules/no-adjacent-inline-elements.md\n[`no-array-index-key`]: docs/rules/no-array-index-key.md\n[`no-arrow-function-lifecycle`]: docs/rules/no-arrow-function-lifecycle.md\n[`no-children-prop`]: docs/rules/no-children-prop.md\n[`no-comment-textnodes`]: docs/rules/jsx-no-comment-textnodes.md\n[`no-danger-with-children`]: docs/rules/no-danger-with-children.md\n[`no-danger`]: docs/rules/no-danger.md\n[`no-deprecated`]: docs/rules/no-deprecated.md\n[`no-did-mount-set-state`]: docs/rules/no-did-mount-set-state.md\n[`no-did-update-set-state`]: docs/rules/no-did-update-set-state.md\n[`no-direct-mutation-state`]: docs/rules/no-direct-mutation-state.md\n[`no-find-dom-node`]: docs/rules/no-find-dom-node.md\n[`no-invalid-html-attribute`]: docs/rules/no-invalid-html-attribute.md\n[`no-is-mounted`]: docs/rules/no-is-mounted.md\n[`no-multi-comp`]: docs/rules/no-multi-comp.md\n[`no-namespace`]: docs/rules/no-namespace.md\n[`no-object-type-as-default-prop`]: docs/rules/no-object-type-as-default-prop.md\n[`no-redundant-should-component-update`]: docs/rules/no-redundant-should-component-update.md\n[`no-render-return-value`]: docs/rules/no-render-return-value.md\n[`no-set-state`]: docs/rules/no-set-state.md\n[`no-string-refs`]: docs/rules/no-string-refs.md\n[`no-this-in-sfc`]: docs/rules/no-this-in-sfc.md\n[`no-typos`]: docs/rules/no-typos.md\n[`no-unescaped-entities`]: docs/rules/no-unescaped-entities.md\n[`no-unknown-property`]: docs/rules/no-unknown-property.md\n[`no-unsafe`]: docs/rules/no-unsafe.md\n[`no-unstable-nested-components`]: docs/rules/no-unstable-nested-components.md\n[`no-unused-class-component-methods`]: docs/rules/no-unused-class-component-methods.md\n[`no-unused-prop-types`]: docs/rules/no-unused-prop-types.md\n[`no-unused-state`]: docs/rules/no-unused-state.md\n[`no-will-update-set-state`]: docs/rules/no-will-update-set-state.md\n[`prefer-es6-class`]: docs/rules/prefer-es6-class.md\n[`prefer-exact-props`]: docs/rules/prefer-exact-props.md\n[`prefer-read-only-props`]: docs/rules/prefer-read-only-props.md\n[`prefer-stateless-function`]: docs/rules/prefer-stateless-function.md\n[`prop-types`]: docs/rules/prop-types.md\n[`react-in-jsx-scope`]: docs/rules/react-in-jsx-scope.md\n[`require-default-props`]: docs/rules/require-default-props.md\n[`require-extension`]: docs/rules/require-extension.md\n[`require-optimization`]: docs/rules/require-optimization.md\n[`require-render-return`]: docs/rules/require-render-return.md\n[`self-closing-comp`]: docs/rules/self-closing-comp.md\n[`sort-comp`]: docs/rules/sort-comp.md\n[`sort-default-props`]: docs/rules/sort-default-props.md\n[`sort-prop-types`]: docs/rules/sort-prop-types.md\n[`state-in-constructor`]: docs/rules/state-in-constructor.md\n[`static-property-placement`]: docs/rules/static-property-placement.md\n[`style-prop-object`]: docs/rules/style-prop-object.md\n[`void-dom-elements-no-children`]: docs/rules/void-dom-elements-no-children.md\n[`wrap-multilines`]: docs/rules/jsx-wrap-multilines.md\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to `eslint-plugin-react`\n\n## `eslint` Rules\n\n### Markup\n\nFiles documenting individual rules live in docs/rules folder. They're annotated\nusing Markdown, which adds extra layer of legibility and better visual orientation\nto the documents. Consider this when writing supporting text for the rules.\n\nSee the list below for some guidelines that need to be followed when adding to the\ncollection.\n\n- Negative adverbs preceding snippets in 'Rule Details' sections must be **bold**.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Yannick Croissant\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# `eslint-plugin-react` <sup>[![Version Badge][npm-version-svg]][package-url]</sup>\n\n===================\n\n[![github actions][actions-image]][actions-url]\n[![Maintenance Status][status-image]][status-url]\n[![NPM version][npm-image]][npm-url]\n[![Tidelift][tidelift-image]][tidelift-url]\n\nReact specific linting rules for `eslint`\n\n## Installation\n\n```sh\nnpm install eslint eslint-plugin-react --save-dev\n```\n\nIt is also possible to install ESLint globally rather than locally (using `npm install -g eslint`). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case.\n\n## Configuration (legacy: `.eslintrc*`) <a id=\"configuration\"></a>\n\nUse [our preset](#recommended) to get reasonable defaults:\n\n```json\n  \"extends\": [\n    \"eslint:recommended\",\n    \"plugin:react/recommended\"\n  ]\n```\n\nIf you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), extend [`react/jsx-runtime`](https://github.com/jsx-eslint/eslint-plugin-react/blob/c8917b0885094b5e4cc2a6f613f7fb6f16fe932e/index.js#L163-L176) in your eslint config (add `\"plugin:react/jsx-runtime\"` to `\"extends\"`) to disable the relevant rules.\n\nYou should also specify settings that will be shared across all the plugin rules. ([More about eslint shared settings](https://eslint.org/docs/latest/use/configure/configuration-files#configuring-shared-settings))\n\n```json5\n{\n  \"settings\": {\n    \"react\": {\n      \"createClass\": \"createReactClass\", // Regex for Component Factory to use,\n                                         // default to \"createReactClass\"\n      \"pragma\": \"React\",  // Pragma to use, default to \"React\"\n      \"fragment\": \"Fragment\",  // Fragment to use (may be a property of <pragma>), default to \"Fragment\"\n      \"version\": \"detect\", // React version. \"detect\" automatically picks the version you have installed.\n                           // You can also use `16.0`, `16.3`, etc, if you want to override the detected value.\n                           // Defaults to the \"defaultVersion\" setting and warns if missing, and to \"detect\" in the future\n      \"defaultVersion\": \"\", // Default React version to use when the version you have installed cannot be detected.\n                            // If not provided, defaults to the latest React version.\n      \"flowVersion\": \"0.53\" // Flow version\n    },\n    \"propWrapperFunctions\": [\n        // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.\n        \"forbidExtraProps\",\n        {\"property\": \"freeze\", \"object\": \"Object\"},\n        {\"property\": \"myFavoriteWrapper\"},\n        // for rules that check exact prop wrappers\n        {\"property\": \"forbidExtraProps\", \"exact\": true}\n    ],\n    \"componentWrapperFunctions\": [\n        // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped.\n        \"observer\", // `property`\n        {\"property\": \"styled\"}, // `object` is optional\n        {\"property\": \"observer\", \"object\": \"Mobx\"},\n        {\"property\": \"observer\", \"object\": \"<pragma>\"} // sets `object` to whatever value `settings.react.pragma` is set to\n    ],\n    \"formComponents\": [\n      // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />\n      \"CustomForm\",\n      {\"name\": \"SimpleForm\", \"formAttribute\": \"endpoint\"},\n      {\"name\": \"Form\", \"formAttribute\": [\"registerEndpoint\", \"loginEndpoint\"]}, // allows specifying multiple properties if necessary\n    ],\n    \"linkComponents\": [\n      // Components used as alternatives to <a> for linking, eg. <Link to={ url } />\n      \"Hyperlink\",\n      {\"name\": \"MyLink\", \"linkAttribute\": \"to\"},\n      {\"name\": \"Link\", \"linkAttribute\": [\"to\", \"href\"]}, // allows specifying multiple properties if necessary\n    ]\n  }\n}\n```\n\nIf you do not use a preset you will need to specify individual rules and add extra configuration.\n\nAdd \"react\" to the plugins section.\n\n```json\n{\n  \"plugins\": [\n    \"react\"\n  ]\n}\n```\n\nEnable JSX support.\n\nWith `eslint` 2+\n\n```json\n{\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  }\n}\n```\n\nEnable the rules that you would like to use.\n\n```json\n  \"rules\": {\n    \"react/jsx-uses-react\": \"error\",\n    \"react/jsx-uses-vars\": \"error\",\n  }\n```\n\n### Shareable configs\n\n#### Recommended\n\nThis plugin exports a `recommended` configuration that enforces React good practices.\n\nTo enable this configuration use the `extends` property in your `.eslintrc` config file:\n\n```json\n{\n  \"extends\": [\"eslint:recommended\", \"plugin:react/recommended\"]\n}\n```\n\nSee [`eslint` documentation](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending configuration files.\n\n#### All\n\nThis plugin also exports an `all` configuration that includes every available rule.\nThis pairs well with the `eslint:all` rule.\n\n```json\n{\n  \"plugins\": [\n    \"react\"\n  ],\n  \"extends\": [\"eslint:all\", \"plugin:react/all\"]\n}\n```\n\n**Note**: These configurations will import `eslint-plugin-react` and enable JSX in [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options).\n\n## Configuration (new: `eslint.config.js`)\n\nFrom [`v8.21.0`](https://github.com/eslint/eslint/releases/tag/v8.21.0), eslint announced a new config system.\nIn the new system, `.eslintrc*` is no longer used. `eslint.config.js` would be the default config file name.\nIn eslint `v8`, the legacy system (`.eslintrc*`) would still be supported, while in eslint `v9`, only the new system would be supported.\n\nAnd from [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0), eslint CLI starts to look up `eslint.config.js`.\n**So, if your eslint is `>=8.23.0`, you're 100% ready to use the new config system.**\n\nYou might want to check out the official blog posts,\n\n- <https://eslint.org/blog/2022/08/new-config-system-part-1/>\n- <https://eslint.org/blog/2022/08/new-config-system-part-2/>\n- <https://eslint.org/blog/2022/08/new-config-system-part-3/>\n\nand the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new).\n\n### Plugin\n\nThe default export of `eslint-plugin-react` is a plugin object.\n\n```js\nconst react = require('eslint-plugin-react');\nconst globals = require('globals');\n\nmodule.exports = [\n  …\n  {\n    files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],\n    plugins: {\n      react,\n    },\n    languageOptions: {\n      parserOptions: {\n        ecmaFeatures: {\n          jsx: true,\n        },\n      },\n      globals: {\n        ...globals.browser,\n      },\n    },\n    rules: {\n      // ... any rules you want\n      'react/jsx-uses-react': 'error',\n      'react/jsx-uses-vars': 'error',\n     },\n    // ... others are omitted for brevity\n  },\n  …\n];\n```\n\n### Configuring shared settings\n\nRefer to the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuring-shared-settings).\n\nThe schema of the `settings.react` object would be identical to that of what's already described above in the legacy config section.\n\n<!-- markdownlint-disable-next-line no-duplicate-heading -->\n### Flat Configs\n\nThis plugin exports 3 flat configs:\n\n- `flat.all`\n- `flat.recommended`\n- `flat['jsx-runtime']`\n\nThe flat configs are available via the root plugin import. They will configure the plugin under the `react/` namespace and enable JSX in [`languageOptions.parserOptions`](https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options).\n\n```js\nconst reactPlugin = require('eslint-plugin-react');\n\nmodule.exports = [\n  …\n  reactPlugin.configs.flat.recommended, // This is not a plugin object, but a shareable config object\n  reactPlugin.configs.flat['jsx-runtime'], // Add this if you are using React 17+\n  …\n];\n```\n\nYou can of course add/override some properties.\n\n**Note**: Our shareable configs does not preconfigure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).\nFor most of the cases, you probably want to configure some properties by yourself.\n\n```js\nconst reactPlugin = require('eslint-plugin-react');\nconst globals = require('globals');\n\nmodule.exports = [\n  …\n  {\n    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],\n    ...reactPlugin.configs.flat.recommended,\n    languageOptions: {\n      ...reactPlugin.configs.flat.recommended.languageOptions,\n      globals: {\n        ...globals.serviceworker,\n        ...globals.browser,\n      },\n    },\n  },\n  …\n];\n```\n\nThe above example is same as the example below, as the new config system is based on chaining.\n\n```js\nconst reactPlugin = require('eslint-plugin-react');\nconst globals = require('globals');\n\nmodule.exports = [\n  …\n  {\n    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],\n    ...reactPlugin.configs.flat.recommended,\n  },\n  {\n    files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],\n    languageOptions: {\n      globals: {\n        ...globals.serviceworker,\n        ...globals.browser,\n      },\n    },\n  },\n  …\n];\n```\n\n## List of supported rules\n\n<!-- begin auto-generated rules list -->\n\n💼 [Configurations](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs) enabled in.\\\n🚫 [Configurations](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs) disabled in.\\\n🏃 Set in the `jsx-runtime` [configuration](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\\\n☑️ Set in the `recommended` [configuration](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\\\n🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\\\n💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\\\n❌ Deprecated.\n\n| Name                                                                                         | Description                                                                                                                                  | 💼 | 🚫 | 🔧 | 💡 | ❌  |\n| :------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | :- | :- | :- | :- | :- |\n| [async-server-action](docs/rules/async-server-action.md)                                     | Require functions with the `use server` directive to be async                                                                                |    |    |    | 💡 |    |\n| [boolean-prop-naming](docs/rules/boolean-prop-naming.md)                                     | Enforces consistent naming for boolean props                                                                                                 |    |    |    |    |    |\n| [button-has-type](docs/rules/button-has-type.md)                                             | Disallow usage of `button` elements without an explicit `type` attribute                                                                     |    |    |    |    |    |\n| [checked-requires-onchange-or-readonly](docs/rules/checked-requires-onchange-or-readonly.md) | Enforce using `onChange` or `readonly` attribute when `checked` is used                                                                      |    |    |    |    |    |\n| [default-props-match-prop-types](docs/rules/default-props-match-prop-types.md)               | Enforce all defaultProps have a corresponding non-required PropType                                                                          |    |    |    |    |    |\n| [destructuring-assignment](docs/rules/destructuring-assignment.md)                           | Enforce consistent usage of destructuring assignment of props, state, and context                                                            |    |    | 🔧 |    |    |\n| [display-name](docs/rules/display-name.md)                                                   | Disallow missing displayName in a React component definition                                                                                 | ☑️ |    |    |    |    |\n| [forbid-component-props](docs/rules/forbid-component-props.md)                               | Disallow certain props on components                                                                                                         |    |    |    |    |    |\n| [forbid-dom-props](docs/rules/forbid-dom-props.md)                                           | Disallow certain props on DOM Nodes                                                                                                          |    |    |    |    |    |\n| [forbid-elements](docs/rules/forbid-elements.md)                                             | Disallow certain elements                                                                                                                    |    |    |    |    |    |\n| [forbid-foreign-prop-types](docs/rules/forbid-foreign-prop-types.md)                         | Disallow using another component's propTypes                                                                                                 |    |    |    |    |    |\n| [forbid-prop-types](docs/rules/forbid-prop-types.md)                                         | Disallow certain propTypes                                                                                                                   |    |    |    |    |    |\n| [forward-ref-uses-ref](docs/rules/forward-ref-uses-ref.md)                                   | Require all forwardRef components include a ref parameter                                                                                    |    |    |    | 💡 |    |\n| [function-component-definition](docs/rules/function-component-definition.md)                 | Enforce a specific function type for function components                                                                                     |    |    | 🔧 |    |    |\n| [hook-use-state](docs/rules/hook-use-state.md)                                               | Ensure destructuring and symmetric naming of useState hook value and setter variables                                                        |    |    |    | 💡 |    |\n| [iframe-missing-sandbox](docs/rules/iframe-missing-sandbox.md)                               | Enforce sandbox attribute on iframe elements                                                                                                 |    |    |    |    |    |\n| [jsx-boolean-value](docs/rules/jsx-boolean-value.md)                                         | Enforce boolean attributes notation in JSX                                                                                                   |    |    | 🔧 |    |    |\n| [jsx-child-element-spacing](docs/rules/jsx-child-element-spacing.md)                         | Enforce or disallow spaces inside of curly braces in JSX attributes and expressions                                                          |    |    |    |    |    |\n| [jsx-closing-bracket-location](docs/rules/jsx-closing-bracket-location.md)                   | Enforce closing bracket location in JSX                                                                                                      |    |    | 🔧 |    |    |\n| [jsx-closing-tag-location](docs/rules/jsx-closing-tag-location.md)                           | Enforce closing tag location for multiline JSX                                                                                               |    |    | 🔧 |    |    |\n| [jsx-curly-brace-presence](docs/rules/jsx-curly-brace-presence.md)                           | Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes |    |    | 🔧 |    |    |\n| [jsx-curly-newline](docs/rules/jsx-curly-newline.md)                                         | Enforce consistent linebreaks in curly braces in JSX attributes and expressions                                                              |    |    | 🔧 |    |    |\n| [jsx-curly-spacing](docs/rules/jsx-curly-spacing.md)                                         | Enforce or disallow spaces inside of curly braces in JSX attributes and expressions                                                          |    |    | 🔧 |    |    |\n| [jsx-equals-spacing](docs/rules/jsx-equals-spacing.md)                                       | Enforce or disallow spaces around equal signs in JSX attributes                                                                              |    |    | 🔧 |    |    |\n| [jsx-filename-extension](docs/rules/jsx-filename-extension.md)                               | Disallow file extensions that may contain JSX                                                                                                |    |    |    |    |    |\n| [jsx-first-prop-new-line](docs/rules/jsx-first-prop-new-line.md)                             | Enforce proper position of the first property in JSX                                                                                         |    |    | 🔧 |    |    |\n| [jsx-fragments](docs/rules/jsx-fragments.md)                                                 | Enforce shorthand or standard form for React fragments                                                                                       |    |    | 🔧 |    |    |\n| [jsx-handler-names](docs/rules/jsx-handler-names.md)                                         | Enforce event handler naming conventions in JSX                                                                                              |    |    |    |    |    |\n| [jsx-indent](docs/rules/jsx-indent.md)                                                       | Enforce JSX indentation                                                                                                                      |    |    | 🔧 |    |    |\n| [jsx-indent-props](docs/rules/jsx-indent-props.md)                                           | Enforce props indentation in JSX                                                                                                             |    |    | 🔧 |    |    |\n| [jsx-key](docs/rules/jsx-key.md)                                                             | Disallow missing `key` props in iterators/collection literals                                                                                | ☑️ |    |    |    |    |\n| [jsx-max-depth](docs/rules/jsx-max-depth.md)                                                 | Enforce JSX maximum depth                                                                                                                    |    |    |    |    |    |\n| [jsx-max-props-per-line](docs/rules/jsx-max-props-per-line.md)                               | Enforce maximum of props on a single line in JSX                                                                                             |    |    | 🔧 |    |    |\n| [jsx-newline](docs/rules/jsx-newline.md)                                                     | Require or prevent a new line after jsx elements and expressions.                                                                            |    |    | 🔧 |    |    |\n| [jsx-no-bind](docs/rules/jsx-no-bind.md)                                                     | Disallow `.bind()` or arrow functions in JSX props                                                                                           |    |    |    |    |    |\n| [jsx-no-comment-textnodes](docs/rules/jsx-no-comment-textnodes.md)                           | Disallow comments from being inserted as text nodes                                                                                          | ☑️ |    |    |    |    |\n| [jsx-no-constructed-context-values](docs/rules/jsx-no-constructed-context-values.md)         | Disallows JSX context provider values from taking values that will cause needless rerenders                                                  |    |    |    |    |    |\n| [jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md)                               | Disallow duplicate properties in JSX                                                                                                         | ☑️ |    |    |    |    |\n| [jsx-no-leaked-render](docs/rules/jsx-no-leaked-render.md)                                   | Disallow problematic leaked values from being rendered                                                                                       |    |    | 🔧 |    |    |\n| [jsx-no-literals](docs/rules/jsx-no-literals.md)                                             | Disallow usage of string literals in JSX                                                                                                     |    |    |    |    |    |\n| [jsx-no-script-url](docs/rules/jsx-no-script-url.md)                                         | Disallow usage of `javascript:` URLs                                                                                                         |    |    |    |    |    |\n| [jsx-no-target-blank](docs/rules/jsx-no-target-blank.md)                                     | Disallow `target=\"_blank\"` attribute without `rel=\"noreferrer\"`                                                                              | ☑️ |    | 🔧 |    |    |\n| [jsx-no-undef](docs/rules/jsx-no-undef.md)                                                   | Disallow undeclared variables in JSX                                                                                                         | ☑️ |    |    |    |    |\n| [jsx-no-useless-fragment](docs/rules/jsx-no-useless-fragment.md)                             | Disallow unnecessary fragments                                                                                                               |    |    | 🔧 |    |    |\n| [jsx-one-expression-per-line](docs/rules/jsx-one-expression-per-line.md)                     | Require one JSX element per line                                                                                                             |    |    | 🔧 |    |    |\n| [jsx-pascal-case](docs/rules/jsx-pascal-case.md)                                             | Enforce PascalCase for user-defined JSX components                                                                                           |    |    |    |    |    |\n| [jsx-props-no-multi-spaces](docs/rules/jsx-props-no-multi-spaces.md)                         | Disallow multiple spaces between inline JSX props                                                                                            |    |    | 🔧 |    |    |\n| [jsx-props-no-spread-multi](docs/rules/jsx-props-no-spread-multi.md)                         | Disallow JSX prop spreading the same identifier multiple times                                                                               |    |    |    |    |    |\n| [jsx-props-no-spreading](docs/rules/jsx-props-no-spreading.md)                               | Disallow JSX prop spreading                                                                                                                  |    |    |    |    |    |\n| [jsx-sort-default-props](docs/rules/jsx-sort-default-props.md)                               | Enforce defaultProps declarations alphabetical sorting                                                                                       |    |    |    |    | ❌  |\n| [jsx-sort-props](docs/rules/jsx-sort-props.md)                                               | Enforce props alphabetical sorting                                                                                                           |    |    | 🔧 |    |    |\n| [jsx-space-before-closing](docs/rules/jsx-space-before-closing.md)                           | Enforce spacing before closing bracket in JSX                                                                                                |    |    | 🔧 |    | ❌  |\n| [jsx-tag-spacing](docs/rules/jsx-tag-spacing.md)                                             | Enforce whitespace in and around the JSX opening and closing brackets                                                                        |    |    | 🔧 |    |    |\n| [jsx-uses-react](docs/rules/jsx-uses-react.md)                                               | Disallow React to be incorrectly marked as unused                                                                                            | ☑️ | 🏃 |    |    |    |\n| [jsx-uses-vars](docs/rules/jsx-uses-vars.md)                                                 | Disallow variables used in JSX to be incorrectly marked as unused                                                                            | ☑️ |    |    |    |    |\n| [jsx-wrap-multilines](docs/rules/jsx-wrap-multilines.md)                                     | Disallow missing parentheses around multiline JSX                                                                                            |    |    | 🔧 |    |    |\n| [no-access-state-in-setstate](docs/rules/no-access-state-in-setstate.md)                     | Disallow when this.state is accessed within setState                                                                                         |    |    |    |    |    |\n| [no-adjacent-inline-elements](docs/rules/no-adjacent-inline-elements.md)                     | Disallow adjacent inline elements not separated by whitespace.                                                                               |    |    |    |    |    |\n| [no-array-index-key](docs/rules/no-array-index-key.md)                                       | Disallow usage of Array index in keys                                                                                                        |    |    |    |    |    |\n| [no-arrow-function-lifecycle](docs/rules/no-arrow-function-lifecycle.md)                     | Lifecycle methods should be methods on the prototype, not class fields                                                                       |    |    | 🔧 |    |    |\n| [no-children-prop](docs/rules/no-children-prop.md)                                           | Disallow passing of children as props                                                                                                        | ☑️ |    |    |    |    |\n| [no-danger](docs/rules/no-danger.md)                                                         | Disallow usage of dangerous JSX properties                                                                                                   |    |    |    |    |    |\n| [no-danger-with-children](docs/rules/no-danger-with-children.md)                             | Disallow when a DOM element is using both children and dangerouslySetInnerHTML                                                               | ☑️ |    |    |    |    |\n| [no-deprecated](docs/rules/no-deprecated.md)                                                 | Disallow usage of deprecated methods                                                                                                         | ☑️ |    |    |    |    |\n| [no-did-mount-set-state](docs/rules/no-did-mount-set-state.md)                               | Disallow usage of setState in componentDidMount                                                                                              |    |    |    |    |    |\n| [no-did-update-set-state](docs/rules/no-did-update-set-state.md)                             | Disallow usage of setState in componentDidUpdate                                                                                             |    |    |    |    |    |\n| [no-direct-mutation-state](docs/rules/no-direct-mutation-state.md)                           | Disallow direct mutation of this.state                                                                                                       | ☑️ |    |    |    |    |\n| [no-find-dom-node](docs/rules/no-find-dom-node.md)                                           | Disallow usage of findDOMNode                                                                                                                | ☑️ |    |    |    |    |\n| [no-invalid-html-attribute](docs/rules/no-invalid-html-attribute.md)                         | Disallow usage of invalid attributes                                                                                                         |    |    |    | 💡 |    |\n| [no-is-mounted](docs/rules/no-is-mounted.md)                                                 | Disallow usage of isMounted                                                                                                                  | ☑️ |    |    |    |    |\n| [no-multi-comp](docs/rules/no-multi-comp.md)                                                 | Disallow multiple component definition per file                                                                                              |    |    |    |    |    |\n| [no-namespace](docs/rules/no-namespace.md)                                                   | Enforce that namespaces are not used in React elements                                                                                       |    |    |    |    |    |\n| [no-object-type-as-default-prop](docs/rules/no-object-type-as-default-prop.md)               | Disallow usage of referential-type variables as default param in functional component                                                        |    |    |    |    |    |\n| [no-redundant-should-component-update](docs/rules/no-redundant-should-component-update.md)   | Disallow usage of shouldComponentUpdate when extending React.PureComponent                                                                   |    |    |    |    |    |\n| [no-render-return-value](docs/rules/no-render-return-value.md)                               | Disallow usage of the return value of ReactDOM.render                                                                                        | ☑️ |    |    |    |    |\n| [no-set-state](docs/rules/no-set-state.md)                                                   | Disallow usage of setState                                                                                                                   |    |    |    |    |    |\n| [no-string-refs](docs/rules/no-string-refs.md)                                               | Disallow using string references                                                                                                             | ☑️ |    |    |    |    |\n| [no-this-in-sfc](docs/rules/no-this-in-sfc.md)                                               | Disallow `this` from being used in stateless functional components                                                                           |    |    |    |    |    |\n| [no-typos](docs/rules/no-typos.md)                                                           | Disallow common typos                                                                                                                        |    |    |    |    |    |\n| [no-unescaped-entities](docs/rules/no-unescaped-entities.md)                                 | Disallow unescaped HTML entities from appearing in markup                                                                                    | ☑️ |    |    | 💡 |    |\n| [no-unknown-property](docs/rules/no-unknown-property.md)                                     | Disallow usage of unknown DOM property                                                                                                       | ☑️ |    | 🔧 |    |    |\n| [no-unsafe](docs/rules/no-unsafe.md)                                                         | Disallow usage of unsafe lifecycle methods                                                                                                   |    | ☑️ |    |    |    |\n| [no-unstable-nested-components](docs/rules/no-unstable-nested-components.md)                 | Disallow creating unstable components inside components                                                                                      |    |    |    |    |    |\n| [no-unused-class-component-methods](docs/rules/no-unused-class-component-methods.md)         | Disallow declaring unused methods of component class                                                                                         |    |    |    |    |    |\n| [no-unused-prop-types](docs/rules/no-unused-prop-types.md)                                   | Disallow definitions of unused propTypes                                                                                                     |    |    |    |    |    |\n| [no-unused-state](docs/rules/no-unused-state.md)                                             | Disallow definitions of unused state                                                                                                         |    |    |    |    |    |\n| [no-will-update-set-state](docs/rules/no-will-update-set-state.md)                           | Disallow usage of setState in componentWillUpdate                                                                                            |    |    |    |    |    |\n| [prefer-es6-class](docs/rules/prefer-es6-class.md)                                           | Enforce ES5 or ES6 class for React Components                                                                                                |    |    |    |    |    |\n| [prefer-exact-props](docs/rules/prefer-exact-props.md)                                       | Prefer exact proptype definitions                                                                                                            |    |    |    |    |    |\n| [prefer-read-only-props](docs/rules/prefer-read-only-props.md)                               | Enforce that props are read-only                                                                                                             |    |    | 🔧 |    |    |\n| [prefer-stateless-function](docs/rules/prefer-stateless-function.md)                         | Enforce stateless components to be written as a pure function                                                                                |    |    |    |    |    |\n| [prop-types](docs/rules/prop-types.md)                                                       | Disallow missing props validation in a React component definition                                                                            | ☑️ |    |    |    |    |\n| [react-in-jsx-scope](docs/rules/react-in-jsx-scope.md)                                       | Disallow missing React when using JSX                                                                                                        | ☑️ | 🏃 |    |    |    |\n| [require-default-props](docs/rules/require-default-props.md)                                 | Enforce a defaultProps definition for every prop that is not a required prop                                                                 |    |    |    |    |    |\n| [require-optimization](docs/rules/require-optimization.md)                                   | Enforce React components to have a shouldComponentUpdate method                                                                              |    |    |    |    |    |\n| [require-render-return](docs/rules/require-render-return.md)                                 | Enforce ES5 or ES6 class for returning value in render function                                                                              | ☑️ |    |    |    |    |\n| [self-closing-comp](docs/rules/self-closing-comp.md)                                         | Disallow extra closing tags for components without children                                                                                  |    |    | 🔧 |    |    |\n| [sort-comp](docs/rules/sort-comp.md)                                                         | Enforce component methods order                                                                                                              |    |    |    |    |    |\n| [sort-default-props](docs/rules/sort-default-props.md)                                       | Enforce defaultProps declarations alphabetical sorting                                                                                       |    |    |    |    |    |\n| [sort-prop-types](docs/rules/sort-prop-types.md)                                             | Enforce propTypes declarations alphabetical sorting                                                                                          |    |    | 🔧 |    |    |\n| [state-in-constructor](docs/rules/state-in-constructor.md)                                   | Enforce class component state initialization style                                                                                           |    |    |    |    |    |\n| [static-property-placement](docs/rules/static-property-placement.md)                         | Enforces where React component static properties should be positioned.                                                                       |    |    |    |    |    |\n| [style-prop-object](docs/rules/style-prop-object.md)                                         | Enforce style prop value is an object                                                                                                        |    |    |    |    |    |\n| [void-dom-elements-no-children](docs/rules/void-dom-elements-no-children.md)                 | Disallow void DOM elements (e.g. `<img />`, `<br />`) from receiving children                                                                |    |    |    |    |    |\n\n<!-- end auto-generated rules list -->\n\n## Other useful plugins\n\n- Rules of Hooks: [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks)\n- JSX accessibility: [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)\n- React Native: [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native)\n\n## License\n\n`eslint-plugin-react` is licensed under the [MIT License](https://opensource.org/licenses/mit-license.php).\n\n[npm-url]: https://npmjs.org/package/eslint-plugin-react\n[npm-image]: https://img.shields.io/npm/v/eslint-plugin-react.svg\n\n[status-url]: https://github.com/jsx-eslint/eslint-plugin-react/pulse\n[status-image]: https://img.shields.io/github/last-commit/jsx-eslint/eslint-plugin-react.svg\n\n[tidelift-url]: https://tidelift.com/subscription/pkg/npm-eslint-plugin-react?utm_source=npm-eslint-plugin-react&utm_medium=referral&utm_campaign=readme\n[tidelift-image]: https://tidelift.com/badges/package/npm/eslint-plugin-react?style=flat\n\n[package-url]: https://npmjs.org/package/eslint-plugin-react\n[npm-version-svg]: https://versionbadg.es/jsx-eslint/eslint-plugin-react.svg\n\n[actions-image]: https://img.shields.io/github/check-runs/jsx-eslint/eslint-plugin-react/master\n[actions-url]: https://github.com/jsx-eslint/eslint-plugin-react/actions\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nThis is the list of versions of `eslint-plugin-react` which are currently being supported with security updates.\n\n| Version  | Supported          |\n| -------- | ------------------ |\n| 7.x      | :white_check_mark: |\n| < 7.x    | :x:                |\n\n## Reporting a Vulnerability\n\nTo report a security vulnerability, please [file a private vulnerability report via GitHub](https://github.com/jsx-eslint/eslint-plugin-react/security/advisories/new).\n"
  },
  {
    "path": "build.tsconfig.json",
    "content": "{\n  \"extends\": \"./tsconfig\",\n  \"files\": [\n    \"index.js\"\n  ],\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"noEmit\": false,\n    \"emitDeclarationOnly\": true\n  }\n}\n"
  },
  {
    "path": "configs/all.js",
    "content": "'use strict';\n\nconst plugin = require('..');\n\nconst legacyConfig = plugin.configs.all;\n\nmodule.exports = {\n  plugins: { react: plugin },\n  rules: legacyConfig.rules,\n  languageOptions: { parserOptions: legacyConfig.parserOptions },\n};\n\nObject.defineProperty(module.exports, 'languageOptions', { enumerable: false });\n"
  },
  {
    "path": "configs/jsx-runtime.js",
    "content": "'use strict';\n\nconst plugin = require('..');\n\nconst legacyConfig = plugin.configs['jsx-runtime'];\n\nmodule.exports = {\n  plugins: { react: plugin },\n  rules: legacyConfig.rules,\n  languageOptions: { parserOptions: legacyConfig.parserOptions },\n};\n\nObject.defineProperty(module.exports, 'languageOptions', { enumerable: false });\n"
  },
  {
    "path": "configs/recommended.js",
    "content": "'use strict';\n\nconst plugin = require('..');\n\nconst legacyConfig = plugin.configs.recommended;\n\nmodule.exports = {\n  plugins: { react: plugin },\n  rules: legacyConfig.rules,\n  languageOptions: { parserOptions: legacyConfig.parserOptions },\n};\n\nObject.defineProperty(module.exports, 'languageOptions', { enumerable: false });\n"
  },
  {
    "path": "docs/rules/async-server-action.md",
    "content": "# react/async-server-action\n\n📝 Require functions with the `use server` directive to be async.\n\n💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\nRequire Server Actions (functions with the `use server` directive) to be async, as mandated by the `use server` [spec](https://react.dev/reference/react/use-server).\n\nThis must be the case even if the function does not use `await` or `return` a promise.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<form\n  action={() => {\n    'use server';\n    ...\n  }}\n>\n  ...\n</form>\n```\n\n```jsx\nfunction action() {\n  'use server';\n  ...\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<form\n  action={async () => {\n    'use server';\n    ...\n  }}\n>\n  ...\n</form>\n```\n\n```jsx\nasync function action() {\n  'use server';\n  ...\n}\n```\n\n## When Not To Use It\n\nIf you are not using React Server Components.\n"
  },
  {
    "path": "docs/rules/boolean-prop-naming.md",
    "content": "# react/boolean-prop-naming\n\n📝 Enforces consistent naming for boolean props.\n\n<!-- end auto-generated rule header -->\n\nAllows you to enforce a consistent naming pattern for props which expect a boolean value.\n\n> **Note**: You can provide types in runtime types using [PropTypes] and/or\nstatically using [TypeScript] or [Flow]. This rule will validate your prop types\nregardless of how you define them.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  propTypes: {\n    enabled: PropTypes.bool\n  },\n  render: function() { return <div />; };\n});\n```\n\n```jsx\ntype Props = {\n  enabled: boolean\n}\nconst Hello = (props: Props) => <div />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  propTypes: {\n    isEnabled: PropTypes.bool\n  },\n  render: function() { return <div />; };\n});\n```\n\n```jsx\ntype Props = {\n  isEnabled: boolean\n}\nconst Hello = (props: Props) => <div />\n```\n\n## Rule Options\n\n```js\n...\n\"react/boolean-prop-naming\": [<enabled>, {\n  \"propTypeNames\": Array<string>,\n  \"rule\": <string>,\n  \"message\": <string>,\n  \"validateNested\": <boolean>\n}]\n...\n```\n\n### `propTypeNames`\n\nThe list of prop type names that are considered to be booleans. By default this is set to `['bool']` but you can include other custom types like so:\n\n```jsx\n\"react/boolean-prop-naming\": [\"error\", { \"propTypeNames\": [\"bool\", \"mutuallyExclusiveTrueProps\"] }]\n```\n\n### `rule`\n\nThe RegExp pattern to use when validating the name of the prop. The default value for this option is set to: `\"^(is|has)[A-Z]([A-Za-z0-9]?)+\"` to enforce `is` and `has` prefixes.\n\nFor supporting \"is\" and \"has\" naming (default):\n\n- isEnabled\n- isAFK\n- hasCondition\n- hasLOL\n\n```jsx\n\"react/boolean-prop-naming\": [\"error\", { \"rule\": \"^(is|has)[A-Z]([A-Za-z0-9]?)+\" }]\n```\n\nFor supporting \"is\" naming:\n\n- isEnabled\n- isAFK\n\n```jsx\n\"react/boolean-prop-naming\": [\"error\", { \"rule\": \"^is[A-Z]([A-Za-z0-9]?)+\" }]\n```\n\n### `message`\n\nThe custom message to display upon failure to match the rule. This overrides the default message.\n\nIf you choose to use a custom message, you have access to two template variables.\n\n- `propName` – the name of the prop that does not match the pattern\n- `pattern` – the pattern against which all prop names are tested\n\nFor example, if a prop is named `something`, and if the rule's pattern is set to `\"^(is|has)[A-Z]([A-Za-z0-9]?)+\"`, you could set the custom message as follows:\n\n```js\nmessage: 'It is better if your prop ({{ propName }}) matches this pattern: ({{ pattern }})'\n```\n\nAnd the failure would look like so:\n\n```plaintext\nIt is better if your prop (something) matches this pattern: (^is[A-Z]([A-Za-z0-9]?)+)\n```\n\n### `validateNested`\n\nThis value is boolean. It tells if nested props should be validated as well. By default this is set to false but you can change it to true, to validate deeper layers of object:\n\n```jsx\n\"react/boolean-prop-naming\": [\"error\", { \"validateNested\": true }]\n```\n\n[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html\n[TypeScript]: https://www.typescriptlang.org/\n[Flow]: https://flow.org/\n"
  },
  {
    "path": "docs/rules/button-has-type.md",
    "content": "# react/button-has-type\n\n📝 Disallow usage of `button` elements without an explicit `type` attribute.\n\n<!-- end auto-generated rule header -->\n\nThe default value of the `type` attribute for HTML `button` elements is `\"submit\"`. This is often not the desired behavior and may lead to unexpected page reloads.\nThis rules enforces an explicit `type` attribute for all `button` elements and checks that its value is valid per the spec (i.e., is one of `\"button\"`, `\"submit\"`, and `\"reset\"`).\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = <button>Hello</button>\nvar Hello = <button type=\"foo\">Hello</button>\nvar Hello = <button type={foo}>Hello</button>\n\nvar Hello = React.createElement('button', {}, 'Hello')\nvar Hello = React.createElement('button', {type: 'foo'}, 'Hello')\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = <span>Hello</span>\nvar Hello = <span type=\"foo\">Hello</span>\nvar Hello = <button type=\"button\">Hello</button>\nvar Hello = <button type=\"submit\">Hello</button>\nvar Hello = <button type=\"reset\">Hello</button>\nvar Hello = <button type={condition ? \"button\" : \"submit\"}>Hello</button>\n\nvar Hello = React.createElement('span', {}, 'Hello')\nvar Hello = React.createElement('span', {type: 'foo'}, 'Hello')\nvar Hello = React.createElement('button', {type: 'button'}, 'Hello')\nvar Hello = React.createElement('button', {type: 'submit'}, 'Hello')\nvar Hello = React.createElement('button', {type: 'reset'}, 'Hello')\nvar Hello = React.createElement('button', {type: condition ? 'button' : 'submit'}, 'Hello')\n```\n\n## Rule Options\n\n```js\n...\n\"react/button-has-type\": [<enabled>, {\n  \"button\": <boolean>,\n  \"submit\": <boolean>,\n  \"reset\": <boolean>\n}]\n...\n```\n\nYou can forbid particular type attribute values by passing `false` as corresponding option (by default all of them are `true`).\n\nExamples of **incorrect** code for this rule, when configured with `{ \"reset\": false }`:\n\n```jsx\nvar Hello = <button type=\"reset\">Hello</button>\nvar Hello = <button type={condition ? \"button\" : \"reset\"}>Hello</button>\n\nvar Hello = React.createElement('button', {type: 'reset'}, 'Hello')\nvar Hello = React.createElement('button', {type: condition ? \"button\" : \"reset\"}, 'Hello')\n```\n\n## When Not To Use It\n\nIf you use only `\"submit\"` buttons, you can disable this rule\n"
  },
  {
    "path": "docs/rules/checked-requires-onchange-or-readonly.md",
    "content": "# react/checked-requires-onchange-or-readonly\n\n📝 Enforce using `onChange` or `readonly` attribute when `checked` is used.\n\n<!-- end auto-generated rule header -->\n\nThis rule enforces `onChange` or `readonly` attribute for `checked` property of input elements.\n\nIt also warns when `checked` and `defaultChecked` properties are used together.\n\n## Rule Details\n\nExample of **incorrect** code for this rule:\n\n```jsx\n<input type=\"checkbox\" checked />\n<input type=\"checkbox\" checked defaultChecked />\n<input type=\"radio\" checked defaultChecked />\n\nReact.createElement('input', { checked: false });\nReact.createElement('input', { type: 'checkbox', checked: true });\nReact.createElement('input', { type: 'checkbox', checked: true, defaultChecked: true });\n```\n\nExample of **correct** code for this rule:\n\n```jsx\n<input type=\"checkbox\" checked onChange={() => {}} />\n<input type=\"checkbox\" checked readOnly />\n<input type=\"checkbox\" checked onChange readOnly />\n<input type=\"checkbox\" defaultChecked />\n\nReact.createElement('input', { type: 'checkbox', checked: true, onChange() {} });\nReact.createElement('input', { type: 'checkbox', checked: true, readOnly: true });\nReact.createElement('input', { type: 'checkbox', checked: true, onChange() {}, readOnly: true });\nReact.createElement('input', { type: 'checkbox', defaultChecked: true });\n```\n\n## Rule Options\n\n```js\n\"react/checked-requires-onchange-or-readonly\": [<enabled>, {\n  \"ignoreMissingProperties\": <boolean>,\n  \"ignoreExclusiveCheckedAttribute\": <boolean>\n}]\n```\n"
  },
  {
    "path": "docs/rules/default-props-match-prop-types.md",
    "content": "# react/default-props-match-prop-types\n\n📝 Enforce all defaultProps have a corresponding non-required PropType.\n\n<!-- end auto-generated rule header -->\n\nThis rule aims to ensure that any prop in `defaultProps` has a non-required type\ndefinition.\n\n> **Note**: You can provide types in runtime types using [PropTypes] and/or\nstatically using [TypeScript] or [Flow]. This rule will validate your prop types\nregardless of how you define them.\n\nHaving `defaultProps` for non-existent prop types is likely the result of errors\nin refactoring or a sign of a missing prop type. Having a `defaultProp` for a\nrequired property similarly indicates a possible refactoring problem.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: React.PropTypes.string.isRequired,\n  bar: React.PropTypes.string\n};\n\nMyStatelessComponent.defaultProps = {\n  foo: \"foo\"\n};\n```\n\n```jsx\nvar Greeting = React.createClass({\n  render: function() {\n    return <div>Hello {this.props.foo} {this.props.bar}</div>;\n  },\n\n  propTypes: {\n    foo: React.PropTypes.string,\n    bar: React.PropTypes.string\n  },\n\n  getDefaultProps: function() {\n    return {\n      baz: \"baz\"\n    };\n  }\n});\n```\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n}\n\nGreeting.propTypes = {\n  foo: React.PropTypes.string.isRequired,\n  bar: React.PropTypes.string\n};\n\nGreeting.defaultProps = {\n  foo: \"foo\"\n};\n```\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: React.PropTypes.string,\n    bar: React.PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    baz: \"baz\"\n  };\n}\n```\n\n```jsx\ntype Props = {\n  foo: string,\n  bar?: string\n};\n\nfunction MyStatelessComponent(props: Props) {\n  return <div>Hello {props.foo} {props.bar}</div>;\n}\n\nMyStatelessComponent.defaultProps = {\n  foo: \"foo\",\n  bar: \"bar\"\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: React.PropTypes.string,\n  bar: React.PropTypes.string.isRequired\n};\n```\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: React.PropTypes.string.isRequired,\n  bar: React.PropTypes.string\n};\n\nMyStatelessComponent.defaultProps = {\n  bar: 'some default'\n};\n```\n\n```jsx\ntype Props = {\n  foo: string,\n  bar?: string\n};\n\nfunction MyStatelessComponent(props: Props) {\n  return <div>Hello {props.foo} {props.bar}</div>;\n}\n\nMyStatelessComponent.defaultProps = {\n  bar: 'some default'\n};\n```\n\n```js\nfunction NotAComponent({ foo, bar }) {}\n\nNotAComponent.propTypes = {\n  foo: React.PropTypes.string,\n  bar: React.PropTypes.string.isRequired\n};\n```\n\n## Rule Options\n\n```js\n...\n\"react/default-props-match-prop-types\": [<enabled>, { \"allowRequiredDefaults\": <boolean> }]\n...\n```\n\n### `allowRequiredDefaults`\n\nWhen `true` the rule will ignore `defaultProps` for required prop types.\n\nExamples of **correct** code for this rule, when configured with `{ \"allowRequiredDefaults\": true }`:\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: React.PropTypes.string.isRequired,\n  bar: React.PropTypes.string\n};\n\nMyStatelessComponent.defaultProps = {\n  foo: \"foo\"\n};\n```\n\n## When Not To Use It\n\nIf you don't care about stray `defaultsProps` in your components, you can disable this rule.\n\n## Related rules\n\n- [require-default-props](./require-default-props.md)\n\n## Resources\n\n- [Official React documentation on defaultProps](https://legacy.reactjs.org/docs/typechecking-with-proptypes.html#default-prop-values)\n\n[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html\n[TypeScript]: https://www.typescriptlang.org/\n[Flow]: https://flow.org/\n"
  },
  {
    "path": "docs/rules/destructuring-assignment.md",
    "content": "# react/destructuring-assignment\n\n📝 Enforce consistent usage of destructuring assignment of props, state, and context.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nRule can be set to either of `always` or `never`;\n\n```js\n\"react/destructuring-assignment\": [<enabled>, 'always']\n```\n\n## Rule Details\n\nBy default rule is set to `always` enforce destructuring assignment. Examples of **incorrect** code for this rule:\n\n```js\nconst MyComponent = (props) => {\n  return (<div id={props.id} />)\n};\n```\n\n```js\nconst Foo = class extends React.PureComponent {\n  render() {\n    return <div>{this.context.foo}</div>;\n  }\n};\n```\n\nBelow pattern is correct:\n\n```js\nconst MyComponent = ({id}) => {\n  return (<div id={id} />)\n};\n```\n\n```js\nconst MyComponent = (props, context) => {\n  const { id } = props;\n  return (<div id={id} />)\n};\n```\n\n```js\nconst Foo = class extends React.PureComponent {\n  render() {\n    const { title } = this.context;\n    return <div>{title}</div>;\n  }\n};\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`:\n\n```js\nconst MyComponent = ({id}) => {\n  return (<div id={id} />)\n};\n```\n\n```js\nconst MyComponent = (props) => {\n  const { id } = props;\n  return (<div id={id} />)\n};\n```\n\n```js\nconst Foo = class extends React.PureComponent {\n  render() {\n    const { title } = this.state;\n    return <div>{title}</div>;\n  }\n};\n```\n\nand below pattern is correct:\n\n```js\nconst MyComponent = (props) => {\n  return (<div id={props.id} />)\n};\n```\n\n```js\nconst Foo = class extends React.PureComponent {\n  render() {\n    return <div>{this.state.title}</div>;\n  }\n};\n```\n\n## Rule Options\n\n```js\n...\n\"react/destructuring-assignment\": [<enabled>, \"always\", { \"ignoreClassFields\": <boolean>, \"destructureInSignature\": \"always\" | \"ignore\" }]\n...\n```\n\n### `ignoreClassFields`\n\nWhen configured with `true`, the rule will ignore class field declarations. Examples of **correct** code for this rule:\n\n```jsx\nclass Foo extends React.PureComponent {\n  bar = this.props.bar\n}\n```\n\n### `destructureInSignature` (default: \"ignore\")\n\nThis option can be one of `always` or `ignore`. When configured with `always`, the rule will require props destructuring happens in the function signature.\n\nExamples of **incorrect** code for `destructureInSignature: 'always'` :\n\n```jsx\nfunction Foo(props) {\n  const {a} = props;\n  return <>{a}</>\n}\n```\n\nExamples of **correct** code for `destructureInSignature: 'always'` :\n\n```jsx\nfunction Foo({a}) {\n  return <>{a}</>\n}\n```\n\n```jsx\n// Ignores when props is used elsewhere\nfunction Foo(props) {\n  const {a} = props;\n  useProps(props); // NOTE: it is a bad practice to pass the props object anywhere else!\n  return <Goo a={a}/>\n}\n```\n"
  },
  {
    "path": "docs/rules/display-name.md",
    "content": "# react/display-name\n\n📝 Disallow missing displayName in a React component definition.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nDisplayName allows you to name your component. This name is used by React in debugging messages.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n\nconst Hello = React.memo(({ a }) => {\n  return <>{a}</>\n})\n\nexport default ({ a }) => {\n  return <>{a}</>\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  displayName: 'Hello',\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n\nconst Hello = React.memo(function Hello({ a }) {\n  return <>{a}</>\n})\n```\n\n## Rule Options\n\n```js\n...\n\"react/display-name\": [<enabled>, { \"ignoreTranspilerName\": <boolean>, \"checkContextObjects\": <boolean> }]\n...\n```\n\n### `ignoreTranspilerName` (default: `false`)\n\nWhen `true` the rule will ignore the name set by the transpiler and require a `displayName` property in this case.\n\nExamples of **correct** code for `{ ignoreTranspilerName: true }` option:\n\n```jsx\nvar Hello = createReactClass({\n  displayName: 'Hello',\n\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\nmodule.exports = Hello;\n```\n\n```jsx\nexport default class Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\nHello.displayName = 'Hello';\n```\n\n```jsx\nexport default function Hello({ name }) {\n  return <div>Hello {name}</div>;\n}\nHello.displayName = 'Hello';\n```\n\nExamples of **incorrect** code for `{ ignoreTranspilerName: true }` option:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\nmodule.exports = Hello;\n```\n\n```jsx\nexport default class Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\n```jsx\nmodule.exports = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n```jsx\nexport default class extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\n```jsx\nfunction HelloComponent() {\n  return createReactClass({\n    render: function() {\n      return <div>Hello {this.props.name}</div>;\n    }\n  });\n}\nmodule.exports = HelloComponent();\n```\n\n### checkContextObjects (default: `false`)\n\n`displayName` allows you to [name your context](https://reactjs.org/docs/context.html#contextdisplayname) object. This name is used in the React dev tools for the context's `Provider` and `Consumer`.\nWhen `true` this rule will warn on context objects without a `displayName`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nconst Hello = React.createContext();\n```\n\n```jsx\nconst Hello = createContext();\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst Hello = React.createContext();\nHello.displayName = \"HelloContext\";\n```\n\n```jsx\nconst Hello = createContext();\nHello.displayName = \"HelloContext\";\n```\n\n## About component detection\n\nFor this rule to work we need to detect React components, this could be very hard since components could be declared in a lot of ways.\n\nFor now we should detect components created with:\n\n- `createReactClass()`\n- an ES6 class that inherit from `React.Component` or `Component`\n- a stateless function that return JSX or the result of a `React.createElement` call.\n"
  },
  {
    "path": "docs/rules/forbid-component-props.md",
    "content": "# react/forbid-component-props\n\n📝 Disallow certain props on components.\n\n<!-- end auto-generated rule header -->\n\nBy default this rule prevents passing of [props that add lots of complexity](https://medium.com/brigade-engineering/don-t-pass-css-classes-between-components-e9f7ab192785) (`className`, `style`) to Components. This rule only applies to Components (e.g. `<Foo />`) and not DOM nodes (e.g. `<div />`). The list of forbidden props can be customized with the `forbid` option.\n\n## Rule Details\n\nThis rule checks all JSX elements and verifies that no forbidden props are used\non Components. This rule is off by default.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello className='foo' />\n```\n\n```jsx\n<Hello style={{color: 'red'}} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name='Joe' />\n```\n\n```jsx\n<div className='foo' />\n```\n\n```jsx\n<div style={{color: 'red'}} />\n```\n\n## Rule Options\n\n```js\n...\n\"react/forbid-component-props\": [<enabled>, { \"forbid\": [<string>|<object>] }]\n...\n```\n\n### `forbid`\n\nAn array specifying the names of props that are forbidden. The default value of this option is `['className', 'style']`.\nEach array element can either be a string with the property name or object specifying the property name or glob string, an optional\ncustom message, and a component allowlist:\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"allowedFor\": [\"SomeComponent\", \"AnotherComponent\"],\n  \"message\": \"Avoid using someProp except SomeComponent and AnotherComponent\"\n}\n```\n\nUse `disallowedFor` as an exclusion list to warn on props for specific components. `disallowedFor` must have at least one item.\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"disallowedFor\": [\"SomeComponent\", \"AnotherComponent\"],\n  \"message\": \"Avoid using someProp for SomeComponent and AnotherComponent\"\n}\n```\n\nFor `propNamePattern` glob string patterns:\n\n```js\n{\n  \"propNamePattern\": '**-**',\n  \"allowedFor\": ['div'],\n  \"message\": \"Avoid using kebab-case except div\"\n}\n```\n\n```js\n{\n  \"propNamePattern\": '**-**',\n  \"allowedForPatterns\": [\"*Component\"],\n  \"message\": \"Avoid using kebab-case except components that match the `*Component` pattern\"\n}\n```\n\nUse `allowedForPatterns` for glob string patterns:\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"allowedForPatterns\": [\"*Component\"],\n  \"message\": \"Avoid using `someProp` except components that match the `*Component` pattern\"\n}\n```\n\nUse `disallowedForPatterns` for glob string patterns:\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"disallowedForPatterns\": [\"*Component\"],\n  \"message\": \"Avoid using `someProp` for components that match the `*Component` pattern\"\n}\n```\n\nCombine several properties to cover more cases:\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"allowedFor\": ['div'],\n  \"allowedForPatterns\": [\"*Component\"],\n  \"message\": \"Avoid using `someProp` except `div` and components that match the `*Component` pattern\"\n}\n```\n\n### Related rules\n\n- [forbid-dom-props](./forbid-dom-props.md)\n"
  },
  {
    "path": "docs/rules/forbid-dom-props.md",
    "content": "# react/forbid-dom-props\n\n📝 Disallow certain props on DOM Nodes.\n\n<!-- end auto-generated rule header -->\n\nThis rule prevents passing of props to elements. This rule only applies to DOM Nodes (e.g. `<div />`) and not Components (e.g. `<Component />`).\nThe list of forbidden props can be customized with the `forbid` option.\n\n## Rule Details\n\nThis rule checks all JSX elements and verifies that no forbidden props are used\non DOM Nodes. This rule is off by default.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// [1, { \"forbid\": [\"id\"] }]\n<div id='Joe' />\n```\n\n```jsx\n// [1, { \"forbid\": [\"style\"] }]\n<div style={{color: 'red'}} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// [1, { \"forbid\": [\"id\"] }]\n<Hello id='foo' />\n```\n\n```jsx\n// [1, { \"forbid\": [\"id\"] }]\n<Hello id={{color: 'red'}} />\n```\n\n## Rule Options\n\n```js\n...\n\"react/forbid-dom-props\": [<enabled>, { \"forbid\": [<string>|<object>] }]\n...\n```\n\n### `forbid`\n\nAn array of strings, with the names of props that are forbidden. The default value of this option is `[]`.\nEach array element can either be a string with the property name or object specifying the property name, an optional\ncustom message, DOM nodes disallowed list (e.g. `<div />`), and a list of prohibited values:\n\n```js\n{\n  \"propName\": \"someProp\",\n  \"disallowedFor\": [\"DOMNode\", \"AnotherDOMNode\"],\n  \"disallowedValues\": [\"someValue\"],\n  \"message\": \"Avoid using someProp\"\n}\n```\n\nExample of **incorrect** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedFor: ['span'] }] }`.\n\n```jsx\nconst First = (props) => (\n  <span someProp=\"bar\" />\n);\n```\n\nExample of **correct** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedFor: ['span'] }] }`.\n\n```jsx\nconst First = (props) => (\n  <div someProp=\"bar\" />\n);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedValues: ['someValue'] }] }`.\n\n```jsx\nconst First = (props) => (\n  <div someProp=\"someValue\" />\n);\n```\n\n```jsx\nconst First = (props) => (\n  <span someProp=\"someValue\" />\n);\n```\n\nExamples of **correct** code for this rule, when configured with `{ forbid: [{ propName: 'someProp', disallowedValues: ['someValue'] }] }`.\n\n```jsx\nconst First = (props) => (\n  <Foo someProp=\"someValue\" />\n);\n```\n\n```jsx\nconst First = (props) => (\n  <div someProp=\"value\" />\n);\n```\n\n### Related rules\n\n- [forbid-component-props](./forbid-component-props.md)\n"
  },
  {
    "path": "docs/rules/forbid-elements.md",
    "content": "# react/forbid-elements\n\n📝 Disallow certain elements.\n\n<!-- end auto-generated rule header -->\n\nYou may want to forbid usage of certain elements in favor of others, (e.g. forbid all `<div />` and use `<Box />` instead). This rule allows you to configure a list of forbidden elements and to specify their desired replacements.\n\n## Rule Details\n\nThis rule checks all JSX elements and `React.createElement` calls and verifies that no forbidden elements are used. This rule is off by default. If on, no elements are forbidden by default.\n\n## Rule Options\n\n```js\n...\n\"react/forbid-elements\": [<enabled>, { \"forbid\": [<string|object>] }]\n...\n```\n\n### `forbid`\n\nAn array of strings and/or objects. An object in this array may have the following properties:\n\n- `element` (required): the name of the forbidden element (e.g. `'button'`, `'Modal'`)\n- `message`: additional message that gets reported\n\nA string item in the array is a shorthand for `{ element: string }`.\n\nExamples of **correct** code for this rule:\n\n```jsx\n// [1, { \"forbid\": [\"button\"] }]\n<Button />\n\n// [1, { \"forbid\": [{ \"element\": \"button\" }] }]\n<Button />\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// [1, { \"forbid\": [\"button\"] }]\n<button />\nReact.createElement('button');\n\n// [1, { \"forbid\": [\"Modal\"] }]\n<Modal />\nReact.createElement(Modal);\n\n// [1, { \"forbid\": [\"Namespaced.Element\"] }]\n<Namespaced.Element />\nReact.createElement(Namespaced.Element);\n\n// [1, { \"forbid\": [{ \"element\": \"button\", \"message\": \"use <Button> instead\" }, \"input\"] }]\n<div><button /><input /></div>\nReact.createElement('div', {}, React.createElement('button', {}, React.createElement('input')));\n```\n\n## When Not To Use It\n\nIf you don't want to forbid any elements.\n"
  },
  {
    "path": "docs/rules/forbid-foreign-prop-types.md",
    "content": "# react/forbid-foreign-prop-types\n\n📝 Disallow using another component's propTypes.\n\n<!-- end auto-generated rule header -->\n\nThis rule forbids using another component's prop types unless they are explicitly imported/exported. This allows people who want to use [babel-plugin-transform-react-remove-prop-types](https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types) to remove propTypes from their components in production builds, to do so safely.\n\nIn order to ensure that imports are explicitly exported it is recommended to use the [\"named\" rule in eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import/blob/HEAD/docs/rules/named.md) in conjunction with this rule.\n\n## Rule Details\n\nThis rule checks all objects and ensures that the `propTypes` property is not used.\n\nExamples of **incorrect** code for this rule:\n\n```js\nimport SomeComponent from './SomeComponent';\nSomeComponent.propTypes;\n\nvar { propTypes } = SomeComponent;\n\nSomeComponent['propTypes'];\n```\n\nExamples of **correct** code for this rule:\n\n```js\nimport SomeComponent, {propTypes as someComponentPropTypes} from './SomeComponent';\n```\n\n## Rule Options\n\n```js\n...\n\"react/forbid-foreign-prop-types\": [<enabled>, { \"allowInPropTypes\": [<boolean>] }]\n...\n```\n\n### `allowInPropTypes`\n\nIf `true`, the rule will not warn on foreign propTypes usage inside a propTypes declaration.\n\n## When Not To Use It\n\nThis rule aims to make a certain production optimization, removing prop types, less prone to error. This rule may not be relevant to you if you do not wish to make use of this optimization.\n\nIf you are writing a higher-order component that hoists the wrapped component's propTypes, you might want to disable this rule.\n"
  },
  {
    "path": "docs/rules/forbid-prop-types.md",
    "content": "# react/forbid-prop-types\n\n📝 Disallow certain propTypes.\n\n<!-- end auto-generated rule header -->\n\nBy default this rule prevents vague prop types with more specific alternatives available (`any`, `array`, `object`), but any prop type can be disabled if desired. The defaults are chosen because they have obvious replacements. `any` should be replaced with, well, anything. `array` and `object` can be replaced with `arrayOf` and `shape`, respectively.\n\n## Rule Details\n\nThis rule checks all JSX components and verifies that no forbidden propsTypes are used.\nThis rule is off by default.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Component = createReactClass({\n  propTypes: {\n    a: PropTypes.any,\n    r: PropTypes.array,\n    o: PropTypes.object\n  },\n...\n});\n\nclass Component extends React.Component {\n  ...\n}\nComponent.propTypes = {\n  a: PropTypes.any,\n  r: PropTypes.array,\n  o: PropTypes.object\n};\n\nclass Component extends React.Component {\n  static propTypes = {\n    a: PropTypes.any,\n    r: PropTypes.array,\n    o: PropTypes.object\n  }\n  render() {\n    return <div />;\n  }\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/forbid-prop-types\": [<enabled>, { \"forbid\": [<string>], \"checkContextTypes\": <boolean>, \"checkChildContextTypes\": <boolean> }]\n...\n```\n\n### `forbid`\n\nAn array of strings, with the names of `PropTypes` keys that are forbidden. The default value for this option is `['any', 'array', 'object']`.\n\n### `checkContextTypes`\n\nWhether or not to check `contextTypes` for forbidden prop types. The default value is `false`.\n\n### `checkChildContextTypes`\n\nWhether or not to check `childContextTypes` for forbidden prop types. The default value is `false`.\n\n## When Not To Use It\n\nThis rule is a formatting/documenting preference and not following it won't negatively affect the quality of your code. This rule encourages prop types that more specifically document their usage.\n"
  },
  {
    "path": "docs/rules/forward-ref-uses-ref.md",
    "content": "# react/forward-ref-uses-ref\n\n📝 Require all forwardRef components include a ref parameter.\n\n💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\nRequires that components wrapped with `forwardRef` must have a `ref` parameter. Omitting the `ref` argument is usually a bug, and components not using `ref` don't need to be wrapped by `forwardRef`.\n\nSee <https://react.dev/reference/react/forwardRef>\n\n## Rule Details\n\nThis rule checks all React components using `forwardRef` and verifies that there is a second parameter.\n\nThe following patterns are considered warnings:\n\n```jsx\nvar React = require('react');\n\nvar Component = React.forwardRef((props) => (\n    <div />\n));\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nvar React = require('react');\n\nvar Component = React.forwardRef((props, ref) => (\n    <div ref={ref} />\n));\n\nvar Component = React.forwardRef((props, ref) => (\n    <div />\n));\n\nfunction Component(props) {\n    return <div />;\n};\n```\n\n## When not to use\n\nIf you don't want to enforce that components using `forwardRef` utilize the forwarded ref.\n"
  },
  {
    "path": "docs/rules/function-component-definition.md",
    "content": "# react/function-component-definition\n\n📝 Enforce a specific function type for function components.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nThis option enforces a specific function type for function components.\n\n## Rule Details\n\nThis rule is aimed to enforce consistent function types for function components. By default it prefers function declarations for named components and function expressions for unnamed components.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// function expression for named component\nconst Component = function (props) {\n  return <div>{props.content}</div>;\n};\n\n// arrow function for named component\nconst Component = (props) => {\n  return <div>{props.content}</div>;\n};\n\n// arrow function for unnamed component\nfunction getComponent() {\n  return (props) => {\n    return <div>{props.content}</div>;\n  };\n}\n```\n\n## Rule Options\n\nThis rule takes an options object as a second parameter where the preferred function type for components can be specified.\nThe first property of the options object is `\"namedComponents\"` which can be `\"function-declaration\"`, `\"function-expression\"`, `\"arrow-function\"`, or an array containing any of those, and has `'function-declaration'` as its default.\nThe second property is `\"unnamedComponents\"` that can be either `\"function-expression\"`, `\"arrow-function\"`, or an array containing any of those, and has `'function-expression'` as its default.\n\n```js\n...\n\"react/function-component-definition\": [<enabled>, {\n  \"namedComponents\": \"function-declaration\" | \"function-expression\" | \"arrow-function\" | Array<\"function-declaration\" | \"function-expression\" | \"arrow-function\">,\n  \"unnamedComponents\": \"function-expression\" | \"arrow-function\" | Array<\"function-expression\" | \"arrow-function\">\n}]\n...\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// only function declarations for named components\n// [2, { \"namedComponents\": \"function-declaration\" }]\nconst Component = function (props) {\n  return <div />;\n};\n\nconst Component = (props) => {\n  return <div />;\n};\n\n// only function expressions for named components\n// [2, { \"namedComponents\": \"function-expression\" }]\nfunction Component (props) {\n  return <div />;\n};\n\nconst Component = (props) => {\n  return <div />;\n};\n\n// only arrow functions for named components\n// [2, { \"namedComponents\": \"arrow-function\" }]\nfunction Component (props) {\n  return <div />;\n};\n\nconst Component = function (props) {\n  return <div />;\n};\n\n// only function expressions for unnamed components\n// [2, { \"unnamedComponents\": \"function-expression\" }]\nfunction getComponent () {\n  return (props) => {\n    return <div />;\n  };\n}\n\n// only arrow functions for unnamed components\n// [2, { \"unnamedComponents\": \"arrow-function\" }]\nfunction getComponent () {\n  return function (props) {\n    return <div />;\n  };\n}\n\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n\n// only function declarations for named components\n// [2, { \"namedComponents\": \"function-declaration\" }]\nfunction Component (props) {\n  return <div />;\n}\n\n// only function expressions for named components\n// [2, { \"namedComponents\": \"function-expression\" }]\nconst Component = function (props) {\n  return <div />;\n};\n\n// only arrow functions for named components\n// [2, { \"namedComponents\": \"arrow-function\" }]\nconst Component = (props) => {\n  return <div />;\n};\n\n// only function expressions for unnamed components\n// [2, { \"unnamedComponents\": \"function-expression\" }]\nfunction getComponent () {\n  return function (props) {\n    return <div />;\n  };\n}\n\n// only arrow functions for unnamed components\n// [2, { \"unnamedComponents\": \"arrow-function\" }]\nfunction getComponent () {\n  return (props) => {\n    return <div />;\n  };\n}\n\n```\n\n## Unfixable patterns\n\nThere is one unfixable pattern in JavaScript.\n\nIt has to do with the fact that this is valid syntax:\n\n```js\nexport default function getComponent () {\n  return <div />;\n}\n```\n\nWhile these are not:\n\n```js\nexport default var getComponent = () => {\n  return <div />;\n}\n\nexport default var getComponent = function () {\n  return <div />;\n}\n```\n\nThese patterns have to be manually fixed.\n\n## Heads up, TypeScript users\n\nNote that the autofixer is somewhat constrained for TypeScript users.\n\nThe following patterns can **not** be autofixed in TypeScript:\n\n```tsx\n// function expressions and arrow functions that have type annotations cannot be autofixed to function declarations\n// [2, { \"namedComponents\": \"function-declaration\" }]\nconst Component: React.FC<Props> = function (props) {\n  return <div />;\n};\n\nconst Component: React.FC<Props> = (props) => {\n  return <div />;\n};\n\n// function components with one unconstrained type parameter cannot be autofixed to arrow functions because the syntax conflicts with jsx\n// [2, { \"namedComponents\": \"arrow-function\" }]\nfunction Component<T>(props: Props<T>) {\n  return <div />;\n};\n\nconst Component = function <T>(props: Props<T>) {\n  return <div />;\n};\n\n// [2, { \"unnamedComponents\": \"arrow-function\" }]\nfunction getComponent() {\n  return function <T>(props: Props<T>) => {\n    return <div />;\n  }\n}\n```\n\nType parameters do not produce syntax conflicts if either there are multiple type parameters or, if there is only one constrained type parameter.\n\nThe following patterns can be autofixed in TypeScript:\n\n```tsx\n// autofix to function expression with type annotation\n// [2, { \"namedComponents\": \"function-expression\" }]\nconst Component: React.FC<Props> = (props) => {\n  return <div />;\n};\n\n// autofix to arrow function with type annotation\n// [2, { \"namedComponents\": \"function-expression\" }]\nconst Component: React.FC<Props> = function (props) {\n  return <div />;\n};\n\n// autofix to named arrow function with one constrained type parameter\n// [2, { \"namedComponents\": \"arrow-function\" }]\nfunction Component<T extends {}>(props: Props<T>) {\n  return <div />;\n}\n\nconst Component = function <T extends {}>(props: Props<T>) {\n  return <div />;\n};\n\n// autofix to named arrow function with multiple type parameters\n// [2, { \"namedComponents\": \"arrow-function\" }]\nfunction Component<T1, T2>(props: Props<T1, T2>) {\n  return <div />;\n}\n\nconst Component = function <T1, T2>(props: Props<T2>) {\n  return <div />;\n};\n\n// autofix to unnamed arrow function with one constrained type parameter\n// [2, { \"unnamedComponents\": \"arrow-function\" }]\nfunction getComponent() {\n  return function <T extends {}> (props: Props<T>) => {\n    return <div />;\n  };\n}\n\n// autofix to unnamed arrow function with multiple type parameters\n// [2, { \"unnamedComponents\": \"arrow-function\" }]\nfunction getComponent() {\n  return function <T1, T2>(props: Props<T1, T2>) => {\n    return <div />;\n  }\n}\n\n```\n\n## When Not To Use It\n\nIf you are not interested in consistent types of function components.\n"
  },
  {
    "path": "docs/rules/hook-use-state.md",
    "content": "# react/hook-use-state\n\n📝 Ensure destructuring and symmetric naming of useState hook value and setter variables.\n\n💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\n💡 This rule provides editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).\n\n## Rule Details\n\nThis rule checks whether the value and setter variables destructured from a `React.useState()` call are named symmetrically.\n\nExamples of **incorrect** code for this rule:\n\n```js\nimport React from 'react';\nexport default function useColor() {\n  // useState call is not destructured into value + setter pair\n  const useStateResult = React.useState();\n  return useStateResult;\n}\n```\n\n```js\nimport React from 'react';\nexport default function useColor() {\n  // useState call is destructured into value + setter pair, but identifier\n  // names do not follow the [thing, setThing] naming convention\n  const [color, updateColor] = React.useState();\n  return [color, updateColor];\n}\n```\n\nExamples of **correct** code for this rule:\n\n```js\nimport React from 'react';\nexport default function useColor() {\n  // useState call is destructured into value + setter pair whose identifiers\n  // follow the [thing, setThing] naming convention\n  const [color, setColor] = React.useState();\n  return [color, setColor];\n}\n```\n\n```js\nimport React from 'react';\nexport default function useColor() {\n  // useState result is directly returned\n  return React.useState();\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/hook-use-state\": [<enabled>, { \"allowDestructuredState\": <boolean> }]\n...\n```\n\n### `allowDestructuredState`\n\nWhen `true` the rule will ignore the name of the destructured value.\n\nExamples of **correct** code for this rule, when configured with `{ \"allowDestructuredState\": true }`:\n\n```jsx\nimport React from 'react';\nconst [{foo, bar, baz}, setFooBarBaz] = React.useState({foo: \"bbb\", bar: \"aaa\", baz: \"qqq\"})\n```\n"
  },
  {
    "path": "docs/rules/iframe-missing-sandbox.md",
    "content": "# react/iframe-missing-sandbox\n\n📝 Enforce sandbox attribute on iframe elements.\n\n<!-- end auto-generated rule header -->\n\nThe sandbox attribute enables an extra set of restrictions for the content in the iframe. Using sandbox attribute is considered a good security practice.\n\nSee <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox>\n\n## Rule Details\n\nThis rule checks all React iframe elements and verifies that there is sandbox attribute and that it's value is valid. In addition to that it also reports cases where attribute contains `allow-scripts` and `allow-same-origin` at the same time as this combination allows the embedded document to remove the sandbox attribute and bypass the restrictions.\n\nThe following patterns are considered warnings:\n\n```jsx\nvar React = require('react');\n\nvar Frame = () => (\n    <div>\n        <iframe></iframe>\n        {React.createElement('iframe')}\n    </div>\n);\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nvar React = require('react');\n\nvar Frame = <iframe sandbox=\"allow-popups\"/>;\nvar Frame = () => (\n    <div>\n        <iframe sandbox=\"allow-popups\"></iframe>\n        {React.createElement('iframe', { sandbox: \"allow-popups\" })}\n    </div>\n);\n```\n\n## When not to use\n\nIf you don't want to enforce sandbox attribute on iframe elements.\n"
  },
  {
    "path": "docs/rules/jsx-boolean-value.md",
    "content": "# react/jsx-boolean-value\n\n📝 Enforce boolean attributes notation in JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nWhen using a [boolean attribute in JSX](https://web.archive.org/web/20160607204033/http://facebook.github.io/react/docs/jsx-in-depth.html#boolean-attributes), you can set the attribute value to `true` or omit the value.\n\n## Rule Details\n\nThis rule will enforce one or the other to keep consistency in your code.\n\n## Rule Options\n\nThis rule takes two arguments. If the first argument is `\"always\"` then it warns whenever an attribute is missing its value. If `\"never\"` then it warns if an attribute has a `true` value. The default value of this option is `\"never\"`.\n\nThe second argument is optional. If provided, it must be an object. These properties are supported:\n\nFirst, the `\"never\"` and `\"always\"` properties are one set. The two properties cannot be set together. `\"never\"` must be used when the first argument is `\"always\"` and `\"always\"`  must be used when the first argument is `\"never\"`. This property’s value must be an array of strings representing prop names.\n\nWhen the first argument is `\"never\"`, a boolean `\"assumeUndefinedIsFalse\"` may be provided, which defaults to `false`. When `true`, an absent boolean prop will be treated as if it were explicitly set to `false`.\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`, or with `\"always\", { \"never\": [\"personal\"] }`:\n\n```jsx\nvar Hello = <Hello personal={true} />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\"`, or with `\"always\", { \"never\": [\"personal\"] }`:\n\n```jsx\nvar Hello = <Hello personal />;\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"`, or with `\"never\", { \"always\": [\"personal\"] }`:\n\n```jsx\nvar Hello = <Hello personal />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"always\"`, or with `\"never\", { \"always\": [\"personal\"] }`:\n\n```jsx\nvar Hello = <Hello personal={true} />;\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\", { \"assumeUndefinedIsFalse\": true }`, or with  `\"always\", { \"never\": [\"personal\"], \"assumeUndefinedIsFalse\": true }`:\n\n```jsx\nvar Hello = <Hello personal={false} />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\", { \"assumeUndefinedIsFalse\": true }`, or with  `\"always\", { \"never\": [\"personal\"], \"assumeUndefinedIsFalse\": true }`:\n\n```jsx\nvar Hello = <Hello />;\n```\n\n## When Not To Use It\n\nIf you do not want to enforce any style for boolean attributes, then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-child-element-spacing.md",
    "content": "# react/jsx-child-element-spacing\n\n📝 Enforce or disallow spaces inside of curly braces in JSX attributes and expressions.\n\n<!-- end auto-generated rule header -->\n\n## Rule Details\n\nSince React removes extraneous new lines between elements when possible, it is possible to end up with inline elements that are not rendered with spaces between them and adjacent text. This is often indicative of an error, so this rule attempts to detect JSX markup with ambiguous spacing.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div>\n  Here is a\n  <a>link</a>\n</div>\n```\n\n```jsx\n<div>\n  <b>This text</b>\n  is bold\n</div>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>\n  Spacing is\n  {' '}\n  <a>explicit</a>\n</div>\n```\n\n```jsx\n<div>\n  Lack of spacing is{/*\n  */}<a>explicit</a>\n</div>\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with inline elements appearing adjacent to text,\nor if you always explicitly include `{' '}` between elements to denote spacing.\n"
  },
  {
    "path": "docs/rules/jsx-closing-bracket-location.md",
    "content": "# react/jsx-closing-bracket-location\n\n📝 Enforce closing bracket location in JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nEnforce the closing bracket location for JSX multiline elements.\n\n## Rule Details\n\nThis rule checks all JSX multiline elements and verifies the location of the closing bracket. By default this one must be aligned with the opening tag.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello\n  lastName=\"Smith\"\n  firstName=\"John\" />;\n\n<Hello\n  lastName=\"Smith\"\n  firstName=\"John\"\n  />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello firstName=\"John\" lastName=\"Smith\" />;\n\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n```\n\n## Rule Options\n\nThere are two ways to configure this rule.\n\nThe first form is a string shortcut corresponding to the `location` values specified below. If omitted, it defaults to `\"tag-aligned\"`.\n\n```js\n\"react/jsx-closing-bracket-location\": <enabled> // -> [<enabled>, \"tag-aligned\"]\n\"react/jsx-closing-bracket-location\": [<enabled>, \"<location>\"]\n```\n\nThe second form allows you to distinguish between non-empty and self-closing tags. Both properties are optional, and both default to `\"tag-aligned\"`. You can also disable the rule for one particular type of tag by setting the value to `false`.\n\n```js\n\"react/jsx-closing-bracket-location\": [<enabled>, {\n  \"nonEmpty\": \"<location>\" || false,\n  \"selfClosing\": \"<location>\" || false\n}]\n```\n\n### `location`\n\nEnforced location for the closing bracket.\n\n- `tag-aligned`: must be aligned with the opening tag.\n- `line-aligned`: must be aligned with the line containing the opening tag.\n- `after-props`: must be placed right after the last prop.\n- `props-aligned`: must be aligned with the last prop.\n\nDefaults to `tag-aligned`.\n\nFor backward compatibility, you may pass an object `{ \"location\": <location> }` that is equivalent to the first string shortcut form.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 'jsx-closing-bracket-location': 1\n// 'jsx-closing-bracket-location': [1, 'tag-aligned']\n// 'jsx-closing-bracket-location': [1, 'line-aligned']\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n  />;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\">\n  Hello\n</Say>;\n\n// 'jsx-closing-bracket-location': 1\n// 'jsx-closing-bracket-location': [1, 'tag-aligned']\nvar x = <Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n\nvar x = function() {\n  return <Say\n    firstName=\"John\"\n    lastName=\"Smith\"\n  >\n    Hello\n  </Say>;\n};\n\n// 'jsx-closing-bracket-location': [1, 'line-aligned']\nvar x = <Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n        />;\n\nvar x = function() {\n  return <Say\n    firstName=\"John\"\n    lastName=\"Smith\"\n         >\n    Hello\n         </Say>;\n};\n\n// 'jsx-closing-bracket-location': [1, 'after-props']\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\" />;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\">\n  Hello\n</Say>;\n\n// 'jsx-closing-bracket-location': [1, 'props-aligned']\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n  />;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\"\n  >\n  Hello\n</Say>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// 'jsx-closing-bracket-location': 1\n// 'jsx-closing-bracket-location': [1, 'tag-aligned']\n// 'jsx-closing-bracket-location': [1, 'line-aligned']\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\"\n>\n  Hello\n</Say>;\n\n// 'jsx-closing-bracket-location': 1\n// 'jsx-closing-bracket-location': [1, 'tag-aligned']\nvar x = <Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n        />;\n\nvar x = function() {\n  return <Say\n    firstName=\"John\"\n    lastName=\"Smith\"\n         >\n    Hello\n         </Say>;\n};\n\n// 'jsx-closing-bracket-location': [1, 'line-aligned']\nvar x = <Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n\nvar x = function() {\n  return <Say\n    firstName=\"John\"\n    lastName=\"Smith\"\n  >\n    Hello\n  </Say>;\n};\n\n// 'jsx-closing-bracket-location': [1, {selfClosing: 'after-props'}]\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\" />;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\"\n>\n  Hello\n</Say>;\n\n// 'jsx-closing-bracket-location': [1, {selfClosing: 'props-aligned', nonEmpty: 'after-props'}]\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n  />;\n\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\">\n  Hello\n</Say>;\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-closing-tag-location.md",
    "content": "# react/jsx-closing-tag-location\n\n📝 Enforce closing tag location for multiline JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nEnforce the closing tag location for multiline JSX elements.\n\n## Rule Details\n\nThis rule checks all JSX multiline elements with children (non-self-closing) and verifies the location of the closing tag. The expectation is that the closing tag is aligned with the opening tag on its own line.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello>\n  marklar\n  </Hello>\n```\n\n```jsx\n<Hello>\n  marklar</Hello>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello>\n  marklar\n</Hello>\n```\n\n```jsx\n<Hello>marklar</Hello>\n```\n\n## Rule Options\n\nThere is one way to configure this rule.\n\nThe configuration is a string shortcut corresponding to the `location` values specified below. If omitted, it defaults to `\"tag-aligned\"`.\n\n```js\n\"react/jsx-closing-tag-location\": <enabled> // -> [<enabled>, \"tag-aligned\"]\n\"react/jsx-closing-tag-location\": [<enabled>, \"<location>\"]\n```\n\n### `location`\n\nEnforced location for the closing tag.\n\n- `tag-aligned`: must be aligned with the opening tag.\n- `line-aligned`: must be aligned with the line containing the opening tag.\n\nDefaults to `tag-aligned`.\n\nFor backward compatibility, you may pass an object `{ \"location\": <location> }` that is equivalent to the first string shortcut form.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 'jsx-closing-tag-location': 1\n// 'jsx-closing-tag-location': [1, 'tag-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'tag-aligned'}]\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\">\n  Hello\n  </Say>;\n\n// 'jsx-closing-tag-location': [1, 'tag-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'tag-aligned'}]\nconst App = <Bar>\n  Foo\n</Bar>;\n\n\n// 'jsx-closing-tag-location': [1, 'line-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'line-aligned'}]\nconst App = <Bar>\n  Foo\n            </Bar>;\n\n\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// 'jsx-closing-tag-location': 1\n// 'jsx-closing-tag-location': [1, 'tag-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'tag-aligned'}]\n<Say\n  firstName=\"John\"\n  lastName=\"Smith\">\n  Hello\n</Say>;\n\n// 'jsx-closing-tag-location': [1, 'tag-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'tag-aligned'}]\nconst App = <Bar>\n  Foo\n            </Bar>;\n\n// 'jsx-closing-tag-location': [1, 'line-aligned']\n// 'jsx-closing-tag-location': [1, {\"location\":'line-aligned'}]\nconst App = <Bar>\n  Foo\n</Bar>;\n\n```\n\n## When Not To Use It\n\nIf you do not care about closing tag JSX alignment then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-curly-brace-presence.md",
    "content": "# react/jsx-curly-brace-presence\n\n📝 Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nThis rule allows you to enforce curly braces or disallow unnecessary curly braces in JSX props and/or children.\n\nFor situations where JSX expressions are unnecessary, please refer to [the React doc](https://legacy.reactjs.org/docs/jsx-in-depth.html) and [this page about JSX gotchas](https://github.com/facebook/react/blob/v15.4.0-rc.3/docs/docs/02.3-jsx-gotchas.md#html-entities).\n\n## Rule Details\n\nBy default, this rule will check for and warn about unnecessary curly braces in both JSX props and children. For the sake of backwards compatibility, prop values that are JSX elements are not considered by default.\n\nYou can pass in options to enforce the presence of curly braces on JSX props, children, JSX prop values that are JSX elements, or any combination of the three. The same options are available for not allowing unnecessary curly braces as well as ignoring the check.\n\n**Note**: it is _highly recommended_ that you configure this rule with an object, and that you set \"propElementValues\" to \"always\". The ability to omit curly braces around prop values that are JSX elements is obscure, and intentionally undocumented, and should not be relied upon.\n\n## Rule Options\n\n```js\n...\n\"react/jsx-curly-brace-presence\": [<enabled>, { \"props\": <string>, \"children\": <string>, \"propElementValues\": <string> }]\n...\n```\n\nor alternatively\n\n```js\n...\n\"react/jsx-curly-brace-presence\": [<enabled>, <string>]\n...\n```\n\n### Valid options for `<string>`\n\nThey are `always`, `never` and `ignore` for checking on JSX props and children.\n\n- `always`: always enforce curly braces inside JSX props, children, and/or JSX prop values that are JSX Elements\n- `never`: never allow unnecessary curly braces inside JSX props, children, and/or JSX prop values that are JSX Elements\n- `ignore`: ignore the rule for JSX props, children, and/or JSX prop values that are JSX Elements\n\nIf passed in the option to fix, this is how a style violation will get fixed\n\n- `always`: wrap a JSX attribute in curly braces/JSX expression and/or a JSX child the same way but also with double quotes\n- `never`: get rid of curly braces from a JSX attribute and/or a JSX child\n\n- All fixing operations use double quotes.\n\nFor examples:\n\nExamples of **incorrect** code for this rule, when configured with `{ props: \"always\", children: \"always\" }`:\n\n```jsx\n<App>Hello world</App>;\n<App prop='Hello world'>{'Hello world'}</App>;\n```\n\nThey can be fixed to:\n\n```jsx\n<App>{\"Hello world\"}</App>;\n<App prop={\"Hello world\"}>{'Hello world'}</App>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ props: \"never\", children: \"never\" }`:\n\n```jsx\n<App>{'Hello world'}</App>;\n<App prop={'Hello world'} attr={\"foo\"} />;\n```\n\nThey can be fixed to:\n\n```jsx\n<App>Hello world</App>;\n<App prop=\"Hello world\" attr=\"foo\" />;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ props: \"always\", children: \"always\", \"propElementValues\": \"always\" }`:\n\n```jsx\n<App prop=<div /> />;\n```\n\nThey can be fixed to:\n\n```jsx\n<App prop={<div />} />;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ props: \"never\", children: \"never\", \"propElementValues\": \"never\" }`:\n\n```jsx\n<App prop={<div />} />;\n```\n\nThey can be fixed to:\n\n```jsx\n<App prop=<div /> />;\n```\n\n### Alternative syntax\n\nThe options are also `always`, `never`, and `ignore` for the same meanings.\n\nIn this syntax, only a string is provided and the default will be set to that option for checking on both JSX props and children.\n\nFor examples:\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<App>Hello world</App>;\n<App prop='Hello world' attr=\"foo\">Hello world</App>;\n```\n\nThey can be fixed to:\n\n```jsx\n<App>{\"Hello world\"}</App>;\n<App prop={\"Hello world\"} attr={\"foo\"}>{\"Hello world\"}</App>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<App prop={'foo'} attr={\"bar\"}>{'Hello world'}</App>;\n```\n\nIt can fixed to:\n\n```jsx\n<App prop=\"foo\" attr=\"bar\">Hello world</App>;\n```\n\n## Edge cases\n\nThe fix also deals with template literals, strings with quotes, and strings with escapes characters.\n\n- If the rule is set to get rid of unnecessary curly braces and the template literal inside a JSX expression has no expression, it will throw a warning and be fixed with double quotes. For example:\n\n```jsx\n<App prop={`Hello world`}>{`Hello world`}</App>;\n```\n\nwill be warned and fixed to:\n\n```jsx\n<App prop=\"Hello world\">Hello world</App>;\n```\n\n- If the rule is set to enforce curly braces and the strings have quotes, it will be fixed with double quotes for JSX children and the normal way for JSX attributes. Also, double quotes will be escaped in the fix.\n\nFor example:\n\n```jsx\n<App prop='Hello \"foo\" world'>Hello 'foo' \"bar\" world</App>;\n```\n\nwill warned and fixed to:\n\n```jsx\n<App prop={\"Hello \\\"foo\\\" world\"}>{\"Hello 'foo' \\\"bar\\\" world\"}</App>;\n```\n\n- If the rule is set to get rid of unnecessary curly braces(JSX expression) and there are characters that need to be escaped in its JSX form, such as quote characters, [forbidden JSX text characters](https://facebook.github.io/jsx/), escaped characters and anything that looks like HTML entity names, the code will not be warned because the fix may make the code less readable.\n\nExamples of **correct** code for this rule, even when configured with `\"never\"`:\n\n```jsx\n<Color text={\"\\u00a0\"} />\n<App>{\"Hello \\u00b7 world\"}</App>;\n<style type=\"text/css\">{'.main { margin-top: 0; }'}</style>;\n/**\n * there's no way to inject a whitespace into jsx without a container so this\n * will always be allowed.\n */\n<App>{' '}</App>\n<App>{'     '}</App>\n<App>{/* comment */ <Bpp />}</App> // the comment makes the container necessary\n```\n\n## When Not To Use It\n\nYou should turn this rule off if you are not concerned about maintaining consistency regarding the use of curly braces in JSX props and/or children as well as the use of unnecessary JSX expressions.\n"
  },
  {
    "path": "docs/rules/jsx-curly-newline.md",
    "content": "# react/jsx-curly-newline\n\n📝 Enforce consistent linebreaks in curly braces in JSX attributes and expressions.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nMany style guides require or disallow newlines inside of jsx curly expressions.\n\n## Rule Details\n\nThis rule enforces consistent linebreaks inside of curlies of jsx curly expressions.\n\n## Rule Options\n\nThis rule accepts either an object option:\n\n```ts\n{\n  multiline: \"consistent\" | \"forbid\" | \"require\", // default to 'consistent'\n  singleline: \"consistent\" | \"forbid\" | \"require\", // default to 'consistent'\n}\n```\n\nOption `multiline` takes effect when the jsx expression inside the curlies occupies multiple lines.\n\nOption `singleline` takes effect when the jsx expression inside the curlies occupies a single line.\n\n- `consistent` enforces either both curly braces have a line break directly inside them, or no line breaks are present.\n- `forbid` disallows linebreaks directly inside curly braces.\n- `require` enforces the presence of linebreaks directly inside curlies.\n\nor a string option:\n\n- `consistent` (default) is an alias for `{ multiline: \"consistent\", singleline: \"consistent\" }`.\n- `never` is an alias for `{ multiline: \"forbid\", singleline: \"forbid\" }`\n\nor an\n\n### consistent (default)\n\nExamples of **incorrect** code for this rule, when configured with `consistent` or `{ multiline: \"consistent\", singleline: \"consistent\" }`:\n\n```jsx\n<div>\n  { foo\n  }\n</div>\n\n<div>\n  {\n    foo }\n</div>\n\n<div>\n  { foo &&\n    foo.bar\n  }\n</div>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>\n  { foo }\n</div>\n\n<div>\n  {\n    foo\n  }\n</div>\n```\n\n### never\n\nExamples of **incorrect** code for this rule, when configured with `never` or `{ multiline: \"forbid\", singleline: \"forbid\" }`:\n\n```jsx\n<div>\n  {\n    foo &&\n    foo.bar\n  }\n</div>\n\n<div>\n  {\n    foo\n  }\n</div>\n\n<div>\n  { foo\n  }\n</div>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>\n  { foo &&\n    foo.bar }\n</div>\n\n<div>\n  { foo }\n</div>\n```\n\n## require\n\nExamples of **incorrect** code for this rule, when configured with `{ multiline: \"require\", singleline: \"require\" }`:\n\n```jsx\n<div>\n  { foo &&\n    foo.bar }\n</div>\n\n<div>\n  { foo }\n</div>\n\n<div>\n  { foo\n  }\n</div>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>\n  {\n    foo &&\n    foo.bar\n  }\n</div>\n\n<div>\n  {\n    foo\n  }\n</div>\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with the consistency of padding linebreaks inside of JSX attributes or expressions.\n"
  },
  {
    "path": "docs/rules/jsx-curly-spacing.md",
    "content": "# react/jsx-curly-spacing\n\n📝 Enforce or disallow spaces inside of curly braces in JSX attributes and expressions.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nWhile formatting preferences are very personal, a number of style guides require or disallow spaces between curly braces.\n\n## Rule Details\n\nThis rule aims to maintain consistency around the spacing inside of JSX attributes and expressions inside element children.\n\nIt either requires or disallows spaces between those braces and the values inside of them.\n\n## Rule Options\n\nThere are two main options for the rule:\n\n- `{\"when\": \"always\"}` enforces a space inside of curly braces\n- `{\"when\": \"never\"}` disallows spaces inside of curly braces (default)\n\nThere are also two properties that allow specifying how the rule should work with the attributes (`attributes`) and the expressions (`children`). The possible values are:\n\n- `true` enables checking for the spacing using the options (default for `attributes`), e.g. `{\"attributes\": false}` disables checking the attributes\n- `false` disables checking for the spacing (default for `children`, for backward compatibility), e.g. `{\"children\": true}` enables checking the expressions\n- an object containing options that override the global options, e.g. `{\"when\": \"always\", \"children\": {\"when\": \"never\"}}` enforces a space inside attributes, but disallows spaces inside expressions\n\n### never\n\nExamples of **incorrect** code for this rule, when configured with `{ \"when\": \"never\" }`:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={{ firstname: 'John', lastname: 'Doe' }} />;\n<Hello name={\n  firstname\n} />;\n<Hello>{firstname}</Hello>;\n<Hello>{ firstname }</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"when\": \"never\", \"children\": true }`:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n<Hello>{ firstname }</Hello>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={{ firstname: 'John', lastname: 'Doe' }} />;\n<Hello name={\n  firstname\n} />;\n<Hello>{firstname}</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\n### always\n\nExamples of **incorrect** code for this rule, when configured with `{ \"when\": \"always\" }`:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ {firstname: 'John', lastname: 'Doe'} } />;\n<Hello name={\n  firstname\n} />;\n<Hello>{ firstname }</Hello>;\n<Hello>{firstname}</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"when\": \"always\", \"children\": true }`:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n<Hello>{firstname}</Hello>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ {firstname: 'John', lastname: 'Doe'} } />;\n<Hello name={\n  firstname\n} />;\n<Hello>{ firstname }</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\n### Braces spanning multiple lines\n\nBy default, braces spanning multiple lines are allowed with either setting. If you want to disallow them you can specify an additional `allowMultiline` property with the value `false`:\n\n```json\n\"react/jsx-curly-spacing\": [2, {\"when\": \"never\", \"allowMultiline\": false}]\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"` and `\"allowMultiline\": false`:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n<Hello name={\n  firstname\n} />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={{ firstname: 'John', lastname: 'Doe' }} />;\n<Hello>{firstname}</Hello>;\n<Hello>{ firstname }</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"` and `\"allowMultiline\": false`:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name={ firstname} />;\n<Hello name={firstname } />;\n<Hello name={\n  firstname\n} />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={ {firstname: 'John', lastname: 'Doe'} } />;\n<Hello>{firstname}</Hello>;\n<Hello>{ firstname }</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"when\": \"never\", \"attributes\": { \"allowMultiline\": false }, \"children\": true }`:\n\n```jsx\n<Hello name={ firstname } />;\n<Hello name={\n  firstname\n} />;\n<Hello>{ firstname }</Hello>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello name={firstname} />;\n<Hello>{firstname}</Hello>;\n<Hello>{\n  firstname\n}</Hello>;\n```\n\n### Granular spacing controls\n\nYou can specify an additional `spacing` property that is an object with the following possible values:\n\n```json\n\"react/jsx-curly-spacing\": [2, {\"when\": \"always\", \"spacing\": {\n  \"objectLiterals\": \"never\"\n}}]\n```\n\n- `objectLiterals`: This controls different spacing requirements when the value inside the jsx curly braces is an object literal.\n\nAll spacing options accept either the string `\"always\"` or the string `\"never\"`. Note that the default value for all \"spacing\" options matches the first \"always\"/\"never\" option provided.\n\nExamples of **correct** code for this rule, when configured with `\"always\"` and `{ \"objectLiterals\": \"never\" }`:\n\n```jsx\n<App blah={ 3 } foo={{ bar: true, baz: true }} />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\"` and `{ \"objectLiterals\": \"always\" }`:\n\n```jsx\n<App blah={3} foo={ {bar: true, baz: true} } />;\n```\n\nPlease note that spacing of the object literal curly braces themselves is controlled by the built-in [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing) rule.\n\n### Shorthand options\n\nTo preserve backward compatibility, two additional options are supported:\n\n```json\n\"react/jsx-curly-spacing\": [2, \"always\"]\n```\n\nwhich is a shorthand for\n\n```json\n\"react/jsx-curly-spacing\": [2, {\"when\": \"always\"}]\n```\n\nand\n\n```json\n\"react/jsx-curly-spacing\": [2, \"never\"]\n```\n\nwhich is a shorthand for\n\n```json\n\"react/jsx-curly-spacing\": [2, {\"when\": \"never\"}]\n```\n\nWhen using the shorthand options, only attributes will be checked. To specify other options, use another argument:\n\n```json\n\"react/jsx-curly-spacing\": [2, \"never\", {\n  \"allowMultiline\": false,\n  \"spacing\": {\"objectLiterals\": \"always\"}\n}]\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with the consistency around the spacing inside of JSX attributes or expressions.\n"
  },
  {
    "path": "docs/rules/jsx-equals-spacing.md",
    "content": "# react/jsx-equals-spacing\n\n📝 Enforce or disallow spaces around equal signs in JSX attributes.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nSome style guides require or disallow spaces around equal signs.\n\n## Rule Details\n\nThis rule will enforce consistency of spacing around equal signs in JSX attributes, by requiring or disallowing one or more spaces before and after `=`.\n\n## Rule Options\n\nThere are two options for the rule:\n\n- `\"always\"` enforces spaces around the equal sign\n- `\"never\"` disallows spaces around the equal sign (default)\n\nDepending on your coding conventions, you can choose either option by specifying it in your configuration:\n\n```json\n\"react/jsx-equals-spacing\": [2, \"always\"]\n```\n\n### never\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello name = {firstname} />;\n<Hello name ={firstname} />;\n<Hello name= {firstname} />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name />;\n<Hello {...props} />;\n```\n\n### always\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello name={firstname} />;\n<Hello name ={firstname} />;\n<Hello name= {firstname} />;\n```\n\nExamples of **correct** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello name = {firstname} />;\n<Hello name />;\n<Hello {...props} />;\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with the consistency of spacing around equal signs in JSX attributes.\n"
  },
  {
    "path": "docs/rules/jsx-filename-extension.md",
    "content": "# react/jsx-filename-extension\n\n📝 Disallow file extensions that may contain JSX.\n\n<!-- end auto-generated rule header -->\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// filename: MyComponent.js\nfunction MyComponent() {\n  return <div />;\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// filename: MyComponent.jsx\nfunction MyComponent() {\n  return <div />;\n}\n```\n\nBeware this rule **only** reports JSX syntax, **not** other non-standard syntax such as experimental features or type annotations.\n\n## Rule Options\n\n### `allow` (default: `\"always\"`)\n\nWhen to allow a JSX filename extension. By default all files may have a JSX extension. Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.\n\n```js\n\"rules\": {\n  \"react/jsx-filename-extension\": [1, { \"allow\": \"as-needed\" }]\n}\n```\n\n### `extensions` (default: `[\".jsx\"]`)\n\nThe set of allowed extensions is configurable. By default '.jsx' is allowed. If you wanted to allow both '.jsx' and '.js', the configuration would be:\n\n```js\n\"rules\": {\n  \"react/jsx-filename-extension\": [1, { \"extensions\": [\".js\", \".jsx\"] }]\n}\n```\n\n### `ignoreFilesWithoutCode` (default: `false`)\n\nIf enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.\n\n```js\n\"rules\": {\n  \"react/jsx-filename-extension\": [1, { \"ignoreFilesWithoutCode\": true }]\n}\n```\n\n## When Not To Use It\n\nIf you don't care about restricting the file extensions that may contain JSX.\n"
  },
  {
    "path": "docs/rules/jsx-first-prop-new-line.md",
    "content": "# react/jsx-first-prop-new-line\n\n📝 Enforce proper position of the first property in JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nEnsure correct position of the first property.\n\nNote: The fixer does not include indentation. Please rerun lint to correct those errors.\n\n## Rule Details\n\nThis rule checks whether the first property of all JSX elements is correctly placed. There are the possible configurations:\n\n- `always`: The first property should always be placed on a new line.\n- `never` : The first property should never be placed on a new line, e.g. should always be on the same line as the Component opening tag.\n- `multiline`: The first property should always be placed on a new line when the JSX tag takes up multiple lines.\n- `multiprop`: The first property should never be placed on a new line unless there are multiple properties.\n- `multiline-multiprop`: The first property should always be placed on a new line if the JSX tag takes up multiple lines and there are multiple properties. This is the `default` value.\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello personal={true} />\n\n<Hello personal={true}\n    foo=\"bar\"\n/>\n```\n\nExamples of **correct** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello\n    personal />\n\n<Hello\n    personal\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello\n    personal />\n\n<Hello\n    personal\n/>\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello personal={true} />\n\n<Hello personal={true}\n    foo=\"bar\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"multiline\"`:\n\n```jsx\n<Hello personal\n    prop />\n```\n\n```jsx\n<Hello foo={{\n}} />\n```\n\nExamples of **correct** code for this rule, when configured with `\"multiline\"`:\n\n```jsx\n<Hello personal={true} />\n\n<Hello\n    personal={true}\n    foo=\"bar\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"multiline-multiprop\"`:\n\n```jsx\n<Hello foo={{\n    }}\n    bar />\n```\n\nExamples of **correct** code for this rule, when configured with `\"multiline-multiprop\"`:\n\n```jsx\n<Hello foo={{\n}} />\n\n<Hello\n    foo={{\n    }}\n    bar\n/>\n```\n\n## Rule Options\n\n```jsx\n\"react/jsx-first-prop-new-line\": `\"always\" | \"never\" | \"multiline\" | \"multiprop\" | \"multiline-multiprop\"`\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-fragments.md",
    "content": "# react/jsx-fragments\n\n📝 Enforce shorthand or standard form for React fragments.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nIn JSX, a React [fragment] is created either with `<React.Fragment>...</React.Fragment>`, or, using the shorthand syntax, `<>...</>`.\n\n## Rule Details\n\nThis rule allows you to enforce one way or the other.\n\nSupport for fragments was added in React v16.2, so the rule will warn on either of these forms if an older React version is specified in [shared settings][shared_settings].\n\n## Rule Options\n\n```js\n...\n\"react/jsx-fragments\": [<enabled>, <mode>]\n...\n```\n\n### `syntax` mode\n\nThis is the default mode. It will enforce the shorthand syntax for React fragments, with one exception. [Keys or attributes are not supported by the shorthand syntax][short_syntax], so the rule will not warn on standard-form fragments that use those.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<React.Fragment><Foo /></React.Fragment>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<><Foo /></>\n```\n\n```jsx\n<React.Fragment key=\"key\"><Foo /></React.Fragment>\n```\n\n### `element` mode\n\nThis mode enforces the standard form for React fragments.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<><Foo /></>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<React.Fragment><Foo /></React.Fragment>\n```\n\n```jsx\n<React.Fragment key=\"key\"><Foo /></React.Fragment>\n```\n\n[fragment]: https://reactjs.org/docs/fragments.html\n[shared_settings]: /README.md#configuration\n[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax\n"
  },
  {
    "path": "docs/rules/jsx-handler-names.md",
    "content": "# react/jsx-handler-names\n\n📝 Enforce event handler naming conventions in JSX.\n\n<!-- end auto-generated rule header -->\n\nEnsures that any component or prop methods used to handle events are correctly prefixed.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<MyComponent handleChange={this.handleChange} />\n```\n\n```jsx\n<MyComponent onChange={this.componentChanged} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<MyComponent onChange={this.handleChange} />\n```\n\n```jsx\n<MyComponent onChange={this.props.onFoo} />\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-handler-names\": [<enabled>, {\n  \"eventHandlerPrefix\": <eventHandlerPrefix>,\n  \"eventHandlerPropPrefix\": <eventHandlerPropPrefix>,\n  \"checkLocalVariables\": <boolean>,\n  \"checkInlineFunction\": <boolean>,\n  \"ignoreComponentNames\": Array<string>\n}]\n...\n```\n\n- `eventHandlerPrefix`: Prefix for component methods used as event handlers. Defaults to `handle`\n- `eventHandlerPropPrefix`: Prefix for props that are used as event handlers. Defaults to `on`\n- `checkLocalVariables`: Determines whether event handlers stored as local variables are checked. Defaults to `false`\n- `checkInlineFunction`: Determines whether event handlers set as inline functions are checked. Defaults to `false`\n- `ignoreComponentNames`: Array of glob strings, when matched with component name, ignores the rule on that component. Defaults to `[]`. Supports namespaced component names (e.g., `A.TestComponent`, `A.MyLib*`)\n\n## When Not To Use It\n\nIf you are not using JSX, or if you don't want to enforce specific naming conventions for event handlers.\n"
  },
  {
    "path": "docs/rules/jsx-indent-props.md",
    "content": "# react/jsx-indent-props\n\n📝 Enforce props indentation in JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nThis option validates a specific indentation style for props.\n\n## Rule Details\n\nThis rule is aimed to enforce consistent indentation style. The default style is `4 spaces`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 2 spaces indentation\n<Hello\n  firstName=\"John\"\n/>\n\n// no indentation\n<Hello\nfirstName=\"John\"\n/>\n\n// 1 tab indentation\n<Hello\n  firstName=\"John\"\n/>\n```\n\n## Rule Options\n\nIt takes an option as the second parameter which can either be the indent mode or an object to define further settings.\nThe indent mode can be `\"tab\"` for tab-based indentation, a positive number for space indentations or `\"first\"` for aligning the first prop for each line with the tag's first prop.\nNote that using the `\"first\"` option allows very inconsistent indentation unless you also enable a rule that enforces the position of the first prop.\nIf the second parameter is an object, it can be used to specify the indent mode as well as the option `ignoreTernaryOperator`, which causes the indent level not to be increased by a `?` or `:` operator (default is `false`).\n\n```js\n...\n\"react/jsx-indent-props\": [<enabled>, 'tab'|<number>|'first'|<object>]\n...\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 2 spaces indentation\n// [2, 2]\n<Hello\n    firstName=\"John\"\n/>\n\n// tab indentation\n// [2, 'tab']\n<Hello\n  firstName=\"John\"\n/>\n\n// aligned with first prop\n// [2, 'first']\n<Hello\n  firstName=\"John\"\n    lastName=\"Doe\"\n/>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n\n// 2 spaces indentation\n// [2, 2]\n<Hello\n  firstName=\"John\"\n/>\n\n<Hello\n  firstName=\"John\" />\n\n// tab indentation\n// [2, 'tab']\n<Hello\n  firstName=\"John\"\n/>\n\n// no indentation\n// [2, 0]\n<Hello\nfirstName=\"John\"\n/>\n\n// aligned with first prop\n// [2, 'first']\n<Hello\n  firstName=\"John\"\n  lastName=\"Doe\"\n/>\n\n<Hello\n       firstName=\"John\"\n       lastName=\"Doe\"\n/>\n\n<Hello firstName=\"Jane\"\n       lastName=\"Doe\" />\n\n// indent level increase on ternary operator (default setting)\n// [2, 2]\n? <Hello\n    firstName=\"John\"\n    lastName=\"Doe\"\n  />\n\n// no indent level increase on ternary operator\n// [2, { indentMode: 2, ignoreTernaryOperator: true} ]\n? <Hello\n  firstName=\"John\"\n  lastName=\"Doe\"\n/>\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-indent.md",
    "content": "# react/jsx-indent\n\n📝 Enforce JSX indentation.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nThis option validates a specific indentation style for JSX.\n\nNote: The fixer will fix whitespace and tabs indentation.\n\n## Rule Details\n\nThis rule is aimed to enforce consistent indentation style. The default style is `4 spaces`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 2 spaces indentation\n<App>\n  <Hello />\n</App>\n\n// no indentation\n<App>\n<Hello />\n</App>\n\n// 1 tab indentation\n<App>\n  <Hello />\n</App>\n```\n\n## Rule Options\n\nIt takes an option as the second parameter which can be `\"tab\"` for tab-based indentation or a positive number for space indentations.\nTo enable checking the indentation of attributes or add indentation to logical expressions, use the third parameter to turn on the `checkAttributes` (default is false) and `indentLogicalExpressions` (default is false) respectively.\n\n```js\n...\n\"react/jsx-indent\": [<enabled>, 'tab'|<number>, {checkAttributes: <boolean>, indentLogicalExpressions: <boolean>}]\n...\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 2 spaces indentation\n// [2, 2]\n<App>\n    <Hello />\n</App>\n\n// tab indentation\n// [2, 'tab']\n<App>\n  <Hello />\n</App>\n\n// [2, 2, {checkAttributes: true}]\n<App render={\n  <Hello render={\n    (bar) => <div>hi</div>\n}\n  />\n  }>\n</App>\n\n// [2, 2, {indentLogicalExpressions: true}]\n<App>\n  {condition && (\n  <Hello />\n  )}\n</App>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n\n// 2 spaces indentation\n// [2, 2]\n<App>\n  <Hello />\n</App>\n\n// tab indentation\n// [2, 'tab']\n<App>\n  <Hello />\n</App>\n\n// no indentation\n// [2, 0]\n<App>\n<Hello />\n</App>\n\n// [2, 2, {checkAttributes: false}]\n<App render={\n  <Hello render={\n    (bar) => <div>hi</div>\n}\n  />\n  }>\n</App>\n\n// [2, 2, {indentLogicalExpressions: true}]\n<App>\n  {condition && (\n    <Hello />\n  )}\n</App>\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-key.md",
    "content": "# react/jsx-key\n\n📝 Disallow missing `key` props in iterators/collection literals.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nWarn if an element that likely requires a `key` prop--namely, one present in an\narray literal or an arrow function expression.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n[<Hello />, <Hello />, <Hello />];\n```\n\n```jsx\ndata.map(x => <Hello>{x}</Hello>);\n```\n\n```jsx\nArray.from([1, 2, 3], (x) => <Hello>{x}</Hello>);\n```\n\n```jsx\n<Hello {...{ key: id, id, caption }} />\n```\n\nIn the last example the key is being spread, which is currently possible, but discouraged in favor of the statically provided key.\n\nExamples of **correct** code for this rule:\n\n```jsx\n[<Hello key=\"first\" />, <Hello key=\"second\" />, <Hello key=\"third\" />];\n```\n\n```jsx\ndata.map((x) => <Hello key={x.id}>{x}</Hello>);\n```\n\n```jsx\nArray.from([1, 2, 3], (x) => <Hello key={x}>{x}</Hello>);\n```\n\n```jsx\n<Hello key={id} {...{ id, caption }} />\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-key\": [<enabled>, { \"checkFragmentShorthand\": <boolean> }]\n...\n```\n\n### `checkFragmentShorthand` (default: `false`)\n\nWhen `true` the rule will check if usage of the [shorthand fragment syntax][short_syntax] requires a key. This option was added to avoid a breaking change and will be the default in the next major version.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n[<></>, <></>, <></>];\n```\n\n```jsx\ndata.map(x => <>{x}</>);\n```\n\n### `checkKeyMustBeforeSpread` (default: `false`)\n\nWhen `true` the rule will check if key prop after spread to avoid [createElement fallback](https://github.com/facebook/react/issues/20031#issuecomment-710346866).\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<span {...spread} key={\"key-after-spread\"} />;\n```\n\n### `warnOnDuplicates` (default: `false`)\n\nWhen `true` the rule will check for any duplicate key prop values.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nconst spans = [\n    <span key=\"notunique\"/>,\n    <span key=\"notunique\"/>,\n];\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n\nAlso, if you have some prevalent situation where you use arrow functions to\nreturn JSX that will not be held in an iterable, you may want to disable this\nrule.\n\n[short_syntax]: https://reactjs.org/docs/fragments.html#short-syntax\n"
  },
  {
    "path": "docs/rules/jsx-max-depth.md",
    "content": "# react/jsx-max-depth\n\n📝 Enforce JSX maximum depth.\n\n<!-- end auto-generated rule header -->\n\nThis option validates a specific depth for JSX.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<App>\n  <Foo>\n    <Bar>\n      <Baz />\n    </Bar>\n  </Foo>\n</App>\n\n```\n\n## Rule Options\n\nIt takes an option as the second parameter which can be a positive number for depth count.\n\n```js\n...\n\"react/jsx-max-depth\": [<enabled>, { \"max\": <number> }]\n...\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// [2, { \"max\": 1 }]\n<App>\n  <Foo>\n    <Bar />\n  </Foo>\n</App>\n\n// [2, { \"max\": 1 }]\nconst foobar = <Foo><Bar /></Foo>;\n<App>\n  {foobar}\n</App>\n\n// [2, { \"max\": 2 }]\n<App>\n  <Foo>\n    <Bar>\n      <Baz />\n    </Bar>\n  </Foo>\n</App>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n\n// [2, { \"max\": 1 }]\n<App>\n  <Hello />\n</App>\n\n// [2,{ \"max\": 2 }]\n<App>\n  <Foo>\n    <Bar />\n  </Foo>\n</App>\n\n// [2, { \"max\": 3 }]\n<App>\n  <Foo>\n    <Bar>\n      <Baz />\n    </Bar>\n  </Foo>\n</App>\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-max-props-per-line.md",
    "content": "# react/jsx-max-props-per-line\n\n📝 Enforce maximum of props on a single line in JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nLimiting the maximum of props on a single line can improve readability.\n\nNote: The fixer does not include indentation. Please rerun lint to correct those errors.\n\n## Rule Details\n\nThis rule checks all JSX elements and verifies that the number of props per line do not exceed the maximum allowed. Props are considered to be in a new line if there is a line break between the start of the prop and the end of the previous prop. A spread attribute counts as one prop. This rule is off by default and when on the default maximum of props on one line is `1`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello lastName=\"Smith\" firstName=\"John\" />;\n\n<Hello foo={{\n  bar\n}} baz />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n\n<Hello\n  {...this.props}\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>;\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-max-props-per-line\": [<enabled>, { \"maximum\": <number>, \"when\": <string> }]\n...\n\n// OR\n\n...\n\"react/jsx-max-props-per-line\": [<enabled>, { \"maximum\": { \"single\": <number>, \"multi\": <number> } }]\n...\n```\n\n### `maximum`\n\nMaximum number of props allowed on a single line. Default to `1`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// [1, { \"maximum\": 2 }]\n<Hello firstName=\"John\" lastName=\"Smith\" tel={5555555} />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// [1, { \"maximum\": 2 }]\n<Hello\n  firstName=\"John\" lastName=\"Smith\"\n  tel={5555555}\n/>;\n```\n\nMaximum can be specified as object `{ single: 1, multi: 1 }` to specify maximum allowed number of props for single line and multiple line tags.\n\n### `when`\n\n _when only applied if `maximum` is specified as number._\n\nPossible values:\n\n- `always` (default) - Always check for max props per line.\n- `multiline` - Only check for max props per line when jsx tag spans multiple lines.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// [1, { \"when\": \"always\" }]\n<Hello firstName=\"John\" lastName=\"Smith\" />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// [1, { \"when\": \"multiline\" }]\n<Hello firstName=\"John\" lastName=\"Smith\" />\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-newline.md",
    "content": "# react/jsx-newline\n\n📝 Require or prevent a new line after jsx elements and expressions.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\n## Rule Details\n\nThis is a stylistic rule intended to make JSX code more readable by requiring or preventing lines between adjacent JSX elements and expressions.\n\n## Rule Options\n\n```json5\n...\n\"react/jsx-newline\": [<enabled>, { \"prevent\": <boolean>, \"allowMultilines\": <boolean> }]\n...\n```\n\n- enabled: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- prevent: optional boolean. If `true` prevents empty lines between adjacent JSX elements and expressions. Defaults to `false`.\n- allowMultilines: optional boolean. If `true` and `prevent` is also equal to `true`, it allows newlines after multiline JSX elements and expressions. Defaults to `false`.\n\n## Examples\n\nExamples of **incorrect** code for this rule, when configured with `{ \"prevent\": false }`:\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n  <List />\n</div>\n```\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n  {showSomething === true && <Something />}\n</div>\n```\n\n```jsx\n<div>\n  {showSomething === true && <Something />}\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"prevent\": false }`:\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n\n  <List />\n\n  <Button>\n    <IconPreview />\n    Button 2\n\n    <span></span>\n  </Button>\n\n  {showSomething === true && <Something />}\n\n  <Button>Button 3</Button>\n\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"prevent\": true }`:\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n\n  <List />\n\n  <Button>\n    <IconPreview />\n    Button 2\n\n    <span></span>\n  </Button>\n\n  {showSomething === true && <Something />}\n\n  <Button>Button 3</Button>\n\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"prevent\": true }`:\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n  <List />\n</div>\n```\n\n```jsx\n<div>\n  <Button>{data.label}</Button>\n  {showSomething === true && <Something />}\n</div>\n```\n\n```jsx\n<div>\n  {showSomething === true && <Something />}\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"prevent\": true, \"allowMultilines\": true }`:\n\n```jsx\n<div>\n  {showSomething === true && <Something />}\n\n  <Button>Button 3</Button>\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"prevent\": true, \"allowMultilines\": true }`:\n\n```jsx\n<div>\n  {showSomething === true && <Something />}\n\n  <Button>Button 3</Button>\n\n  {showSomethingElse === true ? (\n    <SomethingElse />\n  ) : (\n    <ErrorMessage />\n  )}\n</div>\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with spacing between your JSX elements and expressions.\n"
  },
  {
    "path": "docs/rules/jsx-no-bind.md",
    "content": "# react/jsx-no-bind\n\n📝 Disallow `.bind()` or arrow functions in JSX props.\n\n<!-- end auto-generated rule header -->\n\nUsing `bind` on a function or declaring a function in the render method of a component or the body of a functional component, and then passing that function as a prop will mean that the brand new function that is created on every single render will be considered a completely different function. This can affect performance in some situations, as it may cause unnecessary re-renders if a brand new function is passed as a prop to a component that uses reference equality check on the prop to determine if it should update, such as a component wrapped with [`memo`](https://react.dev/reference/react/memo#memo), or if the prop is used in any hook's \"dependency array\".\n\nNote that this behavior is different for `ref` props, which is a special case in React that **does not** cause re-renders when a brand new function is passed.  See [`ignore-refs`](#ignorerefs) below for more information.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Foo onClick={this._handleClick.bind(this)}></Foo>\n```\n\n```jsx\n<Foo onClick={() => console.log('Hello!')}></Foo>\n```\n\n```jsx\nfunction onClick() { console.log('Hello!'); }\n<Foo onClick={onClick} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Foo onClick={this._handleClick}></Foo>\n```\n\n## Rule Options\n\n```js\n\"react/jsx-no-bind\": [<enabled>, {\n  \"ignoreDOMComponents\": <boolean> || false,\n  \"ignoreRefs\": <boolean> || false,\n  \"allowArrowFunctions\": <boolean> || false,\n  \"allowFunctions\": <boolean> || false,\n  \"allowBind\": <boolean> || false\n}]\n```\n\n### `ignoreDOMComponents`\n\nExamples of **correct** code for this rule, when `ignoreDOMComponents` is `true`:\n\n```jsx\n<div onClick={this._handleClick.bind(this) />\n<span onClick={() => console.log(\"Hello!\")} />\n<button type=\"button\" onClick={function() { alert(\"1337\") }} />\n```\n\n### `ignoreRefs`\n\nRefs are a special-case that do not behave like other props. Sending a new function in on ever render will **not** cause re-renders like it could with any other prop.\n\nHowever, there is a [caveat with callback refs](https://reactjs.org/docs/refs-and-the-dom.html#caveats-with-callback-refs):\n> If the ref callback is defined as an inline function, it will get called twice during updates, first with null and then again with the DOM element. This is because a new instance of the function is created with each render, so React needs to clear the old ref and set up the new one. You can avoid this by defining the ref callback as a bound method on the class, but note that it shouldn’t matter in most cases.\n\nYou can also avoid this behavior using [`createRef`](https://reactjs.org/docs/react-api.html#reactcreateref) or [`useRef`](https://reactjs.org/docs/hooks-reference.html#useref) (or [`useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback) if you have custom logic).\n\nIf you are using a simple setter (as shown below) then you may not need this rule to fire for `ref`s, and can disable it specifically for refs with `ignoreRefs`.\n\nExamples of **correct** code for this rule, when `ignoreRefs` is `true`:\n\n```jsx\n<Foo ref={ref => { this._div = ref; }} />\n<Foo ref={this._refCallback.bind(this)} />\n```\n\n### `allowArrowFunctions`\n\nExamples of **correct** code for this rule, when `allowArrowFunctions` is `true`:\n\n```jsx\n<Foo onClick={() => alert(\"1337\")} />\n```\n\n### `allowFunctions`\n\nExamples of **correct** code for this rule, when `allowFunctions` is `true`:\n\n```jsx\n<Foo onClick={function () { alert(\"1337\") }} />\n```\n\n```jsx\nfunction onClick() { alert(\"1337\"); }\n<Foo onClick={onClick} />\n```\n\n### `allowBind`\n\nExamples of **correct** code for this rule, when `allowBind` is `true`:\n\n```jsx\n<Foo onClick={this._handleClick.bind(this)} />\n```\n\n## Protips\n\n### Lists of Items\n\nA common use case of `bind` in render is when rendering a list, to have a separate callback per list item:\n\n```jsx\nvar List = createReactClass({\n  render() {\n    return (\n      <ul>\n        {this.props.items.map(item =>\n          <li key={item.id} onClick={this.props.onItemClick.bind(null, item.id)}>\n            ...\n          </li>\n        )}\n      </ul>\n    );\n  }\n});\n```\n\nRather than doing it this way, pull the repeated section into its own component:\n\n```jsx\nvar List = createReactClass({\n  render() {\n    return (\n      <ul>\n        {this.props.items.map(item =>\n          <ListItem key={item.id} item={item} onItemClick={this.props.onItemClick} />\n        )}\n      </ul>\n    );\n  }\n});\n\nvar ListItem = createReactClass({\n  render() {\n    return (\n      <li onClick={this._onClick}>\n        ...\n      </li>\n    );\n  },\n  _onClick() {\n    this.props.onItemClick(this.props.item.id);\n  }\n});\n```\n\nThis will speed up rendering, as it avoids the need to create new functions (through `bind` calls) on every render.\n\n### ES6 Classes\n\nUnfortunately [React ES6 classes](https://legacy.reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html#es6-classes) do not autobind their methods like components created with the older `createReactClass` syntax. There are several approaches to binding methods for ES6 classes. A basic approach is to just manually bind the methods in the constructor:\n\n```jsx\nclass Foo extends React.Component {\n  constructor(...args) {\n    super(...args);\n    this._onClick = this._onClick.bind(this);\n  }\n  render() {\n    return (\n      <div onClick={this._onClick}>\n        Hello!\n      </div>\n    );\n  }\n  _onClick() {\n    // Do whatever you like, referencing \"this\" as appropriate\n  }\n}\n```\n\nA more sophisticated approach would be to use something like an [autobind ES7 decorator](https://www.npmjs.com/package/core-decorators#autobind) or [property initializers](https://legacy.reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding).\n\n### React Hooks\n\nFunctional components are often used alongside hooks, and the most trivial case would occur if your callback is completely independent from your state. In this case, the solution is as simple as moving the callback out of your component:\n\n```jsx\nconst onClick = () => {\n  console.log(\"Independent callback\");\n};\nconst Button = () => {\n  return (\n    <button type=\"button\" onClick={onClick}>Label</button>\n  );\n};\n```\n\nOtherwise, the idiomatic way to avoid redefining callbacks on every render would be to memoize them using the [`useCallback`](https://legacy.reactjs.org/docs/hooks-reference.html#usecallback) hook:\n\n```jsx\nconst Button = () => {\n  const [text, setText] = useState(\"Before click\");\n  const onClick = useCallback(() => {\n    setText(\"After click\");\n  }, [setText]); // Array of dependencies for which the memoization should update\n  return (\n    <button type=\"button\" onClick={onClick}>{text}</button>\n  );\n};\n```\n\n## When Not To Use It\n\nIf you do not use JSX or do not want to enforce that `bind`, functions declared in the render method of a component, or functions declared in the body of a functional component are not used in props, then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-no-comment-textnodes.md",
    "content": "# react/jsx-no-comment-textnodes\n\n📝 Disallow comments from being inserted as text nodes.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nThis rule prevents comment strings (e.g. beginning with `//` or `/*`) from being accidentally\ninjected as a text node in JSX statements.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return (\n      <div>// empty div</div>\n    );\n  }\n});\n\nvar Hello = createReactClass({\n  render: function() {\n    return (\n      <div>\n        /* empty div */\n      </div>\n    );\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  displayName: 'Hello',\n  render: function() {\n    return <div>{/* empty div */}</div>;\n  }\n});\n\nvar Hello = createReactClass({\n  displayName: 'Hello',\n  render: function() {\n    return <div /* empty div */></div>;\n  }\n});\n\nvar Hello = createReactClass({\n  displayName: 'Hello',\n  render: function() {\n    return <div className={'foo' /* temp class */}</div>;\n  }\n});\n```\n\n## Legitimate uses\n\nIt's possible you may want to legitimately output comment start characters (`//` or `/*`) in a JSX text node. In which case, you can do the following:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return (\n      <div>{'/* This will be output as a text node */'}</div>\n    );\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/jsx-no-constructed-context-values.md",
    "content": "# react/jsx-no-constructed-context-values\n\n📝 Disallows JSX context provider values from taking values that will cause needless rerenders.\n\n<!-- end auto-generated rule header -->\n\nThis rule prevents non-stable values (i.e. object identities) from being used as a value for `Context.Provider`.\n\n## Rule Details\n\nOne way to resolve this issue may be to wrap the value in a `useMemo()`. If it's a function then `useCallback()` can be used as well.\n\nIf you _expect_ the context to be rerun on each render, then consider adding a comment/lint suppression explaining why.\n\n## Examples\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nreturn (\n    <SomeContext.Provider value={{foo: 'bar'}}>\n        ...\n    </SomeContext.Provider>\n)\n```\n\n```jsx\nimport React from 'react';\n\nconst MyContext = React.createContext();\nfunction Component() {\n    function foo() {}\n    return (<MyContext value={foo}></MyContext>);\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst foo = useMemo(() => ({foo: 'bar'}), []);\nreturn (\n    <SomeContext.Provider value={foo}>\n        ...\n    </SomeContext.Provider>\n)\n```\n\n```jsx\nconst SomeContext = createContext();\nconst Component = () => <SomeContext value=\"Some string\"><SomeContext>;\n```\n\n## Legitimate Uses\n\nReact Context, and all its child nodes and Consumers are rerendered whenever the value prop changes. Because each Javascript object carries its own _identity_, things like object expressions (`{foo: 'bar'}`) or function expressions get a new identity on every run through the component. This makes the context think it has gotten a new object and can cause needless rerenders and unintended consequences.\n\nThis can be a pretty large performance hit because not only will it cause the context providers and consumers to rerender with all the elements in its subtree, the processing for the tree scan react does to render the provider and find consumers is also wasted.\n"
  },
  {
    "path": "docs/rules/jsx-no-duplicate-props.md",
    "content": "# react/jsx-no-duplicate-props\n\n📝 Disallow duplicate properties in JSX.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nCreating JSX elements with duplicate props can cause unexpected behavior in your application.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello name=\"John\" name=\"John\" />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello firstname=\"John\" lastname=\"Doe\" />;\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-no-duplicate-props\": [<enabled>, { \"ignoreCase\": <boolean> }]\n...\n```\n\n### `ignoreCase`\n\nWhen `true` the rule ignores the case of the props. Default to `false`.\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-no-leaked-render.md",
    "content": "# react/jsx-no-leaked-render\n\n📝 Disallow problematic leaked values from being rendered.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nUsing the `&&` operator to render some element conditionally in JSX can cause unexpected values being rendered, or even crashing the rendering.\n\n## Rule Details\n\nThis rule aims to prevent dangerous leaked values from being rendered since they can cause unexpected values reaching the final DOM or even crashing your render method.\n\nIn React, you might end up rendering unexpected values like `0` or `NaN`. In React Native, your render method will even crash if you render these values:\n\n```jsx\nconst Example = () => {\n  return (\n    <>\n      {0 && <Something />}\n      {/* React: renders undesired 0 */}\n      {/* React Native: crashes 💥 */}\n\n      {NaN && <Something />}\n      {/* React: renders undesired NaN */}\n      {/* React Native: crashes 💥 */}\n\n      {'' && <Something />}\n      {/* React: renders nothing */}\n      {/* React Native, with React < 18: crashes 💥 */}\n    </>\n  )\n}\n```\n\nThis can be avoided by:\n\n- coercing the conditional to a boolean: `{!!someValue && <Something />}`\n- transforming the binary expression into a ternary expression which returns `null` for falsy values: `{someValue ? <Something /> : null}`\n\nThis rule is autofixable; check the Options section to read more about the different strategies available.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{count && title}</div>\n}\n```\n\n```jsx\nconst Component = ({ count }) => {\n  return <div>{count && <span>There are {count} results</span>}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements.length && <List elements={elements} />}</div>\n}\n```\n\n```jsx\nconst Component = ({ nestedCollection }) => {\n  return (\n    <div>\n      {nestedCollection.elements.length && <List elements={nestedCollection.elements} />}\n    </div>\n  )\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements[0] && <List elements={elements} />}</div>\n}\n```\n\n```jsx\nconst Component = ({ numberA, numberB }) => {\n  return <div>{(numberA || numberB) && <Results>{numberA + numberB}</Results>}</div>\n}\n```\n\n```jsx\n// If the condition is a boolean value, this rule will report the logical expression\n// since it can't infer the type of the condition.\nconst Component = ({ someBool }) => {\n  return <div>{someBool && <Results>{numberA + numberB}</Results>}</div>\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements}</div>\n}\n```\n\n```jsx\n// An OR condition it's considered valid since it's assumed as a way\n// to render some fallback if the first value is falsy, not to render something conditionally.\nconst Component = ({ customTitle }) => {\n  return <div>{customTitle || defaultTitle}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>There are {elements.length} elements</div>\n}\n```\n\n```jsx\nconst Component = ({ elements, count }) => {\n  return <div>{!count && 'No results found'}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{!!elements.length && <List elements={elements} />}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{Boolean(elements.length) && <List elements={elements} />}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements.length > 0 && <List elements={elements} />}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements.length ? <List elements={elements} /> : null}</div>\n}\n```\n\n```jsx\nconst Component = ({ elements }) => {\n  return <div>{elements.length ? <List elements={elements} /> : <EmptyList />}</div>\n}\n```\n\n## Rule Options\n\nThe supported options are:\n\n### `ignoreAttributes`\n\nBoolean. When set to `true`, this option ignores all attributes except for `children` during validation, preventing false positives in scenarios where these attributes are used safely or validated internally. Default is `false`.\n\nIt can be set like:\n\n```jsonc\n{\n  // ...\n  \"react/jsx-no-leaked-render\": [<enabled>, { \"ignoreAttributes\": true }]\n  // ...\n}\n```\n\nAssuming the following options: `{ \"ignoreAttributes\": true }`\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nfunction MyComponent({ value }) {\n  return (\n    <MyChildComponent nonChildrenProp={value && 'default'}>\n      {value && <MyInnerChildComponent />}\n    </MyChildComponent>\n  );\n}\n```\n\nEven with `ignoreAttributes: true`, `children` expressions are still checked. In the example above, `{value && <MyInnerChildComponent />}` will still be flagged.\n\nNested JSX children within attributes are also still checked:\n\n```jsx\nconst Component = ({ enabled }) => {\n  return (\n    <Foo bar={\n      <Something>{enabled && <MuchWow />}</Something>\n    } />\n  )\n}\n```\n\nHere, even though `<Something>…</Something>` is inside an attribute of `<Foo>`, the `{enabled && <MuchWow />}` expression is children of `<Something>`, so it is still flagged.\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\nconst Component = ({ enabled, checked }) => {\n  return <CheckBox checked={enabled && checked} />\n}\n```\n\nWith `ignoreAttributes: true`, logical expressions in non-children attributes like `checked` are not flagged.\n\n### `validStrategies`\n\nAn array containing `\"coerce\"`, `\"ternary\"`, or both (default: `[\"ternary\", \"coerce\"]`) - Decide which strategies are considered valid to prevent leaked renders (at least 1 is required). The \"coerce\" option will transform the conditional of the JSX expression to a boolean. The \"ternary\" option transforms the binary expression into a ternary expression returning `null` for falsy values. The first option from the array will be the strategy used when autofixing, so the order of the values matters.\n\nIt can be set like:\n\n```json5\n{\n  // ...\n  \"react/jsx-no-leaked-render\": [<enabled>, { \"validStrategies\": [\"ternary\", \"coerce\"] }]\n  // ...\n}\n```\n\nAssuming the following options: `{ \"validStrategies\": [\"ternary\"] }`\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{count && title}</div>\n}\n```\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{!!count && title}</div>\n}\n```\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{count ? title : null}</div>\n}\n```\n\n```jsx\nconst Component = ({ count, title, empty }) => {\n  return <div>{count ? title : empty}</div>\n}\n```\n\nAssuming the following options: `{ \"validStrategies\": [\"coerce\"] }`\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{count && title}</div>\n}\n```\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{count ? title : null}</div>\n}\n```\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\nconst Component = ({ count, title }) => {\n  return <div>{!!count && title}</div>\n}\n```\n\n```jsx\nconst Component = ({ count, title, empty }) => {\n  return <div>{count ? title : empty}</div>\n}\n```\n\n## When Not To Use It\n\nIf you are working in a typed-codebase which encourages you to always use boolean conditions, this rule can be disabled.\n\n## Further Reading\n\n- [React docs: Inline If with Logical && Operator](https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator)\n- [Good advice on JSX conditionals - Beware of zero](https://thoughtspile.github.io/2022/01/17/jsx-conditionals/)\n- [Twitter: rendering falsy values in React and React Native](https://twitter.com/kadikraman/status/1507654900376875011?s=21&t=elEXXbHhzWthrgKaPRMjNg)\n"
  },
  {
    "path": "docs/rules/jsx-no-literals.md",
    "content": "# react/jsx-no-literals\n\n📝 Disallow usage of string literals in JSX.\n\n<!-- end auto-generated rule header -->\n\nThere are a few scenarios where you want to avoid string literals in JSX. You may want to enforce consistency, reduce syntax highlighting issues, or ensure that strings are part of a translation system.\n\n## Rule Details\n\nBy default this rule requires that you wrap all literal strings in a JSX container `{'TEXT'}`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = <div>test</div>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = <div>{'test'}</div>;\n```\n\n```jsx\nvar Hello = <div>\n  {'test'}\n</div>;\n```\n\n## Rule Options\n\nThe supported options are:\n\n- `noStrings` (default: `false`) - Enforces no string literals used as children, wrapped or unwrapped.\n- `allowedStrings` - An array of unique string values that would otherwise warn, but will be ignored.\n- `ignoreProps` (default: `false`) - When `true` the rule ignores literals used in props, wrapped or unwrapped.\n- `noAttributeStrings` (default: `false`) - Enforces no string literals used in attributes when set to `true`.\n- `restrictedAttributes` - An array of unique attribute names where string literals should be restricted. Only the specified attributes will be checked for string literals when this option is used. **Note**: When `noAttributeStrings` is `true`, this option is ignored at the root level.\n- `elementOverrides` - An object where the keys are the element names and the values are objects with the same options as above. This allows you to specify different options for different elements.\n\n### `elementOverrides`\n\nThe `elementOverrides` option allows you to specify different options for different elements. This is useful when you want to enforce different rules for different elements. For example, you may want to allow string literals in `Button` elements, but not in the rest of your application.\n\nThe element name only accepts component names.\nHTML element tag names are not supported. Component names are case-sensitive and should exactly match the name of the component as it is used in the JSX.\nIt can also be the name of a compound component (ie. `Modal.Button`).\n\nSpecifying options creates a new context for the rule, so the rule will only apply the new options to the specified element and its children (if `applyToNestedElements` is `true` - see below).\nThis means that the root rule options will not apply to the specified element.\n\nIn addition to the options above (`noStrings`, `allowedStrings`, `noAttributeStrings` and `ignoreProps`), you can also specify the the following options that are specific to `elementOverrides`:\n\n- `allowElement` (default: `false`) - When `true` the rule will allow the specified element to have string literals as children, wrapped or unwrapped without warning.\n- `applyToNestedElements` (default: `true`) - When `false` the rule will not apply the current options set to nested elements. This is useful when you want to apply the rule to a specific element, but not to its children.\n\n**Note**: As this rule has no way of differentiating between different componets with the same name, it is recommended to use this option with specific components that are unique to your application.\n\n#### `elementOverrides` Examples\n\nThe following are **correct** examples that demonstrate how to use the `elementOverrides` option:\n\n```js\n// \"react/jsx-no-literals\": [<enabled>, {\"elementOverrides\": { \"Button\": {\"allowElement\": true} }}]\n\nvar Hello = <div>{'test'}</div>;\nvar World = <Button>test</Button>;\n```\n\n```js\n// \"react/jsx-no-literals\": [<enabled>, {\"elementOverrides\": { \"Text\": {\"allowElement\": true} }}]\n\nvar World = <Text>Hello <a href=\"a\">world</a></Text>;\n```\n\n```js\n// \"react/jsx-no-literals\": [<enabled>, {\"elementOverrides\": { \"Text\": {\"allowElement\": true, \"applyToNestedElements\": false} }}]\n\nvar linkText = 'world';\nvar World = <Text>Hello <a href=\"a\">{linkText}</a></Text>;\n```\n\n```js\n// \"react/jsx-no-literals\": [<enabled>, {\"noStrings\": true, \"elementOverrides\": { \"Button\": {\"noStrings\": false} }}]\n// OR\n// \"react/jsx-no-literals\": [<enabled>, {\"noStrings\": true, \"elementOverrides\": { \"Button\": {} }}]\n\nvar test = 'test'\nvar Hello = <div>{test}</div>;\nvar World = <Button>{'test'}</Button>;\n```\n\n## Examples\n\nTo use, you can specify as follows:\n\n```js\n\"react/jsx-no-literals\": [<enabled>, {\"noStrings\": true, \"allowedStrings\": [\"allowed\"], \"ignoreProps\": false, \"noAttributeStrings\": true }]\n```\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nvar Hello = <div>test</div>;\n```\n\n```jsx\nvar Hello = <div>{'test'}</div>;\n```\n\n```jsx\nvar Hello = <div>\n  {'test'}\n</div>;\n```\n\n```jsx\nvar Hello = <div>\n<img alt=\"test\"> </img>\n</div>;\n```\n\n```jsx\nvar Hello = <div class='xx' />;\n```\n\n```jsx\nvar Hello = <div class={'xx'} />;\n```\n\n```jsx\nvar Hello = <div class={`xx`} />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// When using something like `react-intl`\nvar Hello = <div><Text {...message} /></div>\n```\n\n```jsx\n// When using something similar to Rails translations\nvar Hello = <div>{translate('my.translation.key')}</div>\n```\n\n```jsx\n// an allowed string\nvar Hello = <div>allowed</div>\n```\n\n```jsx\n// an allowed string surrounded by only whitespace\nvar Hello = <div>\n  allowed\n</div>;\n```\n\n```jsx\n// a string value stored within a variable used as an attribute's value\nvar Hello = <div>\n<img alt={imageDescription} {...props} />\n</div>;\n```\n\n```jsx\n// spread props object\nvar Hello = <Text {...props} />\n```\n\n```jsx\n// use variable for prop values\nvar Hello = <div class={xx} />\n```\n\n```jsx\n// cache\nclass Comp1 extends Component {\n  asdf() {}\n\n  render() {\n    return (\n      <div onClick={this.asdf}>\n        {'asdjfl'}\n        test\n        {'foo'}\n      </div>\n    );\n  }\n}\n```\n\n## When Not To Use It\n\nIf you do not want to enforce any style JSX literals, then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-no-script-url.md",
    "content": "# react/jsx-no-script-url\n\n📝 Disallow usage of `javascript:` URLs.\n\n<!-- end auto-generated rule header -->\n\n**In React 16.9** any URLs starting with `javascript:` [scheme](https://wiki.whatwg.org/wiki/URL_schemes#javascript:_URLs) log a warning.\nReact considers the pattern as a dangerous attack surface, see [details](https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#deprecating-javascript-urls).\n**In a future major release**, React will throw an error if it encounters a `javascript:` URL.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<a href=\"javascript:\"></a>\n<a href=\"javascript:void(0)\"></a>\n<a href=\"j\\n\\n\\na\\rv\\tascript:\"></a>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Foo href=\"javascript:\"></Foo>\n<a href={\"javascript:\"}></a>\n```\n\nThis rule takes the `linkComponents` setting into account.\n\n## Rule Options\n\nThis rule accepts array option (optional) and object option (optional).\n\n### Array option (default `[]`)\n\n```json\n{\n  \"react/jsx-no-script-url\": [\n    \"error\",\n    [\n      {\n        \"name\": \"Link\",\n        \"props\": [\"to\"]\n      },\n      {\n        \"name\": \"Foo\",\n        \"props\": [\"href\", \"to\"]\n      }\n    ]\n  ]\n}\n```\n\nAllows you to indicate a specific list of properties used by a custom component to be checked.\n\n#### name\n\nComponent name.\n\n#### props\n\nList of properties that should be validated.\n\nExamples of **incorrect** code for this rule, when configured with the above options:\n\n```jsx\n<Link to=\"javascript:void(0)\"></Link>\n<Foo href=\"javascript:void(0)\"></Foo>\n<Foo to=\"javascript:void(0)\"></Foo>\n```\n\n### Object option\n\n#### includeFromSettings (default `false`)\n\nIndicates if the `linkComponents` config in [global shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration) should also be taken into account. If enabled, components and properties defined in settings will be added to the list provided in first option (if provided):\n\n```json\n{\n  \"react/jsx-no-script-url\": [\n    \"error\",\n    [\n      {\n        \"name\": \"Link\",\n        \"props\": [\"to\"]\n      },\n      {\n        \"name\": \"Foo\",\n        \"props\": [\"href\", \"to\"]\n      }\n    ],\n    { \"includeFromSettings\": true }\n  ]\n}\n```\n\nIf only global settings should be used for this rule, the array option can be omitted:\n\n```jsonc\n{\n  // same as [\"error\", [], { \"includeFromSettings\": true }]\n  \"react/jsx-no-script-url\": [\"error\", { \"includeFromSettings\": true }]\n}\n```\n"
  },
  {
    "path": "docs/rules/jsx-no-target-blank.md",
    "content": "# react/jsx-no-target-blank\n\n📝 Disallow `target=\"_blank\"` attribute without `rel=\"noreferrer\"`.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nWhen creating a JSX element that has an `a` tag, it is often desired to have the link open in a new tab using the `target='_blank'` attribute. Using this attribute unaccompanied by `rel='noreferrer'`, however, is a severe security vulnerability (see [noreferrer docs](https://html.spec.whatwg.org/multipage/links.html#link-type-noreferrer) and [noopener docs](https://html.spec.whatwg.org/multipage/links.html#link-type-noopener) for more details)\nThis rules requires that you accompany `target='_blank'` attributes with `rel='noreferrer'`.\n\n## Rule Details\n\nThis rule aims to prevent user generated link hrefs and form actions from creating security vulnerabilities by requiring `rel='noreferrer'` for external link hrefs and form actions, and optionally any dynamically generated link hrefs and form actions.\n\n## Rule Options\n\n```js\n...\n\"react/jsx-no-target-blank\": [<enabled>, {\n  \"allowReferrer\": <allow-referrer>,\n  \"enforceDynamicLinks\": <enforce>,\n  \"warnOnSpreadAttributes\": <warn>,\n  \"links\": <boolean>,\n  \"forms\": <boolean>,\n}]\n...\n```\n\n- `enabled`: for enabling the rule.\n- `allowReferrer`: optional boolean. If `true` does not require `noreferrer` (i. e. `noopener` alone is enough, this leaves IE vulnerable). Defaults to `false`.\n- `enforceDynamicLinks`: optional string, `'always'` or `'never'`.\n- `warnOnSpreadAttributes`: optional boolean. Defaults to `false`.\n- `links`: prevent usage of unsafe `target='_blank'` inside links, defaults to `true`.\n- `forms`: prevent usage of unsafe `target='_blank'` inside forms, defaults to `false`.\n\n### `enforceDynamicLinks`\n\n#### always\n\n`{\"enforceDynamicLinks\": \"always\"}` enforces the rule if the href is a dynamic link (default)\n\nExamples of **incorrect** code for this rule, when configured with `{ \"enforceDynamicLinks\": \"always\" }`:\n\n```jsx\nvar Hello = <a target='_blank' href=\"https://example.com/\"></a>\nvar Hello = <a target='_blank' href={dynamicLink}></a>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = <p target=\"_blank\"></p>\nvar Hello = <a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com\"></a>\nvar Hello = <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://example.com\"></a>\nvar Hello = <a target=\"_blank\" href=\"relative/path/in/the/host\"></a>\nvar Hello = <a target=\"_blank\" href=\"/absolute/path/in/the/host\"></a>\nvar Hello = <a></a>\n```\n\n#### never\n\n`{\"enforceDynamicLinks\": \"never\"}` does not enforce the rule if the href is a dynamic link\n\nExamples of **correct** code for this rule, when configured with `{ \"enforceDynamicLinks\": \"never\" }`:\n\n```jsx\nvar Hello = <a target='_blank' href={dynamicLink}></a>\n```\n\n### `warnOnSpreadAttributes`\n\nSpread attributes are a handy way of passing programmatically-generated props to components, but may contain unsafe props e.g.\n\n```jsx\nconst unsafeProps = {\n  href: \"https://example.com\",\n  target: \"_blank\",\n};\n\n<a {...unsafeProps}></a>\n```\n\nDefaults to false. If false, this rule will ignore all spread attributes. If true, this rule will treat all spread attributes as if they contain an unsafe combination of props, unless specifically overridden by props _after_ the last spread attribute prop e.g. the following would not be violations:\n\n```jsx\n<a {...unsafeProps} rel=\"noreferrer\"></a>\n<a {...unsafeProps} target=\"_self\"></a>\n<a {...unsafeProps} href=\"/some-page\"></a>\n```\n\n### `links` / `forms`\n\nWhen option `forms` is set to `true`, the following is considered an error:\n\n```jsx\nvar Hello = <form target=\"_blank\" action=\"https://example.com/\"></form>;\n```\n\nWhen option `links` is set to `true`, the following is considered an error:\n\n```jsx\nvar Hello = <a target='_blank' href=\"https://example.com/\"></form>\n```\n\n### Custom link components\n\nThis rule supports the ability to use custom components for links, such as `<Link />` which is popular in libraries like `react-router`, `next.js` and `gatsby`. To enable this, define your custom link components in the global [shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration) under the `linkComponents` configuration area. Once configured, this rule will check those components as if they were `<a />` elements.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = <Link target=\"_blank\" to=\"https://example.com/\"></Link>\nvar Hello = <Link target=\"_blank\" to={dynamicLink}></Link>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = <Link target=\"_blank\" rel=\"noopener noreferrer\" to=\"https://example.com\"></Link>\nvar Hello = <Link target=\"_blank\" to=\"relative/path/in/the/host\"></Link>\nvar Hello = <Link target=\"_blank\" to=\"/absolute/path/in/the/host\"></Link>\nvar Hello = <Link />\n```\n\n### Custom form components\n\nThis rule supports the ability to use custom components for forms. To enable this, define your custom form components in the global [shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration) under the `formComponents` configuration area. Once configured, this rule will check those components as if they were `<form />` elements.\n\n## When To Override It\n\nModern browsers (Chrome ≥ 88, Edge ≥ 88, Firefox ≥ 79 and Safari ≥ 12.2) automatically imply `rel=\"noopener\"`. Therefore this rule is no longer needed, if legacy browsers are not supported. See <https://web.dev/external-anchors-use-rel-noopener/> and <https://caniuse.com/mdn-html_elements_a_implicit_noopener> for more details.\n\nFor links to a trusted host (e.g. internal links to your own site, or links to a another host you control, where you can be certain this security vulnerability does not exist), you may want to keep the HTTP Referer header for analytics purposes.\n\nIf you do not support Internet Explorer (any version), Chrome < 49, Opera < 36, Firefox < 52, desktop Safari < 10.1 or iOS Safari < 10.3, you may set `allowReferrer` to `true`, keep the HTTP Referer header and only add `rel=\"noopener\"` to your links.\n\n## When Not To Use It\n\nIf you do not have any external links or forms, you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-no-undef.md",
    "content": "# react/jsx-no-undef\n\n📝 Disallow undeclared variables in JSX.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nThis rule helps locate potential ReferenceErrors resulting from misspellings or missing components.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello name=\"John\" />;\n```\n\n```jsx\n// will ignore Text in the global scope and warn\nvar Hello = React.createClass({\n  render: function() {\n    return <Text>Hello</Text>;\n  }\n});\nmodule.exports = Hello;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = require('./Hello');\n\n<Hello name=\"John\" />;\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-no-undef\": [<enabled>, { \"allowGlobals\": <boolean> }]\n...\n```\n\n### `allowGlobals`\n\nWhen `true` the rule will consider the global scope when checking for defined Components.\n\nExamples of **correct** code for this rule, when `\"allowGlobals\"` is `true`:\n\n```jsx\nvar Text = require('./Text');\nvar Hello = React.createClass({\n  render: function() {\n    return <Text>Hello</Text>;\n  }\n});\nmodule.exports = Hello;\n```\n\n## When Not To Use It\n\nIf you are not using JSX then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-no-useless-fragment.md",
    "content": "# react/jsx-no-useless-fragment\n\n📝 Disallow unnecessary fragments.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nA fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a [keyed fragment](https://reactjs.org/docs/fragments.html#keyed-fragments).\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<>{foo}</>\n\n<><Foo /></>\n\n<p><>foo</></p>\n\n<></>\n\n<Fragment>foo</Fragment>\n\n<React.Fragment>foo</React.Fragment>\n\n<section>\n  <>\n    <div />\n    <div />\n  </>\n</section>\n\n{showFullName ? <>{fullName}</> : <>{firstName}</>}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n{foo}\n\n<Foo />\n\n<>\n  <Foo />\n  <Bar />\n</>\n\n<>foo {bar}</>\n\n<> {foo}</>\n\nconst cat = <>meow</>\n\n<SomeComponent>\n  <>\n    <div />\n    <div />\n  </>\n</SomeComponent>\n\n<Fragment key={item.id}>{item.value}</Fragment>\n\n{showFullName ? fullName : firstName}\n```\n\n## Rule Options\n\n### `allowExpressions`\n\nWhen `true` single expressions in a fragment will be allowed. This is useful in\nplaces like Typescript where `string` does not satisfy the expected return type\nof `JSX.Element`. A common workaround is to wrap the variable holding a string\nin a fragment and expression.\n\nExamples of **correct** code for the rule, when `\"allowExpressions\"` is `true`:\n\n```jsx\n<>{foo}</>\n\n<>\n  {foo}\n</>\n```\n"
  },
  {
    "path": "docs/rules/jsx-one-expression-per-line.md",
    "content": "# react/jsx-one-expression-per-line\n\n📝 Require one JSX element per line.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nThis option limits every line in JSX to one expression each.\n\nNote: The fixer will insert line breaks between any expression that are on the same line.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<App><Hello /></App>\n\n<App><Hello />\n</App>\n\n<App>\n  <Hello>\n  </Hello></App>\n\n<App>\n  <Hello /> World\n</App>\n\n<App>\n  <Hello /> { 'World' }\n</App>\n\n<App>\n  <Hello /> { this.world() }\n</App>\n\n<App>\n  { 'Hello' }{ ' ' }{ 'World' }\n</App>\n\n<App\n  foo\n><Hello />\n</App>\n\n<App><Hello\n  foo\n/>\n</App>\n\n<App><Hello1 />\n     <Hello2 />\n     <Hello3 />\n</App>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<App>\n  <Hello />\n</App>\n\n<App>\n  <Hello>\n  </Hello>\n</App>\n\n<App>\n  <Hello />\n  World\n</App>\n\n<App>\n  <Hello />\n  { 'World' }\n</App>\n\n<App>\n  <Hello />\n  { this.world() }\n</App>\n\n<App>\n  { 'Hello' }\n  { ' ' }\n  { 'World' }\n</App>\n\n<App\n  foo\n>\n  <Hello />\n</App>\n\n<App>\n  <Hello\n    foo\n  />\n</App>\n\n<App>\n  <Hello1 />\n  <Hello2 />\n  <Hello3 />\n</App>\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-one-expression-per-line\": [<enabled>, { \"allow\": \"none\"|\"literal\"|\"single-child\" }]\n...\n```\n\n### `allow`\n\nDefaults to `none`.\n\nExamples of **correct** code for this rule, when configured as `\"literal\"`:\n\n```jsx\n<App>Hello</App>\n```\n\nExamples of **correct** code for this rule, when configured as `\"single-child\"`:\n\n```jsx\n<App>Hello</App>\n\n<App>{\"Hello\"}</App>\n\n<App><Hello /></App>\n```\n\nExamples of **correct** code for this rule, when configured as `\"non-jsx\"`:\n\n```jsx\n<App>Hello {someVariable}</App>\n\n<App>Hello {<Hello />} there!</App>\n```\n"
  },
  {
    "path": "docs/rules/jsx-pascal-case.md",
    "content": "# react/jsx-pascal-case\n\n📝 Enforce PascalCase for user-defined JSX components.\n\n<!-- end auto-generated rule header -->\n\nEnforces coding style that user-defined JSX components are defined and referenced in PascalCase.\n\nNote that since React's JSX uses the upper vs. lower case convention to distinguish between local component classes and HTML tags this rule will not warn on components that start with a lower case letter.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Test_component />\n```\n\n```jsx\n<TEST_COMPONENT />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div />\n```\n\n```jsx\n<TestComponent />\n```\n\n```jsx\n<TestComponent>\n  <div />\n</TestComponent>\n```\n\n```jsx\n<CSSTransitionGroup />\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-pascal-case\": [<enabled>, { allowAllCaps: <allowAllCaps>, allowNamespace: <allowNamespace>, allowLeadingUnderscore: <allowLeadingUnderscore>, ignore: <ignore> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `allowAllCaps`: optional boolean set to `true` to allow components name in all caps (default to `false`).\n- `allowLeadingUnderscore`: optional boolean set to `true` to allow components name with that starts with an underscore (default to `false`).\n- `allowNamespace`: optional boolean set to `true` to ignore namespaced components (default to `false`).\n- `ignore`: optional string-array of component names to ignore during validation (supports [minimatch](https://github.com/isaacs/minimatch)-style globs).\n\n### `allowAllCaps`\n\nExamples of **correct** code for this rule, when `allowAllCaps` is `true`:\n\n```jsx\n<ALLOWED />\n<TEST_COMPONENT />\n```\n\n### `allowNamespace`\n\nExamples of **correct** code for this rule, when `allowNamespace` is `true`:\n\n```jsx\n<Allowed.div />\n<TestComponent.p />\n```\n\n### `allowLeadingUnderscore`\n\nExamples of **correct** code for this rule, when `allowLeadingUnderscore` is `true`:\n\n```jsx\n<_AllowedComponent />\n<_AllowedComponent>\n  <div />\n</_AllowedComponent>\n```\n\n**WARNING:** Adding a leading underscore to the name of a component does **NOT** affect the visibility or accessibility of that component.  Attempting to use leading underscores to enforce privacy of your components is an error.\n\n## When Not To Use It\n\nIf you are not using JSX.\n"
  },
  {
    "path": "docs/rules/jsx-props-no-multi-spaces.md",
    "content": "# react/jsx-props-no-multi-spaces\n\n📝 Disallow multiple spaces between inline JSX props.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nEnforces that there is exactly one space between all attributes and after tag name and the first attribute in the same line.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<App  spacy />\n```\n\n```jsx\n<App too  spacy />\n```\n\n```jsx\n<App\n  prop1='abc'\n\n  prop2='def' />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<App cozy />\n```\n\n```jsx\n<App very cozy />\n```\n\n```jsx\n<App\n  prop1='abc'\n  prop2='def' />\n```\n\n## When Not To Use It\n\nIf you are not using JSX or don't care about the space between two props in the same line.\n\nIf you have enabled the core rule `no-multi-spaces` with eslint >= 3, you don't need this rule.\n"
  },
  {
    "path": "docs/rules/jsx-props-no-spread-multi.md",
    "content": "# react/jsx-props-no-spread-multi\n\n📝 Disallow JSX prop spreading the same identifier multiple times.\n\n<!-- end auto-generated rule header -->\n\nEnforces that any unique expression is only spread once.\nGenerally spreading the same expression twice is an indicator of a mistake since any attribute between the spreads may be overridden when the intent was not to.\nEven when that is not the case this will lead to unnecessary computations being performed.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<App {...props} myAttr=\"1\" {...props} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<App myAttr=\"1\" {...props} />\n<App {...props} myAttr=\"1\" />\n```\n\n## When Not To Use It\n\nWhen spreading the same expression multiple times yields different results.\n"
  },
  {
    "path": "docs/rules/jsx-props-no-spreading.md",
    "content": "# react/jsx-props-no-spreading\n\n📝 Disallow JSX prop spreading.\n\n<!-- end auto-generated rule header -->\n\nEnforces that there is no spreading for any JSX attribute. This enhances readability of code by being more explicit about what props are received by the component. It is also good for maintainability by avoiding passing unintentional extra props and allowing react to emit warnings when invalid HTML props are passed to HTML elements.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<App {...props} />\n<MyCustomComponent {...props} some_other_prop={some_other_prop} />\n<img {...props} />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst {src, alt} = props;\nconst {one_prop, two_prop} = otherProps;\n<MyCustomComponent one_prop={one_prop} two_prop={two_prop} />\n<img src={src} alt={alt} />\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-props-no-spreading\": [<enabled>, {\n    \"html\": \"ignore\" | \"enforce\",\n    \"custom\": \"ignore\" | \"enforce\",\n    \"explicitSpread\": \"ignore\" | \"enforce\",\n    \"exceptions\": [<string>]\n}]\n...\n```\n\n### html\n\n`html` set to `ignore` will ignore all html jsx tags like `div`, `img` etc. Default is set to `enforce`.\n\nExamples of **correct** code for this rule, when `html` is set to `ignore`:\n\n```jsx\n<img {...props} />\n```\n\nExamples of **incorrect** code for this rule, when `html` is set to `ignore`:\n\n```jsx\n<MyCustomComponent {...props} />\n```\n\n### custom\n\n`custom` set to `ignore` will ignore all custom jsx tags like `App`, `MyCustomComponent` etc. Default is set to `enforce`.\n\nExamples of **correct** code for this rule, when `custom` is set to `ignore`:\n\n```jsx\n<MyCustomComponent {...props} />\n```\n\nExamples of **incorrect** code for this rule, when `custom` is set to `ignore`:\n\n```jsx\n<img {...props} />\n```\n\n### explicitSpread\n\n`explicitSpread` set to `ignore` will ignore spread operators that are explicitly listing all object properties within that spread. Default is set to `enforce`.\n\nExamples of **correct** code for this rule, when `explicitSpread` is set to `ignore`:\n\n```jsx\n<img {...{ prop1, prop2, prop3 }} />\n```\n\n### exceptions\n\nAn \"exception\" will always flip the resulting html or custom setting for that component - ie, html set to `ignore`, with an exception of `div` will enforce on an `div`; custom set to `enforce` with an exception of `Foo` will ignore `Foo`.\n\n```js\n{ \"exceptions\": [\"Image\", \"img\"] }\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst {src, alt} = props;\n<Image {...props} />\n<img {...props} />\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<MyCustomComponent {...props} />\n```\n\n```js\n{ \"html\": \"ignore\", \"exceptions\": [\"MyCustomComponent\", \"img\"] }\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst {src, alt} = props;\nconst {one_prop, two_prop} = otherProps;\n<img src={src} alt={alt} />\n<MyCustomComponent {...otherProps} />\n```\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<img {...props} />\n```\n\n## When Not To Use It\n\nIf you are not using JSX or have lots of props to be passed or the props spreading is used inside HOC.\n"
  },
  {
    "path": "docs/rules/jsx-sort-default-props.md",
    "content": "# react/jsx-sort-default-props\n\n📝 Enforce defaultProps declarations alphabetical sorting.\n\n❌ This rule is deprecated. It was replaced by [`react/sort-default-props`](sort-default-props.md).\n\n<!-- end auto-generated rule header -->\n\nSome developers prefer to sort `defaultProps` declarations alphabetically to be able to find necessary declarations easier at a later time. Others feel that it adds complexity and becomes a burden to maintain.\n\n## Rule Details\n\nThis rule checks all components and verifies that all `defaultProps` declarations are sorted alphabetically. A spread attribute resets the verification. The default configuration of the rule is case-sensitive.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Component = createReactClass({\n...\n  getDefaultProps: function() {\n    return {\n      z: \"z\",\n      a: \"a\",\n      b: \"b\"\n    };\n  },\n...\n});\n\nclass Component extends React.Component {\n  ...\n}\nComponent.defaultProps = {\n  z: \"z\",\n  a: \"a\",\n  b: \"b\"\n};\n\nclass Component extends React.Component {\n  static defaultProps = {\n    z: \"z\",\n    y: \"y\",\n    a: \"a\"\n  }\n  render() {\n    return <div />;\n  }\n}\n\nconst Component = (props) => (...);\nComponent.defaultProps = {\n  z: \"z\",\n  y: \"y\",\n  a: \"a\"\n};\n\nconst defaults = {\n  b: \"b\"\n};\nconst types = {\n  a: PropTypes.string,\n  b: PropTypes.string,\n  c: PropTypes.string'\n};\nfunction StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n  return <div>{a}{b}{c}</div>;\n}\nStatelessComponentWithSpreadInPropTypes.propTypes = types;\nStatelessComponentWithSpreadInPropTypes.defaultProps = {\n  c: \"c\",\n  a: \"a\",\n  ...defaults,\n};\n\nexport default class ClassWithSpreadInPropTypes extends BaseClass {\n  static propTypes = {\n    a: PropTypes.string,\n    b: PropTypes.string,\n    c: PropTypes.string,\n    d: PropTypes.string,\n    e: PropTypes.string,\n    f: PropTypes.string\n  }\n  static defaultProps = {\n    b: \"b\",\n    a: \"a\",\n    ...c.defaultProps,\n    f: \"f\",\n    e: \"e\",\n    ...d.defaultProps\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Component = createReactClass({\n...\n  getDefaultProps: function() {\n    return {\n      a: \"a\",\n      b: \"b\",\n      c: \"c\"\n    };\n  },\n...\n});\n\nclass Component extends React.Component {\n  ...\n}\nComponent.defaultProps = {\n  a: \"a\",\n  b: \"b\",\n  c: \"c\"\n};\n\nclass Component extends React.Component {\n  static defaultProps = {\n    a: PropTypes.any,\n    b: PropTypes.any,\n    c: PropTypes.any\n  }\n  render() {\n    return <div />;\n  }\n}\n\nconst Component = (props) => (...);\nComponent.defaultProps = {\n  a: \"a\",\n  y: \"y\",\n  z: \"z\"\n};\n\nconst defaults = {\n  b: \"b\"\n};\nconst types = {\n  a: PropTypes.string,\n  b: PropTypes.string,\n  c: PropTypes.string'\n};\nfunction StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n  return <div>{a}{b}{c}</div>;\n}\nStatelessComponentWithSpreadInPropTypes.propTypes = types;\nStatelessComponentWithSpreadInPropTypes.defaultProps = {\n  a: \"a\",\n  c: \"c\",\n  ...defaults,\n};\n\nexport default class ClassWithSpreadInPropTypes extends BaseClass {\n  static propTypes = {\n    a: PropTypes.string,\n    b: PropTypes.string,\n    c: PropTypes.string,\n    d: PropTypes.string,\n    e: PropTypes.string,\n    f: PropTypes.string\n  }\n  static defaultProps = {\n    a: \"a\",\n    b: \"b\",\n    ...c.defaultProps,\n    e: \"e\",\n    f: \"f\",\n    ...d.defaultProps\n  }\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-sort-default-props\": [<enabled>, {\n  \"ignoreCase\": <boolean>,\n}]\n...\n```\n\n### `ignoreCase`\n\nWhen `true` the rule ignores the case-sensitivity of the declarations order.\n\n## When Not To Use It\n\nThis rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing `defaultProps` declarations isn't a part of your coding standards, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/jsx-sort-props.md",
    "content": "# react/jsx-sort-props\n\n📝 Enforce props alphabetical sorting.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nSome developers prefer to sort props names alphabetically to be able to find necessary props easier at the later time. Others feel that it adds complexity and becomes burden to maintain.\n\n## Rule Details\n\nThis rule checks all JSX components and verifies that all props are sorted alphabetically. A spread attribute resets the verification. The default configuration of the rule is case-sensitive.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<Hello lastName=\"Smith\" firstName=\"John\" />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<Hello firstName=\"John\" lastName=\"Smith\" />;\n<Hello tel={5555555} {...this.props} firstName=\"John\" lastName=\"Smith\" />;\n```\n\n## Rule Options\n\n```js\n...\n\"react/jsx-sort-props\": [<enabled>, {\n  \"callbacksLast\": <boolean>,\n  \"shorthandFirst\": <boolean>,\n  \"shorthandLast\": <boolean>,\n  \"multiline\": \"ignore\" | \"first\" | \"last\",\n  \"ignoreCase\": <boolean>,\n  \"noSortAlphabetically\": <boolean>,\n  \"reservedFirst\": <boolean>|<array<string>>,\n  \"sortFirst\": <array<string>>,\n  \"locale\": \"auto\" | \"any valid locale\"\n}]\n...\n```\n\n### `ignoreCase`\n\nWhen `true` the rule ignores the case-sensitivity of the props order.\n\nExamples of **correct** code for this rule\n\n```jsx\n<Hello name=\"John\" Number=\"2\" />\n```\n\n### `callbacksLast`\n\nWhen `true`, callbacks must be listed after all other props, even if `shorthandLast` is set :\n\n```jsx\n<Hello tel={5555555} onClick={this._handleClick} />\n```\n\n### `shorthandFirst`\n\nWhen `true`, short hand props must be listed before all other props, but still respecting the alphabetical order:\n\n```jsx\n<Hello active validate name=\"John\" tel={5555555} />\n```\n\n### `shorthandLast`\n\nWhen `true`, short hand props must be listed after all other props (unless `callbacksLast` is set), but still respecting the alphabetical order:\n\n```jsx\n<Hello name=\"John\" tel={5555555} active validate />\n```\n\n### `multiline`\n\nEnforced sorting for multiline props\n\n- `ignore`: Multiline props will not be taken in consideration for sorting.\n\n- `first`: Multiline props must be listed before all other props (unless `shorthandFirst` is set), but still respecting the alphabetical order.\n\n- `last`: Multiline props must be listed after all other props (unless either `callbacksLast` or `shorthandLast` are set), but still respecting the alphabetical order.\n\nDefaults to `ignore`.\n\n```jsx\n// 'jsx-sort-props': [1, { multiline: 'first' }]\n<Hello\n  classes={{\n    greetings: classes.greetings,\n  }}\n  active\n  validate\n  name=\"John\"\n  tel={5555555}\n/>\n\n// 'jsx-sort-props': [1, { multiline: 'last' }]\n<Hello\n  active\n  validate\n  name=\"John\"\n  tel={5555555}\n  classes={{\n    greetings: classes.greetings,\n  }}\n/>\n```\n\n### `noSortAlphabetically`\n\nWhen `true`, alphabetical order is **not** enforced:\n\n```jsx\n<Hello tel={5555555} name=\"John\" />\n```\n\n### `reservedFirst`\n\nThis can be a boolean or an array option.\n\nWhen `reservedFirst` is defined, React reserved props (`children`, `dangerouslySetInnerHTML` - **only for DOM components**, `key`, and `ref`) must be listed before all other props, but still respecting the alphabetical order:\n\n```jsx\n<Hello key={0} ref={johnRef} name=\"John\">\n  <div dangerouslySetInnerHTML={{__html: 'ESLint Plugin React!'}} ref={dangerDivRef} />\n</Hello>\n```\n\nIf given as an array, the array's values will override the default list of reserved props. **Note**: the values in the array may only be a **subset** of React reserved props.\n\nWith `reservedFirst: [\"key\"]`, the following will **not** warn:\n\n```jsx\n<Hello key={'uuid'} name=\"John\" ref={johnRef} />\n```\n\n### `sortFirst`\n\nWhen `sortFirst` is defined as an array of prop names, those props must be listed before all other props, maintaining the exact order specified in the array. This option has the highest priority and takes precedence over all other sorting options (including `reservedFirst`, `shorthandFirst`, `callbacksLast`, and `multiline`).\n\nThe prop names in the array are matched case-sensitively by default, but respect the `ignoreCase` option when enabled.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n// 'jsx-sort-props': [1, { sortFirst: ['className'] }]\n<Hello name=\"John\" className=\"test\" />\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// 'jsx-sort-props': [1, { sortFirst: ['className'] }]\n<Hello className=\"test\" name=\"John\" />\n\n// 'jsx-sort-props': [1, { sortFirst: ['className', 'id'] }]\n<Hello className=\"test\" id=\"test\" name=\"John\" />\n\n// 'jsx-sort-props': [1, { sortFirst: ['className'], ignoreCase: true }]\n<Hello classname=\"test\" name=\"John\" />\n```\n\n### `locale`\n\nDefaults to `\"auto\"`, meaning, the locale of the current environment.\n\nAny other string provided here may be passed to `String.prototype.localeCompare` - note that an unknown or invalid locale may throw an exception and crash.\n\n## When Not To Use It\n\nThis rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props isn't a part of your coding standards, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/jsx-space-before-closing.md",
    "content": "# react/jsx-space-before-closing\n\n📝 Enforce spacing before closing bracket in JSX.\n\n❌ This rule is deprecated. It was replaced by [`react/jsx-tag-spacing`](jsx-tag-spacing.md).\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nPlease use the `\"beforeSelfClosing\"` option of the [jsx-tag-spacing](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md) rule instead.\n\nEnforce or forbid spaces before the closing bracket of self-closing JSX elements.\n\n## Rule Details\n\nThis rule checks if there is one or more spaces before the closing bracket of self-closing JSX elements.\n\n## Rule Options\n\nThis rule takes one argument. If it is `\"always\"` then it warns whenever a space is missing before the closing bracket. If `\"never\"` then it warns if a space is present before the closing bracket. The default value of this option is `\"always\"`.\n\nExamples of **incorrect** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello/>\n<Hello firstname=\"John\"/>\n```\n\nExamples of **correct** code for this rule, when configured with `\"always\"`:\n\n```jsx\n<Hello />\n<Hello firstName=\"John\" />\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello />\n<Hello firstName=\"John\" />\n```\n\nExamples of **correct** code for this rule, when configured with `\"never\"`:\n\n```jsx\n<Hello/>\n<Hello firstname=\"John\"/>\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with the consistency of spacing before closing brackets.\n"
  },
  {
    "path": "docs/rules/jsx-tag-spacing.md",
    "content": "# react/jsx-tag-spacing\n\n📝 Enforce whitespace in and around the JSX opening and closing brackets.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nEnforce or forbid spaces after the opening bracket, before the closing bracket, before the closing bracket of self-closing elements, and between the angle bracket and slash of JSX closing or self-closing elements.\n\n## Rule Details\n\nThis rule checks the whitespace inside and surrounding the JSX syntactic elements.\n\n## Rule Options\n\nThis rule takes one argument, an object with 4 possible keys: `closingSlash`, `beforeSelfClosing`, `afterOpening`, and `beforeClosing`. Each key can receive the value `\"allow\"` to disable that specific check.\n\nThe default values are:\n\n```json\n{\n  \"closingSlash\": \"never\",\n  \"beforeSelfClosing\": \"always\",\n  \"afterOpening\": \"never\",\n  \"beforeClosing\": \"allow\"\n}\n```\n\nThe options for each sub-option are documented in the following subsections.\n\n### `closingSlash`\n\nThis check can be set to `\"always\"`, `\"never\"` or `\"allow\"` (to disable it).\n\nIf it is `\"never\"`, the check warns whenever a space is separating the two characters in the JSX tokens `</` and `/>`. If it is `\"always\"` then it warns whenever a space is missing separating the mentioned two characters. The default value of this check is `\"never\"`.\n\nExamples of **incorrect** code for this rule, when configured with `{ \"closingSlash\": \"never\" }`:\n\n```jsx\n<App/ >\n<input/\n>\n<Provider>< /Provider>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"closingSlash\": \"never\" }`:\n\n```jsx\n<App/>\n<input/>\n<Provider></Provider>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"closingSlash\": \"always\" }`:\n\n```jsx\n<Hello/>\n<Goodbye></Goodbye>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"closingSlash\": \"always\" }`:\n\n```jsx\n<Hello/ >\n<Goodbye>< /Goodbye>\n```\n\n### `beforeSelfClosing`\n\nThis check can be set to `\"always\"`, `\"never\"`, `\"proportional-always\"`, or `\"allow\"` (to disable it).\n\nIf it is `\"always\"`, the check warns whenever a space is missing before the closing bracket. If `\"never\"` then it warns if a space is present before the closing bracket. The default value of this check is `\"always\"`.\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeSelfClosing\": \"always\" }`:\n\n```jsx\n<Hello/>\n<Hello firstname=\"John\"/>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeSelfClosing\": \"always\" }`:\n\n```jsx\n<Hello />\n<Hello firstName=\"John\" />\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeSelfClosing\": \"never\" }`:\n\n```jsx\n<Hello />\n<Hello firstName=\"John\" />\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeSelfClosing\": \"never\" }`:\n\n```jsx\n<Hello/>\n<Hello firstname=\"John\"/>\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeSelfClosing\": \"proportional-always\" }`:\n\n```jsx\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\" />\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"/>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeSelfClosing\": \"proportional-always\" }`:\n\n```jsx\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\n### `afterOpening`\n\nThis check can be set to `\"always\"`, `\"never\"`, `\"allow-multiline\"` or `\"allow\"` (to disable it).\n\nIf it is `\"always\"`, the check warns whenever a space is missing after the opening bracket of either a JSX opening element or closing element. If `\"never\"` then it warns if a space is present after the opening bracket of either a JSX opening element or closing element. If `\"allow-multiline\"` then it behaves like `\"never\"`, but allows if the separator includes a newline character. The default value of this check is `\"never\"`.\n\nExamples of **incorrect** code for this rule, when configured with `{ \"afterOpening\": \"always\" }`:\n\n```jsx\n<Hello></Hello>\n<Hello firstname=\"John\"/>\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"afterOpening\": \"always\" }`:\n\n```jsx\n< Hello></ Hello>\n< Hello firstName=\"John\"/>\n<\n  Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"afterOpening\": \"never\" }`:\n\n```jsx\n< Hello></ Hello>\n< Hello firstName=\"John\"/>\n<\n  Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"afterOpening\": \"never\" }`:\n\n```jsx\n<Hello></Hello>\n<Hello firstname=\"John\"/>\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"afterOpening\": \"allow-multiline\" }`:\n\n```jsx\n< Hello></ Hello>\n< Hello firstName=\"John\"/>\n< Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"afterOpening\": \"allow-multiline\" }`:\n\n```jsx\n<Hello></Hello>\n<Hello firstName=\"John\"/>\n<\n  Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n/>\n```\n\n### `beforeClosing`\n\nThis check can be set to `\"always\"`, `\"never\"`, `\"proportional-always\"`, or `\"allow\"` (to disable it).\n\nIf it is `\"always\"` the check warns whenever whitespace is missing before the closing bracket of a JSX opening element or whenever a space is missing before the closing bracket closing element. If `\"never\"`, then it warns if a space is present before the closing bracket of either a JSX opening element or closing element. This rule will never warn for self closing JSX elements. The default value of this check is `\"allow\"`.\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeClosing\": \"always\" }`:\n\n```jsx\n<Hello></Hello>\n<Hello></Hello >\n<Hello ></Hello>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeClosing\": \"always\" }`:\n\n```jsx\n<Hello ></Hello >\n<Hello\n  firstName=\"John\"\n>\n</Hello >\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeClosing\": \"never\" }`:\n\n```jsx\n<Hello ></Hello>\n<Hello></Hello >\n<Hello ></Hello >\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeClosing\": \"never\" }`:\n\n```jsx\n<Hello></Hello>\n<Hello\n  firstName=\"John\"\n>\n</Hello>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ \"beforeClosing\": \"proportional-always\" }`:\n\n```jsx\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\">\n</Hello>\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\" >\n  Goodbye\n</Hello>\n```\n\nExamples of **correct** code for this rule, when configured with `{ \"beforeClosing\": \"proportional-always\" }`:\n\n```jsx\n<Hello\n  firstName=\"John\"\n  lastName=\"Smith\"\n>\n  Goodbye\n</Hello>\n```\n\n## When Not To Use It\n\nYou can turn this rule off if you are not concerned with the consistency of spacing in or around JSX brackets.\n"
  },
  {
    "path": "docs/rules/jsx-uses-react.md",
    "content": "# react/jsx-uses-react\n\n📝 Disallow React to be incorrectly marked as unused.\n\n💼🚫 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs). This rule is _disabled_ in the 🏃 `jsx-runtime` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nJSX expands to a call to `React.createElement`, a file which includes `React`\nbut only uses JSX should consider the `React` variable as used.\n\nIf you are using the @jsx pragma this rule will mark the designated variable and not the `React` one.\n\nThis rule has no effect if the `no-unused-vars` rule is not enabled.\n\nYou can use the [shared settings](/README.md#configuration) to specify a custom pragma.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```js\nvar React = require('react');\n\n// nothing to do with React\n```\n\n```jsx\n/** @jsx Foo */\nvar React = require('react');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n```jsx\n/** @jsx Foo */\nvar Foo = require('foo');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n## When Not To Use It\n\nIf you are not using JSX, if React is declared as global variable, or if you do not use the `no-unused-vars` rule.\n\nIf you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), you should disable this rule by extending [`react/jsx-runtime`](https://github.com/jsx-eslint/eslint-plugin-react/blob/HEAD/index.js#L163-L176) in your eslint config (add `\"plugin:react/jsx-runtime\"` to `\"extends\"`).\n"
  },
  {
    "path": "docs/rules/jsx-uses-vars.md",
    "content": "# react/jsx-uses-vars\n\n📝 Disallow variables used in JSX to be incorrectly marked as unused.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nSince 0.17.0 the `eslint` `no-unused-vars` rule does not detect variables used in JSX ([see details](https://eslint.org/blog/2015/03/eslint-0.17.0-released#changes-to-jsxreact-handling)). This rule will find variables used in JSX and mark them as used.\n\nThis rule only has an effect when the `no-unused-vars` rule is enabled.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```js\nvar Hello = require('./Hello');\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = require('./Hello');\n\n<Hello name=\"John\" />;\n```\n\n## When Not To Use It\n\nIf you are not using JSX or if you do not use the `no-unused-vars` rule then you can disable this rule.\n"
  },
  {
    "path": "docs/rules/jsx-wrap-multilines.md",
    "content": "# react/jsx-wrap-multilines\n\n📝 Disallow missing parentheses around multiline JSX.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nWrapping multiline JSX in parentheses can improve readability and/or convenience.\n\n## Rule Details\n\nThis rule optionally takes a second parameter in the form of an object, containing places to apply the rule. By default, all the syntax listed below will be checked except the conditions out of declaration or assignment, logical expressions and JSX attributes, but these can be explicitly disabled. Any syntax type missing in the object will follow the default behavior displayed below.\n\n```json\n{\n  \"declaration\": \"parens\",\n  \"assignment\": \"parens\",\n  \"return\": \"parens\",\n  \"arrow\": \"parens\",\n  \"condition\": \"ignore\",\n  \"logical\": \"ignore\",\n  \"prop\": \"ignore\"\n}\n```\n\nNote: conditions are checked by default in declarations or assignments.\n\n## Rule Options\n\nExamples of **incorrect** code for this rule, when configured with `parens` or `parens-new-line`:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>\n      <p>Hello {this.props.name}</p>\n    </div>;\n  }\n});\n```\n\nExamples of **incorrect** code for this rule, when configured with `parens-new-line`:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return (<div>\n      <p>Hello {this.props.name}</p>\n    </div>);\n  }\n});\n```\n\nExamples of **correct** code for this rule, when configured with either `parens` or `parens-new-line`:\n\n```jsx\nvar singleLineJSX = <p>Hello</p>\n\nvar Hello = createReactClass({\n  render: function() {\n    return (\n      <div>\n        <p>Hello {this.props.name}</p>\n      </div>\n    );\n  }\n});\n```\n\nExamples of **incorrect** code for this rule, when configured with `never`:\n\n```jsx\nvar singleLineJSX = <p>Hello</p>\n\nvar Hello = createReactClass({\n  render: function() {\n    return (\n      <div>\n        <p>Hello {this.props.name}</p>\n      </div>\n    );\n  }\n});\n```\n\nExamples of **correct** code for this rule, when configured with `never`:\n\n```jsx\nvar singleLineJSX = <p>Hello</p>\n\nvar Hello = createReactClass({\n  render: function() {\n    return <div>\n      <p>Hello {this.props.name}</p>\n    </div>;\n  }\n});\n```\n\n### `declaration`\n\nExamples of **incorrect** code for this rule, when configured with `{ declaration: \"parens\" }`:\n\n```jsx\nvar hello = <div>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured with `{ declaration: \"parens\" }`:\n\n```jsx\nvar hello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\n```jsx\nvar hello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ declaration: \"parens-new-line\" }`:\n\n```jsx\nvar hello = <div>\n  <p>Hello</p>\n</div>;\n```\n\n```jsx\nvar hello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\nExamples of **correct** code for this rule, when configured with `{ declaration: \"parens-new-line\" }`.\n\n```jsx\nvar hello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ declaration: \"never\" }`:\n\n```jsx\nvar hello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\n```jsx\nvar hello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\nExamples of **correct** code for this rule, when configured with `{ declaration: \"never\" }`.\n\n```jsx\nvar hello = <div>\n  <p>Hello</p>\n</div>;\n```\n\n### `assignment`\n\nExamples of **incorrect** code for this rule, when configured with `{ assignment: \"parens\" }`.\n\n```jsx\nvar hello;\nhello = <div>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured with `{ assignment: \"parens\" }`.\n\n```jsx\nvar hello;\nhello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\n```jsx\nvar hello;\nhello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ assignment: \"parens-new-line\" }`.\n\n```jsx\nvar hello;\nhello = <div>\n  <p>Hello</p>\n</div>;\n```\n\n```jsx\nvar hello;\nhello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\nExamples of **correct** code for this rule, when configured with `{ assignment: \"parens-new-line\" }`.\n\n```jsx\nvar hello;\nhello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ assignment: \"never\" }`.\n\n```jsx\nvar hello;\nhello = (<div>\n  <p>Hello</p>\n</div>);\n```\n\n```jsx\nvar hello;\nhello = (\n  <div>\n    <p>Hello</p>\n  </div>\n);\n```\n\nExamples of **correct** code for this rule, when configured with `{ assignment: \"never\" }`.\n\n```jsx\nvar hello;\nhello = <div>\n  <p>Hello</p>\n</div>;\n```\n\n### `return`\n\nExamples of **incorrect** code for this rule, when configured with `{ return: \"parens\" }`.\n\n```jsx\nfunction hello() {\n  return <div>\n    <p>Hello</p>\n  </div>;\n}\n```\n\nExamples of **correct** code for this rule, when configured with `{ return: \"parens\" }`.\n\n```jsx\nfunction hello() {\n  return (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n}\n```\n\n```jsx\nfunction hello() {\n  return (<div>\n    <p>Hello</p>\n  </div>);\n}\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ return: \"parens-new-line\" }`.\n\n```jsx\nfunction hello() {\n  return <div>\n    <p>Hello</p>\n  </div>;\n}\n```\n\n```jsx\nfunction hello() {\n  return (<div>\n    <p>Hello</p>\n  </div>);\n}\n```\n\nExamples of **correct** code for this rule, when configured with `{ return: \"parens-new-line\" }`.\n\n```jsx\nfunction hello() {\n  return (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n}\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ return: \"never\" }`.\n\n```jsx\nfunction hello() {\n  return (<div>\n    <p>Hello</p>\n  </div>);\n}\n```\n\n```jsx\nfunction hello() {\n  return (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n}\n```\n\nExamples of **correct** code for this rule, when configured with `{ return: \"never\" }`.\n\n```jsx\nfunction hello() {\n  return <div>\n    <p>Hello</p>\n  </div>;\n}\n```\n\n### `arrow`\n\nExamples of **incorrect** code for this rule, when configured with `{ arrow: \"parens\" }`.\n\n```jsx\nvar hello = () => <div>\n  <p>World</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured `{ arrow: \"parens\" }`.\n\n```jsx\nvar hello = () => (\n  <div>\n    <p>World</p>\n  </div>\n);\n```\n\n```jsx\nvar hello = () => (<div>\n  <p>World</p>\n</div>);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ arrow: \"parens-new-line\" }`.\n\n```jsx\nvar hello = () => <div>\n  <p>World</p>\n</div>;\n```\n\n```jsx\nvar hello = () => (<div>\n  <p>World</p>\n</div>);\n```\n\nExamples of **correct** code for this rule, when configured with `{ arrow: \"parens-new-line\" }`.\n\n```jsx\nvar hello = () => (\n  <div>\n    <p>World</p>\n  </div>\n);\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ arrow: \"never\" }`.\n\n```jsx\nvar hello = () => (<div>\n  <p>World</p>\n</div>);\n```\n\n```jsx\nvar hello = () => (\n  <div>\n    <p>World</p>\n  </div>\n);\n```\n\nExamples of **correct** code for this rule, when configured with `{ arrow: \"never\" }`.\n\n```jsx\nvar hello = () => <div>\n  <p>World</p>\n</div>;\n```\n\n### `condition`\n\nExamples of **incorrect** code for this rule, when configured with `{ condition: \"parens\" }`.\n\n```jsx\n<div>\n  {foo ? <div>\n      <p>Hello</p>\n    </div> : null}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ condition: \"parens\" }`.\n\n```jsx\n<div>\n  {foo ? (<div>\n      <p>Hello</p>\n  </div>) : null}\n</div>\n```\n\n```jsx\n<div>\n  {foo ? (\n    <div>\n      <p>Hello</p>\n    </div>\n  ): null}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ condition: \"parens-new-line\" }`.\n\n```jsx\n<div>\n  {foo ? <div>\n      <p>Hello</p>\n    </div> : null}\n</div>\n```\n\n```jsx\n<div>\n  {foo ? (<div>\n      <p>Hello</p>\n  </div>) : null}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ condition: \"parens-new-line\" }`.\n\n```jsx\n<div>\n  {foo ? (\n    <div>\n      <p>Hello</p>\n    </div>\n  ): null}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ condition: \"never\" }`.\n\n```jsx\n<div>\n  {foo ? (<div>\n      <p>Hello</p>\n  </div>) : null}\n</div>\n```\n\n```jsx\n<div>\n  {foo ? (\n    <div>\n      <p>Hello</p>\n    </div>\n  ): null}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ condition: \"never\" }`.\n\n```jsx\n<div>\n  {foo ? <div>\n      <p>Hello</p>\n    </div> : null}\n</div>\n```\n\n### `logical`\n\nExamples of **incorrect** code for this rule, when configured with `{ logical: \"parens\" }`.\n\n```jsx\n<div>\n  {foo &&\n    <div>\n      <p>Hello World</p>\n    </div>\n  }\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ logical: \"parens\" }`.\n\n```jsx\n<div>\n  {foo &&\n    (<div>\n      <p>Hello World</p>\n    </div>)\n  }\n</div>\n```\n\n```jsx\n<div>\n  {foo && (\n    <div>\n      <p>Hello World</p>\n    </div>\n  )}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ logical: \"parens-new-line\" }`.\n\n```jsx\n<div>\n  {foo &&\n    <div>\n      <p>Hello World</p>\n    </div>\n  }\n</div>\n```\n\n```jsx\n<div>\n  {foo &&\n    (<div>\n      <p>Hello World</p>\n    </div>)\n  }\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ logical: \"parens-new-line\" }`.\n\n```jsx\n<div>\n  {foo && (\n    <div>\n      <p>Hello World</p>\n    </div>\n  )}\n</div>\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ logical: \"never\" }`.\n\n```jsx\n<div>\n  {foo &&\n    (<div>\n      <p>Hello World</p>\n    </div>)\n  }\n</div>\n```\n\n```jsx\n<div>\n  {foo && (\n    <div>\n      <p>Hello World</p>\n    </div>\n  )}\n</div>\n```\n\nExamples of **correct** code for this rule, when configured with `{ logical: \"never\" }`.\n\n```jsx\n<div>\n  {foo &&\n    <div>\n      <p>Hello World</p>\n    </div>\n  }\n</div>\n```\n\n### `prop`\n\nExamples of **incorrect** code for this rule, when configured with `{ prop: \"parens\" }`.\n\n```jsx\n<div foo={<div>\n    <p>Hello</p>\n  </div>}>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured with `{ prop: \"parens\" }`.\n\n```jsx\n<div foo={(<div>\n    <p>Hello</p>\n  </div>)}>\n  <p>Hello</p>\n</div>;\n```\n\n```jsx\n<div foo={(\n  <div>\n    <p>Hello</p>\n  </div>\n)}>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ prop: \"parens-new-line\" }`.\n\n```jsx\n<div foo={<div>\n    <p>Hello</p>\n  </div>}>\n  <p>Hello</p>\n</div>;\n```\n\n```jsx\n<div foo={(<div>\n    <p>Hello</p>\n  </div>)}>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured with `{ prop: \"parens-new-line\" }`.\n\n```jsx\n<div foo={(\n  <div>\n    <p>Hello</p>\n  </div>\n)}>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **incorrect** code for this rule, when configured with `{ prop: \"never\" }`.\n\n```jsx\n<div foo={(<div>\n    <p>Hello</p>\n  </div>)}>\n  <p>Hello</p>\n</div>;\n```\n\n```jsx\n<div foo={(\n  <div>\n    <p>Hello</p>\n  </div>\n)}>\n  <p>Hello</p>\n</div>;\n```\n\nExamples of **correct** code for this rule, when configured with `{ prop: \"never\" }`.\n\n```jsx\n<div foo={<div>\n    <p>Hello</p>\n  </div>}>\n  <p>Hello</p>\n</div>;\n```\n"
  },
  {
    "path": "docs/rules/no-access-state-in-setstate.md",
    "content": "# react/no-access-state-in-setstate\n\n📝 Disallow when this.state is accessed within setState.\n\n<!-- end auto-generated rule header -->\n\nUsage of `this.state` inside `setState` calls might result in errors when two state calls are called in batch and thus referencing old state and not the current state.\n\n## Rule Details\n\nThis rule should prevent usage of `this.state` inside `setState` calls.\n\n## Examples\n\nAn example can be an increment function:\n\n```javascript\nfunction increment() {\n  this.setState({value: this.state.value + 1});\n}\n```\n\nIf two `setState` operations are grouped together in a batch, they both evaluate the old state. Given that `state.value` is 1:\n\n```javascript\nthis.setState({value: this.state.value + 1}) // 2\nthis.setState({value: this.state.value + 1}) // 2, not 3\n```\n\nThis can be avoided with using callbacks which takes the previous state as first argument:\n\n```javascript\nfunction increment() {\n  this.setState(prevState => ({value: prevState.value + 1}));\n}\n```\n\nThen react will call the argument with the correct and updated state, even when things happen in batches. And the example above will be something like:\n\n```javascript\nsetState({value: 1 + 1})\nsetState({value: 2 + 1})\n```\n"
  },
  {
    "path": "docs/rules/no-adjacent-inline-elements.md",
    "content": "# react/no-adjacent-inline-elements\n\n📝 Disallow adjacent inline elements not separated by whitespace.\n\n<!-- end auto-generated rule header -->\n\nAdjacent inline elements not separated by whitespace will bump up against each\nother when viewed in an unstyled manner, which usually isn't desirable.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div><a></a><a></a></div>\n<div><a></a><span></span></div>\n\nReact.createElement(\"div\", undefined, [React.createElement(\"a\"), React.createElement(\"span\")]);\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div><div></div><div></div></div>\n<div><a></a> <a></a></div>\n\nReact.createElement(\"div\", undefined, [React.createElement(\"a\"), \" \", React.createElement(\"a\")]);\n```\n"
  },
  {
    "path": "docs/rules/no-array-index-key.md",
    "content": "# react/no-array-index-key\n\n📝 Disallow usage of Array index in keys.\n\n<!-- end auto-generated rule header -->\n\nWarn if an element uses an Array index in its `key`.\n\nThe `key` is used by React to [identify which items have changed, are added, or are removed and should be stable](https://react.dev/learn/rendering-lists#why-does-react-need-keys).\n\nIt's a bad idea to use the array index since it doesn't uniquely identify your elements. In cases where the array is sorted or an element is added to the beginning of the array, the index will be changed even though the element representing that index may be the same. This results in unnecessary renders.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nthings.map((thing, index) => (\n  <Hello key={index} />\n));\n\nthings.map((thing, index) => (\n  <Hello key={`hello-${index}`} />\n));\n\nthings.map((thing, index) => (\n  React.cloneElement(thing, { key: index })\n));\n\nthings.map((thing, index) => (\n  React.cloneElement(thing, { key: `hello-${index}` })\n));\n\nthings.forEach((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.filter((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.some((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.every((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.find((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.findIndex((thing, index) => {\n  otherThings.push(<Hello key={index} />);\n});\n\nthings.flatMap((thing, index) => (\n  <Hello key={index} />\n));\n\nthings.reduce((collection, thing, index) => (\n  collection.concat(<Hello key={index} />)\n), []);\n\nthings.reduceRight((collection, thing, index) => (\n  collection.concat(<Hello key={index} />)\n), []);\n\nReact.Children.map(this.props.children, (child, index) => (\n  React.cloneElement(child, { key: index })\n))\n\nChildren.forEach(this.props.children, (child, index) => (\n  React.cloneElement(child, { key: index })\n))\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nthings.map((thing) => (\n  <Hello key={thing.id} />\n));\n\nthings.map((thing) => (\n  <Hello key={`hello-${thing.id}`} />\n));\n\nthings.map((thing) => (\n  React.cloneElement(thing, { key: thing.id })\n));\n\nthings.map((thing) => (\n  React.cloneElement(thing, { key: `hello-${thing.id}` })\n));\n\nthings.forEach((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.filter((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.some((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.every((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.find((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.findIndex((thing) => {\n  otherThings.push(<Hello key={thing.id} />);\n});\n\nthings.reduce((collection, thing) => (\n  collection.concat(<Hello key={thing.id} />)\n), []);\n\nthings.reduceRight((collection, thing) => (\n  collection.concat(<Hello key={thing.id} />)\n), []);\n```\n\n## When Not To Use It\n\nIf there is nothing unique about the items, for example [you are breaking an array down in to chunks](https://github.com/jsx-eslint/eslint-plugin-react/issues/1123), then you may want to disable this rule with an override.\n"
  },
  {
    "path": "docs/rules/no-arrow-function-lifecycle.md",
    "content": "# react/no-arrow-function-lifecycle\n\n📝 Lifecycle methods should be methods on the prototype, not class fields.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nIt is not necessary to use arrow function for lifecycle methods. This makes things harder to test, conceptually less performant (although in practice, performance will not be affected, since most engines will optimize efficiently), and can break hot reloading patterns.\n\n## Rule Details\n\nThe following patterns are considered warnings:\n\n```jsx\nclass Hello extends React.Component {\n  render = () => {\n    return <div />;\n  }\n}\n\nvar AnotherHello = createReactClass({\n  render: () => {\n    return <div />;\n  },\n});\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div />;\n  }\n}\n\nvar AnotherHello = createReactClass({\n  render() {\n    return <div />;\n  },\n});\n\n```\n\n## When Not To Use It\n\nIf you don't care about performance of your application or conceptual correctness of class property placement, you can disable this rule.\n"
  },
  {
    "path": "docs/rules/no-children-prop.md",
    "content": "# react/no-children-prop\n\n📝 Disallow passing of children as props.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nChildren should always be actual children, not passed in as a prop.\n\nWhen using JSX, the children should be nested between the opening and closing\ntags. When not using JSX, the children should be passed as additional\narguments to `React.createElement`.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div children='Children' />\n\n<MyComponent children={<AnotherComponent />} />\n<MyComponent children={['Child 1', 'Child 2']} />\n\nReact.createElement(\"div\", { children: 'Children' })\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>Children</div>\n\n<MyComponent>Children</MyComponent>\n\n<MyComponent>\n  <span>Child 1</span>\n  <span>Child 2</span>\n</MyComponent>\n\nReact.createElement(\"div\", {}, 'Children')\nReact.createElement(\"div\", 'Child 1', 'Child 2')\n```\n\n## Rule Options\n\n```js\n\"react/no-children-prop\": [<enabled>, {\n  \"allowFunctions\": <boolean> || false\n}]\n```\n\n### `allowFunctions`\n\nWhen `true`, and passing a function as `children`, it must be in prop position and not child position.\n\nThe following patterns are considered warnings:\n\n```jsx\n<MyComponent>{data => data.value}</MyComponent>\nReact.createElement(MyComponent, {}, data => data.value)\n```\n\nThe following are **not** considered warnings:\n\n```jsx\n<MyComponent children={data => data.value} />\nReact.createElement(MyComponent, { children: data => data.value })\n```\n"
  },
  {
    "path": "docs/rules/no-danger-with-children.md",
    "content": "# react/no-danger-with-children\n\n📝 Disallow when a DOM element is using both children and dangerouslySetInnerHTML.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nThis rule helps prevent problems caused by using children and the dangerouslySetInnerHTML prop at the same time.\nReact will throw a warning if this rule is ignored.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div dangerouslySetInnerHTML={{ __html: \"HTML\" }}>\n  Children\n</div>\n\n<Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }}>\n  Children\n</Hello>\n\n```\n\n```js\nReact.createElement(\"div\", { dangerouslySetInnerHTML: { __html: \"HTML\" } }, \"Children\");\n\nReact.createElement(\"Hello\", { dangerouslySetInnerHTML: { __html: \"HTML\" } }, \"Children\");\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div dangerouslySetInnerHTML={{ __html: \"HTML\" }} />\n\n<Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }} />\n\n<div>\n  Children\n</div>\n\n<Hello>\n  Children\n</Hello>\n\n```\n\n```js\nReact.createElement(\"div\", { dangerouslySetInnerHTML: { __html: \"HTML\" } });\n\nReact.createElement(\"Hello\", { dangerouslySetInnerHTML: { __html: \"HTML\" } });\n\nReact.createElement(\"div\", {}, \"Children\");\n\nReact.createElement(\"Hello\", {}, \"Children\");\n```\n"
  },
  {
    "path": "docs/rules/no-danger.md",
    "content": "# react/no-danger\n\n📝 Disallow usage of dangerous JSX properties.\n\n<!-- end auto-generated rule header -->\n\nDangerous properties in React are those whose behavior is known to be a common source of application vulnerabilities. The properties' names clearly indicate they are dangerous and should be avoided unless great care is taken.\n\nSee <https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html>\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div dangerouslySetInnerHTML={{ __html: \"Hello World\" }}></div>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div>Hello World</div>;\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-danger\": [<enabled>, {\n  \"customComponentNames\": Array<string>,\n}]\n...\n```\n\n### customComponentNames\n\nDefaults to `[]`, if you want to enable this rule for all custom components you can pass `customComponentNames` as `['*']`, or else you can pass specific components name to the array.\n\n## When Not To Use It\n\nIf you are certain the content passed to dangerouslySetInnerHTML is sanitized HTML you can disable this rule.\n"
  },
  {
    "path": "docs/rules/no-deprecated.md",
    "content": "# react/no-deprecated\n\n📝 Disallow usage of deprecated methods.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nSeveral methods are deprecated between React versions. This rule will warn you if you try to use a deprecated method. Use the [shared settings](/README.md#configuration) to specify the React version.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nReact.render(<MyComponent />, root);\n\nReact.unmountComponentAtNode(root);\n\nReact.findDOMNode(this.refs.foo);\n\nReact.renderToString(<MyComponent />);\n\nReact.renderToStaticMarkup(<MyComponent />);\n\nReact.createClass({ /* Class object */ });\n\nconst propTypes = {\n  foo: PropTypes.bar,\n};\n\n//Any factories under React.DOM\nReact.DOM.div();\n\nimport React, { PropTypes } from 'react';\n\n// old lifecycles (since React 16.9)\ncomponentWillMount() { }\ncomponentWillReceiveProps() { }\ncomponentWillUpdate() { }\n\n// React 18 deprecations\nimport { render } from 'react-dom';\nReactDOM.render(<div></div>, container);\n\nimport { hydrate } from 'react-dom';\nReactDOM.hydrate(<div></div>, container);\n\nimport {unmountComponentAtNode} from 'react-dom';\nReactDOM.unmountComponentAtNode(container);\n\nimport { renderToNodeStream } from 'react-dom/server';\nReactDOMServer.renderToNodeStream(element);\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n// when React < 18\nReactDOM.render(<MyComponent />, root);\n\n// when React is < 0.14\nReactDOM.findDOMNode(this.refs.foo);\n\nimport { PropTypes } from 'prop-types';\n\nUNSAFE_componentWillMount() { }\nUNSAFE_componentWillReceiveProps() { }\nUNSAFE_componentWillUpdate() { }\n\nReactDOM.createPortal(child, container);\n\nimport { createRoot } from 'react-dom/client';\nconst root = createRoot(container);\nroot.unmount();\n\nimport { hydrateRoot } from 'react-dom/client';\nconst root = hydrateRoot(container, <App/>);\n```\n"
  },
  {
    "path": "docs/rules/no-did-mount-set-state.md",
    "content": "# react/no-did-mount-set-state\n\n📝 Disallow usage of setState in componentDidMount.\n\n<!-- end auto-generated rule header -->\n\nUpdating the state after a component mount will trigger a second `render()` call and can lead to property/layout thrashing.\n\n## Rule Details\n\nThis rule is aimed to forbid the use of `this.setState` in `componentDidMount` outside of functions, such as callbacks.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.setState({\n      name: this.props.name.toUpperCase()\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.onMount(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.props.onMount();\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-did-mount-set-state\": [<enabled>, <mode>]\n...\n```\n\n### `disallow-in-func` mode\n\nBy default this rule forbids any call to `this.setState` in `componentDidMount` outside of functions. The `disallow-in-func` mode makes this rule more strict by disallowing calls to `this.setState` even within functions.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.setState({\n      name: this.props.name.toUpperCase()\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.onMount(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/no-did-update-set-state.md",
    "content": "# react/no-did-update-set-state\n\n📝 Disallow usage of setState in componentDidUpdate.\n\n<!-- end auto-generated rule header -->\n\nUpdating the state after a component update will trigger a second `render()` call and can lead to property/layout thrashing.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidUpdate: function() {\n     this.setState({\n        name: this.props.name.toUpperCase()\n      });\n    },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidUpdate: function() {\n    this.props.onUpdate();\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentDidUpdate: function() {\n    this.onUpdate(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-did-update-set-state\": [<enabled>, <mode>]\n...\n```\n\n### `disallow-in-func` mode\n\nBy default this rule forbids any call to `this.setState` in `componentDidUpdate` outside of functions. The `disallow-in-func` mode makes this rule more strict by disallowing calls to `this.setState` even within functions.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidUpdate: function() {\n     this.setState({\n        name: this.props.name.toUpperCase()\n      });\n    },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentDidUpdate: function() {\n    this.onUpdate(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/no-direct-mutation-state.md",
    "content": "# react/no-direct-mutation-state\n\n📝 Disallow direct mutation of this.state.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nNEVER mutate `this.state` directly, as calling `setState()` afterwards may replace\nthe mutation you made. Treat `this.state` as if it were immutable.\n\nThe only place that's acceptable to assign this.state is in a ES6 `class` component constructor.\n\n## Rule Details\n\nThis rule is aimed to forbid the use of mutating `this.state` directly.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.state.name = this.props.name.toUpperCase();\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n\nclass Hello extends React.Component {\n  constructor(props) {\n    super(props)\n\n    // Assign at instance creation time, not on a callback\n    doSomethingAsync(() => {\n      this.state = 'bad';\n    });\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    this.setState({\n      name: this.props.name.toUpperCase();\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n\nclass Hello extends React.Component {\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      foo: 'bar',\n    }\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/no-find-dom-node.md",
    "content": "# react/no-find-dom-node\n\n📝 Disallow usage of findDOMNode.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nFacebook will eventually deprecate `findDOMNode` as it blocks certain improvements in React in the future.\n\nIt is recommended to use callback refs instead. See [Dan Abramov comments and examples](https://github.com/jsx-eslint/eslint-plugin-react/issues/678#issue-165177220).\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass MyComponent extends Component {\n  componentDidMount() {\n    findDOMNode(this).scrollIntoView();\n  }\n  render() {\n    return <div />\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass MyComponent extends Component {\n  componentDidMount() {\n    this.node.scrollIntoView();\n  }\n  render() {\n    return <div ref={node => this.node = node} />\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/no-invalid-html-attribute.md",
    "content": "# react/no-invalid-html-attribute\n\n📝 Disallow usage of invalid attributes.\n\n💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\nSome HTML elements have a specific set of valid values for some attributes.\nFor instance the elements: `a`, `area`, `link`, or `form` all have an attribute called `rel`.\nThere is a fixed list of values that have any meaning for this attribute on these tags (see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)).\nTo help with minimizing confusion while reading code, only the appropriate values should be on each attribute.\n\n## Rule Details\n\nThis rule aims to remove invalid attribute values.\n\n## Rule Options\n\nThe options is a list of attributes to check. Defaults to `[\"rel\"]`.\n\n## When Not To Use It\n\nWhen you don't want to enforce attribute value correctness.\n"
  },
  {
    "path": "docs/rules/no-is-mounted.md",
    "content": "# react/no-is-mounted\n\n📝 Disallow usage of isMounted.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\n[`isMounted` is an anti-pattern][anti-pattern], is not available when using ES6 classes, and it is on its way to being officially deprecated.\n\n[anti-pattern]: https://legacy.reactjs.org/blog/2015/12/16/ismounted-antipattern.html\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  handleClick: function() {\n    setTimeout(function() {\n      if (this.isMounted()) {\n        return;\n      }\n    });\n  },\n  render: function() {\n    return <div onClick={this.handleClick.bind(this)}>Hello</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div onClick={this.props.handleClick}>Hello</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/no-multi-comp.md",
    "content": "# react/no-multi-comp\n\n📝 Disallow multiple component definition per file.\n\n<!-- end auto-generated rule header -->\n\nDeclaring only one component per file improves readability and reusability of components.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n\nvar HelloJohn = createReactClass({\n  render: function() {\n    return <Hello name=\"John\" />;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = require('./components/Hello');\n\nvar HelloJohn = createReactClass({\n  render: function() {\n    return <Hello name=\"John\" />;\n  }\n});\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-multi-comp\": [<enabled>, { \"ignoreStateless\": <boolean> }]\n...\n```\n\n### `ignoreStateless`\n\nWhen `true` the rule will ignore stateless components and will allow you to have multiple stateless components, or one stateful component and some stateless components in the same file.\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction Hello(props) {\n  return <div>Hello {props.name}</div>;\n}\nfunction HelloAgain(props) {\n  return <div>Hello again {props.name}</div>;\n}\n```\n\n```jsx\nfunction Hello(props) {\n  return <div>Hello {props.name}</div>;\n}\nclass HelloJohn extends React.Component {\n  render() {\n    return <Hello name=\"John\" />;\n  }\n}\nmodule.exports = HelloJohn;\n```\n\n## When Not To Use It\n\nIf you prefer to declare multiple components per file you can disable this rule.\n"
  },
  {
    "path": "docs/rules/no-namespace.md",
    "content": "# react/no-namespace\n\n📝 Enforce that namespaces are not used in React elements.\n\n<!-- end auto-generated rule header -->\n\nEnforces the absence of a namespace in React elements, such as with `svg:circle`, as they are not supported in React.\n\n## Rule Details\n\nThe following patterns are considered warnings:\n\n```jsx\n<ns:TestComponent />\n```\n\n```jsx\n<Ns:TestComponent />\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\n<TestComponent />\n```\n\n```jsx\n<testComponent />\n```\n\n## When Not To Use It\n\nIf you are not using React.\n"
  },
  {
    "path": "docs/rules/no-object-type-as-default-prop.md",
    "content": "# react/no-object-type-as-default-prop\n\n📝 Disallow usage of referential-type variables as default param in functional component.\n\n<!-- end auto-generated rule header -->\n\nWarns if in a functional component, an object type value (such as array/object literal/function/etc) is used as default prop, to prevent potential unnecessary rerenders, and performance regressions.\n\n## Rule Details\n\nCertain values (like arrays, objects, functions, etc) are compared by identity instead of by value. This means that, for example, whilst two empty arrays conceptually represent the same value - JavaScript semantics dictate that they are distinct and unequal as they represent two distinct values.\n\nWhen using object destructuring syntax you can set the default value for a given property if it does not exist. If you set the default value to one of the values that is compared by identity, it will mean that each time the destructure is evaluated the JS engine will create a new, distinct value in the destructured variable.\n\nIn the context of a React functional component's props argument this means for each render, the property has a new, distinct value. When this value is passed to a hook as a dependency or passed into a child component as a property React will see this as a new value - meaning that a hook will be re-evaluated, or a memoized component will rerender.\n\nThis obviously destroys any performance benefits you get from memoization. Additionally, in certain circumstances this can cause infinite rerender loops, which can often be hard to debug.\n\nIt's worth noting that primitive literal values (`string`, `number`, `boolean`, `null`, and `undefined`) can be considered to be compared \"by value\", or alternatively, as always having the same identity (every `3` is the same exact `3`). Thus, it's safe for those to be inlined as a default value.\n\nTo fix the violations, the easiest way is to use a referencing variable in module scope instead of using the literal values, e.g:\n\n```jsx\nconst emptyArray = [];\n\nfunction Component({\n  items = emptyArray,\n}) {}\n```\n\nExamples of ***invalid*** code for this rule:\n\n```jsx\nfunction Component({\n  items = [],\n}) {}\n\nconst Component = ({\n  items = {},\n}) => {}\n\nconst Component = ({\n  items = () => {},\n}) => {}\n```\n\nExamples of ***valid*** code for this rule:\n\n```jsx\nconst emptyArray = [];\n\nfunction Component({\n  items = emptyArray,\n}) {}\n\nconst emptyObject = {};\nconst Component = ({\n  items = emptyObject,\n}) => {}\n\nconst noopFunc = () => {};\nconst Component = ({\n  items = noopFunc,\n}) => {}\n\n// primitives are all compared by value, so are safe to be inlined\nfunction Component({\n  num = 3,\n  str = 'foo',\n  bool = true,\n}) {}\n```\n"
  },
  {
    "path": "docs/rules/no-redundant-should-component-update.md",
    "content": "# react/no-redundant-should-component-update\n\n📝 Disallow usage of shouldComponentUpdate when extending React.PureComponent.\n\n<!-- end auto-generated rule header -->\n\nWarns if you have `shouldComponentUpdate` defined when defining a component that extends React.PureComponent.\nWhile having `shouldComponentUpdate` will still work, it becomes pointless to extend PureComponent.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Foo extends React.PureComponent {\n  shouldComponentUpdate() {\n    // do check\n  }\n\n  render() {\n    return <div>Radical!</div>\n  }\n}\n\nfunction Bar() {\n  return class Baz extends React.PureComponent {\n    shouldComponentUpdate() {\n      // do check\n    }\n\n    render() {\n      return <div>Groovy!</div>\n    }\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  shouldComponentUpdate() {\n    // do check\n  }\n\n  render() {\n    return <div>Radical!</div>\n  }\n}\n\nfunction Bar() {\n  return class Baz extends React.Component {\n    shouldComponentUpdate() {\n      // do check\n    }\n\n    render() {\n      return <div>Groovy!</div>\n    }\n  }\n}\n\nclass Qux extends React.PureComponent {\n  render() {\n    return <div>Tubular!</div>\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/no-render-return-value.md",
    "content": "# react/no-render-return-value\n\n📝 Disallow usage of the return value of ReactDOM.render.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\n> `ReactDOM.render()` currently returns a reference to the root `ReactComponent` instance. However, using this return value is legacy and should be avoided because future versions of React may render components asynchronously in some cases. If you need a reference to the root `ReactComponent` instance, the preferred solution is to attach a [callback ref](https://legacy.reactjs.org/docs/refs-and-the-dom.html#callback-refs) to the root element.\n\nSource: [ReactDOM documentation](https://legacy.reactjs.org/docs/react-dom.html#render)\n\n## Rule Details\n\nThis rule will warn you if you try to use the `ReactDOM.render()` return value.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nconst inst = ReactDOM.render(<App />, document.body);\ndoSomethingWithInst(inst);\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nReactDOM.render(<App ref={doSomethingWithInst} />, document.body);\n\nReactDOM.render(<App />, document.body, doSomethingWithInst);\n```\n"
  },
  {
    "path": "docs/rules/no-set-state.md",
    "content": "# react/no-set-state\n\n📝 Disallow usage of setState.\n\n<!-- end auto-generated rule header -->\n\nWhen using an architecture that separates your application state from your UI components (e.g. Flux), it may be desirable to forbid the use of local component state. This rule is especially helpful in read-only applications (that don't use forms), since local component state should rarely be necessary in such cases.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  getInitialState: function() {\n    return {\n      name: this.props.name\n    };\n  },\n  handleClick: function() {\n    this.setState({\n      name: this.props.name.toUpperCase()\n    });\n  },\n  render: function() {\n    return <div onClick={this.handleClick.bind(this)}>Hello {this.state.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div onClick={this.props.handleClick}>Hello {this.props.name}</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/no-string-refs.md",
    "content": "# react/no-string-refs\n\n📝 Disallow using string references.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nCurrently, two ways are supported by React to refer to components. The first way, providing a string identifier, is now considered legacy in the official documentation. The documentation now prefers a second method -- referring to components by setting a property on the `this` object in the reference callback.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n render: function() {\n  return <div ref=\"hello\">Hello, world.</div>;\n }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    var component = this.refs.hello;\n    // ...do something with component\n  },\n  render: function() {\n    return <div ref=\"hello\">Hello, world.</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentDidMount: function() {\n    var component = this.hello;\n    // ...do something with component\n  },\n  render() {\n    return <div ref={(c) => { this.hello = c; }}>Hello, world.</div>;\n  }\n});\n```\n\n## Rule Options\n\n```js\n\"react/no-string-refs\": [<enabled>, {\"noTemplateLiterals\": <boolean>}]\n```\n\n### `noTemplateLiterals`\n\nWhen set to `true`, it will give warning when using template literals for refs.\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n render: function() {\n  return <div ref={`hello`}>Hello, world.</div>;\n }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n render: function() {\n  return <div ref={`hello${index}`}>Hello, world.</div>;\n }\n});\n```\n"
  },
  {
    "path": "docs/rules/no-this-in-sfc.md",
    "content": "# react/no-this-in-sfc\n\n📝 Disallow `this` from being used in stateless functional components.\n\n<!-- end auto-generated rule header -->\n\nIn React, there are two styles of component. One is a class component: `class Foo extends React.Component {...}`, which accesses its props, context, and state as properties of `this`: `this.props.foo`, etc. The other are stateless functional components (SFCs): `function Foo(props, context) {...}`. As you can see, there's no `state` (hence the name - hooks do not change this), and the props and context are provided as its two functional arguments. In an SFC, state is usually best implements with a [React hook](https://reactjs.org/docs/hooks-overview.html) such as `React.useState()`.\n\nAttempting to access properties on `this` can sometimes be valid, but it's very commonly an error caused by unfamiliarity with the differences between the two styles of components, or a missed reference when converting a class component to an SFC.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nfunction Foo(props) {\n  return (\n    <div>{this.props.bar}</div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props) {\n  const { bar } = this.props;\n  return (\n    <div>{bar}</div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props, context) {\n  return (\n    <div>\n      {this.context.foo ? this.props.bar : ''}\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props, context) {\n  const { foo } = this.context;\n  const { bar } = this.props;\n  return (\n    <div>\n      {foo ? bar : ''}\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props) {\n  if (this.state.loading) {\n    return <Loader />;\n  }\n  return (\n    <div>\n      {this.props.bar}\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props) {\n  const { loading } = this.state;\n  const { bar } = this.props;\n  if (loading) {\n    return <Loader />;\n  }\n  return (\n    <div>\n      {bar}\n    </div>\n  );\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction Foo(props) {\n  return (\n    <div>{props.bar}</div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props) {\n  const { bar } = props;\n  return (\n    <div>{bar}</div>\n  );\n}\n```\n\n```jsx\nfunction Foo({ bar }) {\n  return (\n    <div>{bar}</div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props, context) {\n  return (\n    <div>\n      {context.foo ? props.bar : ''}\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Foo(props, context) {\n  const { foo } = context;\n  const { bar } = props;\n  return (\n    <div>\n      {foo ? bar : ''}\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Foo({ bar }, { foo }) {\n  return (\n    <div>\n      {foo ? bar : ''}\n    </div>\n  );\n}\n```\n"
  },
  {
    "path": "docs/rules/no-typos.md",
    "content": "# react/no-typos\n\n📝 Disallow common typos.\n\n<!-- end auto-generated rule header -->\n\nEnsure no casing typos were made declaring static class properties and lifecycle methods.\nChecks that declared `propTypes`, `contextTypes` and `childContextTypes` is supported by [react-props](https://github.com/facebook/prop-types)\n\n## Rule Details\n\nThis rule checks whether the declared static class properties and lifecycle methods related to React components do not contain any typos.\n\nIt makes sure that the following class properties have\nno casing typos:\n\n- propTypes\n- contextTypes\n- childContextTypes\n- defaultProps\n\nand the following react lifecycle methods:\n\n- getDerivedStateFromProps\n- componentWillMount\n- UNSAFE_componentWillMount\n- componentDidMount\n- componentWillReceiveProps\n- UNSAFE_componentWillReceiveProps\n- shouldComponentUpdate\n- componentWillUpdate\n- UNSAFE_componentWillUpdate\n- getSnapshotBeforeUpdate\n- componentDidUpdate\n- componentDidCatch\n- componentWillUnmount\n- render\n\nExamples of **incorrect** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static PropTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static proptypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static ContextTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static contexttypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static ChildContextTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static childcontexttypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static DefaultProps = {}\n}\n\nclass MyComponent extends React.Component {\n  static defaultprops = {}\n}\n\nclass MyComponent extends React.Component {\n  componentwillMount() {}\n}\n\nclass MyComponent extends React.Component {\n  ComponentWillReceiveProps() {}\n}\n\nclass MyComponent extends React.Component {\n  componentdidupdate() {}\n}\n\nclass MyComponent extends React.Component {\n  static propTypes = {\n    a: PropTypes.typo\n  }\n}\n\nclass MyComponent extends React.Component {\n  getDerivedStateFromProps() {}\n}\n```\n\nExamples of **correct** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static propTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static contextTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static childContextTypes = {}\n}\n\nclass MyComponent extends React.Component {\n  static defaultProps = {}\n}\n\nclass MyComponent extends React.Component {\n  componentWillMount() {}\n}\n\nclass MyComponent extends React.Component {\n  componentWillReceiveProps() {}\n}\n\nclass MyComponent extends React.Component {\n  componentDidUpdate() {}\n}\n\nclass MyComponent extends React.Component {\n  static propTypes = {\n    a: PropTypes.bool.isRequired\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/no-unescaped-entities.md",
    "content": "# react/no-unescaped-entities\n\n📝 Disallow unescaped HTML entities from appearing in markup.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\nThis rule prevents characters that you may have meant as JSX escape characters\nfrom being accidentally injected as a text node in JSX statements.\n\nFor example, if one were to misplace their closing `>` in a tag:\n\n```jsx\n<MyComponent\n  name=\"name\"\n  type=\"string\"\n  foo=\"bar\">  {/* oops! */}\n  x=\"y\">\n  Body Text\n</MyComponent>\n```\n\nThe body text of this would render as `x=\"y\"> Body Text`, which is probably not\nwhat was intended. This rule requires that these special characters are\nescaped if they appear in the body of a tag.\n\nAnother example is when one accidentally includes an extra closing brace.\n\n```jsx\n<MyComponent>{'Text'}}</MyComponent>\n```\n\nThe extra brace will be rendered, and the body text will be `Text}`.\n\nThis rule will also check for `\"` and `'`, which might be accidentally included\nwhen the closing `>` is in the wrong place.\n\n```jsx\n<MyComponent\n  a=\"b\">  {/* oops! */}\n  c=\"d\"\n  Intended body text\n</MyComponent>\n```\n\nThe preferred way to include one of these characters is to use the HTML escape code.\n\n- `>` can be replaced with `&gt;`\n- `\"` can be replaced with `&quot;`, `&ldquo;`, `&#34;` or `&rdquo;`\n- `'` can be replaced with `&apos;`, `&lsquo;`, `&#39;` or `&rsquo;`\n- `}` can be replaced with `&#125;`\n\nAlternatively, you can include the literal character inside a subexpression\n(such as `<div>{'>'}</div>`.\n\nThe characters `<` and `{` should also be escaped, but they are not checked by this\nrule because it is a syntax error to include those tokens inside of a tag.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div> > </div>\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div> &gt; </div>\n```\n\n```jsx\n<div> {'>'} </div>\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-unescaped-entities\": [<enabled>, { \"forbid\": Array<string> }]\n...\n```\n\n### `forbid`\n\nOverwrite the default forbidden entities array `['>', '\"', '\\'', '}']` with your own:\n\n```js\n\"react/no-unescaped-entities\": [\"error\", {\"forbid\": [\">\", \"}\"]}],\n// or\n\"react/no-unescaped-entities\": [\"error\", {\"forbid\": [{\n  char: \">\",\n  alternatives: ['&gt;']\n}, {\n  char: \"}\",\n  alternatives: ['&#125;']\n}]}],\n```\n\nWhere `char` is a special character and `alternatives` is the correct escapes.\n"
  },
  {
    "path": "docs/rules/no-unknown-property.md",
    "content": "# react/no-unknown-property\n\n📝 Disallow usage of unknown DOM property.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nIn JSX most DOM properties and attributes should be camelCased to be consistent with standard JavaScript style. This can be a possible source of error if you are used to writing plain HTML.\nOnly `data-*` and `aria-*` attributes are usings hyphens and lowercase letters in JSX.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div class=\"hello\">Hello World</div>;\nvar Alphabet = <div abc=\"something\">Alphabet</div>;\n\n// Invalid aria-* attribute\nvar IconButton = <div aria-foo=\"bar\" />;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div className=\"hello\">Hello World</div>;\nvar Button = <button disabled>Cannot click me</button>;\nvar Img = <img src={catImage} alt=\"A cat sleeping on a keyboard\" />;\n\n// aria-* attributes\nvar IconButton = <button aria-label=\"Close\" onClick={this.close}>{closeIcon}</button>;\n\n// data-* attributes\nvar Data = <div data-index={12}>Some data</div>;\n\n// React components are ignored\nvar MyComponent = <App class=\"foo-bar\"/>;\nvar AnotherComponent = <Foo.bar for=\"bar\" />;\n\n// Custom web components are ignored\nvar MyElem = <div class=\"foo\" is=\"my-elem\"></div>;\nvar AtomPanel = <atom-panel class=\"foo\"></atom-panel>;\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-unknown-property\": [<enabled>, { ignore: <ignore>, requireDataLowercase: <requireDataLowercase> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `ignore`: optional array of property and attribute names to ignore during validation.\n- `requireDataLowercase`: optional (default: `false`), require data-\\* attributes to contain only lowercase characters. React will issue a warning when data-\\* attributes contain uppercase characters. In order to catch such attributes, set the `requireDataLowercase` option to `true`.\n\nIf you are using a library that passes something as a prop to JSX elements, it is recommended to add those props to the ignored properties.\n\nFor example, if you use [emotion](https://emotion.sh/docs/introduction) and its [`css` prop](https://emotion.sh/docs/css-prop),\nadd the following to your `.eslintrc` config file:\n\n```js\n...\n\"react/no-unknown-property\": ['error', { ignore: ['css'] }]\n...\n```\n\nNow, the following code passes:\n\n```jsx\nvar StyledDiv = <div css={{ color: 'pink' }}></div>;\n```\n\n## When Not To Use It\n\nIf you are not using JSX you can disable this rule.\n"
  },
  {
    "path": "docs/rules/no-unsafe.md",
    "content": "# react/no-unsafe\n\n📝 Disallow usage of unsafe lifecycle methods.\n\n🚫 This rule is _disabled_ in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nCertain legacy lifecycle methods are [unsafe for use in async React applications][async_rendering] and cause warnings in [_strict mode_][strict_mode]. These also happen to be the lifecycles that cause the most [confusion within the React community][component_lifecycle_changes].\n\n[async_rendering]: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html\n[strict_mode]: https://reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles\n[component_lifecycle_changes]: https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes\n\nThe rule checks the following methods:\n\n- `componentWillMount` (and `UNSAFE_componentWillMount` alias)\n- `componentWillReceiveProps` (and `UNSAFE_componentWillReceiveProps` alias)\n- `componentWillUpdate` (and `UNSAFE_componentWillUpdate` alias)\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  UNSAFE_componentWillMount() {}\n  UNSAFE_componentWillReceiveProps() {}\n  UNSAFE_componentWillUpdate() {}\n}\n```\n\n```jsx\nconst Foo = createReactClass({\n  UNSAFE_componentWillMount: function() {},\n  UNSAFE_componentWillReceiveProps: function() {},\n  UNSAFE_componentWillUpdate: function() {}\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends Bar {\n  UNSAFE_componentWillMount() {}\n  UNSAFE_componentWillReceiveProps() {}\n  UNSAFE_componentWillUpdate() {}\n}\n```\n\n```jsx\nconst Foo = bar({\n  UNSAFE_componentWillMount: function() {},\n  UNSAFE_componentWillReceiveProps: function() {},\n  UNSAFE_componentWillUpdate: function() {}\n});\n```\n\n## Rule Options\n\n```json5\n...\n\"react/no-unsafe\": [<enabled>, { \"checkAliases\": <boolean> }]\n...\n```\n\n### `checkAliases` (default: `false`)\n\nWhen `true` the rule will also check aliases of unsafe methods: `componentWillMount`, `componentWillReceiveProps`, `componentWillUpdate`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  componentWillMount() {}\n  componentWillReceiveProps() {}\n  componentWillUpdate() {}\n}\n```\n\n```jsx\nconst Foo = createReactClass({\n  componentWillMount: function() {},\n  componentWillReceiveProps: function() {},\n  componentWillUpdate: function() {}\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends Bar {\n  componentWillMount() {}\n  componentWillReceiveProps() {}\n  componentWillUpdate() {}\n}\n```\n\n```jsx\nconst Foo = bar({\n  componentWillMount: function() {},\n  componentWillReceiveProps: function() {},\n  componentWillUpdate: function() {}\n});\n```\n"
  },
  {
    "path": "docs/rules/no-unstable-nested-components.md",
    "content": "# react/no-unstable-nested-components\n\n📝 Disallow creating unstable components inside components.\n\n<!-- end auto-generated rule header -->\n\nCreating components inside components (nested components) will cause React to throw away the state of those nested components on each re-render of their parent.\n\nReact reconciliation performs element type comparison with [reference equality](https://reactjs.org/docs/reconciliation.html#elements-of-different-types). The reference to the same element changes on each re-render when defining components inside the render block. This leads to complete recreation of the current node and all its children. As a result the virtual DOM has to do extra unnecessary work and [possible bugs are introduced](https://codepen.io/ariperkkio/pen/vYLodLB).\n\n## Rule Details\n\nThe following patterns are considered warnings:\n\n```jsx\nfunction Component() {\n  function UnstableNestedComponent() {\n    return <div />;\n  }\n\n  return (\n    <div>\n      <UnstableNestedComponent />\n    </div>\n  );\n}\n```\n\n```jsx\nfunction SomeComponent({ footer: Footer }) {\n  return (\n    <div>\n      <Footer />\n    </div>\n  );\n}\n\nfunction Component() {\n  return (\n    <div>\n      <SomeComponent footer={() => <div />} />\n    </div>\n  );\n}\n```\n\n```jsx\nclass Component extends React.Component {\n  render() {\n    function UnstableNestedComponent() {\n      return <div />;\n    }\n\n    return (\n      <div>\n        <UnstableNestedComponent />\n      </div>\n    );\n  }\n}\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nfunction OutsideDefinedComponent(props) {\n  return <div />;\n}\n\nfunction Component() {\n  return (\n    <div>\n      <OutsideDefinedComponent />\n    </div>\n  );\n}\n```\n\n```jsx\nfunction Component() {\n  return <SomeComponent footer={<div />} />;\n}\n```\n\n⚠️ WARNING ⚠️:\n\nCreating nested but memoized components is currently not detected by this rule but should also be avoided.\nIf the `useCallback` or `useMemo` hook has no dependency, you can safely move the component definition out of the render function.\nIf the hook does have dependencies, you should refactor the code so that you're able to move the component definition out of the render function.\nIf you want React to throw away the state of the nested component, use a [`key`](https://reactjs.org/docs/lists-and-keys.html#keys) instead.\n\n```jsx\nfunction Component() {\n  // No ESLint warning but `MemoizedNestedComponent` should be moved outside of `Component`.\n  const MemoizedNestedComponent = React.useCallback(() => <div />, []);\n\n  return (\n    <div>\n      <MemoizedNestedComponent />\n    </div>\n  );\n}\n```\n\nBy default component creation is allowed inside component props only if prop name starts with `render`. See `allowAsProps` option for disabling this limitation completely.\n\n```jsx\nfunction SomeComponent(props) {\n  return <div>{props.renderFooter()}</div>;\n}\n\nfunction Component() {\n  return (\n    <div>\n      <SomeComponent renderFooter={() => <div />} />\n    </div>\n  );\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-unstable-nested-components\": [\n  \"off\" | \"warn\" | \"error\",\n  {\n    \"allowAsProps\": true | false,\n    \"customValidators\": [] /* optional array of validators used for propTypes validation */\n    \"propNamePattern\": string\n  }\n]\n...\n```\n\nYou can allow component creation inside component props by setting `allowAsProps` option to true. When using this option make sure you are **calling** the props in the receiving component and not using them as elements.\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nfunction SomeComponent(props) {\n  return <div>{props.footer()}</div>;\n}\n\nfunction Component() {\n  return (\n    <div>\n      <SomeComponent footer={() => <div />} />\n    </div>\n  );\n}\n```\n\nYou can allow other render prop naming conventions by setting the `propNamePattern` option. By default this option is `\"render*\"`.\n\nFor example, if `propNamePattern` is set to `\"*Renderer\"` the following pattern is **not** considered warnings:\n\n```jsx\n<Table\n  rowRenderer={(rowData) => <Row data={rowData} />}\n/>\n```\n\n## When Not To Use It\n\nIf you are not interested in preventing bugs related to re-creation of the nested components or do not care about optimization of virtual DOM.\n"
  },
  {
    "path": "docs/rules/no-unused-class-component-methods.md",
    "content": "# react/no-unused-class-component-methods\n\n📝 Disallow declaring unused methods of component class.\n\n<!-- end auto-generated rule header -->\n\nWarns you if you have defined a method or property but it is never being used anywhere.\n\n## Rule Details\n\nThe following patterns are considered warnings:\n\n```jsx\nclass Foo extends React.Component {\n  handleClick() {}\n  render() {\n    return null;\n  }\n}\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\nclass Foo extends React.Component {\n  static getDerivedStateFromError(error) {\n    return { hasError: true };\n  }\n  action() {}\n  componentDidMount() {\n    this.action();\n  }\n  render() {\n    return null;\n  }\n}\n});\n```\n"
  },
  {
    "path": "docs/rules/no-unused-prop-types.md",
    "content": "# react/no-unused-prop-types\n\n📝 Disallow definitions of unused propTypes.\n\n<!-- end auto-generated rule header -->\n\nWarns if a prop with a defined type isn't being used.\n\n> **Note**: You can provide types in runtime types using [PropTypes] and/or\nstatically using [TypeScript] or [Flow]. This rule will validate your prop types\nregardless of how you define them.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello Bob</div>;\n  }\n}\n\nHello.propTypes = {\n  name: PropTypes.string\n};\n```\n\n```jsx\ntype Props = {\n  firstname: string;\n  middlename: string; // middlename is never used by the Hello component\n  lastname: string;\n}\n\nclass Hello extends React.Component<Props> {\n  render() {\n    return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n  }\n}\n```\n\n```jsx\ntype Props = {\n  firstname: string;\n  lastname: string;  // lastname isn't used by the Hello component\n};\n\nclass Hello extends React.Component<Props> {\n  render() {\n    return <div>Hello {this.props.firstname}</div>;\n  }\n}\n\nclass Greetings extends React.Component<Props> {\n  render() {\n    return <div>Greetings  {this.props.firstname} {this.props.lastname}</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n\nHello.propTypes = {\n  name: PropTypes.string\n};\n```\n\n## Rule Options\n\nThis rule can take one argument to ignore some specific props during validation.\n\n```js\n...\n\"react/no-unused-prop-types\": [<enabled>, { ignore: <ignore>, customValidators: <customValidator>, skipShapeProps: <skipShapeProps> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `ignore`: optional array of props name to ignore during validation.\n- `customValidators`: optional array of validators used for propTypes validation.\n- `skipShapeProps`: In some cases it is impossible to accurately detect whether or not a `PropTypes.shape`'s values are being used. Setting this option to `true` will skip validation of `PropTypes.shape` (`true` by default).\n\n## Known Issues/Limitations\n\n- [False Positives: SFC (helper render methods)](#false-positives-sfc)\n\n### False Positives SFC\n\nStateless Function Components (SFCs) accept props as an argument and return a JSX expression.\nEven if the function gets called from a component, the props that are only used inside the component are not be considered used by a component.\n\nTriggers false positive:\n\n```js\nfunction AComponent(props) {\n  function helperRenderer(aProp) { // is considered SFC\n    return (\n      <span>{aProp}{props.bProp}</span>\n    );\n  }\n\n  return (\n    <div>\n      {helperRenderer(props.aProp)}\n    </div>\n  );\n}\n\nAComponent.propTypes = {\n  aProp: PropTypes.string,\n  bProp: PropTypes.string // bProp is defined but never used\n};\n```\n\nA suggested fix is to assign a bProp to a variable outside of the SFC.\n\n```js\nfunction AComponent(props) {\n  const { bProp } = props\n  function helperRenderer(aProp) { // is considered SFC\n    return (\n      <span>{aProp}{bProp}</span>\n    );\n  }\n\n  return (\n    <div>\n      {helperRenderer(props.aProp)}\n    </div>\n  );\n}\n\nAComponent.propTypes = {\n  aProp: PropTypes.string,\n  bProp: PropTypes.string\n};\n```\n\n[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html\n[TypeScript]: https://www.typescriptlang.org/\n[Flow]: https://flow.org/\n"
  },
  {
    "path": "docs/rules/no-unused-state.md",
    "content": "# react/no-unused-state\n\n📝 Disallow definitions of unused state.\n\n<!-- end auto-generated rule header -->\n\nWarns you if you have defined a property on the state, but it is not being used anywhere.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass MyComponent extends React.Component {\n  state = { foo: 0 };\n  render() {\n    return <SomeComponent />;\n  }\n}\n\nvar UnusedGetInitialStateTest = createReactClass({\n  getInitialState: function() {\n    return { foo: 0 };\n  },\n  render: function() {\n    return <SomeComponent />;\n  }\n})\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass MyComponent extends React.Component {\n  state = { foo: 0 };\n  render() {\n    return <SomeComponent foo={this.state.foo} />;\n  }\n}\n\nvar UnusedGetInitialStateTest = createReactClass({\n  getInitialState: function() {\n    return { foo: 0 };\n  },\n  render: function() {\n    return <SomeComponent foo={this.state.foo} />;\n  }\n})\n```\n"
  },
  {
    "path": "docs/rules/no-will-update-set-state.md",
    "content": "# react/no-will-update-set-state\n\n📝 Disallow usage of setState in componentWillUpdate.\n\n<!-- end auto-generated rule header -->\n\nUpdating the state during the componentWillUpdate step can lead to indeterminate component state and is not allowed.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentWillUpdate: function() {\n     this.setState({\n        name: this.props.name.toUpperCase()\n      });\n    },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentWillUpdate: function() {\n    this.props.prepareHandler();\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentWillUpdate: function() {\n    this.prepareHandler(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\n## Rule Options\n\n```js\n...\n\"react/no-will-update-set-state\": [<enabled>, <mode>]\n...\n```\n\n### `disallow-in-func` mode\n\nBy default this rule forbids any call to `this.setState` in `componentWillUpdate` outside of functions. The `disallow-in-func` mode makes this rule more strict by disallowing calls to `this.setState` even within functions.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  componentWillUpdate: function() {\n     this.setState({\n        name: this.props.name.toUpperCase()\n      });\n    },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n\n```jsx\nvar Hello = createReactClass({\n  componentWillUpdate: function() {\n    this.prepareHandler(function callback(newName) {\n      this.setState({\n        name: newName\n      });\n    });\n  },\n  render: function() {\n    return <div>Hello {this.state.name}</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/prefer-es6-class.md",
    "content": "# react/prefer-es6-class\n\n📝 Enforce ES5 or ES6 class for React Components.\n\n<!-- end auto-generated rule header -->\n\nReact offers you two ways to create traditional components: using the ES5 `create-react-class` module or the new ES6 class system.\n\n## Rule Details\n\nThis rule allows you to enforce one way or another.\n\n## Rule Options\n\n```js\n...\n\"react/prefer-es6-class\": [<enabled>, <mode>]\n...\n```\n\n### `always` mode\n\nWill enforce ES6 classes for React Components. This is the default mode.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\n### `never` mode\n\nWill enforce ES5 classes for React Components.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n"
  },
  {
    "path": "docs/rules/prefer-exact-props.md",
    "content": "# react/prefer-exact-props\n\n📝 Prefer exact proptype definitions.\n\n<!-- end auto-generated rule header -->\n\nRecommends options to ensure only exact prop definitions are used when writing components. This recommends solutions for PropTypes or for Flow types.\n\nIn React, you can define prop types for components using propTypes. Such an example is below:\n\n```jsx\nclass Foo extends React.Component {\n  render() {\n    return <p>{this.props.bar}</p>;\n  }\n}\n\nFoo.propTypes = {\n  bar: PropTypes.string\n};\n```\n\nThe problem with this is that the consumer of the component could still pass in extra props. There could even be a typo for expected props. In order to prevent those situations, one could use the npm package [prop-types-exact](https://www.npmjs.com/package/prop-types-exact) to warn when unexpected props are passed to the component.\n\nOne can also define props for a component using Flow types. Such an example is below:\n\n```jsx\nclass Foo extends React.Component {\n  props: {\n    bar: string\n  }\n\n  render() {\n    return <p>{this.props.bar}</p>;\n  }\n}\n```\n\nIn this case, one could instead enforce only the exact props being used by using exact type objects, like below:\n\n```jsx\nclass Foo extends React.Component {\n  props: {|\n    bar: string\n  |}\n\n  render() {\n    return <p>{this.props.bar}</p>;\n  }\n}\n```\n\nSee the [Flow docs](https://flow.org/en/docs/types/objects/#toc-exact-object-types) on exact object types for more information.\n\n## Rule Details\n\nThis rule will only produce errors for prop types when combined with the appropriate entries in `propWrapperFunctions`. For example:\n\n```json\n{\n  \"settings\": {\n    \"propWrapperFunctions\": [\n      {\"property\": \"exact\", \"exact\": true}\n    ]\n  }\n}\n```\n\nThe following patterns are considered warnings:\n\n```jsx\n  class Component extends React.Component {\n    render() {\n      return <div />;\n    }\n  }\n  Component.propTypes = {\n    foo: PropTypes.string\n  };\n```\n\n```jsx\n  class Component extends React.Component {\n    static propTypes = {\n      foo: PropTypes.string\n    }\n    render() {\n      return <div />;\n    }\n  }\n```\n\n```jsx\n  class Component extends React.Component {\n    props: {\n      foo: string\n    }\n    render() {\n      return <div />;\n    }\n  }\n```\n\n```jsx\n  function Component(props: { foo: string }) {\n    return <div />;\n  }\n```\n\n```jsx\n  type Props = {\n    foo: string\n  }\n  function Component(props: Props) {\n    return <div />;\n  }\n```\n\nThe following patterns are **not** considered warnings:\n\n```jsx\n  type Props = {|\n    foo: string\n  |}\n  function Component(props: Props) {\n    return <div />;\n  }\n```\n\n```jsx\n  import exact from 'prop-types-exact';\n  class Component extends React.Component {\n    render() {\n      return <div />;\n    }\n  }\n  Component.propTypes = exact({\n    foo: PropTypes.string\n  });\n```\n\n## When Not To Use It\n\nIf you aren't concerned about extra props being passed to a component or potential spelling errors for existing props aren't a common nuisance, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/prefer-read-only-props.md",
    "content": "# react/prefer-read-only-props\n\n📝 Enforce that props are read-only.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nUsing Flow, one can define types for props. This rule enforces that prop types are read-only (covariant).\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\nIn Flow:\n\n```jsx\ntype Props = {\n  name: string,\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n\nfunction Hello(props: {-name: string}) {\n  return <div>Hello {props.name}</div>;\n}\n\nconst Hello = (props: {|name: string|}) => (\n  <div>Hello {props.name}</div>\n);\n```\n\nIn TypeScript:\n\n```tsx\ntype Props = {\n  name: string;\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n\ninterface Props {\n  name: string;\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\nIn Flow:\n\n```jsx\ntype Props = {\n  +name: string,\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n\nfunction Hello(props: {+name: string}) {\n  return <div>Hello {props.name}</div>;\n}\n\nconst Hello = (props: {|+name: string|}) => (\n  <div>Hello {props.name}</div>\n);\n```\n\nIn TypeScript:\n\n```tsx\ntype Props = {\n  readonly name: string;\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n\ninterface Props {\n  readonly name: string;\n}\nclass Hello extends React.Component<Props> {\n  render () {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/prefer-stateless-function.md",
    "content": "# react/prefer-stateless-function\n\n📝 Enforce stateless components to be written as a pure function.\n\n<!-- end auto-generated rule header -->\n\nStateless functional components are simpler than class based components and will benefit from future React performance optimizations specific to these components.\n\n## Rule Details\n\nThis rule will check your class based React components for\n\n- methods/properties other than `displayName`, `propTypes`, `contextTypes`, `defaultProps`, `render` and useless constructor (same detection as `eslint` [no-useless-constructor rule](https://eslint.org/docs/rules/no-useless-constructor))\n- instance property other than `this.props` and `this.context`\n- extension of `React.PureComponent` (if the `ignorePureComponents` flag is true)\n- presence of `ref` attribute in JSX\n- the use of decorators\n- `render` method that return anything but JSX: `undefined`, `null`, etc. (only in React <15.0.0, see [shared settings](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/README.md#configuration) for React version configuration)\n\nIf none of these elements are found, the rule will warn you to write this component as a pure function.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  }\n});\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nconst Foo = function(props, context) {\n  const {\n    location\n  } = context.router;\n\n  return <div>{props.foo}</div>;\n};\n```\n\nExamples of **correct** code for this rule, in React <15.0.0:\n\n```jsx\nclass Foo extends React.Component {\n  render() {\n    if (!this.props.foo) {\n      return null\n    }\n    return <div>{this.props.foo}</div>;\n  }\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/prefer-stateless-function\": [<enabled>, { \"ignorePureComponents\": <ignorePureComponents> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `ignorePureComponents`: optional boolean set to `true` to ignore components extending from `React.PureComponent` (default to `false`).\n\n### `ignorePureComponents`\n\nWhen `true` the rule will ignore Components extending from `React.PureComponent` that use `this.props` or `this.context`.\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends React.PureComponent {\n  render() {\n    return <div>{this.props.foo}</div>;\n  }\n}\n\nclass Bar extends React.PureComponent {\n  render() {\n    return <div>Baz</div>;\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/prop-types.md",
    "content": "# react/prop-types\n\n📝 Disallow missing props validation in a React component definition.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nDefining types for component props improves reusability of your components by\nvalidating received data. It can warn other developers if they make a mistake while reusing the component with improper data type.\n\n> **Note**: You can provide types in runtime types using [PropTypes] and/or\nstatically using [TypeScript] or [Flow]. This rule will validate your prop types\nregardless of how you define them.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nfunction Hello({ name }) {\n  return <div>Hello {name}</div>;\n  // 'name' is missing in props validation\n}\n\nvar Hello = createReactClass({\n  propTypes: {\n    firstname: PropTypes.string.isRequired\n  },\n  render: function() {\n    return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n    // 'lastname' type is missing in props validation\n  }\n});\n\n// Or in ES6\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n    // 'lastname' type is missing in props validation\n  }\n}\nHello.propTypes = {\n  firstname: PropTypes.string.isRequired\n}\n```\n\nIn TypeScript:\n\n```tsx\ninterface Props {\n  age: number\n}\nfunction Hello({ name }: Props) {\n  return <div>Hello {name}</div>;\n  // 'name' type is missing in props validation\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction Hello({ name }) {\n  return <div>Hello {name}</div>;\n}\nHello.propTypes = {\n  name: PropTypes.string.isRequired\n}\n\nvar Hello = createReactClass({\n  propTypes: {\n    name: PropTypes.string.isRequired,\n  },\n  render: function() {\n    return <div>Hello {this.props.name}</div>;\n  },\n});\n\n// Or in ES6:\nclass HelloEs6 extends React.Component {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\nHelloEs6.propTypes = {\n  name: PropTypes.string.isRequired,\n};\n\n// ES6 + Public Class Fields (draft: https://tc39.github.io/proposal-class-public-fields/)\nclass HelloEs6WithPublicClassField extends React.Component {\n  static propTypes = {\n    name: PropTypes.string.isRequired,\n  }\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\nIn TypeScript:\n\n```tsx\n// destructured default prop values\n\nfunction Foo({ bar = \"\" }): JSX.Element {\n  return <div>{bar}</div>;\n}\n\nfunction Foo({ bar = \"\" as string }): JSX.Element {\n  return <div>{bar}</div>;\n}\n```\n\nIn Flow:\n\n```tsx\ntype Props = {\n  name: string\n}\nclass Hello extends React.Component<Props> {\n  render() {\n    return <div>Hello {this.props.name}</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction Hello() {\n  return <div>Hello World</div>;\n}\n\n// Referencing an external object disable the rule for the component\nfunction Hello({ name }) {\n  return <div>Hello {name}</div>;\n}\nHello.propTypes = myPropTypes;\n```\n\n## Rule Options\n\nThis rule can take one argument to ignore some specific props during validation.\n\n```js\n...\n\"react/prop-types\": [<enabled>, { ignore: <ignore>, customValidators: <customValidator>, skipUndeclared: <skipUndeclared> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `ignore`: optional array of props name to ignore during validation.\n- `customValidators`: optional array of validators used for propTypes validation.\n- `skipUndeclared`: optional boolean to only error on components that have a propTypes block declared.\n\n### As for \"exceptions\"\n\nIt would seem that some common properties such as `props.children` or `props.className`\n(and alike) need to be treated as exceptions.\n\nAs it aptly noticed in\n[#7](https://github.com/jsx-eslint/eslint-plugin-react/issues/7)\n\n> Why should children be an exception?\n> Most components don't need `this.props.children`, so that makes it extra important\nto document `children` in the prop types.\n\nGenerally, you should use `PropTypes.node` or static type `React.Node` for\n`children`. It accepts anything that can be rendered: numbers, strings, elements\nor an array containing these types.\n\nSince 2.0.0 children is no longer ignored for props validation.\n\n## About component detection\n\nFor this rule to work we need to detect React components, this could be very hard since components could be declared in a lot of ways.\n\nFor now we should detect components created with:\n\n- a function that return JSX or the result of a `React.createElement` call.\n- `createReactClass()`\n- an ES6 class that inherit from `React.Component` or `Component`\n\n[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html\n[TypeScript]: https://www.typescriptlang.org/\n[Flow]: https://flow.org/\n"
  },
  {
    "path": "docs/rules/react-in-jsx-scope.md",
    "content": "# react/react-in-jsx-scope\n\n📝 Disallow missing React when using JSX.\n\n💼🚫 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs). This rule is _disabled_ in the 🏃 `jsx-runtime` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nWhen using JSX, `<a />` expands to `React.createElement(\"a\")`. Therefore the `React` variable must be in scope.\n\nIf you are using the @jsx pragma this rule will check the designated variable and not the `React` one.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n```jsx\n/** @jsx Foo.bar */\nvar React = require('react');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nimport React from 'react';\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n```jsx\nvar React = require('react');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n```jsx\n/** @jsx Foo.bar */\nvar Foo = require('foo');\n\nvar Hello = <div>Hello {this.props.name}</div>;\n```\n\n## When Not To Use It\n\nIf you are not using JSX, or if you are setting `React` as a global variable.\n\nIf you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), you should disable this rule by extending [`react/jsx-runtime`](https://github.com/jsx-eslint/eslint-plugin-react/blob/8cf47a8ac2242ee00ea36eac4b6ae51956ba4411/index.js#L165-L179) in your eslint config (add `\"plugin:react/jsx-runtime\"` to `\"extends\"`).\n"
  },
  {
    "path": "docs/rules/require-default-props.md",
    "content": "# react/require-default-props\n\n📝 Enforce a defaultProps definition for every prop that is not a required prop.\n\n<!-- end auto-generated rule header -->\n\nThis rule aims to ensure that any non-required prop types of a component has a\ncorresponding `defaultProps` value.\n\n> **Note**: You can provide types in runtime types using [PropTypes] and/or\nstatically using [TypeScript] or [Flow]. This rule will validate your prop types\nregardless of how you define them.\n\nOne advantage of `defaultProps` over custom default logic in your code is that\n`defaultProps` are resolved by React before the `PropTypes` typechecking\nhappens, so typechecking will also apply to your `defaultProps`. The same also\nholds true for stateless functional components: default function parameters do\nnot behave the same as `defaultProps` and thus using `defaultProps` is still\npreferred.\n\nTo illustrate, consider the following example:\n\nWith `defaultProps`:\n\n```jsx\nconst HelloWorld = ({ name }) => (\n  <h1>Hello, {name.first} {name.last}!</h1>\n);\n\nHelloWorld.propTypes = {\n  name: PropTypes.shape({\n    first: PropTypes.string,\n    last: PropTypes.string,\n  })\n};\n\nHelloWorld.defaultProps = {\n  name: 'john'\n};\n\n// Logs:\n// Invalid prop `name` of type `string` supplied to `HelloWorld`, expected `object`.\nReactDOM.render(<HelloWorld />, document.getElementById('app'));\n```\n\nWithout `defaultProps`:\n\n```jsx\nconst HelloWorld = ({ name = 'John Doe' }) => (\n  <h1>Hello, {name.first} {name.last}!</h1>\n);\n\nHelloWorld.propTypes = {\n  name: PropTypes.shape({\n    first: PropTypes.string,\n    last: PropTypes.string,\n  })\n};\n\n// Nothing is logged, renders:\n// \"Hello,!\"\nReactDOM.render(<HelloWorld />, document.getElementById('app'));\n```\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string.isRequired,\n  bar: PropTypes.string\n};\n```\n\n```jsx\nvar Greeting = createReactClass({\n  render: function() {\n    return <div>Hello {this.props.foo} {this.props.bar}</div>;\n  },\n\n  propTypes: {\n    foo: PropTypes.string,\n    bar: PropTypes.string\n  },\n\n  getDefaultProps: function() {\n    return {\n      foo: \"foo\"\n    };\n  }\n});\n```\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n}\n\nGreeting.propTypes = {\n  foo: PropTypes.string,\n  bar: PropTypes.string\n};\n\nGreeting.defaultProps = {\n  foo: \"foo\"\n};\n```\n\n```jsx\ntype Props = {\n  foo: string,\n  bar?: string\n};\n\nfunction MyStatelessComponent(props: Props) {\n  return <div>Hello {props.foo} {props.bar}</div>;\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    foo: \"foo\"\n  };\n}\n```\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string.isRequired,\n  bar: PropTypes.string.isRequired\n};\n```\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string.isRequired,\n  bar: PropTypes.string\n};\n\nMyStatelessComponent.defaultProps = {\n  bar: 'some default'\n};\n```\n\n```jsx\ntype Props = {\n  foo: string,\n  bar?: string\n};\n\nfunction MyStatelessComponent(props: Props) {\n  return <div>Hello {props.foo} {props.bar}</div>;\n}\n\nMyStatelessComponent.defaultProps = {\n  bar: 'some default'\n};\n```\n\n```js\nfunction NotAComponent({ foo, bar }) {}\n\nNotAComponent.propTypes = {\n  foo: PropTypes.string,\n  bar: PropTypes.string.isRequired\n};\n```\n\n## Rule Options\n\n```js\n...\n\"react/require-default-props\": [<enabled>, {\n  \"forbidDefaultForRequired\": <boolean>,\n  \"classes\": \"defaultProps\" | \"ignore\",\n  \"functions\": \"defaultProps\" | \"defaultArguments\" | \"ignore\"\n  // @deprecated Use `functions` option instead.\n  \"ignoreFunctionalComponents\": <boolean>,\n}]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `forbidDefaultForRequired`: optional boolean to forbid prop default for a required prop. Defaults to false.\n- `classes`: optional string to determine which strategy a class component uses for defaulting props. Defaults to \"defaultProps\".\n- `functions`: optional string to determine which strategy a functional component uses for defaulting props. Defaults to \"defaultProps\".\n- `ignoreFunctionalComponents`: optional boolean to ignore this rule for functional components. Defaults to false. Deprecated, use `functions` instead.\n\n### `forbidDefaultForRequired`\n\nForbids setting a default for props that are marked as `isRequired`.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    foo: \"foo\",\n    bar: \"bar\"\n  };\n}\n```\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string.isRequired,\n  bar: PropTypes.string\n};\n\nMyStatelessComponent.defaultProps = {\n  foo: 'foo',\n  bar: 'bar'\n};\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    foo: \"foo\"\n  };\n}\n```\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string.isRequired,\n  bar: PropTypes.string.isRequired\n};\n```\n\n### `classes`\n\n- \"defaultProps\": Use `.defaultProps`. It's default.\n- \"ignore\": Ignore this rule for class components.\n\nExamples of **incorrect** code for this rule, when set to `defaultProps`:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n}\n```\n\nExamples of **correct** code for this rule, when set to `defaultProps`:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    foo: \"foo\"\n  };\n}\n```\n\n### `functions`\n\n- \"defaultProps\": Use `.defaultProps`. It's default.\n- \"defaultArguments\": Use default arguments in the function signature.\n- \"ignore\": Ignore this rule for functional components.\n\nExamples of **incorrect** code for this rule, when set to `defaultArguments`:\n\n```jsx\nfunction Hello({ foo }) {\n  return <div>{foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string\n};\nHello.defaultProps = {\n  foo: 'foo'\n}\n```\n\n```jsx\nfunction Hello({ foo = 'foo' }) {\n  return <div>{foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string\n};\nHello.defaultProps = {\n  foo: 'foo'\n}\n```\n\n```jsx\nfunction Hello(props) {\n  return <div>{props.foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string\n};\n```\n\nExamples of **correct** code for this rule, when set to `defaultArguments`:\n\n```jsx\nfunction Hello({ foo = 'foo' }) {\n  return <div>{foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string\n};\n```\n\n```jsx\nfunction Hello({ foo }) {\n  return <div>{foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string.isRequired\n};\n```\n\n```jsx\nfunction Hello(props) {\n  return <div>{props.foo}</div>;\n}\n\nHello.propTypes = {\n  foo: PropTypes.string.isRequired\n};\n```\n\n### `ignoreFunctionalComponents`\n\nWhen set to `true`, ignores this rule for all functional components.\n**Deprecated**, use `functions` instead.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Greeting extends React.Component {\n  render() {\n    return (\n      <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    );\n  }\n\n  static propTypes = {\n    foo: PropTypes.string,\n    bar: PropTypes.string.isRequired\n  };\n\n  static defaultProps = {\n    foo: \"foo\",\n    bar: \"bar\"\n  };\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nfunction MyStatelessComponent({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string,\n  bar: PropTypes.string\n};\n```\n\n```jsx\nconst MyStatelessComponent = ({ foo, bar }) => {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string,\n  bar: PropTypes.string\n};\n```\n\n```jsx\nconst MyStatelessComponent = function({ foo, bar }) {\n  return <div>{foo}{bar}</div>;\n}\n\nMyStatelessComponent.propTypes = {\n  foo: PropTypes.string,\n  bar: PropTypes.string\n};\n```\n\n## When Not To Use It\n\nIf you don't care about using `defaultProps` for your component's props that are not required, you can disable this rule.\n\n## Resources\n\n- [Official React documentation on defaultProps](https://legacy.reactjs.org/docs/typechecking-with-proptypes.html#default-prop-values)\n\n[PropTypes]: https://reactjs.org/docs/typechecking-with-proptypes.html\n[TypeScript]: https://www.typescriptlang.org/\n[Flow]: https://flow.org/\n"
  },
  {
    "path": "docs/rules/require-optimization.md",
    "content": "# react/require-optimization\n\n📝 Enforce React components to have a shouldComponentUpdate method.\n\n<!-- end auto-generated rule header -->\n\nThis rule prevents you from creating React components without declaring a `shouldComponentUpdate` method.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```js\nclass YourComponent extends React.Component {\n\n}\n```\n\n```js\ncreateReactClass({\n});\n```\n\nExamples of **correct** code for this rule:\n\n```js\nclass YourComponent extends React.Component {\n  shouldComponentUpdate () {\n    return false;\n  }\n}\n```\n\n```js\ncreateReactClass({\n  shouldComponentUpdate: function () {\n    return false;\n  }\n});\n```\n\n```js\ncreateReactClass({\n  mixins: [PureRenderMixin]\n});\n```\n\n```js\n@reactMixin.decorate(PureRenderMixin)\ncreateReactClass({\n\n});\n```\n\n## Rule Options\n\n```js\n...\n\"react/require-optimization\": [<enabled>, { allowDecorators: [<allowDecorator>] }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `allowDecorators`: optional array of decorators names to allow validation.\n\n### `allowDecorators`\n\nSets the allowed names of decorators. If the variable is present in the chain of decorators, it validates\n\nExamples of **correct** code for this rule:\n\n```js\n// ['pureRender']\n@pureRender\nclass Hello extends React.Component {}\n```\n\n### Example\n\n```js\n...\n\"react/require-optimization\": [2, {allowDecorators: ['customDecorators']}]\n...\n```\n"
  },
  {
    "path": "docs/rules/require-render-return.md",
    "content": "# react/require-render-return\n\n📝 Enforce ES5 or ES6 class for returning value in render function.\n\n💼 This rule is enabled in the ☑️ `recommended` [config](https://github.com/jsx-eslint/eslint-plugin-react/#shareable-configs).\n\n<!-- end auto-generated rule header -->\n\nWhen writing the `render` method in a component it is easy to forget to return the JSX content. This rule will warn if the `return` statement is missing.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render() {\n    <div>Hello</div>;\n  }\n});\n\nclass Hello extends React.Component {\n  render() {\n    <div>Hello</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render() {\n    return <div>Hello</div>;\n  }\n});\n\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n"
  },
  {
    "path": "docs/rules/self-closing-comp.md",
    "content": "# react/self-closing-comp\n\n📝 Disallow extra closing tags for components without children.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\nComponents without children can be self-closed to avoid unnecessary extra closing tag.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar HelloJohn = <Hello name=\"John\"></Hello>;\n\nvar HelloJohnCompound = <Hello.Compound name=\"John\"></Hello.Compound>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar contentContainer = <div className=\"content\"></div>;\n\nvar intentionalSpace = <div>{' '}</div>;\n\nvar HelloJohn = <Hello name=\"John\" />;\n\nvar HelloJohnCompound = <Hello.Compound name=\"John\" />;\n\nvar Profile = <Hello name=\"John\"><img src=\"picture.png\" /></Hello>;\n\nvar ProfileCompound = <Hello.Compound name=\"John\"><img src=\"picture.png\" /></Hello.Compound>;\n\nvar HelloSpace = <Hello>{' '}</Hello>;\n```\n\n## Rule Options\n\nThe rule can take one argument to select types of tags, which should be self-closed when this is possible. By default custom components tags and html tags should be self-closed.\n\n```js\n...\n\"react/self-closing-comp\": [\"error\", {\n  \"component\": true,\n  \"html\": true\n}]\n...\n```\n\n### `component`\n\nWhen `true`, custom components tags should be self-closed.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar HelloJohn = <Hello name=\"John\"></Hello>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar contentContainer = <div className=\"content\"></div>;\n\nvar intentionalSpace = <div>{' '}</div>;\n\nvar HelloJohn = <Hello name=\"John\" />;\n\nvar HelloJohnCompound = <Hello.Compound name=\"John\" />;\n\nvar Profile = <Hello name=\"John\"><img src=\"picture.png\" /></Hello>;\n\nvar ProfileCompound = <Hello.Compound name=\"John\"><img src=\"picture.png\" /></Hello.Compound>;\n```\n\n### `html`\n\nWhen `true`, html components tags should be self-closed.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar contentContainer = <div className=\"content\"></div>;\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar contentContainer = <div className=\"content\" />;\n\nvar contentContainer = <div className=\"content\"><div /></div>;\n\nvar intentionalSpace = <div>{' '}</div>;\n```\n"
  },
  {
    "path": "docs/rules/sort-comp.md",
    "content": "# react/sort-comp\n\n📝 Enforce component methods order.\n\n<!-- end auto-generated rule header -->\n\n🔧 This rule is automatically fixable using the [`sort-comp` transform](https://github.com/reactjs/react-codemod/blob/master/transforms/sort-comp.js) in [react-codemod](https://www.npmjs.com/package/react-codemod).\n\nWhen creating React components it is more convenient to always follow the same organisation for method order to help you easily find lifecycle methods, event handlers, etc.\n\n## Rule Details\n\nThe default configuration ensures that the following order must be followed:\n\n  1. static methods and properties\n  2. lifecycle methods: `displayName`, `propTypes`, `contextTypes`, `childContextTypes`, `mixins`, `statics`, `defaultProps`, `constructor`, `getDefaultProps`, `state`, `getInitialState`, `getChildContext`, `getDerivedStateFromProps`, `componentWillMount`, `UNSAFE_componentWillMount`, `componentDidMount`, `componentWillReceiveProps`, `UNSAFE_componentWillReceiveProps`, `shouldComponentUpdate`, `componentWillUpdate`, `UNSAFE_componentWillUpdate`, `getSnapshotBeforeUpdate`, `componentDidUpdate`, `componentDidCatch`, `componentWillUnmount` (in this order).\n  3. custom methods\n  4. `render` method\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello</div>;\n  },\n  displayName : 'Hello'\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello</div>;\n  }\n  static displayName = 'Hello';\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Hello = createReactClass({\n  displayName : 'Hello',\n  render: function() {\n    return <div>Hello</div>;\n  }\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  static displayName = 'Hello';\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\n## Rule Options\n\nThis rule can take one argument to customize the components organisation.\n\n```js\n...\n\"react/sort-comp\": [<enabled>, { order: <order>, groups: <groups> }]\n...\n```\n\n- `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0.\n- `order`: optional array of methods to validate.\n- `groups`: optional object of methods groups.\n\nThe default configuration is:\n\n```js\n{\n  order: [\n    'static-methods',\n    'lifecycle',\n    'everything-else',\n    'render'\n  ],\n  groups: {\n    lifecycle: [\n      'displayName',\n      'propTypes',\n      'contextTypes',\n      'childContextTypes',\n      'mixins',\n      'statics',\n      'defaultProps',\n      'constructor',\n      'getDefaultProps',\n      'state',\n      'getInitialState',\n      'getChildContext',\n      'getDerivedStateFromProps',\n      'componentWillMount',\n      'UNSAFE_componentWillMount',\n      'componentDidMount',\n      'componentWillReceiveProps',\n      'UNSAFE_componentWillReceiveProps',\n      'shouldComponentUpdate',\n      'componentWillUpdate',\n      'UNSAFE_componentWillUpdate',\n      'getSnapshotBeforeUpdate',\n      'componentDidUpdate',\n      'componentDidCatch',\n      'componentWillUnmount'\n    ]\n  }\n}\n```\n\n- `static-variables` This group is not specified by default, but can be used to enforce class static variable positioning.\n- `static-methods` is a special keyword that refers to static class methods.\n- `lifecycle` refers to the `lifecycle` group defined in `groups`.\n- `everything-else` is a special group that matches all of the methods that do not match any of the other groups.\n- `render` refers to the `render` method.\n- `type-annotations`. This group is not specified by default, but can be used to enforce flow annotations' positioning.\n- `getters` This group is not specified by default, but can be used to enforce class getters' positioning.\n- `setters` This group is not specified by default, but can be used to enforce class setters' positioning.\n- `instance-variables` This group is not specified by default, but can be used to enforce all other instance variables' positioning.\n- `instance-methods` This group is not specified by default, but can be used to enforce all other instance methods' positioning.\n\nYou can override this configuration to match your needs.\n\nFor example, if you want to place your event handlers (`onClick`, `onSubmit`, etc.) before `render` but the other methods after it:\n\n```js\n\"react/sort-comp\": [1, {\n  order: [\n    'static-methods',\n    'lifecycle',\n    '/^on.+$/',\n    'render',\n    'everything-else'\n  ]\n}]\n```\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nvar Hello = createReactClass({\n  render: function() {\n    return <div>Hello</div>;\n  },\n  onClick: function() {}\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  render() {\n    return <div>Hello</div>;\n  }\n  onClick = this.onClick.bind(this);\n  onClick() {}\n}\n```\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\nvar Hello = createReactClass({\n  onClick: function() {},\n  render: function() {\n    return <div>Hello</div>;\n  }\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  onClick = this.onClick.bind(this);\n  onClick() {}\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\nIf you want to split your `render` method into smaller ones and keep them just before render:\n\n```js\n\"react/sort-comp\": [1, {\n  order: [\n    'static-methods',\n    'lifecycle',\n    'everything-else',\n    'rendering',\n  ],\n  groups: {\n    rendering: [\n      '/^render.+$/',\n      'render'\n    ]\n  }\n}]\n```\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nvar Hello = createReactClass({\n  renderButton: function() {},\n  onClick: function() {},\n  render: function() {\n    return <div>Hello</div>;\n  }\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  renderButton = () => {}\n  onClick = this.onClick.bind(this);\n  onClick() {}\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\nvar Hello = createReactClass({\n  onClick: function() {},\n  renderButton: function() {},\n  render: function() {\n    return <div>Hello</div>;\n  }\n});\n```\n\n```jsx\nclass Hello extends React.Component {\n  onClick = this.onClick.bind(this);\n  onClick() {}\n  renderButton = () => {}\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\nIf you want to flow annotations to be at the top:\n\n```js\n\"react/sort-comp\": [1, {\n  order: [\n    'type-annotations',\n    'static-methods',\n    'lifecycle',\n    'everything-else',\n    'render',\n  ],\n}]\n```\n\nExamples of **incorrect** code for this rule, with the above configuration:\n\n```jsx\nclass Hello extends React.Component<any, Props, void> {\n  onClick() { this._someElem = true; }\n  props: Props;\n  _someElem: bool;\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\nExamples of **correct** code for this rule, with the above configuration:\n\n```jsx\ntype Props = {};\nclass Hello extends React.Component<any, Props, void> {\n  props: Props;\n  _someElem: bool;\n  onClick() { this._someElem = true; }\n  render() {\n    return <div>Hello</div>;\n  }\n}\n```\n\n## When Not To Use It\n\nThis rule is a formatting preference and not following it won't negatively affect the quality of your code. If components organisation isn't a part of your coding standards, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/sort-default-props.md",
    "content": "# react/sort-default-props\n\n📝 Enforce defaultProps declarations alphabetical sorting.\n\n<!-- end auto-generated rule header -->\n\nSome developers prefer to sort `defaultProps` declarations alphabetically to be able to find necessary declarations easier at a later time. Others feel that it adds complexity and becomes a burden to maintain.\n\n## Rule Details\n\nThis rule checks all components and verifies that all `defaultProps` declarations are sorted alphabetically. A spread attribute resets the verification. The default configuration of the rule is case-sensitive.\n\nThe following patterns are considered warnings:\n\n```jsx\nvar Component = createReactClass({\n...\n  getDefaultProps: function() {\n    return {\n      z: \"z\",\n      a: \"a\",\n      b: \"b\"\n    };\n  },\n...\n});\n\nclass Component extends React.Component {\n  ...\n}\nComponent.defaultProps = {\n  z: \"z\",\n  a: \"a\",\n  b: \"b\"\n};\n\nclass Component extends React.Component {\n  static defaultProps = {\n    z: \"z\",\n    y: \"y\",\n    a: \"a\"\n  }\n  render() {\n    return <div />;\n  }\n}\n\nconst Component = (props) => (...);\nComponent.defaultProps = {\n  z: \"z\",\n  y: \"y\",\n  a: \"a\"\n};\n\nconst defaults = {\n  b: \"b\"\n};\nconst types = {\n  a: PropTypes.string,\n  b: PropTypes.string,\n  c: PropTypes.string'\n};\nfunction StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n  return <div>{a}{b}{c}</div>;\n}\nStatelessComponentWithSpreadInPropTypes.propTypes = types;\nStatelessComponentWithSpreadInPropTypes.defaultProps = {\n  c: \"c\",\n  a: \"a\",\n  ...defaults,\n};\n\nexport default class ClassWithSpreadInPropTypes extends BaseClass {\n  static propTypes = {\n    a: PropTypes.string,\n    b: PropTypes.string,\n    c: PropTypes.string,\n    d: PropTypes.string,\n    e: PropTypes.string,\n    f: PropTypes.string\n  }\n  static defaultProps = {\n    b: \"b\",\n    a: \"a\",\n    ...c.defaultProps,\n    f: \"f\",\n    e: \"e\",\n    ...d.defaultProps\n  }\n}\n```\n\nThe following patterns are considered okay and do **not** cause warnings:\n\n```jsx\nvar Component = createReactClass({\n...\n  getDefaultProps: function() {\n    return {\n      a: \"a\",\n      b: \"b\",\n      c: \"c\"\n    };\n  },\n...\n});\n\nclass Component extends React.Component {\n  ...\n}\nComponent.defaultProps = {\n  a: \"a\",\n  b: \"b\",\n  c: \"c\"\n};\n\nclass Component extends React.Component {\n  static defaultProps = {\n    a: PropTypes.any,\n    b: PropTypes.any,\n    c: PropTypes.any\n  }\n  render() {\n    return <div />;\n  }\n}\n\nconst Component = (props) => (...);\nComponent.defaultProps = {\n  a: \"a\",\n  y: \"y\",\n  z: \"z\"\n};\n\nconst defaults = {\n  b: \"b\"\n};\nconst types = {\n  a: PropTypes.string,\n  b: PropTypes.string,\n  c: PropTypes.string'\n};\nfunction StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n  return <div>{a}{b}{c}</div>;\n}\nStatelessComponentWithSpreadInPropTypes.propTypes = types;\nStatelessComponentWithSpreadInPropTypes.defaultProps = {\n  a: \"a\",\n  c: \"c\",\n  ...defaults,\n};\n\nexport default class ClassWithSpreadInPropTypes extends BaseClass {\n  static propTypes = {\n    a: PropTypes.string,\n    b: PropTypes.string,\n    c: PropTypes.string,\n    d: PropTypes.string,\n    e: PropTypes.string,\n    f: PropTypes.string\n  }\n  static defaultProps = {\n    a: \"a\",\n    b: \"b\",\n    ...c.defaultProps,\n    e: \"e\",\n    f: \"f\",\n    ...d.defaultProps\n  }\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/sort-default-props\": [<enabled>, {\n  \"ignoreCase\": <boolean>,\n}]\n...\n```\n\n### `ignoreCase`\n\nWhen `true` the rule ignores the case-sensitivity of the declarations order.\n\n## When not to use\n\nThis rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing `defaultProps` declarations isn't a part of your coding standards, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/sort-prop-types.md",
    "content": "# react/sort-prop-types\n\n📝 Enforce propTypes declarations alphabetical sorting.\n\n🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).\n\n<!-- end auto-generated rule header -->\n\n🔧 This rule is automatically fixable using the `--fix` [flag](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line.\n\nSome developers prefer to sort prop type declarations alphabetically to be able to find necessary declaration easier at the later time. Others feel that it adds complexity and becomes burden to maintain.\n\n## Rule Details\n\nThis rule checks all components and verifies that all propTypes declarations are sorted alphabetically. A spread attribute resets the verification. The default configuration of the rule is case-sensitive.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nvar Component = createReactClass({\n  propTypes: {\n    z: PropTypes.number,\n    a: PropTypes.any,\n    b: PropTypes.string\n  },\n...\n});\n```\n\n```jsx\ntype Props = {\n  z: number,\n  a: any,\n  b: string\n}\nclass Component extends React.Component<Props> {\n  ...\n}\n```\n\n```jsx\nclass Component extends React.Component {\n  static propTypes = {\n    z: PropTypes.any,\n    y: PropTypes.any,\n    a: PropTypes.any\n  }\n  render() {\n    return <div />;\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nvar Component = createReactClass({\n  propTypes: {\n    a: PropTypes.number,\n    b: PropTypes.any,\n    c: PropTypes.string\n  },\n...\n});\n```\n\n```jsx\ntype Props = {\n  a: string,\n  b: any,\n  c: string,\n}\nclass Component extends React.Component<Props> {\n  ...\n}\n```\n\n```jsx\nclass Component extends React.Component {\n  static propTypes = {\n    a: PropTypes.any,\n    b: PropTypes.any,\n    c: PropTypes.any\n  }\n  render() {\n    return <div />;\n  }\n}\n```\n\n## Rule Options\n\n```js\n...\n\"react/sort-prop-types\": [<enabled>, {\n  \"callbacksLast\": <boolean>,\n  \"ignoreCase\": <boolean>,\n  \"requiredFirst\": <boolean>,\n  \"sortShapeProp\": <boolean>,\n  \"noSortAlphabetically\": <boolean>,\n  \"checkTypes\": <boolean>\n}]\n...\n```\n\n### `ignoreCase`\n\nWhen `true` the rule ignores the case-sensitivity of the declarations order.\n\n### `callbacksLast`\n\nWhen `true`, propTypes for props beginning with \"on\" must be listed after all other props:\n\n```js\nvar Component = createReactClass({\n  propTypes: {\n    a: PropTypes.number,\n    z: PropTypes.string,\n    onBar: PropTypes.func,\n    onFoo: PropTypes.func,\n  },\n...\n});\n```\n\n### `requiredFirst`\n\nWhen `true`, prop types for required props must be listed before all other props:\n\n```js\nvar Component = createReactClass({\n  propTypes: {\n    barRequired: PropTypes.any.isRequired,\n    fooRequired: PropTypes.any.isRequired,\n    a: PropTypes.number,\n    z: PropTypes.string,\n  },\n...\n});\n```\n\n### `sortShapeProp`\n\nWhen `true`, props defined in `PropTypes.shape` must be sorted via the same rules as the top-level props:\n\n```js\nvar Component = createReactClass({\n  propTypes: {\n    a: PropTypes.number,\n    b: PropTypes.shape({\n      d: PropTypes.number,\n      e: PropTypes.func,\n      f: PropTypes.bool,\n    }),\n    c: PropTypes.string,\n  },\n...\n});\n```\n\n### `noSortAlphabetically`\n\nWhen `true`, alphabetical order is not enforced:\n\n```js\nvar Component = createReactClass({\n  propTypes: {\n    barRequired: PropTypes.any.isRequired,\n    z: PropTypes.string,\n    a: PropTypes.number,\n  },\n...\n});\n```\n\n### `checkTypes`\n\nWhen `true`, the sorting of prop type definitions are checked.\n\n## When Not To Use It\n\nThis rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props declarations isn't a part of your coding standards, then you can leave this rule off.\n"
  },
  {
    "path": "docs/rules/state-in-constructor.md",
    "content": "# react/state-in-constructor\n\n📝 Enforce class component state initialization style.\n\n<!-- end auto-generated rule header -->\n\n## Rule Details\n\nThis rule will enforce the state initialization style to be either in a constructor or with a class property.\n\n## Rule Options\n\n```js\n...\n\"react/state-in-constructor\": [<enabled>, <mode>]\n...\n```\n\n### `always` mode\n\nWill enforce the state initialization style to be in a constructor. This is the default mode.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  state = { bar: 0 }\n  render() {\n    return <div>Foo</div>\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  constructor(props) {\n    super(props)\n    this.state = { bar: 0 }\n  }\n  render() {\n    return <div>Foo</div>\n  }\n}\n```\n\n### `never` mode\n\nWill enforce the state initialization style to be with a class property.\n\nExamples of **incorrect** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  constructor(props) {\n    super(props)\n    this.state = { bar: 0 }\n  }\n  render() {\n    return <div>Foo</div>\n  }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\nclass Foo extends React.Component {\n  state = { bar: 0 }\n  render() {\n    return <div>Foo</div>\n  }\n}\n```\n\n## When Not To Use It\n\nWhen the way a component state is being initialized doesn't matter.\n"
  },
  {
    "path": "docs/rules/static-property-placement.md",
    "content": "# react/static-property-placement\n\n📝 Enforces where React component static properties should be positioned.\n\n<!-- end auto-generated rule header -->\n\nThis rule allows you to enforce where `childContextTypes`, `contextTypes`, `contextType`, `defaultProps`, `displayName`,\nand `propTypes` are declared in an ES6 class.\n\n## Rule Details\n\nBy default, this rule will check for and warn about declaring any of the above properties outside of the class body.\n\nThe three key options are `static public field`, `static getter`, and `property assignment`.\n\n### When `static public field` is enabled (default)\n\nExamples of **incorrect** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static get childContextTypes() { /*...*/ }\n  static get contextTypes() { /*...*/ }\n  static get contextType() { /*...*/ }\n  static get displayName() { /*...*/ }\n  static get defaultProps() { /*...*/ }\n  static get propTypes() { /*...*/ }\n}\n```\n\n```js\nclass MyComponent extends React.Component { /*...*/ }\nMyComponent.childContextTypes = { /*...*/ };\nMyComponent.contextTypes = { /*...*/ };\nMyComponent.contextType = { /*...*/ };\nMyComponent.displayName = \"Hello\";\nMyComponent.defaultProps = { /*...*/ };\nMyComponent.propTypes = { /*...*/ };\n```\n\nExamples of **correct** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static childContextTypes = { /*...*/ };\n  static contextTypes = { /*...*/ };\n  static contextType = { /*...*/ };\n  static displayName = \"Hello\";\n  static defaultProps = { /*...*/ };\n  static propTypes = { /*...*/ };\n}\n```\n\n### When `static getter` is enabled\n\nExamples of **incorrect** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static childContextTypes = { /*...*/ };\n  static contextTypes = { /*...*/ };\n  static contextType = { /*...*/ };\n  static displayName = \"Hello\";\n  static defaultProps = { /*...*/ };\n  static propTypes = { /*...*/ };\n}\n```\n\n```js\nclass MyComponent extends React.Component { /*...*/ }\nMyComponent.childContextTypes = { /*...*/ };\nMyComponent.contextTypes = { /*...*/ };\nMyComponent.contextType = { /*...*/ };\nMyComponent.displayName = \"Hello\";\nMyComponent.defaultProps = { /*...*/ };\nMyComponent.propTypes = { /*...*/ };\n```\n\nExamples of **correct** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static get childContextTypes() { /*...*/ }\n  static get contextTypes() { /*...*/ }\n  static get contextType() { /*...*/ }\n  static get displayName() { /*...*/ }\n  static get defaultProps() { /*...*/ }\n  static get propTypes() { /*...*/ }\n}\n```\n\n### When `property assignment` is enabled\n\nExamples of **incorrect** code for this rule:\n\n```js\nclass MyComponent extends React.Component {\n  static childContextTypes = { /*...*/ };\n  static contextTypes = { /*...*/ };\n  static contextType = { /*...*/ };\n  static displayName = \"Hello\";\n  static defaultProps = { /*...*/ };\n  static propTypes = { /*...*/ };\n}\n```\n\n```js\nclass MyComponent extends React.Component {\n  static get childContextTypes() { /*...*/ }\n  static get contextTypes() { /*...*/ }\n  static get contextType() { /*...*/ }\n  static get displayName() { /*...*/ }\n  static get defaultProps() { /*...*/ }\n  static get propTypes() { /*...*/ }\n}\n```\n\nExamples of **correct** code for this rule:\n\n```js\nclass MyComponent extends React.Component { /*...*/ }\nMyComponent.childContextTypes = { /*...*/ };\nMyComponent.contextTypes = { /*...*/ };\nMyComponent.contextType = { /*...*/ };\nMyComponent.displayName = \"Hello\";\nMyComponent.defaultProps = { /*...*/ };\nMyComponent.propTypes = { /*...*/ };\n```\n\n## Rule Options\n\n```json5\n...\n\"react/static-property-placement\": [<enabled>]  // `static public field` enabled\n...\n```\n\nor alternatively:\n\n```json5\n...\n\"react/static-property-placement\": [<enabled>, <string>]\n...\n```\n\nor alternatively:\n\n```json5\n...\n\"react/static-property-placement\": [<enabled>, <string>, {\n  childContextTypes: <string>,\n  contextTypes: <string>,\n  contextType: <string>,\n  defaultProps: <string>,\n  displayName: <string>,\n  propTypes: <string>,\n}]\n...\n```\n\nThe `<string>` value must be one these options:\n\n- `static public field`\n- `static getter`\n- `property assignment`\n\nThe `options` schema defined above allows you to specify different rules for the different property fields available.\n\n### Example configuration\n\n_This is only an example, we do not recommend this as a configuration._\n\n```json5\n...\n\"react/static-property-placement\": [\"warn\", \"property assignment\", {\n  childContextTypes: \"static getter\",\n  contextTypes: \"static public field\",\n  contextType: \"static public field\",\n  displayName: \"static public field\",\n}]\n...\n```\n\nBased on the above configuration:\n\n- `defaultProps` and `propTypes` will both enforce the `property assignment` rule.\n- `childContextTypes` will enforce the `static getter` rule.\n- `contextTypes`, `contextType`, and `displayName` will  enforce the `static public field` rule.\n\n## When Not To Use It\n\nIf you have no placement preference for React's static class properties.\n"
  },
  {
    "path": "docs/rules/style-prop-object.md",
    "content": "# react/style-prop-object\n\n📝 Enforce style prop value is an object.\n\n<!-- end auto-generated rule header -->\n\nRequire that the value of the prop `style` be an object or a variable that is\nan object.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<div style=\"color: 'red'\" />\n\n<div style={true} />\n\n<Hello style={true} />\n\nconst styles = true;\n<div style={styles} />\n```\n\n```js\nReact.createElement(\"div\", { style: \"color: 'red'\" });\n\nReact.createElement(\"div\", { style: true });\n\nReact.createElement(\"Hello\", { style: true });\n\nconst styles = true;\nReact.createElement(\"div\", { style: styles });\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div style={{ color: \"red\" }} />\n\n<Hello style={{ color: \"red\" }} />\n\nconst styles = { color: \"red\" };\n<div style={styles} />\n```\n\n```js\nReact.createElement(\"div\", { style: { color: 'red' }});\n\nReact.createElement(\"Hello\", { style: { color: 'red' }});\n\nconst styles = { height: '100px' };\nReact.createElement(\"div\", { style: styles });\n```\n\n## Rule Options\n\n```js\n...\n\"react/style-prop-object\": [<enabled>, {\n  \"allow\": [<string>]\n}]\n...\n```\n\n### `allow`\n\nA list of elements that are allowed to have a non-object value in their style attribute. The default value is `[]`.\n\n#### Example\n\n```js\n{\n  \"allow\": [\"MyComponent\"]\n}\n```\n\nExamples of **incorrect** code for this rule:\n\n```js\n<Hello style=\"a string\">\nReact.createElement(Hello, { style: \"some styling\" });\n```\n\nExamples of **correct** code for this rule:\n\n```js\n<MyComponent style=\"a string\">\nReact.createElement(MyComponent, { style: \"some styling\" });\n```\n"
  },
  {
    "path": "docs/rules/void-dom-elements-no-children.md",
    "content": "# react/void-dom-elements-no-children\n\n📝 Disallow void DOM elements (e.g. `<img />`, `<br />`) from receiving children.\n\n<!-- end auto-generated rule header -->\n\nThere are some HTML elements that are only self-closing (e.g. `img`, `br`, `hr`). These are collectively known as void DOM elements. If you try to give these children, React will give you a warning like:\n\n> Invariant Violation: img is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.\n\n## Rule Details\n\nExamples of **incorrect** code for this rule:\n\n```jsx\n<br>Children</br>\n<br children='Children' />\n<br dangerouslySetInnerHTML={{ __html: 'HTML' }} />\nReact.createElement('br', undefined, 'Children')\nReact.createElement('br', { children: 'Children' })\nReact.createElement('br', { dangerouslySetInnerHTML: { __html: 'HTML' } })\n```\n\nExamples of **correct** code for this rule:\n\n```jsx\n<div>Children</div>\n<div children='Children' />\n<div dangerouslySetInnerHTML={{ __html: 'HTML' }} />\nReact.createElement('div', undefined, 'Children')\nReact.createElement('div', { children: 'Children' })\nReact.createElement('div', { dangerouslySetInnerHTML: { __html: 'HTML' } })\n```\n"
  },
  {
    "path": "index.js",
    "content": "'use strict';\n\nconst fromEntries = require('object.fromentries');\nconst entries = require('object.entries');\n\nconst allRules = require('./lib/rules');\n\nfunction filterRules(rules, predicate) {\n  return fromEntries(entries(rules).filter((entry) => predicate(entry[1])));\n}\n\n/**\n * @param {object} rules - rules object mapping rule name to rule module\n * @returns {Record<string, SEVERITY_ERROR | 'error'>}\n */\nfunction configureAsError(rules) {\n  return fromEntries(Object.keys(rules).map((key) => [`react/${key}`, 2]));\n}\n\n/** @type {Partial<typeof allRules>} */\nconst activeRules = filterRules(allRules, (rule) => !rule.meta.deprecated);\n/** @type {Record<keyof typeof activeRules, 2 | 'error'>} */\nconst activeRulesConfig = configureAsError(activeRules);\n\n/** @type {Partial<typeof allRules>} */\nconst deprecatedRules = filterRules(allRules, (rule) => rule.meta.deprecated);\n\n/** @type {['react']} */\n// for legacy config system\nconst plugins = [\n  'react',\n];\n\n// TODO: with TS 4.5+, inline this\nconst SEVERITY_ERROR = /** @type {2} */ (2);\nconst SEVERITY_OFF = /** @type {0} */ (0);\n\nconst configs = {\n  recommended: {\n    plugins,\n    parserOptions: {\n      ecmaFeatures: {\n        jsx: true,\n      },\n    },\n    rules: {\n      'react/display-name': SEVERITY_ERROR,\n      'react/jsx-key': SEVERITY_ERROR,\n      'react/jsx-no-comment-textnodes': SEVERITY_ERROR,\n      'react/jsx-no-duplicate-props': SEVERITY_ERROR,\n      'react/jsx-no-target-blank': SEVERITY_ERROR,\n      'react/jsx-no-undef': SEVERITY_ERROR,\n      'react/jsx-uses-react': SEVERITY_ERROR,\n      'react/jsx-uses-vars': SEVERITY_ERROR,\n      'react/no-children-prop': SEVERITY_ERROR,\n      'react/no-danger-with-children': SEVERITY_ERROR,\n      'react/no-deprecated': SEVERITY_ERROR,\n      'react/no-direct-mutation-state': SEVERITY_ERROR,\n      'react/no-find-dom-node': SEVERITY_ERROR,\n      'react/no-is-mounted': SEVERITY_ERROR,\n      'react/no-render-return-value': SEVERITY_ERROR,\n      'react/no-string-refs': SEVERITY_ERROR,\n      'react/no-unescaped-entities': SEVERITY_ERROR,\n      'react/no-unknown-property': SEVERITY_ERROR,\n      'react/no-unsafe': SEVERITY_OFF,\n      'react/prop-types': SEVERITY_ERROR,\n      'react/react-in-jsx-scope': SEVERITY_ERROR,\n      'react/require-render-return': SEVERITY_ERROR,\n    },\n  },\n  all: {\n    plugins,\n    parserOptions: {\n      ecmaFeatures: {\n        jsx: true,\n      },\n    },\n    rules: activeRulesConfig,\n  },\n  'jsx-runtime': {\n    plugins,\n    parserOptions: {\n      ecmaFeatures: {\n        jsx: true,\n      },\n      jsxPragma: null, // for @typescript/eslint-parser\n    },\n    rules: {\n      'react/react-in-jsx-scope': SEVERITY_OFF,\n      'react/jsx-uses-react': SEVERITY_OFF,\n    },\n  },\n  flat: /** @type {Record<string, ReactFlatConfig>} */ ({\n    __proto__: null,\n  }),\n};\n\n/** @typedef {{ plugins: { react: typeof plugin }, rules: import('eslint').Linter.RulesRecord, languageOptions: { parserOptions: import('eslint').Linter.ParserOptions } }} ReactFlatConfig */\n\n/** @type {{ deprecatedRules: typeof deprecatedRules, rules: typeof allRules, configs: typeof configs & { flat: Record<string, ReactFlatConfig> }}} */\nconst plugin = {\n  deprecatedRules,\n  rules: allRules,\n  configs,\n};\n\nObject.assign(configs.flat, {\n  recommended: {\n    plugins: { react: plugin },\n    rules: configs.recommended.rules,\n    languageOptions: { parserOptions: configs.recommended.parserOptions },\n  },\n  all: {\n    plugins: { react: plugin },\n    rules: configs.all.rules,\n    languageOptions: { parserOptions: configs.all.parserOptions },\n  },\n  'jsx-runtime': {\n    plugins: { react: plugin },\n    rules: configs['jsx-runtime'].rules,\n    languageOptions: { parserOptions: configs['jsx-runtime'].parserOptions },\n  },\n});\n\nmodule.exports = plugin;\n"
  },
  {
    "path": "lib/rules/async-server-action.js",
    "content": "/**\n * @fileoverview Require functions with the `use server` directive to be async\n * @author Jorge Zreik\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  asyncServerAction: 'Server Actions must be async',\n  suggestAsyncNamed: 'Make {{functionName}} an `async` function',\n  suggestAsyncAnon: 'Make this function `async`',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Require functions with the `use server` directive to be async',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('async-server-action'),\n    },\n\n    messages,\n\n    type: 'suggestion',\n    hasSuggestions: true,\n\n    schema: [],\n  },\n\n  create(context) {\n    return {\n      ':function[async=false][generator=false]>BlockStatement>:first-child[expression.value=\"use server\"]'(node) {\n        const currentFunction = node.parent.parent;\n        const parent = currentFunction.parent;\n        const isMethod = parent.type === 'MethodDefinition' || (parent.type === 'Property' && parent.method);\n\n        let name;\n        if (currentFunction.id) {\n          name = currentFunction.id.name;\n        } else if (isMethod && parent.key && parent.key.type === 'Identifier') {\n          name = parent.key.name;\n        }\n\n        const suggestMessage = name ? messages.suggestAsyncNamed : messages.suggestAsyncAnon;\n        const data = name ? { functionName: `\\`${name}\\`` } : {};\n        report(context, messages.asyncServerAction, 'asyncServerAction', {\n          node: currentFunction,\n          data,\n          suggest: [{\n            desc: suggestMessage,\n            data,\n            fix(fixer) {\n              if (isMethod) {\n                return fixer.insertTextBefore(parent.key, 'async ');\n              }\n              return fixer.insertTextBefore(currentFunction, 'async ');\n            },\n          }],\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/boolean-prop-naming.js",
    "content": "/**\n * @fileoverview Enforces consistent naming for boolean props\n * @author Ev Haus\n */\n\n'use strict';\n\nconst flatMap = require('array.prototype.flatmap');\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst propsUtil = require('../util/props');\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst propWrapperUtil = require('../util/propWrapper');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n/**\n * Checks if prop is nested\n * @param {Object} prop Property object, single prop type declaration\n * @returns {boolean}\n */\nfunction nestedPropTypes(prop) {\n  return (\n    prop.type === 'Property'\n    && astUtil.isCallExpression(prop.value)\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  patternMismatch: 'Prop name `{{propName}}` doesn’t match rule `{{pattern}}`',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      category: 'Stylistic Issues',\n      description: 'Enforces consistent naming for boolean props',\n      recommended: false,\n      url: docsUrl('boolean-prop-naming'),\n    },\n\n    messages,\n\n    schema: [{\n      additionalProperties: false,\n      properties: {\n        propTypeNames: {\n          items: {\n            type: 'string',\n          },\n          minItems: 1,\n          type: 'array',\n          uniqueItems: true,\n        },\n        rule: {\n          default: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          minLength: 1,\n          type: 'string',\n        },\n        message: {\n          minLength: 1,\n          type: 'string',\n        },\n        validateNested: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      type: 'object',\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const config = context.options[0] || {};\n    const rule = config.rule ? new RegExp(config.rule) : null;\n    const propTypeNames = config.propTypeNames || ['bool'];\n\n    // Remembers all Flowtype object definitions\n    const objectTypeAnnotations = new Map();\n\n    /**\n     * Returns the prop key to ensure we handle the following cases:\n     * propTypes: {\n     *   full: React.PropTypes.bool,\n     *   short: PropTypes.bool,\n     *   direct: bool,\n     *   required: PropTypes.bool.isRequired\n     * }\n     * @param {Object} node The node we're getting the name of\n     * @returns {string | null}\n     */\n    function getPropKey(node) {\n      // Check for `ExperimentalSpreadProperty` (eslint 3/4) and `SpreadElement` (eslint 5)\n      // so we can skip validation of those fields.\n      // Otherwise it will look for `node.value.property` which doesn't exist and breaks eslint.\n      if (node.type === 'ExperimentalSpreadProperty' || node.type === 'SpreadElement') {\n        return null;\n      }\n      if (node.value && node.value.property) {\n        const name = node.value.property.name;\n        if (name === 'isRequired') {\n          if (node.value.object && node.value.object.property) {\n            return node.value.object.property.name;\n          }\n          return null;\n        }\n        return name;\n      }\n      if (node.value && node.value.type === 'Identifier') {\n        return node.value.name;\n      }\n      return null;\n    }\n\n    /**\n     * Returns the name of the given node (prop)\n     * @param {Object} node The node we're getting the name of\n     * @returns {string}\n     */\n    function getPropName(node) {\n      // Due to this bug https://github.com/babel/babel-eslint/issues/307\n      // we can't get the name of the Flow object key name. So we have\n      // to hack around it for now.\n      if (node.type === 'ObjectTypeProperty') {\n        return getSourceCode(context).getFirstToken(node).value;\n      }\n\n      return node.key.name;\n    }\n\n    /**\n     * Checks if prop is declared in flow way\n     * @param {Object} prop Property object, single prop type declaration\n     * @returns {boolean}\n     */\n    function flowCheck(prop) {\n      return (\n        prop.type === 'ObjectTypeProperty'\n        && prop.value.type === 'BooleanTypeAnnotation'\n        && rule.test(getPropName(prop)) === false\n      );\n    }\n\n    /**\n     * Checks if prop is declared in regular way\n     * @param {Object} prop Property object, single prop type declaration\n     * @returns {boolean}\n     */\n    function regularCheck(prop) {\n      const propKey = getPropKey(prop);\n      return (\n        propKey\n        && propTypeNames.indexOf(propKey) >= 0\n        && rule.test(getPropName(prop)) === false\n      );\n    }\n\n    function tsCheck(prop) {\n      if (prop.type !== 'TSPropertySignature') return false;\n      const typeAnnotation = (prop.typeAnnotation || {}).typeAnnotation;\n      return (\n        typeAnnotation\n        && typeAnnotation.type === 'TSBooleanKeyword'\n        && rule.test(getPropName(prop)) === false\n      );\n    }\n\n    /**\n     * Runs recursive check on all proptypes\n     * @param {Array} proptypes A list of Property object (for each proptype defined)\n     * @param {Function} addInvalidProp callback to run for each error\n     */\n    function runCheck(proptypes, addInvalidProp) {\n      if (proptypes) {\n        proptypes.forEach((prop) => {\n          if (config.validateNested && nestedPropTypes(prop)) {\n            runCheck(prop.value.arguments[0].properties, addInvalidProp);\n            return;\n          }\n          if (flowCheck(prop) || regularCheck(prop) || tsCheck(prop)) {\n            addInvalidProp(prop);\n          }\n        });\n      }\n    }\n\n    /**\n     * Checks and mark props with invalid naming\n     * @param {Object} node The component node we're testing\n     * @param {Array} proptypes A list of Property object (for each proptype defined)\n     */\n    function validatePropNaming(node, proptypes) {\n      const component = components.get(node) || node;\n      const invalidProps = component.invalidProps || [];\n\n      runCheck(proptypes, (prop) => {\n        invalidProps.push(prop);\n      });\n\n      components.set(node, {\n        invalidProps,\n      });\n    }\n\n    /**\n     * Reports invalid prop naming\n     * @param {Object} component The component to process\n     */\n    function reportInvalidNaming(component) {\n      component.invalidProps.forEach((propNode) => {\n        const propName = getPropName(propNode);\n        report(context, config.message || messages.patternMismatch, !config.message && 'patternMismatch', {\n          node: propNode,\n          data: {\n            component: propName,\n            propName,\n            pattern: config.rule,\n          },\n        });\n      });\n    }\n\n    function checkPropWrapperArguments(node, args) {\n      if (!node || !Array.isArray(args)) {\n        return;\n      }\n      args.filter((arg) => arg.type === 'ObjectExpression').forEach((object) => validatePropNaming(node, object.properties));\n    }\n\n    function getComponentTypeAnnotation(component) {\n      // If this is a functional component that uses a global type, check it\n      if (\n        (component.node.type === 'FunctionDeclaration' || component.node.type === 'ArrowFunctionExpression')\n        && component.node.params\n        && component.node.params.length > 0\n        && component.node.params[0].typeAnnotation\n      ) {\n        return component.node.params[0].typeAnnotation.typeAnnotation;\n      }\n\n      if (\n        !component.node.parent\n        || component.node.parent.type !== 'VariableDeclarator'\n        || !component.node.parent.id\n        || component.node.parent.id.type !== 'Identifier'\n        || !component.node.parent.id.typeAnnotation\n        || !component.node.parent.id.typeAnnotation.typeAnnotation\n      ) {\n        return;\n      }\n\n      const annotationTypeArguments = propsUtil.getTypeArguments(\n        component.node.parent.id.typeAnnotation.typeAnnotation\n      );\n      if (\n        annotationTypeArguments && (\n          annotationTypeArguments.type === 'TSTypeParameterInstantiation'\n          || annotationTypeArguments.type === 'TypeParameterInstantiation'\n        )\n      ) {\n        return annotationTypeArguments.params.find(\n          (param) => param.type === 'TSTypeReference' || param.type === 'GenericTypeAnnotation'\n        );\n      }\n    }\n\n    function findAllTypeAnnotations(identifier, node) {\n      if (node.type === 'TSTypeLiteral' || node.type === 'ObjectTypeAnnotation' || node.type === 'TSInterfaceBody') {\n        const currentNode = [].concat(\n          objectTypeAnnotations.get(identifier.name) || [],\n          node\n        );\n        objectTypeAnnotations.set(identifier.name, currentNode);\n      } else if (\n        node.type === 'TSParenthesizedType'\n        && (\n          node.typeAnnotation.type === 'TSIntersectionType'\n          || node.typeAnnotation.type === 'TSUnionType'\n        )\n      ) {\n        node.typeAnnotation.types.forEach((type) => {\n          findAllTypeAnnotations(identifier, type);\n        });\n      } else if (\n        node.type === 'TSIntersectionType'\n        || node.type === 'TSUnionType'\n        || node.type === 'IntersectionTypeAnnotation'\n        || node.type === 'UnionTypeAnnotation'\n      ) {\n        node.types.forEach((type) => {\n          findAllTypeAnnotations(identifier, type);\n        });\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!rule || !propsUtil.isPropTypesDeclaration(node)) {\n          return;\n        }\n        if (\n          node.value\n          && astUtil.isCallExpression(node.value)\n          && propWrapperUtil.isPropWrapperFunction(\n            context,\n            getText(context, node.value.callee)\n          )\n        ) {\n          checkPropWrapperArguments(node, node.value.arguments);\n        }\n        if (node.value && node.value.properties) {\n          validatePropNaming(node, node.value.properties);\n        }\n        if (node.typeAnnotation && node.typeAnnotation.typeAnnotation) {\n          validatePropNaming(node, node.typeAnnotation.typeAnnotation.properties);\n        }\n      },\n\n      MemberExpression(node) {\n        if (!rule || !propsUtil.isPropTypesDeclaration(node)) {\n          return;\n        }\n        const component = utils.getRelatedComponent(node);\n        if (!component || !node.parent.right) {\n          return;\n        }\n        const right = node.parent.right;\n        if (\n          astUtil.isCallExpression(right)\n          && propWrapperUtil.isPropWrapperFunction(\n            context,\n            getText(context, right.callee)\n          )\n        ) {\n          checkPropWrapperArguments(component.node, right.arguments);\n          return;\n        }\n        validatePropNaming(component.node, node.parent.right.properties);\n      },\n\n      ObjectExpression(node) {\n        if (!rule) {\n          return;\n        }\n\n        // Search for the proptypes declaration\n        node.properties.forEach((property) => {\n          if (!propsUtil.isPropTypesDeclaration(property)) {\n            return;\n          }\n          validatePropNaming(node, property.value.properties);\n        });\n      },\n\n      TypeAlias(node) {\n        findAllTypeAnnotations(node.id, node.right);\n      },\n\n      TSTypeAliasDeclaration(node) {\n        findAllTypeAnnotations(node.id, node.typeAnnotation);\n      },\n\n      TSInterfaceDeclaration(node) {\n        findAllTypeAnnotations(node.id, node.body);\n      },\n\n      // eslint-disable-next-line object-shorthand\n      'Program:exit'() {\n        if (!rule) {\n          return;\n        }\n\n        values(components.list()).forEach((component) => {\n          const annotation = getComponentTypeAnnotation(component);\n\n          if (annotation) {\n            let propType;\n            if (annotation.type === 'GenericTypeAnnotation') {\n              propType = objectTypeAnnotations.get(annotation.id.name);\n            } else if (annotation.type === 'ObjectTypeAnnotation' || annotation.type === 'TSTypeLiteral') {\n              propType = annotation;\n            } else if (annotation.type === 'TSTypeReference') {\n              propType = objectTypeAnnotations.get(annotation.typeName.name);\n            } else if (annotation.type === 'TSIntersectionType') {\n              propType = flatMap(annotation.types, (type) => (\n                type.type === 'TSTypeReference'\n                  ? objectTypeAnnotations.get(type.typeName.name)\n                  : type\n              ));\n            }\n\n            if (propType) {\n              [].concat(propType).filter(Boolean).forEach((prop) => {\n                validatePropNaming(\n                  component.node,\n                  prop.properties || prop.members || prop.body\n                );\n              });\n            }\n          }\n\n          if (component.invalidProps && component.invalidProps.length > 0) {\n            reportInvalidNaming(component);\n          }\n        });\n\n        // Reset cache\n        objectTypeAnnotations.clear();\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/button-has-type.js",
    "content": "/**\n * @fileoverview Forbid \"button\" element without an explicit \"type\" attribute\n * @author Filipp Riabchun\n */\n\n'use strict';\n\nconst getProp = require('jsx-ast-utils/getProp');\nconst getLiteralPropValue = require('jsx-ast-utils/getLiteralPropValue');\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst optionDefaults = {\n  button: true,\n  submit: true,\n  reset: true,\n};\n\nconst messages = {\n  missingType: 'Missing an explicit type attribute for button',\n  complexType: 'The button type attribute must be specified by a static string or a trivial ternary expression',\n  invalidValue: '\"{{value}}\" is an invalid value for button type attribute',\n  forbiddenValue: '\"{{value}}\" is an invalid value for button type attribute',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of `button` elements without an explicit `type` attribute',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('button-has-type'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        button: {\n          default: optionDefaults.button,\n          type: 'boolean',\n        },\n        submit: {\n          default: optionDefaults.submit,\n          type: 'boolean',\n        },\n        reset: {\n          default: optionDefaults.reset,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = Object.assign({}, optionDefaults, context.options[0]);\n\n    function reportMissing(node) {\n      report(context, messages.missingType, 'missingType', {\n        node,\n      });\n    }\n\n    function reportComplex(node) {\n      report(context, messages.complexType, 'complexType', {\n        node,\n      });\n    }\n\n    function checkValue(node, value) {\n      if (!(value in configuration)) {\n        report(context, messages.invalidValue, 'invalidValue', {\n          node,\n          data: {\n            value,\n          },\n        });\n      } else if (!configuration[value]) {\n        report(context, messages.forbiddenValue, 'forbiddenValue', {\n          node,\n          data: {\n            value,\n          },\n        });\n      }\n    }\n\n    function checkExpression(node, expression) {\n      switch (expression.type) {\n        case 'Literal':\n          checkValue(node, expression.value);\n          return;\n        case 'TemplateLiteral':\n          if (expression.expressions.length === 0) {\n            checkValue(node, expression.quasis[0].value.raw);\n          } else {\n            reportComplex(expression);\n          }\n          return;\n        case 'ConditionalExpression':\n          checkExpression(node, expression.consequent);\n          checkExpression(node, expression.alternate);\n          return;\n        default:\n          reportComplex(expression);\n      }\n    }\n\n    return {\n      JSXElement(node) {\n        if (node.openingElement.name.name !== 'button') {\n          return;\n        }\n\n        const typeProp = getProp(node.openingElement.attributes, 'type');\n\n        if (!typeProp) {\n          reportMissing(node);\n          return;\n        }\n\n        if (typeProp.value && typeProp.value.type === 'JSXExpressionContainer') {\n          checkExpression(node, typeProp.value.expression);\n          return;\n        }\n\n        const propValue = getLiteralPropValue(typeProp);\n        checkValue(node, propValue);\n      },\n      CallExpression(node) {\n        if (!isCreateElement(context, node) || node.arguments.length < 1) {\n          return;\n        }\n\n        if (node.arguments[0].type !== 'Literal' || node.arguments[0].value !== 'button') {\n          return;\n        }\n\n        if (!node.arguments[1] || node.arguments[1].type !== 'ObjectExpression') {\n          reportMissing(node);\n          return;\n        }\n\n        const props = node.arguments[1].properties;\n        const typeProp = props.find((prop) => (\n          'key' in prop\n          && prop.key\n          && 'name' in prop.key\n          && prop.key.name === 'type'\n        ));\n\n        if (!typeProp) {\n          reportMissing(node);\n          return;\n        }\n\n        checkExpression(node, 'value' in typeProp ? typeProp.value : undefined);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/checked-requires-onchange-or-readonly.js",
    "content": "/**\n * @fileoverview Enforce the use of the 'onChange' or 'readonly' attribute when 'checked' is used'\n * @author Jaesoekjjang\n */\n\n'use strict';\n\nconst ASTUtils = require('jsx-ast-utils');\nconst flatMap = require('array.prototype.flatmap');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\nconst docsUrl = require('../util/docsUrl');\n\nconst messages = {\n  missingProperty: '`checked` should be used with either `onChange` or `readOnly`.',\n  exclusiveCheckedAttribute: 'Use either `checked` or `defaultChecked`, but not both.',\n};\n\nconst targetPropSet = new Set(['checked', 'onChange', 'readOnly', 'defaultChecked']);\n\nconst defaultOptions = {\n  ignoreMissingProperties: false,\n  ignoreExclusiveCheckedAttribute: false,\n};\n\n/**\n * @param {object[]} properties\n * @param {string} keyName\n * @returns {Set<string>}\n */\nfunction extractTargetProps(properties, keyName) {\n  return new Set(\n    flatMap(\n      properties,\n      (prop) => (\n        prop[keyName] && targetPropSet.has(prop[keyName].name)\n          ? [prop[keyName].name]\n          : []\n      )\n    )\n  );\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce using `onChange` or `readonly` attribute when `checked` is used',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('checked-requires-onchange-or-readonly'),\n    },\n    messages,\n    schema: [{\n      additionalProperties: false,\n      properties: {\n        ignoreMissingProperties: {\n          type: 'boolean',\n        },\n        ignoreExclusiveCheckedAttribute: {\n          type: 'boolean',\n        },\n      },\n    }],\n  },\n  create(context) {\n    const options = Object.assign({}, defaultOptions, context.options[0]);\n\n    function reportMissingProperty(node) {\n      report(\n        context,\n        messages.missingProperty,\n        'missingProperty',\n        { node }\n      );\n    }\n\n    function reportExclusiveCheckedAttribute(node) {\n      report(\n        context,\n        messages.exclusiveCheckedAttribute,\n        'exclusiveCheckedAttribute',\n        { node }\n      );\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @param {Set<string>} propSet\n     * @returns {void}\n     */\n    const checkAttributesAndReport = (node, propSet) => {\n      if (!propSet.has('checked')) {\n        return;\n      }\n\n      if (!options.ignoreExclusiveCheckedAttribute && propSet.has('defaultChecked')) {\n        reportExclusiveCheckedAttribute(node);\n      }\n\n      if (\n        !options.ignoreMissingProperties\n        && !(propSet.has('onChange') || propSet.has('readOnly'))\n      ) {\n        reportMissingProperty(node);\n      }\n    };\n\n    return {\n      JSXOpeningElement(node) {\n        if (ASTUtils.elementType(node) !== 'input') {\n          return;\n        }\n\n        const propSet = extractTargetProps(node.attributes, 'name');\n        checkAttributesAndReport(node, propSet);\n      },\n      CallExpression(node) {\n        if (!isCreateElement(context, node)) {\n          return;\n        }\n\n        const firstArg = node.arguments[0];\n        const secondArg = node.arguments[1];\n        if (\n          !firstArg\n          || firstArg.type !== 'Literal'\n          || firstArg.value !== 'input'\n        ) {\n          return;\n        }\n\n        if (!secondArg || secondArg.type !== 'ObjectExpression') {\n          return;\n        }\n\n        const propSet = extractTargetProps(secondArg.properties, 'key');\n        checkAttributesAndReport(node, propSet);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/default-props-match-prop-types.js",
    "content": "/**\n * @fileOverview Enforce all defaultProps are defined in propTypes\n * @author Vitor Balocco\n * @author Roy Sutton\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  requiredHasDefault: 'defaultProp \"{{name}}\" defined for isRequired propType.',\n  defaultHasNoType: 'defaultProp \"{{name}}\" has no corresponding propTypes declaration.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce all defaultProps have a corresponding non-required PropType',\n      category: 'Best Practices',\n      url: docsUrl('default-props-match-prop-types'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowRequiredDefaults: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    const configuration = context.options[0] || {};\n    const allowRequiredDefaults = configuration.allowRequiredDefaults || false;\n\n    /**\n     * Reports all defaultProps passed in that don't have an appropriate propTypes counterpart.\n     * @param  {Object[]} propTypes    Array of propTypes to check.\n     * @param  {Object}   defaultProps Object of defaultProps to check. Keys are the props names.\n     * @return {void}\n     */\n    function reportInvalidDefaultProps(propTypes, defaultProps) {\n      // If this defaultProps is \"unresolved\" or the propTypes is undefined, then we should ignore\n      // this component and not report any errors for it, to avoid false-positives with e.g.\n      // external defaultProps/propTypes declarations or spread operators.\n      if (defaultProps === 'unresolved' || !propTypes || Object.keys(propTypes).length === 0) {\n        return;\n      }\n\n      Object.keys(defaultProps).forEach((defaultPropName) => {\n        const defaultProp = defaultProps[defaultPropName];\n        const prop = propTypes[defaultPropName];\n\n        if (prop && (allowRequiredDefaults || !prop.isRequired)) {\n          return;\n        }\n\n        if (prop) {\n          report(context, messages.requiredHasDefault, 'requiredHasDefault', {\n            node: defaultProp.node,\n            data: {\n              name: defaultPropName,\n            },\n          });\n        } else {\n          report(context, messages.defaultHasNoType, 'defaultHasNoType', {\n            node: defaultProp.node,\n            data: {\n              name: defaultPropName,\n            },\n          });\n        }\n      });\n    }\n\n    // --------------------------------------------------------------------------\n    // Public API\n    // --------------------------------------------------------------------------\n\n    return {\n      'Program:exit'() {\n        // If no defaultProps could be found, we don't report anything.\n        values(components.list())\n          .filter((component) => component.defaultProps)\n          .forEach((component) => {\n            reportInvalidDefaultProps(\n              component.declaredPropTypes,\n              component.defaultProps || {}\n            );\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/destructuring-assignment.js",
    "content": "/**\n * @fileoverview Enforce consistent usage of destructuring assignment of props, state, and context.\n */\n\n'use strict';\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst isAssignmentLHS = require('../util/ast').isAssignmentLHS;\nconst report = require('../util/report');\n\nconst getScope = eslintUtil.getScope;\nconst getText = eslintUtil.getText;\n\nconst DEFAULT_OPTION = 'always';\n\nfunction createSFCParams() {\n  const queue = [];\n\n  return {\n    push(params) {\n      queue.unshift(params);\n    },\n    pop() {\n      queue.shift();\n    },\n    propsName() {\n      const found = queue.find((params) => {\n        const props = params[0];\n        return props && !props.destructuring && props.name;\n      });\n      return found && found[0] && found[0].name;\n    },\n    contextName() {\n      const found = queue.find((params) => {\n        const context = params[1];\n        return context && !context.destructuring && context.name;\n      });\n      return found && found[1] && found[1].name;\n    },\n  };\n}\n\nfunction evalParams(params) {\n  return params.map((param) => ({\n    destructuring: param.type === 'ObjectPattern',\n    name: param.type === 'Identifier' && param.name,\n  }));\n}\n\nconst messages = {\n  noDestructPropsInSFCArg: 'Must never use destructuring props assignment in SFC argument',\n  noDestructContextInSFCArg: 'Must never use destructuring context assignment in SFC argument',\n  noDestructAssignment: 'Must never use destructuring {{type}} assignment',\n  useDestructAssignment: 'Must use destructuring {{type}} assignment',\n  destructureInSignature: 'Must destructure props in the function signature.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce consistent usage of destructuring assignment of props, state, and context',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('destructuring-assignment'),\n    },\n    fixable: 'code',\n    messages,\n\n    schema: [{\n      type: 'string',\n      enum: [\n        'always',\n        'never',\n      ],\n    }, {\n      type: 'object',\n      properties: {\n        ignoreClassFields: {\n          type: 'boolean',\n        },\n        destructureInSignature: {\n          type: 'string',\n          enum: [\n            'always',\n            'ignore',\n          ],\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const configuration = context.options[0] || DEFAULT_OPTION;\n    const ignoreClassFields = (context.options[1] && (context.options[1].ignoreClassFields === true)) || false;\n    const destructureInSignature = (context.options[1] && context.options[1].destructureInSignature) || 'ignore';\n    const sfcParams = createSFCParams();\n\n    /**\n     * @param {ASTNode} node We expect either an ArrowFunctionExpression,\n     *   FunctionDeclaration, or FunctionExpression\n     */\n    function handleStatelessComponent(node) {\n      const params = evalParams(node.params);\n\n      const SFCComponent = components.get(getScope(context, node).block);\n      if (!SFCComponent) {\n        return;\n      }\n      sfcParams.push(params);\n\n      if (params[0] && params[0].destructuring && components.get(node) && configuration === 'never') {\n        report(context, messages.noDestructPropsInSFCArg, 'noDestructPropsInSFCArg', {\n          node,\n        });\n      } else if (params[1] && params[1].destructuring && components.get(node) && configuration === 'never') {\n        report(context, messages.noDestructContextInSFCArg, 'noDestructContextInSFCArg', {\n          node,\n        });\n      }\n    }\n\n    function handleStatelessComponentExit(node) {\n      const SFCComponent = components.get(getScope(context, node).block);\n      if (SFCComponent) {\n        sfcParams.pop();\n      }\n    }\n\n    function handleSFCUsage(node) {\n      const propsName = sfcParams.propsName();\n      const contextName = sfcParams.contextName();\n      // props.aProp || context.aProp\n      const isPropUsed = (\n        (propsName && node.object.name === propsName)\n          || (contextName && node.object.name === contextName)\n      )\n        && !isAssignmentLHS(node);\n      if (isPropUsed && configuration === 'always' && !node.optional) {\n        report(context, messages.useDestructAssignment, 'useDestructAssignment', {\n          node,\n          data: {\n            type: node.object.name,\n          },\n        });\n      }\n    }\n\n    function isInClassProperty(node) {\n      let curNode = node.parent;\n      while (curNode) {\n        if (curNode.type === 'ClassProperty' || curNode.type === 'PropertyDefinition') {\n          return true;\n        }\n        curNode = curNode.parent;\n      }\n      return false;\n    }\n\n    function handleClassUsage(node) {\n      // this.props.Aprop || this.context.aProp || this.state.aState\n      const isPropUsed = (\n        node.object.type === 'MemberExpression' && node.object.object.type === 'ThisExpression'\n        && (node.object.property.name === 'props' || node.object.property.name === 'context' || node.object.property.name === 'state')\n        && !isAssignmentLHS(node)\n      );\n\n      if (\n        isPropUsed && configuration === 'always'\n        && !(ignoreClassFields && isInClassProperty(node))\n      ) {\n        report(context, messages.useDestructAssignment, 'useDestructAssignment', {\n          node,\n          data: {\n            type: node.object.property.name,\n          },\n        });\n      }\n    }\n\n    // valid-jsdoc cannot read function types\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * Find a parent that satisfy the given predicate\n     * @param {ASTNode} node\n     * @param {(node: ASTNode) => boolean} predicate\n     * @returns {ASTNode | undefined}\n     */\n    function findParent(node, predicate) {\n      let n = node;\n      while (n) {\n        if (predicate(n)) {\n          return n;\n        }\n        n = n.parent;\n      }\n      return undefined;\n    }\n\n    return {\n\n      FunctionDeclaration: handleStatelessComponent,\n\n      ArrowFunctionExpression: handleStatelessComponent,\n\n      FunctionExpression: handleStatelessComponent,\n\n      'FunctionDeclaration:exit': handleStatelessComponentExit,\n\n      'ArrowFunctionExpression:exit': handleStatelessComponentExit,\n\n      'FunctionExpression:exit': handleStatelessComponentExit,\n\n      MemberExpression(node) {\n        const SFCComponent = utils.getParentStatelessComponent(node);\n        if (SFCComponent) {\n          handleSFCUsage(node);\n        }\n\n        const classComponent = utils.getParentComponent(node);\n        if (classComponent) {\n          handleClassUsage(node);\n        }\n      },\n\n      TSQualifiedName(node) {\n        if (configuration !== 'always') {\n          return;\n        }\n        // handle `typeof props.a.b`\n        if (node.left.type === 'Identifier'\n          && node.left.name === sfcParams.propsName()\n          && findParent(node, (n) => n.type === 'TSTypeQuery')\n          && utils.getParentStatelessComponent(node)\n        ) {\n          report(context, messages.useDestructAssignment, 'useDestructAssignment', {\n            node,\n            data: {\n              type: 'props',\n            },\n          });\n        }\n      },\n\n      VariableDeclarator(node) {\n        const classComponent = utils.getParentComponent(node);\n        const SFCComponent = components.get(getScope(context, node).block);\n\n        const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern');\n        // let {foo} = props;\n        const destructuringSFC = destructuring && (node.init.name === 'props' || node.init.name === 'context');\n        // let {foo} = this.props;\n        const destructuringClass = destructuring && node.init.object && node.init.object.type === 'ThisExpression' && (\n          node.init.property.name === 'props' || node.init.property.name === 'context' || node.init.property.name === 'state'\n        );\n\n        if (SFCComponent && destructuringSFC && configuration === 'never') {\n          report(context, messages.noDestructAssignment, 'noDestructAssignment', {\n            node,\n            data: {\n              type: node.init.name,\n            },\n          });\n        }\n\n        if (\n          classComponent && destructuringClass && configuration === 'never'\n          && !(ignoreClassFields && (node.parent.type === 'ClassProperty' || node.parent.type === 'PropertyDefinition'))\n        ) {\n          report(context, messages.noDestructAssignment, 'noDestructAssignment', {\n            node,\n            data: {\n              type: node.init.property.name,\n            },\n          });\n        }\n\n        if (\n          SFCComponent\n          && destructuringSFC\n          && configuration === 'always'\n          && destructureInSignature === 'always'\n          && node.init.name === 'props'\n        ) {\n          const scopeSetProps = getScope(context, node).set.get('props');\n          const propsRefs = scopeSetProps && scopeSetProps.references;\n          if (!propsRefs) {\n            return;\n          }\n\n          // Skip if props is used elsewhere\n          if (propsRefs.length > 1) {\n            return;\n          }\n          report(context, messages.destructureInSignature, 'destructureInSignature', {\n            node,\n            fix(fixer) {\n              const param = SFCComponent.node.params[0];\n              if (!param) {\n                return;\n              }\n              const replaceRange = [\n                param.range[0],\n                param.typeAnnotation ? param.typeAnnotation.range[0] : param.range[1],\n              ];\n              return [\n                fixer.replaceTextRange(replaceRange, getText(context, node.id)),\n                fixer.remove(node.parent),\n              ];\n            },\n          });\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/display-name.js",
    "content": "/**\n * @fileoverview Prevent missing displayName in a React component definition\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst values = require('object.values');\nconst filter = require('es-iterator-helpers/Iterator.prototype.filter');\nconst forEach = require('es-iterator-helpers/Iterator.prototype.forEach');\n\nconst Components = require('../util/Components');\nconst isCreateContext = require('../util/isCreateContext');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst propsUtil = require('../util/props');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noDisplayName: 'Component definition is missing display name',\n  noContextDisplayName: 'Context definition is missing display name',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow missing displayName in a React component definition',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('display-name'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignoreTranspilerName: {\n          type: 'boolean',\n        },\n        checkContextObjects: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const config = context.options[0] || {};\n    const ignoreTranspilerName = config.ignoreTranspilerName || false;\n    const checkContextObjects = (config.checkContextObjects || false) && testReactVersion(context, '>= 16.3.0');\n\n    const contextObjects = new Map();\n\n    /**\n     * Mark a prop type as declared\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markDisplayNameAsDeclared(node) {\n      components.set(node, {\n        hasDisplayName: true,\n      });\n    }\n\n    /**\n     * Checks if React.forwardRef is nested inside React.memo\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if React.forwardRef is nested inside React.memo, false if not.\n     */\n    function isNestedMemo(node) {\n      return astUtil.isCallExpression(node)\n        && node.arguments\n        && astUtil.isCallExpression(node.arguments[0])\n        && utils.isPragmaComponentWrapper(node);\n    }\n\n    /**\n     * Reports missing display name for a given component\n     * @param {Object} component The component to process\n     */\n    function reportMissingDisplayName(component) {\n      if (\n        testReactVersion(context, '^0.14.10 || ^15.7.0 || >= 16.12.0')\n        && isNestedMemo(component.node)\n      ) {\n        return;\n      }\n\n      report(context, messages.noDisplayName, 'noDisplayName', {\n        node: component.node,\n      });\n    }\n\n    /**\n     * Reports missing display name for a given context object\n     * @param {Object} contextObj The context object to process\n     */\n    function reportMissingContextDisplayName(contextObj) {\n      report(context, messages.noContextDisplayName, 'noContextDisplayName', {\n        node: contextObj.node,\n      });\n    }\n\n    /**\n     * Checks if the component have a name set by the transpiler\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if component has a name, false if not.\n     */\n    function hasTranspilerName(node) {\n      const namedObjectAssignment = (\n        node.type === 'ObjectExpression'\n        && node.parent\n        && node.parent.parent\n        && node.parent.parent.type === 'AssignmentExpression'\n        && (\n          !node.parent.parent.left.object\n          || node.parent.parent.left.object.name !== 'module'\n          || node.parent.parent.left.property.name !== 'exports'\n        )\n      );\n      const namedObjectDeclaration = (\n        node.type === 'ObjectExpression'\n        && node.parent\n        && node.parent.parent\n        && node.parent.parent.type === 'VariableDeclarator'\n      );\n      const namedClass = (\n        (node.type === 'ClassDeclaration' || node.type === 'ClassExpression')\n        && node.id\n        && !!node.id.name\n      );\n\n      const namedFunctionDeclaration = (\n        (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression')\n        && node.id\n        && !!node.id.name\n      );\n\n      const namedFunctionExpression = (\n        astUtil.isFunctionLikeExpression(node)\n        && node.parent\n        && (node.parent.type === 'VariableDeclarator' || node.parent.type === 'Property' || node.parent.method === true)\n        && (!node.parent.parent || !componentUtil.isES5Component(node.parent.parent, context))\n      );\n\n      if (\n        namedObjectAssignment || namedObjectDeclaration\n        || namedClass\n        || namedFunctionDeclaration || namedFunctionExpression\n      ) {\n        return true;\n      }\n      return false;\n    }\n\n    function hasVariableDeclaration(node, name) {\n      if (!node) return false;\n\n      if (node.type === 'VariableDeclaration') {\n        return node.declarations.some((decl) => {\n          if (!decl.id) return false;\n\n          // const name = ...\n          if (decl.id.type === 'Identifier' && decl.id.name === name) {\n            return true;\n          }\n\n          // const [name] = ...\n          if (decl.id.type === 'ArrayPattern') {\n            return decl.id.elements.some(\n              (el) => el && el.type === 'Identifier' && el.name === name\n            );\n          }\n\n          // const { name } = ...\n          if (decl.id.type === 'ObjectPattern') {\n            return decl.id.properties.some(\n              (prop) => prop.type === 'Property' && prop.key && prop.key.name === name\n            );\n          }\n\n          return false;\n        });\n      }\n\n      if (node.type === 'BlockStatement' && node.body) {\n        return node.body.some((stmt) => hasVariableDeclaration(stmt, name));\n      }\n\n      return false;\n    }\n\n    function isIdentifierShadowed(node, identifierName) {\n      let currentNode = node;\n\n      while (currentNode && currentNode.parent) {\n        currentNode = currentNode.parent;\n\n        if (\n          currentNode.type === 'FunctionDeclaration'\n          || currentNode.type === 'FunctionExpression'\n          || currentNode.type === 'ArrowFunctionExpression'\n        ) {\n          if (currentNode.body && hasVariableDeclaration(currentNode.body, identifierName)) {\n            return true;\n          }\n        }\n\n        if (currentNode.type === 'BlockStatement') {\n          if (hasVariableDeclaration(currentNode, identifierName)) {\n            return true;\n          }\n        }\n\n        if (\n          (currentNode.type === 'FunctionDeclaration'\n           || currentNode.type === 'FunctionExpression'\n           || currentNode.type === 'ArrowFunctionExpression')\n          && currentNode.params\n        ) {\n          const isParamShadowed = currentNode.params.some((param) => {\n            if (param.type === 'Identifier' && param.name === identifierName) {\n              return true;\n            }\n            if (param.type === 'ObjectPattern') {\n              return param.properties.some(\n                (prop) => prop.type === 'Property' && prop.key && prop.key.name === identifierName\n              );\n            }\n            if (param.type === 'ArrayPattern') {\n              return param.elements.some(\n                (el) => el && el.type === 'Identifier' && el.name === identifierName\n              );\n            }\n            return false;\n          });\n\n          if (isParamShadowed) {\n            return true;\n          }\n        }\n      }\n\n      return false;\n    }\n    /**\n     * Checks whether the component wrapper (e.g. React.memo or forwardRef) is shadowed in the current scope.\n     * @param {ASTNode} node - The CallExpression AST node representing a potential component wrapper.\n     * @returns {boolean} True if the wrapper identifier (e.g. 'React', 'memo', 'forwardRef') is shadowed, false otherwise.\n     */\n    function isShadowedComponent(node) {\n      if (!node || node.type !== 'CallExpression') {\n        return false;\n      }\n\n      if (\n        node.callee.type === 'MemberExpression'\n        && node.callee.object.name === 'React'\n      ) {\n        return isIdentifierShadowed(node, 'React');\n      }\n\n      if (node.callee.type === 'Identifier') {\n        const name = node.callee.name;\n        if (name === 'memo' || name === 'forwardRef') {\n          return isIdentifierShadowed(node, name);\n        }\n      }\n\n      return false;\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      ExpressionStatement(node) {\n        if (checkContextObjects && isCreateContext(node)) {\n          contextObjects.set(node.expression.left.name, { node, hasDisplayName: false });\n        }\n      },\n      VariableDeclarator(node) {\n        if (checkContextObjects && isCreateContext(node)) {\n          contextObjects.set(node.id.name, { node, hasDisplayName: false });\n        }\n      },\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!propsUtil.isDisplayNameDeclaration(node)) {\n          return;\n        }\n        markDisplayNameAsDeclared(node);\n      },\n\n      MemberExpression(node) {\n        if (!propsUtil.isDisplayNameDeclaration(node.property)) {\n          return;\n        }\n        if (\n          checkContextObjects\n          && node.object\n          && node.object.name\n          && contextObjects.has(node.object.name)\n        ) {\n          contextObjects.get(node.object.name).hasDisplayName = true;\n        }\n        const component = utils.getRelatedComponent(node);\n        if (!component) {\n          return;\n        }\n        markDisplayNameAsDeclared(astUtil.unwrapTSAsExpression(component.node));\n      },\n\n      'FunctionExpression, FunctionDeclaration, ArrowFunctionExpression'(node) {\n        if (ignoreTranspilerName || !hasTranspilerName(node)) {\n          return;\n        }\n        if (components.get(node)) {\n          markDisplayNameAsDeclared(node);\n        }\n      },\n\n      MethodDefinition(node) {\n        if (!propsUtil.isDisplayNameDeclaration(node.key)) {\n          return;\n        }\n        markDisplayNameAsDeclared(node);\n      },\n\n      'ClassExpression, ClassDeclaration'(node) {\n        if (ignoreTranspilerName || !hasTranspilerName(node)) {\n          return;\n        }\n        markDisplayNameAsDeclared(node);\n      },\n\n      ObjectExpression(node) {\n        if (!componentUtil.isES5Component(node, context)) {\n          return;\n        }\n        if (ignoreTranspilerName || !hasTranspilerName(node)) {\n          // Search for the displayName declaration\n          node.properties.forEach((property) => {\n            if (!property.key || !propsUtil.isDisplayNameDeclaration(property.key)) {\n              return;\n            }\n            markDisplayNameAsDeclared(node);\n          });\n          return;\n        }\n        markDisplayNameAsDeclared(node);\n      },\n\n      CallExpression(node) {\n        if (!utils.isPragmaComponentWrapper(node)) {\n          return;\n        }\n\n        if (node.arguments.length > 0 && astUtil.isFunctionLikeExpression(node.arguments[0])) {\n          // Skip over React.forwardRef declarations that are embedded within\n          // a React.memo i.e. React.memo(React.forwardRef(/* ... */))\n          // This means that we raise a single error for the call to React.memo\n          // instead of one for React.memo and one for React.forwardRef\n          const isWrappedInAnotherPragma = utils.getPragmaComponentWrapper(node);\n          if (\n            !isWrappedInAnotherPragma\n            && (ignoreTranspilerName || !hasTranspilerName(node.arguments[0]))\n          ) {\n            return;\n          }\n\n          if (components.get(node)) {\n            markDisplayNameAsDeclared(node);\n          }\n        }\n      },\n\n      'Program:exit'() {\n        const list = components.list();\n        // Report missing display name for all components\n        values(list)\n          .filter((component) => !isShadowedComponent(component.node) && !component.hasDisplayName)\n          .forEach((component) => { reportMissingDisplayName(component); });\n        if (checkContextObjects) {\n          // Report missing display name for all context objects\n          forEach(\n            filter(contextObjects.values(), (v) => !v.hasDisplayName),\n            (contextObj) => reportMissingContextDisplayName(contextObj)\n          );\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/forbid-component-props.js",
    "content": "/**\n * @fileoverview Forbid certain props on components\n * @author Joe Lencioni\n */\n\n'use strict';\n\nconst minimatch = require('minimatch');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = ['className', 'style'];\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  propIsForbidden: 'Prop \"{{prop}}\" is forbidden on Components',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow certain props on components',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('forbid-component-props'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbid: {\n          type: 'array',\n          items: {\n            anyOf: [\n              { type: 'string' },\n              {\n                type: 'object',\n                properties: {\n                  propName: { type: 'string' },\n                  allowedFor: {\n                    type: 'array',\n                    uniqueItems: true,\n                    items: { type: 'string' },\n                  },\n                  allowedForPatterns: {\n                    type: 'array',\n                    uniqueItems: true,\n                    items: { type: 'string' },\n                  },\n                  message: { type: 'string' },\n                },\n                additionalProperties: false,\n              },\n              {\n                type: 'object',\n                properties: {\n                  propName: { type: 'string' },\n                  disallowedFor: {\n                    type: 'array',\n                    uniqueItems: true,\n                    minItems: 1,\n                    items: { type: 'string' },\n                  },\n                  disallowedForPatterns: {\n                    type: 'array',\n                    uniqueItems: true,\n                    minItems: 1,\n                    items: { type: 'string' },\n                  },\n                  message: { type: 'string' },\n                },\n                anyOf: [\n                  { required: ['disallowedFor'] },\n                  { required: ['disallowedForPatterns'] },\n                ],\n                additionalProperties: false,\n              },\n              {\n                type: 'object',\n                properties: {\n                  propNamePattern: { type: 'string' },\n                  allowedFor: {\n                    type: 'array',\n                    uniqueItems: true,\n                    items: { type: 'string' },\n                  },\n                  allowedForPatterns: {\n                    type: 'array',\n                    uniqueItems: true,\n                    items: { type: 'string' },\n                  },\n                  message: { type: 'string' },\n                },\n                additionalProperties: false,\n              },\n              {\n                type: 'object',\n                properties: {\n                  propNamePattern: { type: 'string' },\n                  disallowedFor: {\n                    type: 'array',\n                    uniqueItems: true,\n                    minItems: 1,\n                    items: { type: 'string' },\n                  },\n                  disallowedForPatterns: {\n                    type: 'array',\n                    uniqueItems: true,\n                    minItems: 1,\n                    items: { type: 'string' },\n                  },\n                  message: { type: 'string' },\n                },\n                anyOf: [\n                  { required: ['disallowedFor'] },\n                  { required: ['disallowedForPatterns'] },\n                ],\n                additionalProperties: false,\n              },\n            ],\n          },\n        },\n      },\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {\n      const propName = typeof value === 'string' ? value : value.propName;\n      const propPattern = value.propNamePattern;\n      const prop = propName || propPattern;\n      const options = {\n        allowList: [].concat(value.allowedFor || []),\n        allowPatternList: [].concat(value.allowedForPatterns || []),\n        disallowList: [].concat(value.disallowedFor || []),\n        disallowPatternList: [].concat(value.disallowedForPatterns || []),\n        message: typeof value === 'string' ? null : value.message,\n        isPattern: !!value.propNamePattern,\n      };\n      return [prop, options];\n    }));\n\n    function getPropOptions(prop) {\n      // Get config options having pattern\n      const propNamePatternArray = Array.from(forbid.entries()).filter((propEntry) => propEntry[1].isPattern);\n      // Match current prop with pattern options, return if matched\n      const propNamePattern = propNamePatternArray.find((propPatternVal) => minimatch(prop, propPatternVal[0]));\n      // Get options for matched propNamePattern\n      const propNamePatternOptions = propNamePattern && propNamePattern[1];\n\n      const options = forbid.get(prop) || propNamePatternOptions;\n      return options;\n    }\n\n    function isForbidden(prop, tagName) {\n      const options = getPropOptions(prop);\n      if (!options) {\n        return false;\n      }\n\n      function checkIsTagForbiddenByAllowOptions() {\n        if (options.allowList.indexOf(tagName) !== -1) {\n          return false;\n        }\n\n        if (options.allowPatternList.length === 0) {\n          return true;\n        }\n\n        return options.allowPatternList.every(\n          (pattern) => !minimatch(tagName, pattern)\n        );\n      }\n\n      function checkIsTagForbiddenByDisallowOptions() {\n        if (options.disallowList.indexOf(tagName) !== -1) {\n          return true;\n        }\n\n        if (options.disallowPatternList.length === 0) {\n          return false;\n        }\n\n        return options.disallowPatternList.some(\n          (pattern) => minimatch(tagName, pattern)\n        );\n      }\n\n      const hasDisallowOptions = options.disallowList.length > 0 || options.disallowPatternList.length > 0;\n\n      // disallowList should have a least one item (schema configuration)\n      const isTagForbidden = hasDisallowOptions\n        ? checkIsTagForbiddenByDisallowOptions()\n        : checkIsTagForbiddenByAllowOptions();\n\n      // if the tagName is undefined (`<this.something>`), we assume it's a forbidden element\n      return typeof tagName === 'undefined' || isTagForbidden;\n    }\n\n    return {\n      JSXAttribute(node) {\n        const parentName = node.parent.name;\n        // Extract a component name when using a \"namespace\", e.g. `<AntdLayout.Content />`.\n        const tag = parentName.name || `${parentName.object.name}.${parentName.property.name}`;\n        const componentName = parentName.name || parentName.property.name;\n        if (componentName && typeof componentName[0] === 'string' && componentName[0] !== componentName[0].toUpperCase()) {\n          // This is a DOM node, not a Component, so exit.\n          return;\n        }\n\n        const prop = node.name.name;\n\n        if (!isForbidden(prop, tag)) {\n          return;\n        }\n\n        const customMessage = getPropOptions(prop).message;\n\n        report(context, customMessage || messages.propIsForbidden, !customMessage && 'propIsForbidden', {\n          node,\n          data: {\n            prop,\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/forbid-dom-props.js",
    "content": "/**\n * @fileoverview Forbid certain props on DOM Nodes\n * @author David Vázquez\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = [];\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n/** @typedef {{ disallowList: null | string[]; message: null | string; disallowedValues: string[] | null }} ForbidMapType */\n/**\n * @param {Map<string, ForbidMapType>} forbidMap\n * @param {string} prop\n * @param {string} propValue\n * @param {string} tagName\n * @returns {boolean}\n */\nfunction isForbidden(forbidMap, prop, propValue, tagName) {\n  const options = forbidMap.get(prop);\n\n  if (!options) {\n    return false;\n  }\n\n  return (\n    !options.disallowList\n    || options.disallowList.indexOf(tagName) !== -1\n  ) && (\n    !options.disallowedValues\n    || options.disallowedValues.indexOf(propValue) !== -1\n  );\n}\n\nconst messages = {\n  propIsForbidden: 'Prop \"{{prop}}\" is forbidden on DOM Nodes',\n  propIsForbiddenWithValue: 'Prop \"{{prop}}\" with value \"{{propValue}}\" is forbidden on DOM Nodes',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow certain props on DOM Nodes',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('forbid-dom-props'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbid: {\n          type: 'array',\n          items: {\n            anyOf: [{\n              type: 'string',\n            }, {\n              type: 'object',\n              properties: {\n                propName: {\n                  type: 'string',\n                },\n                disallowedFor: {\n                  type: 'array',\n                  uniqueItems: true,\n                  items: {\n                    type: 'string',\n                  },\n                },\n                disallowedValues: {\n                  type: 'array',\n                  uniqueItems: true,\n                  items: {\n                    type: 'string',\n                  },\n                },\n                message: {\n                  type: 'string',\n                },\n              },\n            }],\n            minLength: 1,\n          },\n          uniqueItems: true,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const forbid = new Map((configuration.forbid || DEFAULTS).map((value) => {\n      const propName = typeof value === 'string' ? value : value.propName;\n      return [propName, {\n        disallowList: typeof value === 'string' ? null : (value.disallowedFor || null),\n        disallowedValues: typeof value === 'string' ? null : (value.disallowedValues || null),\n        message: typeof value === 'string' ? null : value.message,\n      }];\n    }));\n\n    return {\n      JSXAttribute(node) {\n        const tag = node.parent.name.name;\n        if (!(tag && typeof tag === 'string' && tag[0] !== tag[0].toUpperCase())) {\n          // This is a Component, not a DOM node, so exit.\n          return;\n        }\n\n        const prop = node.name.name;\n        const propValue = node.value.value;\n\n        if (!isForbidden(forbid, prop, propValue, tag)) {\n          return;\n        }\n\n        const customMessage = forbid.get(prop).message;\n        const isValuesListSpecified = forbid.get(prop).disallowedValues !== null;\n        const message = customMessage || (isValuesListSpecified && messages.propIsForbiddenWithValue) || messages.propIsForbidden;\n        const messageId = !customMessage && ((isValuesListSpecified && 'propIsForbiddenWithValue') || 'propIsForbidden');\n\n        report(context, message, messageId, {\n          node,\n          data: {\n            prop,\n            propValue,\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/forbid-elements.js",
    "content": "/**\n * @fileoverview Forbid certain elements\n * @author Kenneth Chung\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  forbiddenElement: '<{{element}}> is forbidden',\n  forbiddenElement_message: '<{{element}}> is forbidden, {{message}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow certain elements',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('forbid-elements'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbid: {\n          type: 'array',\n          items: {\n            anyOf: [\n              { type: 'string' },\n              {\n                type: 'object',\n                properties: {\n                  element: { type: 'string' },\n                  message: { type: 'string' },\n                },\n                required: ['element'],\n                additionalProperties: false,\n              },\n            ],\n          },\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const forbidConfiguration = configuration.forbid || [];\n\n    /** @type {Record<string, { element: string, message?: string }>} */\n    const indexedForbidConfigs = {};\n\n    forbidConfiguration.forEach((item) => {\n      if (typeof item === 'string') {\n        indexedForbidConfigs[item] = { element: item };\n      } else {\n        indexedForbidConfigs[item.element] = item;\n      }\n    });\n\n    function reportIfForbidden(element, node) {\n      if (has(indexedForbidConfigs, element)) {\n        const message = indexedForbidConfigs[element].message;\n\n        report(\n          context,\n          message ? messages.forbiddenElement_message : messages.forbiddenElement,\n          message ? 'forbiddenElement_message' : 'forbiddenElement',\n          {\n            node,\n            data: {\n              element,\n              message,\n            },\n          }\n        );\n      }\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        reportIfForbidden(getText(context, node.name), node.name);\n      },\n\n      CallExpression(node) {\n        if (!isCreateElement(context, node)) {\n          return;\n        }\n\n        const argument = node.arguments[0];\n        if (!argument) {\n          return;\n        }\n\n        if (argument.type === 'Identifier' && /^[A-Z_]/.test(argument.name)) {\n          reportIfForbidden(argument.name, argument);\n        } else if (argument.type === 'Literal' && /^[a-z][^.]*$/.test(String(argument.value))) {\n          reportIfForbidden(argument.value, argument);\n        } else if (argument.type === 'MemberExpression') {\n          reportIfForbidden(getText(context, argument), argument);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/forbid-foreign-prop-types.js",
    "content": "/**\n * @fileoverview Forbid using another component's propTypes\n * @author Ian Christian Myers\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst ast = require('../util/ast');\nconst report = require('../util/report');\n\nconst messages = {\n  forbiddenPropType: 'Using propTypes from another component is not safe because they may be removed in production builds',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow using another component\\'s propTypes',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('forbid-foreign-prop-types'),\n    },\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          allowInPropTypes: {\n            type: 'boolean',\n          },\n        },\n        additionalProperties: false,\n      },\n    ],\n  },\n\n  create(context) {\n    const config = context.options[0] || {};\n    const allowInPropTypes = config.allowInPropTypes || false;\n\n    // --------------------------------------------------------------------------\n    // Helpers\n    // --------------------------------------------------------------------------\n\n    function findParentAssignmentExpression(node) {\n      let parent = node.parent;\n\n      while (parent && parent.type !== 'Program') {\n        if (parent.type === 'AssignmentExpression') {\n          return parent;\n        }\n        parent = parent.parent;\n      }\n      return null;\n    }\n\n    function findParentClassProperty(node) {\n      let parent = node.parent;\n\n      while (parent && parent.type !== 'Program') {\n        if (parent.type === 'ClassProperty' || parent.type === 'PropertyDefinition') {\n          return parent;\n        }\n        parent = parent.parent;\n      }\n      return null;\n    }\n\n    function isAllowedAssignment(node) {\n      if (!allowInPropTypes) {\n        return false;\n      }\n\n      const assignmentExpression = findParentAssignmentExpression(node);\n\n      if (\n        assignmentExpression\n        && assignmentExpression.left\n        && assignmentExpression.left.property\n        && assignmentExpression.left.property.name === 'propTypes'\n      ) {\n        return true;\n      }\n\n      const classProperty = findParentClassProperty(node);\n\n      if (\n        classProperty\n        && classProperty.key\n        && classProperty.key.name === 'propTypes'\n      ) {\n        return true;\n      }\n      return false;\n    }\n\n    return {\n      MemberExpression(node) {\n        if (\n          (node.property\n          && (\n            !node.computed\n            && node.property.type === 'Identifier'\n            && node.property.name === 'propTypes'\n            && !ast.isAssignmentLHS(node)\n            && !isAllowedAssignment(node)\n          )) || (\n            // @ts-expect-error: The JSXText type is not present in the estree type definitions\n            (node.property.type === 'Literal' || node.property.type === 'JSXText')\n            && 'value' in node.property\n            && node.property.value === 'propTypes'\n            && !ast.isAssignmentLHS(node)\n            && !isAllowedAssignment(node)\n          )\n        ) {\n          report(context, messages.forbiddenPropType, 'forbiddenPropType', {\n            node: node.property,\n          });\n        }\n      },\n\n      ObjectPattern(node) {\n        const propTypesNode = node.properties.find((property) => (\n          property.type === 'Property'\n          && 'name' in property.key\n          && property.key.name === 'propTypes'\n        ));\n\n        if (propTypesNode) {\n          report(context, messages.forbiddenPropType, 'forbiddenPropType', {\n            node: propTypesNode,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/forbid-prop-types.js",
    "content": "/**\n * @fileoverview Forbid certain propTypes\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst propsUtil = require('../util/props');\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst propWrapperUtil = require('../util/propWrapper');\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = ['any', 'array', 'object'];\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  forbiddenPropType: 'Prop type \"{{target}}\" is forbidden',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow certain propTypes',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('forbid-prop-types'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbid: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        checkContextTypes: {\n          type: 'boolean',\n        },\n        checkChildContextTypes: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: true,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const checkContextTypes = configuration.checkContextTypes || false;\n    const checkChildContextTypes = configuration.checkChildContextTypes || false;\n    let propTypesPackageName = null;\n    let reactPackageName = null;\n    let isForeignPropTypesPackage = false;\n\n    function isPropTypesPackage(node) {\n      return (\n        node.type === 'Identifier'\n        && (\n          node.name === null\n          || node.name === propTypesPackageName\n          || !isForeignPropTypesPackage\n        )\n      ) || (\n        node.type === 'MemberExpression'\n        && (\n          node.object.name === null\n          || node.object.name === reactPackageName\n          || !isForeignPropTypesPackage\n        )\n      );\n    }\n\n    function isForbidden(type) {\n      const forbid = configuration.forbid || DEFAULTS;\n      return forbid.indexOf(type) >= 0;\n    }\n\n    function reportIfForbidden(type, declaration, target) {\n      if (isForbidden(type)) {\n        report(context, messages.forbiddenPropType, 'forbiddenPropType', {\n          node: declaration,\n          data: {\n            target,\n          },\n        });\n      }\n    }\n\n    function shouldCheckContextTypes(node) {\n      if (checkContextTypes && propsUtil.isContextTypesDeclaration(node)) {\n        return true;\n      }\n      return false;\n    }\n\n    function shouldCheckChildContextTypes(node) {\n      if (checkChildContextTypes && propsUtil.isChildContextTypesDeclaration(node)) {\n        return true;\n      }\n      return false;\n    }\n\n    /**\n     * Checks if propTypes declarations are forbidden\n     * @param {Array} declarations The array of AST nodes being checked.\n     * @returns {void}\n     */\n    function checkProperties(declarations) {\n      if (declarations) {\n        declarations.forEach((declaration) => {\n          if (declaration.type !== 'Property') {\n            return;\n          }\n          let target;\n          let value = declaration.value;\n          if (\n            value.type === 'MemberExpression'\n            && value.property\n            && value.property.name\n            && value.property.name === 'isRequired'\n          ) {\n            value = value.object;\n          }\n          if (astUtil.isCallExpression(value)) {\n            if (!isPropTypesPackage(value.callee)) {\n              return;\n            }\n            value.arguments.forEach((arg) => {\n              const name = arg.type === 'MemberExpression' ? arg.property.name : arg.name;\n              reportIfForbidden(name, declaration, name);\n            });\n            value = value.callee;\n          }\n          if (!isPropTypesPackage(value)) {\n            return;\n          }\n          if (value.property) {\n            target = value.property.name;\n          } else if (value.type === 'Identifier') {\n            target = value.name;\n          }\n          reportIfForbidden(target, declaration, target);\n        });\n      }\n    }\n\n    function checkNode(node) {\n      if (!node) {\n        return;\n      }\n\n      if (node.type === 'ObjectExpression') {\n        checkProperties(node.properties);\n      } else if (node.type === 'Identifier') {\n        const propTypesObject = variableUtil.findVariableByName(context, node, node.name);\n        if (propTypesObject && propTypesObject.properties) {\n          checkProperties(propTypesObject.properties);\n        }\n      } else if (astUtil.isCallExpression(node)) {\n        const innerNode = node.arguments && node.arguments[0];\n        if (\n          propWrapperUtil.isPropWrapperFunction(context, getText(context, node.callee))\n            && innerNode\n        ) {\n          checkNode(innerNode);\n        }\n      }\n    }\n\n    return {\n      ImportDeclaration(node) {\n        if (node.source && node.source.value === 'prop-types') { // import PropType from \"prop-types\"\n          if (node.specifiers.length > 0) {\n            propTypesPackageName = node.specifiers[0].local.name;\n          }\n        } else if (node.source && node.source.value === 'react') { // import { PropTypes } from \"react\"\n          if (node.specifiers.length > 0) {\n            reactPackageName = node.specifiers[0].local.name; // guard against accidental anonymous `import \"react\"`\n          }\n          if (node.specifiers.length >= 1) {\n            const propTypesSpecifier = node.specifiers.find((specifier) => (\n              'imported' in specifier\n              && specifier.imported\n              && 'name' in specifier.imported\n              && specifier.imported.name === 'PropTypes'\n            ));\n            if (propTypesSpecifier) {\n              propTypesPackageName = propTypesSpecifier.local.name;\n            }\n          }\n        } else { // package is not imported from \"react\" or \"prop-types\"\n          // eslint-disable-next-line no-lonely-if\n          if (node.specifiers.some((x) => x.local.name === 'PropTypes')) { // assert: node.specifiers.length > 1\n            isForeignPropTypesPackage = true;\n          }\n        }\n      },\n\n      'ClassProperty, PropertyDefinition'(node) {\n        if (\n          !propsUtil.isPropTypesDeclaration(node)\n          && !isPropTypesPackage(node)\n          && !shouldCheckContextTypes(node)\n          && !shouldCheckChildContextTypes(node)\n        ) {\n          return;\n        }\n        checkNode(node.value);\n      },\n\n      MemberExpression(node) {\n        if (\n          !propsUtil.isPropTypesDeclaration(node)\n          && !isPropTypesPackage(node)\n          && !shouldCheckContextTypes(node)\n          && !shouldCheckChildContextTypes(node)\n        ) {\n          return;\n        }\n\n        checkNode('right' in node.parent && node.parent.right);\n      },\n\n      CallExpression(node) {\n        if (\n          node.callee.type === 'MemberExpression'\n          && node.callee.object\n          && !isPropTypesPackage(node.callee.object)\n          && !propsUtil.isPropTypesDeclaration(node.callee)\n        ) {\n          return;\n        }\n\n        if (\n          node.arguments.length > 0\n          && (\n            ('name' in node.callee && node.callee.name === 'shape')\n            || astUtil.getPropertyName(node.callee) === 'shape'\n          )\n        ) {\n          checkProperties('properties' in node.arguments[0] && node.arguments[0].properties);\n        }\n      },\n\n      MethodDefinition(node) {\n        if (\n          !propsUtil.isPropTypesDeclaration(node)\n          && !isPropTypesPackage(node)\n          && !shouldCheckContextTypes(node)\n          && !shouldCheckChildContextTypes(node)\n        ) {\n          return;\n        }\n\n        const returnStatement = astUtil.findReturnStatement(node);\n\n        if (returnStatement && returnStatement.argument) {\n          checkNode(returnStatement.argument);\n        }\n      },\n\n      ObjectExpression(node) {\n        node.properties.forEach((property) => {\n          if (!('key' in property) || !property.key) {\n            return;\n          }\n\n          if (\n            !propsUtil.isPropTypesDeclaration(property)\n            && !isPropTypesPackage(property)\n            && !shouldCheckContextTypes(property)\n            && !shouldCheckChildContextTypes(property)\n          ) {\n            return;\n          }\n          if (property.value.type === 'ObjectExpression') {\n            checkProperties(property.value.properties);\n          }\n        });\n      },\n\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/forward-ref-uses-ref.js",
    "content": "/**\n * @fileoverview Require all forwardRef components include a ref parameter\n */\n\n'use strict';\n\nconst isParenthesized = require('../util/ast').isParenthesized;\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getMessageData = require('../util/message');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n/**\n * @param {ASTNode} node\n * @returns {boolean} If the node represents the identifier `forwardRef`.\n */\nfunction isForwardRefIdentifier(node) {\n  return node.type === 'Identifier' && node.name === 'forwardRef';\n}\n\n/**\n * @param {ASTNode} node\n * @returns {boolean} If the node represents a function call `forwardRef()` or `React.forwardRef()`.\n */\nfunction isForwardRefCall(node) {\n  return (\n    node.type === 'CallExpression'\n    && (\n      isForwardRefIdentifier(node.callee)\n      || (node.callee.type === 'MemberExpression' && isForwardRefIdentifier(node.callee.property))\n    )\n  );\n}\n\nconst messages = {\n  missingRefParameter: 'forwardRef is used with this component but no ref parameter is set',\n  addRefParameter: 'Add a ref parameter',\n  removeForwardRef: 'Remove forwardRef wrapper',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Require all forwardRef components include a ref parameter',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('forward-ref-uses-ref'),\n    },\n    messages,\n    schema: [],\n    type: 'suggestion',\n    hasSuggestions: true,\n  },\n\n  create(context) {\n    const sourceCode = context.getSourceCode();\n\n    return {\n      'FunctionExpression, ArrowFunctionExpression'(node) {\n        if (!isForwardRefCall(node.parent)) {\n          return;\n        }\n\n        if (node.params.length === 1) {\n          report(context, messages.missingRefParameter, 'missingRefParameter', {\n            node,\n            suggest: [\n              Object.assign(\n                getMessageData('addRefParameter', messages.addRefParameter),\n                {\n                  fix(fixer) {\n                    const param = node.params[0];\n                    // If using shorthand arrow function syntax, add parentheses around the new parameter pair\n                    const shouldAddParentheses = node.type === 'ArrowFunctionExpression' && !isParenthesized(context, param);\n                    return [].concat(\n                      shouldAddParentheses ? fixer.insertTextBefore(param, '(') : [],\n                      fixer.insertTextAfter(param, `, ref${shouldAddParentheses ? ')' : ''}`)\n                    );\n                  },\n                }\n              ),\n              Object.assign(\n                getMessageData('removeForwardRef', messages.removeForwardRef),\n                {\n                  fix(fixer) {\n                    return fixer.replaceText(node.parent, sourceCode.getText(node));\n                  },\n                }\n              ),\n            ],\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/function-component-definition.js",
    "content": "/**\n * @fileoverview Standardize the way function component get defined\n * @author Stefan Wullems\n */\n\n'use strict';\n\nconst arrayIncludes = require('array-includes');\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst reportC = require('../util/report');\nconst getText = require('../util/eslint').getText;\nconst propsUtil = require('../util/props');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction buildFunction(template, parts) {\n  return Object.keys(parts).reduce(\n    (acc, key) => acc.replace(`{${key}}`, () => parts[key] || ''),\n    template\n  );\n}\n\nconst NAMED_FUNCTION_TEMPLATES = {\n  'function-declaration': 'function {name}{typeParams}({params}){returnType} {body}',\n  'arrow-function': '{varType} {name}{typeAnnotation} = {typeParams}({params}){returnType} => {body}',\n  'function-expression': '{varType} {name}{typeAnnotation} = function{typeParams}({params}){returnType} {body}',\n};\n\nconst UNNAMED_FUNCTION_TEMPLATES = {\n  'function-expression': 'function{typeParams}({params}){returnType} {body}',\n  'arrow-function': '{typeParams}({params}){returnType} => {body}',\n};\n\nfunction hasOneUnconstrainedTypeParam(node) {\n  const nodeTypeArguments = propsUtil.getTypeArguments(node);\n\n  return nodeTypeArguments\n    && nodeTypeArguments.params\n    && nodeTypeArguments.params.length === 1\n    && !nodeTypeArguments.params[0].constraint;\n}\n\nfunction hasName(node) {\n  return (\n    node.type === 'FunctionDeclaration'\n    || node.parent.type === 'VariableDeclarator'\n  );\n}\n\nfunction getNodeText(prop, source) {\n  if (!prop) return null;\n  return source.slice(prop.range[0], prop.range[1]);\n}\n\nfunction getName(node) {\n  if (node.type === 'FunctionDeclaration') {\n    return node.id.name;\n  }\n\n  if (\n    node.type === 'ArrowFunctionExpression'\n    || node.type === 'FunctionExpression'\n  ) {\n    return hasName(node) && node.parent.id.name;\n  }\n}\n\nfunction getParams(node, source) {\n  if (node.params.length === 0) return null;\n  return source.slice(\n    node.params[0].range[0],\n    node.params[node.params.length - 1].range[1]\n  );\n}\n\nfunction getBody(node, source) {\n  const range = node.body.range;\n\n  if (node.body.type !== 'BlockStatement') {\n    return ['{', `  return ${source.slice(range[0], range[1])}`, '}'].join('\\n');\n  }\n\n  return source.slice(range[0], range[1]);\n}\n\nfunction getTypeAnnotation(node, source) {\n  if (!hasName(node) || node.type === 'FunctionDeclaration') return;\n\n  if (\n    node.type === 'ArrowFunctionExpression'\n    || node.type === 'FunctionExpression'\n  ) {\n    return getNodeText(node.parent.id.typeAnnotation, source);\n  }\n}\n\nfunction isUnfixableBecauseOfExport(node) {\n  return (\n    node.type === 'FunctionDeclaration'\n    && node.parent\n    && node.parent.type === 'ExportDefaultDeclaration'\n  );\n}\n\nfunction isFunctionExpressionWithName(node) {\n  return node.type === 'FunctionExpression' && node.id && node.id.name;\n}\n\nconst messages = {\n  'function-declaration': 'Function component is not a function declaration',\n  'function-expression': 'Function component is not a function expression',\n  'arrow-function': 'Function component is not an arrow function',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce a specific function type for function components',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('function-component-definition'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          namedComponents: {\n            anyOf: [\n              {\n                enum: [\n                  'function-declaration',\n                  'arrow-function',\n                  'function-expression',\n                ],\n              },\n              {\n                type: 'array',\n                items: {\n                  type: 'string',\n                  enum: [\n                    'function-declaration',\n                    'arrow-function',\n                    'function-expression',\n                  ],\n                },\n              },\n            ],\n          },\n          unnamedComponents: {\n            anyOf: [\n              { enum: ['arrow-function', 'function-expression'] },\n              {\n                type: 'array',\n                items: {\n                  type: 'string',\n                  enum: ['arrow-function', 'function-expression'],\n                },\n              },\n            ],\n          },\n        },\n      },\n    ],\n  },\n\n  create: Components.detect((context, components) => {\n    const configuration = context.options[0] || {};\n    let fileVarType = 'var';\n\n    const namedConfig = [].concat(\n      configuration.namedComponents || 'function-declaration'\n    );\n    const unnamedConfig = [].concat(\n      configuration.unnamedComponents || 'function-expression'\n    );\n\n    function getFixer(node, options) {\n      const source = getText(context);\n\n      const typeAnnotation = getTypeAnnotation(node, source);\n\n      if (options.type === 'function-declaration' && typeAnnotation) {\n        return;\n      }\n      if (options.type === 'arrow-function' && hasOneUnconstrainedTypeParam(node)) {\n        return;\n      }\n      if (isUnfixableBecauseOfExport(node)) return;\n      if (isFunctionExpressionWithName(node)) return;\n      let varType = fileVarType;\n      if (\n        (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression')\n        && node.parent.type === 'VariableDeclarator'\n      ) {\n        varType = node.parent.parent.kind;\n      }\n\n      const nodeTypeArguments = propsUtil.getTypeArguments(node);\n      return (fixer) => fixer.replaceTextRange(\n        options.range,\n        buildFunction(options.template, {\n          typeAnnotation,\n          typeParams: getNodeText(nodeTypeArguments, source),\n          params: getParams(node, source),\n          returnType: getNodeText(node.returnType, source),\n          body: getBody(node, source),\n          name: getName(node),\n          varType,\n        })\n      );\n    }\n\n    function report(node, options) {\n      reportC(context, messages[options.messageId], options.messageId, {\n        node,\n        fix: getFixer(node, options.fixerOptions),\n      });\n    }\n\n    function validate(node, functionType) {\n      if (!components.get(node)) return;\n\n      if (node.parent && node.parent.type === 'Property') return;\n\n      if (hasName(node) && !arrayIncludes(namedConfig, functionType)) {\n        report(node, {\n          messageId: namedConfig[0],\n          fixerOptions: {\n            type: namedConfig[0],\n            template: NAMED_FUNCTION_TEMPLATES[namedConfig[0]],\n            range:\n              node.type === 'FunctionDeclaration'\n                ? node.range\n                : node.parent.parent.range,\n          },\n        });\n      }\n      if (!hasName(node) && !arrayIncludes(unnamedConfig, functionType)) {\n        report(node, {\n          messageId: unnamedConfig[0],\n          fixerOptions: {\n            type: unnamedConfig[0],\n            template: UNNAMED_FUNCTION_TEMPLATES[unnamedConfig[0]],\n            range: node.range,\n          },\n        });\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n    const validatePairs = [];\n    let hasES6OrJsx = false;\n    return {\n      FunctionDeclaration(node) {\n        validatePairs.push([node, 'function-declaration']);\n      },\n      ArrowFunctionExpression(node) {\n        validatePairs.push([node, 'arrow-function']);\n      },\n      FunctionExpression(node) {\n        validatePairs.push([node, 'function-expression']);\n      },\n      VariableDeclaration(node) {\n        hasES6OrJsx = hasES6OrJsx || node.kind === 'const' || node.kind === 'let';\n      },\n      'Program:exit'() {\n        if (hasES6OrJsx) fileVarType = 'const';\n        validatePairs.forEach((pair) => validate(pair[0], pair[1]));\n      },\n      'ImportDeclaration, ExportNamedDeclaration, ExportDefaultDeclaration, ExportAllDeclaration, ExportSpecifier, ExportDefaultSpecifier, JSXElement, TSExportAssignment, TSImportEqualsDeclaration'() {\n        hasES6OrJsx = true;\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/hook-use-state.js",
    "content": "/**\n * @fileoverview Ensure symmetric naming of useState hook value and setter variables\n * @author Duncan Beevers\n */\n\n'use strict';\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getMessageData = require('../util/message');\nconst getText = require('../util/eslint').getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction isNodeDestructuring(node) {\n  return node && (node.type === 'ArrayPattern' || node.type === 'ObjectPattern');\n}\n\nconst messages = {\n  useStateErrorMessage: 'useState call is not destructured into value + setter pair',\n  useStateErrorMessageOrAddOption: 'useState call is not destructured into value + setter pair (you can allow destructuring by enabling \"allowDestructuredState\" option)',\n  suggestPair: 'Destructure useState call into value + setter pair',\n  suggestMemo: 'Replace useState call with useMemo',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Ensure destructuring and symmetric naming of useState hook value and setter variables',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('hook-use-state'),\n    },\n    messages,\n    schema: [{\n      type: 'object',\n      properties: {\n        allowDestructuredState: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n    type: 'suggestion',\n    hasSuggestions: true,\n  },\n\n  create: Components.detect((context, components, util) => {\n    const configuration = context.options[0] || {};\n    const allowDestructuredState = configuration.allowDestructuredState || false;\n\n    return {\n      CallExpression(node) {\n        const isImmediateReturn = node.parent\n          && node.parent.type === 'ReturnStatement';\n\n        if (isImmediateReturn || !util.isReactHookCall(node, ['useState'])) {\n          return;\n        }\n\n        const isDestructuringDeclarator = node.parent\n          && node.parent.type === 'VariableDeclarator'\n          && node.parent.id.type === 'ArrayPattern';\n\n        if (!isDestructuringDeclarator) {\n          report(\n            context,\n            messages.useStateErrorMessage,\n            'useStateErrorMessage',\n            {\n              node,\n              suggest: false,\n            }\n          );\n          return;\n        }\n\n        const variableNodes = node.parent.id.elements;\n        const valueVariable = variableNodes[0];\n        const setterVariable = variableNodes[1];\n        const isOnlyValueDestructuring = isNodeDestructuring(valueVariable) && !isNodeDestructuring(setterVariable);\n\n        if (allowDestructuredState && isOnlyValueDestructuring) {\n          return;\n        }\n\n        const valueVariableName = valueVariable\n          ? valueVariable.name\n          : undefined;\n\n        const setterVariableName = setterVariable\n          ? setterVariable.name\n          : undefined;\n\n        const caseCandidateMatch = valueVariableName ? valueVariableName.match(/(^[a-z]+)(.*)/) : undefined;\n        const upperCaseCandidatePrefix = caseCandidateMatch ? caseCandidateMatch[1] : undefined;\n        const caseCandidateSuffix = caseCandidateMatch ? caseCandidateMatch[2] : undefined;\n        const expectedSetterVariableNames = upperCaseCandidatePrefix ? [\n          `set${upperCaseCandidatePrefix.charAt(0).toUpperCase()}${upperCaseCandidatePrefix.slice(1)}${caseCandidateSuffix}`,\n          `set${upperCaseCandidatePrefix.toUpperCase()}${caseCandidateSuffix}`,\n        ] : [];\n\n        const isSymmetricGetterSetterPair = valueVariable\n          && setterVariable\n          && expectedSetterVariableNames.indexOf(setterVariableName) !== -1\n          && variableNodes.length === 2;\n\n        if (!isSymmetricGetterSetterPair) {\n          const suggestions = [\n            Object.assign(\n              getMessageData('suggestPair', messages.suggestPair),\n              {\n                fix(fixer) {\n                  if (expectedSetterVariableNames.length > 0) {\n                    return fixer.replaceTextRange(\n                      node.parent.id.range,\n                      `[${valueVariableName}, ${expectedSetterVariableNames[0]}]`\n                    );\n                  }\n                },\n              }\n            ),\n          ];\n\n          const defaultReactImports = components.getDefaultReactImports();\n          const defaultReactImportSpecifier = defaultReactImports\n            ? defaultReactImports[0]\n            : undefined;\n\n          const defaultReactImportName = defaultReactImportSpecifier\n            ? defaultReactImportSpecifier.local.name\n            : undefined;\n\n          const namedReactImports = components.getNamedReactImports();\n          const useStateReactImportSpecifier = namedReactImports\n            ? namedReactImports.find((specifier) => specifier.imported.name === 'useState')\n            : undefined;\n\n          const isSingleGetter = valueVariable && variableNodes.length === 1;\n          const isUseStateCalledWithSingleArgument = node.arguments.length === 1;\n          if (isSingleGetter && isUseStateCalledWithSingleArgument) {\n            const useMemoReactImportSpecifier = namedReactImports\n              && namedReactImports.find((specifier) => specifier.imported.name === 'useMemo');\n\n            let useMemoCode;\n            if (useMemoReactImportSpecifier) {\n              useMemoCode = useMemoReactImportSpecifier.local.name;\n            } else if (defaultReactImportName) {\n              useMemoCode = `${defaultReactImportName}.useMemo`;\n            } else {\n              useMemoCode = 'useMemo';\n            }\n\n            suggestions.unshift(Object.assign(\n              getMessageData('suggestMemo', messages.suggestMemo),\n              {\n                fix: (fixer) => [\n                  // Add useMemo import, if necessary\n                  useStateReactImportSpecifier\n                    && (!useMemoReactImportSpecifier || defaultReactImportName)\n                    && fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'),\n                  // Convert single-value destructure to simple assignment\n                  fixer.replaceTextRange(node.parent.id.range, valueVariableName),\n                  // Convert useState call to useMemo + arrow function + dependency array\n                  fixer.replaceTextRange(\n                    node.range,\n                    `${useMemoCode}(() => ${getText(context, node.arguments[0])}, [])`\n                  ),\n                ].filter(Boolean),\n              }\n            ));\n          }\n\n          if (isOnlyValueDestructuring) {\n            report(\n              context,\n              messages.useStateErrorMessageOrAddOption,\n              'useStateErrorMessageOrAddOption',\n              {\n                node: node.parent.id,\n                suggest: false,\n              }\n            );\n            return;\n          }\n\n          report(\n            context,\n            messages.useStateErrorMessage,\n            'useStateErrorMessage',\n            {\n              node: node.parent.id,\n              suggest: suggestions,\n            }\n          );\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/iframe-missing-sandbox.js",
    "content": "/**\n * @fileoverview TBD\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\nconst messages = {\n  attributeMissing: 'An iframe element is missing a sandbox attribute',\n  invalidValue: 'An iframe element defines a sandbox attribute with invalid value \"{{ value }}\"',\n  invalidCombination: 'An iframe element defines a sandbox attribute with both allow-scripts and allow-same-origin which is invalid',\n};\n\nconst ALLOWED_VALUES = [\n  // From https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-sandbox\n  '',\n  'allow-downloads-without-user-activation',\n  'allow-downloads',\n  'allow-forms',\n  'allow-modals',\n  'allow-orientation-lock',\n  'allow-pointer-lock',\n  'allow-popups',\n  'allow-popups-to-escape-sandbox',\n  'allow-presentation',\n  'allow-same-origin',\n  'allow-scripts',\n  'allow-storage-access-by-user-activation',\n  'allow-top-navigation',\n  'allow-top-navigation-by-user-activation',\n];\n\nfunction validateSandboxAttribute(context, node, attribute) {\n  if (typeof attribute !== 'string') {\n    // Only string literals are supported for now\n    return;\n  }\n  const values = attribute.split(' ');\n  let allowScripts = false;\n  let allowSameOrigin = false;\n  values.forEach((attributeValue) => {\n    const trimmedAttributeValue = attributeValue.trim();\n    if (ALLOWED_VALUES.indexOf(trimmedAttributeValue) === -1) {\n      report(context, messages.invalidValue, 'invalidValue', {\n        node,\n        data: {\n          value: trimmedAttributeValue,\n        },\n      });\n    }\n    if (trimmedAttributeValue === 'allow-scripts') {\n      allowScripts = true;\n    }\n    if (trimmedAttributeValue === 'allow-same-origin') {\n      allowSameOrigin = true;\n    }\n  });\n  if (allowScripts && allowSameOrigin) {\n    report(context, messages.invalidCombination, 'invalidCombination', {\n      node,\n    });\n  }\n}\n\nfunction checkAttributes(context, node) {\n  let sandboxAttributeFound = false;\n  node.attributes.forEach((attribute) => {\n    if (attribute.type === 'JSXAttribute'\n        && attribute.name\n        && attribute.name.type === 'JSXIdentifier'\n        && attribute.name.name === 'sandbox'\n    ) {\n      sandboxAttributeFound = true;\n      if (\n        attribute.value\n        && attribute.value.type === 'Literal'\n        && attribute.value.value\n      ) {\n        validateSandboxAttribute(context, node, attribute.value.value);\n      }\n    }\n  });\n  if (!sandboxAttributeFound) {\n    report(context, messages.attributeMissing, 'attributeMissing', {\n      node,\n    });\n  }\n}\n\nfunction checkProps(context, node) {\n  let sandboxAttributeFound = false;\n  if (node.arguments.length > 1) {\n    const props = node.arguments[1];\n    const sandboxProp = props.properties && props.properties.find((x) => x.type === 'Property' && x.key.name === 'sandbox');\n    if (sandboxProp) {\n      sandboxAttributeFound = true;\n      if (sandboxProp.value && sandboxProp.value.type === 'Literal' && sandboxProp.value.value) {\n        validateSandboxAttribute(context, node, sandboxProp.value.value);\n      }\n    }\n  }\n  if (!sandboxAttributeFound) {\n    report(context, messages.attributeMissing, 'attributeMissing', {\n      node,\n    });\n  }\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce sandbox attribute on iframe elements',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('iframe-missing-sandbox'),\n    },\n\n    schema: [],\n\n    messages,\n  },\n\n  create(context) {\n    return {\n      'JSXOpeningElement[name.name=\"iframe\"]'(node) {\n        checkAttributes(context, node);\n      },\n\n      CallExpression(node) {\n        if (isCreateElement(context, node) && node.arguments && node.arguments.length > 0) {\n          const tag = node.arguments[0];\n          if (tag.type === 'Literal' && tag.value === 'iframe') {\n            checkProps(context, node);\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/index.js",
    "content": "'use strict';\n\n/* eslint global-require: 0 */\n\n/** @satisfies {Record<string, import('eslint').Rule.RuleModule>} */\nconst rules = {\n  'async-server-action': require('./async-server-action'),\n  'boolean-prop-naming': require('./boolean-prop-naming'),\n  'button-has-type': require('./button-has-type'),\n  'checked-requires-onchange-or-readonly': require('./checked-requires-onchange-or-readonly'),\n  'default-props-match-prop-types': require('./default-props-match-prop-types'),\n  'destructuring-assignment': require('./destructuring-assignment'),\n  'display-name': require('./display-name'),\n  'forbid-component-props': require('./forbid-component-props'),\n  'forbid-dom-props': require('./forbid-dom-props'),\n  'forbid-elements': require('./forbid-elements'),\n  'forbid-foreign-prop-types': require('./forbid-foreign-prop-types'),\n  'forbid-prop-types': require('./forbid-prop-types'),\n  'forward-ref-uses-ref': require('./forward-ref-uses-ref'),\n  'function-component-definition': require('./function-component-definition'),\n  'hook-use-state': require('./hook-use-state'),\n  'iframe-missing-sandbox': require('./iframe-missing-sandbox'),\n  'jsx-boolean-value': require('./jsx-boolean-value'),\n  'jsx-child-element-spacing': require('./jsx-child-element-spacing'),\n  'jsx-closing-bracket-location': require('./jsx-closing-bracket-location'),\n  'jsx-closing-tag-location': require('./jsx-closing-tag-location'),\n  'jsx-curly-spacing': require('./jsx-curly-spacing'),\n  'jsx-curly-newline': require('./jsx-curly-newline'),\n  'jsx-equals-spacing': require('./jsx-equals-spacing'),\n  'jsx-filename-extension': require('./jsx-filename-extension'),\n  'jsx-first-prop-new-line': require('./jsx-first-prop-new-line'),\n  'jsx-handler-names': require('./jsx-handler-names'),\n  'jsx-indent': require('./jsx-indent'),\n  'jsx-indent-props': require('./jsx-indent-props'),\n  'jsx-key': require('./jsx-key'),\n  'jsx-max-depth': require('./jsx-max-depth'),\n  'jsx-max-props-per-line': require('./jsx-max-props-per-line'),\n  'jsx-newline': require('./jsx-newline'),\n  'jsx-no-bind': require('./jsx-no-bind'),\n  'jsx-no-comment-textnodes': require('./jsx-no-comment-textnodes'),\n  'jsx-no-constructed-context-values': require('./jsx-no-constructed-context-values'),\n  'jsx-no-duplicate-props': require('./jsx-no-duplicate-props'),\n  'jsx-no-leaked-render': require('./jsx-no-leaked-render'),\n  'jsx-no-literals': require('./jsx-no-literals'),\n  'jsx-no-script-url': require('./jsx-no-script-url'),\n  'jsx-no-target-blank': require('./jsx-no-target-blank'),\n  'jsx-no-useless-fragment': require('./jsx-no-useless-fragment'),\n  'jsx-one-expression-per-line': require('./jsx-one-expression-per-line'),\n  'jsx-no-undef': require('./jsx-no-undef'),\n  'jsx-curly-brace-presence': require('./jsx-curly-brace-presence'),\n  'jsx-pascal-case': require('./jsx-pascal-case'),\n  'jsx-fragments': require('./jsx-fragments'),\n  'jsx-props-no-multi-spaces': require('./jsx-props-no-multi-spaces'),\n  'jsx-props-no-spreading': require('./jsx-props-no-spreading'),\n  'jsx-props-no-spread-multi': require('./jsx-props-no-spread-multi'),\n  'jsx-sort-default-props': require('./jsx-sort-default-props'),\n  'jsx-sort-props': require('./jsx-sort-props'),\n  'jsx-space-before-closing': require('./jsx-space-before-closing'),\n  'jsx-tag-spacing': require('./jsx-tag-spacing'),\n  'jsx-uses-react': require('./jsx-uses-react'),\n  'jsx-uses-vars': require('./jsx-uses-vars'),\n  'jsx-wrap-multilines': require('./jsx-wrap-multilines'),\n  'no-invalid-html-attribute': require('./no-invalid-html-attribute'),\n  'no-access-state-in-setstate': require('./no-access-state-in-setstate'),\n  'no-adjacent-inline-elements': require('./no-adjacent-inline-elements'),\n  'no-array-index-key': require('./no-array-index-key'),\n  'no-arrow-function-lifecycle': require('./no-arrow-function-lifecycle'),\n  'no-children-prop': require('./no-children-prop'),\n  'no-danger': require('./no-danger'),\n  'no-danger-with-children': require('./no-danger-with-children'),\n  'no-deprecated': require('./no-deprecated'),\n  'no-did-mount-set-state': require('./no-did-mount-set-state'),\n  'no-did-update-set-state': require('./no-did-update-set-state'),\n  'no-direct-mutation-state': require('./no-direct-mutation-state'),\n  'no-find-dom-node': require('./no-find-dom-node'),\n  'no-is-mounted': require('./no-is-mounted'),\n  'no-multi-comp': require('./no-multi-comp'),\n  'no-namespace': require('./no-namespace'),\n  'no-set-state': require('./no-set-state'),\n  'no-string-refs': require('./no-string-refs'),\n  'no-redundant-should-component-update': require('./no-redundant-should-component-update'),\n  'no-render-return-value': require('./no-render-return-value'),\n  'no-this-in-sfc': require('./no-this-in-sfc'),\n  'no-typos': require('./no-typos'),\n  'no-unescaped-entities': require('./no-unescaped-entities'),\n  'no-unknown-property': require('./no-unknown-property'),\n  'no-unsafe': require('./no-unsafe'),\n  'no-unstable-nested-components': require('./no-unstable-nested-components'),\n  'no-unused-class-component-methods': require('./no-unused-class-component-methods'),\n  'no-unused-prop-types': require('./no-unused-prop-types'),\n  'no-unused-state': require('./no-unused-state'),\n  'no-object-type-as-default-prop': require('./no-object-type-as-default-prop'),\n  'no-will-update-set-state': require('./no-will-update-set-state'),\n  'prefer-es6-class': require('./prefer-es6-class'),\n  'prefer-exact-props': require('./prefer-exact-props'),\n  'prefer-read-only-props': require('./prefer-read-only-props'),\n  'prefer-stateless-function': require('./prefer-stateless-function'),\n  'prop-types': require('./prop-types'),\n  'react-in-jsx-scope': require('./react-in-jsx-scope'),\n  'require-default-props': require('./require-default-props'),\n  'require-optimization': require('./require-optimization'),\n  'require-render-return': require('./require-render-return'),\n  'self-closing-comp': require('./self-closing-comp'),\n  'sort-comp': require('./sort-comp'),\n  'sort-default-props': require('./sort-default-props'),\n  'sort-prop-types': require('./sort-prop-types'),\n  'state-in-constructor': require('./state-in-constructor'),\n  'static-property-placement': require('./static-property-placement'),\n  'style-prop-object': require('./style-prop-object'),\n  'void-dom-elements-no-children': require('./void-dom-elements-no-children'),\n};\n\nmodule.exports = rules;\n"
  },
  {
    "path": "lib/rules/jsx-boolean-value.js",
    "content": "/**\n * @fileoverview Enforce boolean attributes notation in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst exceptionsSchema = {\n  type: 'array',\n  items: { type: 'string', minLength: 1 },\n  uniqueItems: true,\n};\n\nconst ALWAYS = 'always';\nconst NEVER = 'never';\n\n/**\n * @param {string} configuration\n * @param {Set<string>} exceptions\n * @param {string} propName\n * @returns {boolean} propName\n */\nfunction isAlways(configuration, exceptions, propName) {\n  const isException = exceptions.has(propName);\n  if (configuration === ALWAYS) {\n    return !isException;\n  }\n  return isException;\n}\n/**\n * @param {string} configuration\n * @param {Set<string>} exceptions\n * @param {string} propName\n * @returns {boolean} propName\n */\nfunction isNever(configuration, exceptions, propName) {\n  const isException = exceptions.has(propName);\n  if (configuration === NEVER) {\n    return !isException;\n  }\n  return isException;\n}\n\nconst messages = {\n  omitBoolean: 'Value must be omitted for boolean attribute `{{propName}}`',\n  setBoolean: 'Value must be set for boolean attribute `{{propName}}`',\n  omitPropAndBoolean: 'Value must be omitted for `false` attribute: `{{propName}}`',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce boolean attributes notation in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-boolean-value'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: {\n      anyOf: [{\n        type: 'array',\n        items: [{ enum: [ALWAYS, NEVER] }],\n        additionalItems: false,\n      }, {\n        type: 'array',\n        items: [{\n          enum: [ALWAYS],\n        }, {\n          type: 'object',\n          additionalProperties: false,\n          properties: {\n            [NEVER]: exceptionsSchema,\n            assumeUndefinedIsFalse: {\n              type: 'boolean',\n            },\n          },\n        }],\n        additionalItems: false,\n      }, {\n        type: 'array',\n        items: [{\n          enum: [NEVER],\n        }, {\n          type: 'object',\n          additionalProperties: false,\n          properties: {\n            [ALWAYS]: exceptionsSchema,\n            assumeUndefinedIsFalse: {\n              type: 'boolean',\n            },\n          },\n        }],\n        additionalItems: false,\n      }],\n    },\n  },\n\n  create(context) {\n    const configuration = context.options[0] || NEVER;\n    const configObject = context.options[1] || {};\n    const exceptions = new Set((configuration === ALWAYS ? configObject[NEVER] : configObject[ALWAYS]) || []);\n\n    return {\n      JSXAttribute(node) {\n        const propName = node.name && node.name.name;\n        const value = node.value;\n\n        if (\n          isAlways(configuration, exceptions, propName)\n          && value === null\n        ) {\n          const messageId = 'setBoolean';\n          const data = { propName };\n          report(context, messages[messageId], messageId, {\n            node,\n            data,\n            fix(fixer) {\n              return fixer.insertTextAfter(node, '={true}');\n            },\n          });\n        }\n        if (\n          isNever(configuration, exceptions, propName)\n          && value\n          && value.type === 'JSXExpressionContainer'\n          && value.expression.value === true\n        ) {\n          const messageId = 'omitBoolean';\n          const data = { propName };\n          report(context, messages[messageId], messageId, {\n            node,\n            data,\n            fix(fixer) {\n              return fixer.removeRange([node.name.range[1], value.range[1]]);\n            },\n          });\n        }\n        if (\n          isNever(configuration, exceptions, propName)\n          && configObject.assumeUndefinedIsFalse\n          && value\n          && value.type === 'JSXExpressionContainer'\n          && value.expression.value === false\n        ) {\n          const messageId = 'omitPropAndBoolean';\n          const data = { propName };\n          report(context, messages[messageId], messageId, {\n            node,\n            data,\n            fix(fixer) {\n              return fixer.removeRange([node.name.range[0], value.range[1]]);\n            },\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-child-element-spacing.js",
    "content": "'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// This list is taken from https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements\n\n// Note: 'br' is not included because whitespace around br tags is inconsequential to the rendered output\nconst INLINE_ELEMENTS = new Set([\n  'a',\n  'abbr',\n  'acronym',\n  'b',\n  'bdo',\n  'big',\n  'button',\n  'cite',\n  'code',\n  'dfn',\n  'em',\n  'i',\n  'img',\n  'input',\n  'kbd',\n  'label',\n  'map',\n  'object',\n  'q',\n  'samp',\n  'script',\n  'select',\n  'small',\n  'span',\n  'strong',\n  'sub',\n  'sup',\n  'textarea',\n  'tt',\n  'var',\n]);\n\nconst messages = {\n  spacingAfterPrev: 'Ambiguous spacing after previous element {{element}}',\n  spacingBeforeNext: 'Ambiguous spacing before next element {{element}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce or disallow spaces inside of curly braces in JSX attributes and expressions',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-child-element-spacing'),\n    },\n    fixable: null,\n\n    messages,\n\n    schema: [],\n  },\n  create(context) {\n    const TEXT_FOLLOWING_ELEMENT_PATTERN = /^\\s*\\n\\s*\\S/;\n    const TEXT_PRECEDING_ELEMENT_PATTERN = /\\S\\s*\\n\\s*$/;\n\n    const elementName = (node) => (\n      node.openingElement\n      && node.openingElement.name\n      && node.openingElement.name.type === 'JSXIdentifier'\n      && node.openingElement.name.name\n    );\n\n    const isInlineElement = (node) => (\n      node.type === 'JSXElement'\n      && INLINE_ELEMENTS.has(elementName(node))\n    );\n\n    const handleJSX = (node) => {\n      let lastChild = null;\n      let child = null;\n      (node.children.concat([null])).forEach((nextChild) => {\n        if (\n          (lastChild || nextChild)\n          && (!lastChild || isInlineElement(lastChild))\n          && (child && (child.type === 'Literal' || child.type === 'JSXText'))\n          && (!nextChild || isInlineElement(nextChild))\n          && true\n        ) {\n          if (lastChild && child.value.match(TEXT_FOLLOWING_ELEMENT_PATTERN)) {\n            report(context, messages.spacingAfterPrev, 'spacingAfterPrev', {\n              node: lastChild,\n              loc: lastChild.loc.end,\n              data: {\n                element: elementName(lastChild),\n              },\n            });\n          } else if (nextChild && child.value.match(TEXT_PRECEDING_ELEMENT_PATTERN)) {\n            report(context, messages.spacingBeforeNext, 'spacingBeforeNext', {\n              node: nextChild,\n              loc: nextChild.loc.start,\n              data: {\n                element: elementName(nextChild),\n              },\n            });\n          }\n        }\n        lastChild = child;\n        child = nextChild;\n      });\n    };\n\n    return {\n      JSXElement: handleJSX,\n      JSXFragment: handleJSX,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-closing-bracket-location.js",
    "content": "/**\n * @fileoverview Validate closing bracket location in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst repeat = require('string.prototype.repeat');\n\nconst docsUrl = require('../util/docsUrl');\nconst getSourceCode = require('../util/eslint').getSourceCode;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  bracketLocation: 'The closing bracket must be {{location}}{{details}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce closing bracket location in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-closing-bracket-location'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      anyOf: [\n        {\n          enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned'],\n        },\n        {\n          type: 'object',\n          properties: {\n            location: {\n              enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned'],\n            },\n          },\n          additionalProperties: false,\n        }, {\n          type: 'object',\n          properties: {\n            nonEmpty: {\n              enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned', false],\n            },\n            selfClosing: {\n              enum: ['after-props', 'props-aligned', 'tag-aligned', 'line-aligned', false],\n            },\n          },\n          additionalProperties: false,\n        },\n      ],\n    }],\n  },\n\n  create(context) {\n    const MESSAGE_LOCATION = {\n      'after-props': 'placed after the last prop',\n      'after-tag': 'placed after the opening tag',\n      'props-aligned': 'aligned with the last prop',\n      'tag-aligned': 'aligned with the opening tag',\n      'line-aligned': 'aligned with the line containing the opening tag',\n    };\n    const DEFAULT_LOCATION = 'tag-aligned';\n\n    const config = context.options[0];\n    const options = {\n      nonEmpty: DEFAULT_LOCATION,\n      selfClosing: DEFAULT_LOCATION,\n    };\n\n    if (typeof config === 'string') {\n      // simple shorthand [1, 'something']\n      options.nonEmpty = config;\n      options.selfClosing = config;\n    } else if (typeof config === 'object') {\n      // [1, {location: 'something'}] (back-compat)\n      if (has(config, 'location')) {\n        options.nonEmpty = config.location;\n        options.selfClosing = config.location;\n      }\n      // [1, {nonEmpty: 'something'}]\n      if (has(config, 'nonEmpty')) {\n        options.nonEmpty = config.nonEmpty;\n      }\n      // [1, {selfClosing: 'something'}]\n      if (has(config, 'selfClosing')) {\n        options.selfClosing = config.selfClosing;\n      }\n    }\n\n    /**\n     * Get expected location for the closing bracket\n     * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop\n     * @return {string} Expected location for the closing bracket\n     */\n    function getExpectedLocation(tokens) {\n      let location;\n      // Is always after the opening tag if there is no props\n      if (typeof tokens.lastProp === 'undefined') {\n        location = 'after-tag';\n      // Is always after the last prop if this one is on the same line as the opening bracket\n      } else if (tokens.opening.line === tokens.lastProp.lastLine) {\n        location = 'after-props';\n      // Else use configuration dependent on selfClosing property\n      } else {\n        location = tokens.selfClosing ? options.selfClosing : options.nonEmpty;\n      }\n      return location;\n    }\n\n    /**\n     * Get the correct 0-indexed column for the closing bracket, given the\n     * expected location.\n     * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop\n     * @param {string} expectedLocation Expected location for the closing bracket\n     * @return {?Number} The correct column for the closing bracket, or null\n     */\n    function getCorrectColumn(tokens, expectedLocation) {\n      switch (expectedLocation) {\n        case 'props-aligned':\n          return tokens.lastProp.column;\n        case 'tag-aligned':\n          return tokens.opening.column;\n        case 'line-aligned':\n          return tokens.openingStartOfLine.column;\n        default:\n          return null;\n      }\n    }\n\n    /**\n     * Check if the closing bracket is correctly located\n     * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop\n     * @param {string} expectedLocation Expected location for the closing bracket\n     * @return {boolean} True if the closing bracket is correctly located, false if not\n     */\n    function hasCorrectLocation(tokens, expectedLocation) {\n      switch (expectedLocation) {\n        case 'after-tag':\n          return tokens.tag.line === tokens.closing.line;\n        case 'after-props':\n          return tokens.lastProp.lastLine === tokens.closing.line;\n        case 'props-aligned':\n        case 'tag-aligned':\n        case 'line-aligned': {\n          const correctColumn = getCorrectColumn(tokens, expectedLocation);\n          return correctColumn === tokens.closing.column;\n        }\n        default:\n          return true;\n      }\n    }\n\n    /**\n     * Get the characters used for indentation on the line to be matched\n     * @param {Object} tokens Locations of the opening bracket, closing bracket and last prop\n     * @param {string} expectedLocation Expected location for the closing bracket\n     * @param {number} [correctColumn] Expected column for the closing bracket. Default to 0\n     * @return {string} The characters used for indentation\n     */\n    function getIndentation(tokens, expectedLocation, correctColumn) {\n      const newColumn = correctColumn || 0;\n      let indentation;\n      let spaces = '';\n      switch (expectedLocation) {\n        case 'props-aligned':\n          indentation = /^\\s*/.exec(getSourceCode(context).lines[tokens.lastProp.firstLine - 1])[0];\n          break;\n        case 'tag-aligned':\n        case 'line-aligned':\n          indentation = /^\\s*/.exec(getSourceCode(context).lines[tokens.opening.line - 1])[0];\n          break;\n        default:\n          indentation = '';\n      }\n      if (indentation.length + 1 < newColumn) {\n        // Non-whitespace characters were included in the column offset\n        spaces = repeat(' ', +correctColumn - indentation.length);\n      }\n      return indentation + spaces;\n    }\n\n    /**\n     * Get the locations of the opening bracket, closing bracket, last prop, and\n     * start of opening line.\n     * @param {ASTNode} node The node to check\n     * @return {Object} Locations of the opening bracket, closing bracket, last\n     * prop and start of opening line.\n     */\n    function getTokensLocations(node) {\n      const sourceCode = getSourceCode(context);\n      const opening = sourceCode.getFirstToken(node).loc.start;\n      const closing = sourceCode.getLastTokens(node, node.selfClosing ? 2 : 1)[0].loc.start;\n      const tag = sourceCode.getFirstToken(node.name).loc.start;\n      let lastProp;\n      if (node.attributes.length) {\n        lastProp = node.attributes[node.attributes.length - 1];\n        lastProp = {\n          column: sourceCode.getFirstToken(lastProp).loc.start.column,\n          firstLine: sourceCode.getFirstToken(lastProp).loc.start.line,\n          lastLine: sourceCode.getLastToken(lastProp).loc.end.line,\n        };\n      }\n      const openingLine = sourceCode.lines[opening.line - 1];\n      const closingLine = sourceCode.lines[closing.line - 1];\n      const isTab = {\n        openTab: /^\\t/.test(openingLine),\n        closeTab: /^\\t/.test(closingLine),\n      };\n      const openingStartOfLine = {\n        column: /^\\s*/.exec(openingLine)[0].length,\n        line: opening.line,\n      };\n      return {\n        isTab,\n        tag,\n        opening,\n        closing,\n        lastProp,\n        selfClosing: node.selfClosing,\n        openingStartOfLine,\n      };\n    }\n\n    /**\n     * Get an unique ID for a given JSXOpeningElement\n     *\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {string} Unique ID (based on its range)\n     */\n    function getOpeningElementId(node) {\n      return node.range.join(':');\n    }\n\n    const lastAttributeNode = {};\n\n    return {\n      JSXAttribute(node) {\n        lastAttributeNode[getOpeningElementId(node.parent)] = node;\n      },\n\n      JSXSpreadAttribute(node) {\n        lastAttributeNode[getOpeningElementId(node.parent)] = node;\n      },\n\n      'JSXOpeningElement:exit'(node) {\n        const attributeNode = lastAttributeNode[getOpeningElementId(node)];\n        const cachedLastAttributeEndPos = attributeNode ? attributeNode.range[1] : null;\n\n        let expectedNextLine;\n        const tokens = getTokensLocations(node);\n        const expectedLocation = getExpectedLocation(tokens);\n        let usingSameIndentation = true;\n\n        if (expectedLocation === 'tag-aligned') {\n          usingSameIndentation = tokens.isTab.openTab === tokens.isTab.closeTab;\n        }\n\n        if (hasCorrectLocation(tokens, expectedLocation) && usingSameIndentation) {\n          return;\n        }\n\n        const data = {\n          location: MESSAGE_LOCATION[expectedLocation],\n          details: '',\n        };\n        const correctColumn = getCorrectColumn(tokens, expectedLocation);\n\n        if (correctColumn !== null) {\n          expectedNextLine = tokens.lastProp\n            && (tokens.lastProp.lastLine === tokens.closing.line);\n          data.details = ` (expected column ${correctColumn + 1}${expectedNextLine ? ' on the next line)' : ')'}`;\n        }\n\n        report(context, messages.bracketLocation, 'bracketLocation', {\n          node,\n          loc: tokens.closing,\n          data,\n          fix(fixer) {\n            const closingTag = tokens.selfClosing ? '/>' : '>';\n            switch (expectedLocation) {\n              case 'after-tag':\n                if (cachedLastAttributeEndPos) {\n                  return fixer.replaceTextRange([cachedLastAttributeEndPos, node.range[1]],\n                    (expectedNextLine ? '\\n' : '') + closingTag);\n                }\n                return fixer.replaceTextRange([node.name.range[1], node.range[1]],\n                  (expectedNextLine ? '\\n' : ' ') + closingTag);\n              case 'after-props':\n                return fixer.replaceTextRange([cachedLastAttributeEndPos, node.range[1]],\n                  (expectedNextLine ? '\\n' : '') + closingTag);\n              case 'props-aligned':\n              case 'tag-aligned':\n              case 'line-aligned':\n                return fixer.replaceTextRange([cachedLastAttributeEndPos, node.range[1]],\n                  `\\n${getIndentation(tokens, expectedLocation, correctColumn)}${closingTag}`);\n              default:\n                return true;\n            }\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-closing-tag-location.js",
    "content": "/**\n * @fileoverview Validate closing tag location in JSX\n * @author Ross Solomon\n */\n\n'use strict';\n\nconst repeat = require('string.prototype.repeat');\nconst has = require('hasown');\n\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst getSourceCode = require('../util/eslint').getSourceCode;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  onOwnLine: 'Closing tag of a multiline JSX expression must be on its own line.',\n  matchIndent: 'Expected closing tag to match indentation of opening.',\n  alignWithOpening: 'Expected closing tag to be aligned with the line containing the opening tag',\n};\n\nconst defaultOption = 'tag-aligned';\n\nconst optionMessageMap = {\n  'tag-aligned': 'matchIndent',\n  'line-aligned': 'alignWithOpening',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce closing tag location for multiline JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-closing-tag-location'),\n    },\n    fixable: 'whitespace',\n    messages,\n    schema: [{\n      anyOf: [\n        {\n          enum: ['tag-aligned', 'line-aligned'],\n        },\n        {\n          type: 'object',\n          properties: {\n            location: {\n              enum: ['tag-aligned', 'line-aligned'],\n            },\n          },\n          additionalProperties: false,\n        },\n      ],\n    }],\n  },\n\n  create(context) {\n    const config = context.options[0];\n    let option = defaultOption;\n\n    if (typeof config === 'string') {\n      option = config;\n    } else if (typeof config === 'object') {\n      if (has(config, 'location')) {\n        option = config.location;\n      }\n    }\n\n    function getIndentation(openingStartOfLine, opening) {\n      if (option === 'line-aligned') return openingStartOfLine.column;\n      if (option === 'tag-aligned') return opening.loc.start.column;\n    }\n\n    function handleClosingElement(node) {\n      if (!node.parent) {\n        return;\n      }\n      const sourceCode = getSourceCode(context);\n\n      const opening = node.parent.openingElement || node.parent.openingFragment;\n      const openingLoc = sourceCode.getFirstToken(opening).loc.start;\n      const openingLine = sourceCode.lines[openingLoc.line - 1];\n\n      const openingStartOfLine = {\n        column: /^\\s*/.exec(openingLine)[0].length,\n        line: openingLoc.line,\n      };\n\n      if (opening.loc.start.line === node.loc.start.line) {\n        return;\n      }\n\n      if (\n        opening.loc.start.column === node.loc.start.column\n        && option === 'tag-aligned'\n      ) {\n        return;\n      }\n\n      if (\n        openingStartOfLine.column === node.loc.start.column\n        && option === 'line-aligned'\n      ) {\n        return;\n      }\n\n      const messageId = astUtil.isNodeFirstInLine(context, node)\n        ? optionMessageMap[option]\n        : 'onOwnLine';\n\n      report(context, messages[messageId], messageId, {\n        node,\n        loc: node.loc,\n        fix(fixer) {\n          const indent = repeat(\n            ' ',\n            getIndentation(openingStartOfLine, opening)\n          );\n\n          if (astUtil.isNodeFirstInLine(context, node)) {\n            return fixer.replaceTextRange(\n              [node.range[0] - node.loc.start.column, node.range[0]],\n              indent\n            );\n          }\n\n          return fixer.insertTextBefore(node, `\\n${indent}`);\n        },\n      });\n    }\n\n    return {\n      JSXClosingElement: handleClosingElement,\n      JSXClosingFragment: handleClosingElement,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-curly-brace-presence.js",
    "content": "/**\n * @fileoverview Enforce curly braces or disallow unnecessary curly brace in JSX\n * @author Jacky Ho\n * @author Simon Lydell\n */\n\n'use strict';\n\nconst arrayIncludes = require('array-includes');\n\nconst docsUrl = require('../util/docsUrl');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst OPTION_ALWAYS = 'always';\nconst OPTION_NEVER = 'never';\nconst OPTION_IGNORE = 'ignore';\n\nconst OPTION_VALUES = [\n  OPTION_ALWAYS,\n  OPTION_NEVER,\n  OPTION_IGNORE,\n];\nconst DEFAULT_CONFIG = { props: OPTION_NEVER, children: OPTION_NEVER, propElementValues: OPTION_IGNORE };\n\nconst HTML_ENTITY_REGEX = () => /&[A-Za-z\\d#]+;/g;\n\nfunction containsLineTerminators(rawStringValue) {\n  return /[\\n\\r\\u2028\\u2029]/.test(rawStringValue);\n}\n\nfunction containsBackslash(rawStringValue) {\n  return arrayIncludes(rawStringValue, '\\\\');\n}\n\nfunction containsHTMLEntity(rawStringValue) {\n  return HTML_ENTITY_REGEX().test(rawStringValue);\n}\n\nfunction containsOnlyHtmlEntities(rawStringValue) {\n  return rawStringValue.replace(HTML_ENTITY_REGEX(), '').trim() === '';\n}\n\nfunction containsDisallowedJSXTextChars(rawStringValue) {\n  return /[{<>}]/.test(rawStringValue);\n}\n\nfunction containsQuoteCharacters(value) {\n  return /['\"]/.test(value);\n}\n\nfunction containsMultilineComment(value) {\n  return /\\/\\*/.test(value);\n}\n\nfunction escapeDoubleQuotes(rawStringValue) {\n  return rawStringValue.replace(/\\\\\"/g, '\"').replace(/\"/g, '\\\\\"');\n}\n\nfunction escapeBackslashes(rawStringValue) {\n  return rawStringValue.replace(/\\\\/g, '\\\\\\\\');\n}\n\nfunction needToEscapeCharacterForJSX(raw, node) {\n  return (\n    containsBackslash(raw)\n    || containsHTMLEntity(raw)\n    || (node.parent.type !== 'JSXAttribute' && containsDisallowedJSXTextChars(raw))\n  );\n}\n\nfunction containsWhitespaceExpression(child) {\n  if (child.type === 'JSXExpressionContainer') {\n    const value = child.expression.value;\n    return value ? jsxUtil.isWhiteSpaces(value) : false;\n  }\n  return false;\n}\n\nfunction isLineBreak(text) {\n  return containsLineTerminators(text) && text.trim() === '';\n}\n\nfunction wrapNonHTMLEntities(text) {\n  const HTML_ENTITY = '<HTML_ENTITY>';\n  const withCurlyBraces = text.split(HTML_ENTITY_REGEX()).map((word) => (\n    word === '' ? '' : `{${JSON.stringify(word)}}`\n  )).join(HTML_ENTITY);\n\n  const htmlEntities = text.match(HTML_ENTITY_REGEX());\n  return htmlEntities.reduce((acc, htmlEntity) => (\n    acc.replace(HTML_ENTITY, htmlEntity)\n  ), withCurlyBraces);\n}\n\nfunction wrapWithCurlyBraces(rawText) {\n  if (!containsLineTerminators(rawText)) {\n    return `{${JSON.stringify(rawText)}}`;\n  }\n\n  return rawText.split('\\n').map((line) => {\n    if (line.trim() === '') {\n      return line;\n    }\n    const firstCharIndex = line.search(/[^\\s]/);\n    const leftWhitespace = line.slice(0, firstCharIndex);\n    const text = line.slice(firstCharIndex);\n\n    if (containsHTMLEntity(line)) {\n      return `${leftWhitespace}${wrapNonHTMLEntities(text)}`;\n    }\n    return `${leftWhitespace}{${JSON.stringify(text)}}`;\n  }).join('\\n');\n}\n\nfunction isWhiteSpaceLiteral(node) {\n  return node.type && node.type === 'Literal' && node.value && jsxUtil.isWhiteSpaces(node.value);\n}\n\nfunction isStringWithTrailingWhiteSpaces(value) {\n  return /^\\s|\\s$/.test(value);\n}\n\nfunction isLiteralWithTrailingWhiteSpaces(node) {\n  return node.type && node.type === 'Literal' && node.value && isStringWithTrailingWhiteSpaces(node.value);\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  unnecessaryCurly: 'Curly braces are unnecessary here.',\n  missingCurly: 'Need to wrap this literal in a JSX expression.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow unnecessary JSX expressions when literals alone are sufficient or enforce JSX expressions on literals in JSX children or attributes',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-curly-brace-presence'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [\n      {\n        anyOf: [\n          {\n            type: 'object',\n            properties: {\n              props: { enum: OPTION_VALUES },\n              children: { enum: OPTION_VALUES },\n              propElementValues: { enum: OPTION_VALUES },\n            },\n            additionalProperties: false,\n          },\n          {\n            enum: OPTION_VALUES,\n          },\n        ],\n      },\n    ],\n  },\n\n  create(context) {\n    const ruleOptions = context.options[0];\n    const userConfig = typeof ruleOptions === 'string'\n      ? { props: ruleOptions, children: ruleOptions, propElementValues: OPTION_IGNORE }\n      : Object.assign({}, DEFAULT_CONFIG, ruleOptions);\n\n    /**\n     * Report and fix an unnecessary curly brace violation on a node\n     * @param {ASTNode} JSXExpressionNode - The AST node with an unnecessary JSX expression\n     */\n    function reportUnnecessaryCurly(JSXExpressionNode) {\n      report(context, messages.unnecessaryCurly, 'unnecessaryCurly', {\n        node: JSXExpressionNode,\n        fix(fixer) {\n          const expression = JSXExpressionNode.expression;\n\n          let textToReplace;\n          if (jsxUtil.isJSX(expression)) {\n            textToReplace = getText(context, expression);\n          } else {\n            const expressionType = expression && expression.type;\n            const parentType = JSXExpressionNode.parent.type;\n\n            if (parentType === 'JSXAttribute') {\n              if (expressionType !== 'TemplateLiteral' && /[\"]/.test(expression.raw.slice(1, -1))) {\n                textToReplace = expression.raw;\n              } else {\n                textToReplace = `\"${expressionType === 'TemplateLiteral'\n                  ? expression.quasis[0].value.raw\n                  : expression.raw.slice(1, -1)\n                }\"`;\n              }\n            } else if (jsxUtil.isJSX(expression)) {\n              textToReplace = getText(context, expression);\n            } else {\n              textToReplace = expressionType === 'TemplateLiteral'\n                ? expression.quasis[0].value.cooked : expression.value;\n            }\n          }\n\n          return fixer.replaceText(JSXExpressionNode, textToReplace);\n        },\n      });\n    }\n\n    function reportMissingCurly(literalNode) {\n      report(context, messages.missingCurly, 'missingCurly', {\n        node: literalNode,\n        fix(fixer) {\n          if (jsxUtil.isJSX(literalNode)) {\n            return fixer.replaceText(literalNode, `{${getText(context, literalNode)}}`);\n          }\n\n          // If a HTML entity name is found, bail out because it can be fixed\n          // by either using the real character or the unicode equivalent.\n          // If it contains any line terminator character, bail out as well.\n          if (\n            containsOnlyHtmlEntities(literalNode.raw)\n            || (literalNode.parent.type === 'JSXAttribute' && containsLineTerminators(literalNode.raw))\n            || isLineBreak(literalNode.raw)\n          ) {\n            return null;\n          }\n\n          const expression = literalNode.parent.type === 'JSXAttribute'\n            ? `{\"${escapeDoubleQuotes(escapeBackslashes(\n              literalNode.raw.slice(1, -1)\n            ))}\"}`\n            : wrapWithCurlyBraces(literalNode.raw);\n\n          return fixer.replaceText(literalNode, expression);\n        },\n      });\n    }\n\n    // Bail out if there is any character that needs to be escaped in JSX\n    // because escaping decreases readability and the original code may be more\n    // readable anyway or intentional for other specific reasons\n    function lintUnnecessaryCurly(JSXExpressionNode) {\n      const expression = JSXExpressionNode.expression;\n      const expressionType = expression.type;\n\n      const sourceCode = getSourceCode(context);\n      // Curly braces containing comments are necessary\n      if (sourceCode.getCommentsInside && sourceCode.getCommentsInside(JSXExpressionNode).length > 0) {\n        return;\n      }\n\n      if (\n        (expressionType === 'Literal' || expressionType === 'JSXText')\n          && typeof expression.value === 'string'\n          && (\n            (JSXExpressionNode.parent.type === 'JSXAttribute' && !isWhiteSpaceLiteral(expression))\n            || !isLiteralWithTrailingWhiteSpaces(expression)\n          )\n          && !containsMultilineComment(expression.value)\n          && !needToEscapeCharacterForJSX(expression.raw, JSXExpressionNode) && (\n          jsxUtil.isJSX(JSXExpressionNode.parent)\n          || (!containsQuoteCharacters(expression.value) || typeof expression.value === 'string')\n        )\n      ) {\n        reportUnnecessaryCurly(JSXExpressionNode);\n      } else if (\n        expressionType === 'TemplateLiteral'\n        && expression.expressions.length === 0\n        && expression.quasis[0].value.raw.indexOf('\\n') === -1\n        && !isStringWithTrailingWhiteSpaces(expression.quasis[0].value.raw)\n        && !needToEscapeCharacterForJSX(expression.quasis[0].value.raw, JSXExpressionNode)\n        && !containsQuoteCharacters(expression.quasis[0].value.cooked)\n      ) {\n        reportUnnecessaryCurly(JSXExpressionNode);\n      } else if (jsxUtil.isJSX(expression)) {\n        reportUnnecessaryCurly(JSXExpressionNode);\n      }\n    }\n\n    function areRuleConditionsSatisfied(parent, config, ruleCondition) {\n      return (\n        parent.type === 'JSXAttribute'\n          && typeof config.props === 'string'\n          && config.props === ruleCondition\n      ) || (\n        jsxUtil.isJSX(parent)\n          && typeof config.children === 'string'\n          && config.children === ruleCondition\n      );\n    }\n\n    function getAdjacentSiblings(node, children) {\n      for (let i = 1; i < children.length - 1; i++) {\n        const child = children[i];\n        if (node === child) {\n          return [children[i - 1], children[i + 1]];\n        }\n      }\n      if (node === children[0] && children[1]) {\n        return [children[1]];\n      }\n      if (node === children[children.length - 1] && children[children.length - 2]) {\n        return [children[children.length - 2]];\n      }\n      return [];\n    }\n\n    function hasAdjacentJsxExpressionContainers(node, children) {\n      if (!children) {\n        return false;\n      }\n      const childrenExcludingWhitespaceLiteral = children.filter((child) => !isWhiteSpaceLiteral(child));\n      const adjSiblings = getAdjacentSiblings(node, childrenExcludingWhitespaceLiteral);\n\n      return adjSiblings.some((x) => x.type && x.type === 'JSXExpressionContainer');\n    }\n    function hasAdjacentJsx(node, children) {\n      if (!children) {\n        return false;\n      }\n      const childrenExcludingWhitespaceLiteral = children.filter((child) => !isWhiteSpaceLiteral(child));\n      const adjSiblings = getAdjacentSiblings(node, childrenExcludingWhitespaceLiteral);\n\n      return adjSiblings.some((x) => x.type && arrayIncludes(['JSXExpressionContainer', 'JSXElement'], x.type));\n    }\n    function shouldCheckForUnnecessaryCurly(node, config) {\n      const parent = node.parent;\n      // Bail out if the parent is a JSXAttribute & its contents aren't\n      // StringLiteral or TemplateLiteral since e.g\n      // <App prop1={<CustomEl />} prop2={<CustomEl>...</CustomEl>} />\n\n      if (\n        parent.type && parent.type === 'JSXAttribute'\n        && (node.expression && node.expression.type\n          && node.expression.type !== 'Literal'\n          && node.expression.type !== 'StringLiteral'\n          && node.expression.type !== 'TemplateLiteral')\n      ) {\n        return false;\n      }\n\n      // If there are adjacent `JsxExpressionContainer` then there is no need,\n      // to check for unnecessary curly braces.\n      if (jsxUtil.isJSX(parent) && hasAdjacentJsxExpressionContainers(node, parent.children)) {\n        return false;\n      }\n      if (containsWhitespaceExpression(node) && hasAdjacentJsx(node, parent.children)) {\n        return false;\n      }\n      if (\n        parent.children\n        && parent.children.length === 1\n        && containsWhitespaceExpression(node)\n      ) {\n        return false;\n      }\n\n      return areRuleConditionsSatisfied(parent, config, OPTION_NEVER);\n    }\n\n    function shouldCheckForMissingCurly(node, config) {\n      if (jsxUtil.isJSX(node)) {\n        return config.propElementValues !== OPTION_IGNORE;\n      }\n      if (\n        isLineBreak(node.raw)\n        || containsOnlyHtmlEntities(node.raw)\n      ) {\n        return false;\n      }\n      const parent = node.parent;\n      if (\n        parent.children\n        && parent.children.length === 1\n        && containsWhitespaceExpression(parent.children[0])\n      ) {\n        return false;\n      }\n\n      return areRuleConditionsSatisfied(parent, config, OPTION_ALWAYS);\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      'JSXAttribute > JSXExpressionContainer > JSXElement'(node) {\n        if (userConfig.propElementValues === OPTION_NEVER) {\n          reportUnnecessaryCurly(node.parent);\n        }\n      },\n\n      JSXExpressionContainer(node) {\n        if (shouldCheckForUnnecessaryCurly(node, userConfig)) {\n          lintUnnecessaryCurly(node);\n        }\n      },\n\n      'JSXAttribute > JSXElement, Literal, JSXText'(node) {\n        if (shouldCheckForMissingCurly(node, userConfig)) {\n          reportMissingCurly(node);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-curly-newline.js",
    "content": "/**\n * @fileoverview enforce consistent line breaks inside jsx curly\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst report = require('../util/report');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction getNormalizedOption(context) {\n  const rawOption = context.options[0] || 'consistent';\n\n  if (rawOption === 'consistent') {\n    return {\n      multiline: 'consistent',\n      singleline: 'consistent',\n    };\n  }\n\n  if (rawOption === 'never') {\n    return {\n      multiline: 'forbid',\n      singleline: 'forbid',\n    };\n  }\n\n  return {\n    multiline: rawOption.multiline || 'consistent',\n    singleline: rawOption.singleline || 'consistent',\n  };\n}\n\nconst messages = {\n  expectedBefore: 'Expected newline before \\'}\\'.',\n  expectedAfter: 'Expected newline after \\'{\\'.',\n  unexpectedBefore: 'Unexpected newline before \\'}\\'.',\n  unexpectedAfter: 'Unexpected newline after \\'{\\'.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    type: 'layout',\n\n    docs: {\n      description: 'Enforce consistent linebreaks in curly braces in JSX attributes and expressions',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-curly-newline'),\n    },\n\n    fixable: 'whitespace',\n\n    schema: [\n      {\n        anyOf: [\n          {\n            enum: ['consistent', 'never'],\n          },\n          {\n            type: 'object',\n            properties: {\n              singleline: { enum: ['consistent', 'require', 'forbid'] },\n              multiline: { enum: ['consistent', 'require', 'forbid'] },\n            },\n            additionalProperties: false,\n          },\n        ],\n      },\n    ],\n\n    messages,\n  },\n\n  create(context) {\n    const sourceCode = getSourceCode(context);\n    const option = getNormalizedOption(context);\n\n    // ----------------------------------------------------------------------\n    // Helpers\n    // ----------------------------------------------------------------------\n\n    /**\n     * Determines whether two adjacent tokens are on the same line.\n     * @param {Object} left - The left token object.\n     * @param {Object} right - The right token object.\n     * @returns {boolean} Whether or not the tokens are on the same line.\n     */\n    function isTokenOnSameLine(left, right) {\n      return left.loc.end.line === right.loc.start.line;\n    }\n\n    /**\n     * Determines whether there should be newlines inside curlys\n     * @param {ASTNode} expression The expression contained in the curlys\n     * @param {boolean} hasLeftNewline `true` if the left curly has a newline in the current code.\n     * @returns {boolean} `true` if there should be newlines inside the function curlys\n     */\n    function shouldHaveNewlines(expression, hasLeftNewline) {\n      const isMultiline = expression.loc.start.line !== expression.loc.end.line;\n\n      switch (isMultiline ? option.multiline : option.singleline) {\n        case 'forbid': return false;\n        case 'require': return true;\n        case 'consistent':\n        default: return hasLeftNewline;\n      }\n    }\n\n    /**\n     * Validates curlys\n     * @param {Object} curlys An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token\n     * @param {ASTNode} expression The expression inside the curly\n     * @returns {void}\n     */\n    function validateCurlys(curlys, expression) {\n      const leftCurly = curlys.leftCurly;\n      const rightCurly = curlys.rightCurly;\n      const tokenAfterLeftCurly = sourceCode.getTokenAfter(leftCurly);\n      const tokenBeforeRightCurly = sourceCode.getTokenBefore(rightCurly);\n      const hasLeftNewline = !isTokenOnSameLine(leftCurly, tokenAfterLeftCurly);\n      const hasRightNewline = !isTokenOnSameLine(tokenBeforeRightCurly, rightCurly);\n      const needsNewlines = shouldHaveNewlines(expression, hasLeftNewline);\n\n      if (hasLeftNewline && !needsNewlines) {\n        report(context, messages.unexpectedAfter, 'unexpectedAfter', {\n          node: leftCurly,\n          fix(fixer) {\n            return getText(context)\n              .slice(leftCurly.range[1], tokenAfterLeftCurly.range[0])\n              .trim()\n              ? null // If there is a comment between the { and the first element, don't do a fix.\n              : fixer.removeRange([leftCurly.range[1], tokenAfterLeftCurly.range[0]]);\n          },\n        });\n      } else if (!hasLeftNewline && needsNewlines) {\n        report(context, messages.expectedAfter, 'expectedAfter', {\n          node: leftCurly,\n          fix: (fixer) => fixer.insertTextAfter(leftCurly, '\\n'),\n        });\n      }\n\n      if (hasRightNewline && !needsNewlines) {\n        report(context, messages.unexpectedBefore, 'unexpectedBefore', {\n          node: rightCurly,\n          fix(fixer) {\n            return getText(context)\n              .slice(tokenBeforeRightCurly.range[1], rightCurly.range[0])\n              .trim()\n              ? null // If there is a comment between the last element and the }, don't do a fix.\n              : fixer.removeRange([\n                tokenBeforeRightCurly.range[1],\n                rightCurly.range[0],\n              ]);\n          },\n        });\n      } else if (!hasRightNewline && needsNewlines) {\n        report(context, messages.expectedBefore, 'expectedBefore', {\n          node: rightCurly,\n          fix: (fixer) => fixer.insertTextBefore(rightCurly, '\\n'),\n        });\n      }\n    }\n\n    // ----------------------------------------------------------------------\n    // Public\n    // ----------------------------------------------------------------------\n\n    return {\n      JSXExpressionContainer(node) {\n        const curlyTokens = {\n          leftCurly: sourceCode.getFirstToken(node),\n          rightCurly: sourceCode.getLastToken(node),\n        };\n        validateCurlys(curlyTokens, node.expression);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-curly-spacing.js",
    "content": "/**\n * @fileoverview Enforce or disallow spaces inside of curly braces in JSX attributes.\n * @author Jamund Ferguson\n * @author Brandyn Bennett\n * @author Michael Ficarra\n * @author Vignesh Anand\n * @author Jamund Ferguson\n * @author Yannick Croissant\n * @author Erik Wendel\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst docsUrl = require('../util/docsUrl');\nconst getSourceCode = require('../util/eslint').getSourceCode;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst SPACING = {\n  always: 'always',\n  never: 'never',\n};\nconst SPACING_VALUES = [SPACING.always, SPACING.never];\n\nconst messages = {\n  noNewlineAfter: 'There should be no newline after \\'{{token}}\\'',\n  noNewlineBefore: 'There should be no newline before \\'{{token}}\\'',\n  noSpaceAfter: 'There should be no space after \\'{{token}}\\'',\n  noSpaceBefore: 'There should be no space before \\'{{token}}\\'',\n  spaceNeededAfter: 'A space is required after \\'{{token}}\\'',\n  spaceNeededBefore: 'A space is required before \\'{{token}}\\'',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce or disallow spaces inside of curly braces in JSX attributes and expressions',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-curly-spacing'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: {\n      definitions: {\n        basicConfig: {\n          type: 'object',\n          properties: {\n            when: {\n              enum: SPACING_VALUES,\n            },\n            allowMultiline: {\n              type: 'boolean',\n            },\n            spacing: {\n              type: 'object',\n              properties: {\n                objectLiterals: {\n                  enum: SPACING_VALUES,\n                },\n              },\n            },\n          },\n        },\n        basicConfigOrBoolean: {\n          anyOf: [{\n            $ref: '#/definitions/basicConfig',\n          }, {\n            type: 'boolean',\n          }],\n        },\n      },\n      type: 'array',\n      items: [{\n        anyOf: [{\n          allOf: [{\n            $ref: '#/definitions/basicConfig',\n          }, {\n            type: 'object',\n            properties: {\n              attributes: {\n                $ref: '#/definitions/basicConfigOrBoolean',\n              },\n              children: {\n                $ref: '#/definitions/basicConfigOrBoolean',\n              },\n            },\n          }],\n        }, {\n          enum: SPACING_VALUES,\n        }],\n      }, {\n        type: 'object',\n        properties: {\n          allowMultiline: {\n            type: 'boolean',\n          },\n          spacing: {\n            type: 'object',\n            properties: {\n              objectLiterals: {\n                enum: SPACING_VALUES,\n              },\n            },\n          },\n        },\n        additionalProperties: false,\n      }],\n    },\n  },\n\n  create(context) {\n    function normalizeConfig(configOrTrue, defaults, lastPass) {\n      const config = configOrTrue === true ? {} : configOrTrue;\n      const when = config.when || defaults.when;\n      const allowMultiline = has(config, 'allowMultiline') ? config.allowMultiline : defaults.allowMultiline;\n      const spacing = config.spacing || {};\n      let objectLiteralSpaces = spacing.objectLiterals || defaults.objectLiteralSpaces;\n      if (lastPass) {\n        // On the final pass assign the values that should be derived from others if they are still undefined\n        objectLiteralSpaces = objectLiteralSpaces || when;\n      }\n\n      return {\n        when,\n        allowMultiline,\n        objectLiteralSpaces,\n      };\n    }\n\n    const DEFAULT_WHEN = SPACING.never;\n    const DEFAULT_ALLOW_MULTILINE = true;\n    const DEFAULT_ATTRIBUTES = true;\n    const DEFAULT_CHILDREN = false;\n\n    let originalConfig = context.options[0] || {};\n    if (SPACING_VALUES.indexOf(originalConfig) !== -1) {\n      originalConfig = Object.assign({ when: context.options[0] }, context.options[1]);\n    }\n    const defaultConfig = normalizeConfig(originalConfig, {\n      when: DEFAULT_WHEN,\n      allowMultiline: DEFAULT_ALLOW_MULTILINE,\n    });\n    const attributes = has(originalConfig, 'attributes') ? originalConfig.attributes : DEFAULT_ATTRIBUTES;\n    const attributesConfig = attributes ? normalizeConfig(attributes, defaultConfig, true) : null;\n    const children = has(originalConfig, 'children') ? originalConfig.children : DEFAULT_CHILDREN;\n    const childrenConfig = children ? normalizeConfig(children, defaultConfig, true) : null;\n\n    // --------------------------------------------------------------------------\n    // Helpers\n    // --------------------------------------------------------------------------\n\n    /**\n     * Determines whether two adjacent tokens have a newline between them.\n     * @param {Object} left - The left token object.\n     * @param {Object} right - The right token object.\n     * @returns {boolean} Whether or not there is a newline between the tokens.\n     */\n    function isMultiline(left, right) {\n      return left.loc.end.line !== right.loc.start.line;\n    }\n\n    /**\n     * Trims text of whitespace between two ranges\n     * @param {Fixer} fixer - the eslint fixer object\n     * @param {number} fromLoc - the start location\n     * @param {number} toLoc - the end location\n     * @param {string} mode - either 'start' or 'end'\n     * @param {string=} spacing - a spacing value that will optionally add a space to the removed text\n     * @returns {Object|*|{range, text}}\n     */\n    function fixByTrimmingWhitespace(fixer, fromLoc, toLoc, mode, spacing) {\n      let replacementText = getSourceCode(context).text.slice(fromLoc, toLoc);\n      if (mode === 'start') {\n        replacementText = replacementText.replace(/^\\s+/gm, '');\n      } else {\n        replacementText = replacementText.replace(/\\s+$/gm, '');\n      }\n      if (spacing === SPACING.always) {\n        if (mode === 'start') {\n          replacementText += ' ';\n        } else {\n          replacementText = ` ${replacementText}`;\n        }\n      }\n      return fixer.replaceTextRange([fromLoc, toLoc], replacementText);\n    }\n\n    /**\n    * Reports that there shouldn't be a newline after the first token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @param {string} spacing\n    * @returns {void}\n    */\n    function reportNoBeginningNewline(node, token, spacing) {\n      report(context, messages.noNewlineAfter, 'noNewlineAfter', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          const nextToken = getSourceCode(context).getTokenAfter(token);\n          return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start', spacing);\n        },\n      });\n    }\n\n    /**\n    * Reports that there shouldn't be a newline before the last token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @param {string} spacing\n    * @returns {void}\n    */\n    function reportNoEndingNewline(node, token, spacing) {\n      report(context, messages.noNewlineBefore, 'noNewlineBefore', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          const previousToken = getSourceCode(context).getTokenBefore(token);\n          return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end', spacing);\n        },\n      });\n    }\n\n    /**\n    * Reports that there shouldn't be a space after the first token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @returns {void}\n    */\n    function reportNoBeginningSpace(node, token) {\n      report(context, messages.noSpaceAfter, 'noSpaceAfter', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          const sourceCode = getSourceCode(context);\n          const nextToken = sourceCode.getTokenAfter(token);\n          let nextComment;\n\n          // eslint >=4.x\n          if (sourceCode.getCommentsAfter) {\n            nextComment = sourceCode.getCommentsAfter(token);\n          // eslint 3.x\n          } else {\n            const potentialComment = sourceCode.getTokenAfter(token, { includeComments: true });\n            nextComment = nextToken === potentialComment ? [] : [potentialComment];\n          }\n\n          // Take comments into consideration to narrow the fix range to what is actually affected. (See #1414)\n          if (nextComment.length > 0) {\n            return fixByTrimmingWhitespace(fixer, token.range[1], Math.min(nextToken.range[0], nextComment[0].range[0]), 'start');\n          }\n\n          return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start');\n        },\n      });\n    }\n\n    /**\n    * Reports that there shouldn't be a space before the last token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @returns {void}\n    */\n    function reportNoEndingSpace(node, token) {\n      report(context, messages.noSpaceBefore, 'noSpaceBefore', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          const sourceCode = getSourceCode(context);\n          const previousToken = sourceCode.getTokenBefore(token);\n          let previousComment;\n\n          // eslint >=4.x\n          if (sourceCode.getCommentsBefore) {\n            previousComment = sourceCode.getCommentsBefore(token);\n          // eslint 3.x\n          } else {\n            const potentialComment = sourceCode.getTokenBefore(token, { includeComments: true });\n            previousComment = previousToken === potentialComment ? [] : [potentialComment];\n          }\n\n          // Take comments into consideration to narrow the fix range to what is actually affected. (See #1414)\n          if (previousComment.length > 0) {\n            return fixByTrimmingWhitespace(fixer, Math.max(previousToken.range[1], previousComment[0].range[1]), token.range[0], 'end');\n          }\n\n          return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end');\n        },\n      });\n    }\n\n    /**\n    * Reports that there should be a space after the first token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @returns {void}\n    */\n    function reportRequiredBeginningSpace(node, token) {\n      report(context, messages.spaceNeededAfter, 'spaceNeededAfter', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          return fixer.insertTextAfter(token, ' ');\n        },\n      });\n    }\n\n    /**\n    * Reports that there should be a space before the last token\n    * @param {ASTNode} node - The node to report in the event of an error.\n    * @param {Token} token - The token to use for the report.\n    * @returns {void}\n    */\n    function reportRequiredEndingSpace(node, token) {\n      report(context, messages.spaceNeededBefore, 'spaceNeededBefore', {\n        node,\n        loc: token.loc.start,\n        data: {\n          token: token.value,\n        },\n        fix(fixer) {\n          return fixer.insertTextBefore(token, ' ');\n        },\n      });\n    }\n\n    /**\n     * Determines if spacing in curly braces is valid.\n     * @param {ASTNode} node The AST node to check.\n     * @returns {void}\n     */\n    function validateBraceSpacing(node) {\n      let config;\n      switch (node.parent.type) {\n        case 'JSXAttribute':\n        case 'JSXOpeningElement':\n          config = attributesConfig;\n          break;\n\n        case 'JSXElement':\n        case 'JSXFragment':\n          config = childrenConfig;\n          break;\n\n        default:\n          return;\n      }\n      if (config === null) {\n        return;\n      }\n\n      const sourceCode = getSourceCode(context);\n      const first = sourceCode.getFirstToken(node);\n      const last = sourceCode.getLastToken(node);\n      let second = sourceCode.getTokenAfter(first, { includeComments: true });\n      let penultimate = sourceCode.getTokenBefore(last, { includeComments: true });\n\n      if (!second) {\n        second = sourceCode.getTokenAfter(first);\n        const leadingComments = sourceCode.getNodeByRangeIndex(second.range[0]).leadingComments;\n        second = leadingComments ? leadingComments[0] : second;\n      }\n      if (!penultimate) {\n        penultimate = sourceCode.getTokenBefore(last);\n        const trailingComments = sourceCode.getNodeByRangeIndex(penultimate.range[0]).trailingComments;\n        penultimate = trailingComments ? trailingComments[trailingComments.length - 1] : penultimate;\n      }\n\n      const isObjectLiteral = first.value === second.value;\n      const spacing = isObjectLiteral ? config.objectLiteralSpaces : config.when;\n      if (spacing === SPACING.always) {\n        if (!sourceCode.isSpaceBetweenTokens(first, second)) {\n          reportRequiredBeginningSpace(node, first);\n        } else if (!config.allowMultiline && isMultiline(first, second)) {\n          reportNoBeginningNewline(node, first, spacing);\n        }\n        if (!sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n          reportRequiredEndingSpace(node, last);\n        } else if (!config.allowMultiline && isMultiline(penultimate, last)) {\n          reportNoEndingNewline(node, last, spacing);\n        }\n      } else if (spacing === SPACING.never) {\n        if (isMultiline(first, second)) {\n          if (!config.allowMultiline) {\n            reportNoBeginningNewline(node, first, spacing);\n          }\n        } else if (sourceCode.isSpaceBetweenTokens(first, second)) {\n          reportNoBeginningSpace(node, first);\n        }\n        if (isMultiline(penultimate, last)) {\n          if (!config.allowMultiline) {\n            reportNoEndingNewline(node, last, spacing);\n          }\n        } else if (sourceCode.isSpaceBetweenTokens(penultimate, last)) {\n          reportNoEndingSpace(node, last);\n        }\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXExpressionContainer: validateBraceSpacing,\n      JSXSpreadAttribute: validateBraceSpacing,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-equals-spacing.js",
    "content": "/**\n * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.\n * @author ryym\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getSourceCode = require('../util/eslint').getSourceCode;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noSpaceBefore: 'There should be no space before \\'=\\'',\n  noSpaceAfter: 'There should be no space after \\'=\\'',\n  needSpaceBefore: 'A space is required before \\'=\\'',\n  needSpaceAfter: 'A space is required after \\'=\\'',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce or disallow spaces around equal signs in JSX attributes',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-equals-spacing'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      enum: ['always', 'never'],\n    }],\n  },\n\n  create(context) {\n    const config = context.options[0] || 'never';\n\n    /**\n     * Determines a given attribute node has an equal sign.\n     * @param {ASTNode} attrNode - The attribute node.\n     * @returns {boolean} Whether or not the attriute node has an equal sign.\n     */\n    function hasEqual(attrNode) {\n      return attrNode.type !== 'JSXSpreadAttribute' && attrNode.value !== null;\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXOpeningElement(node) {\n        node.attributes.forEach((attrNode) => {\n          if (!hasEqual(attrNode)) {\n            return;\n          }\n\n          const sourceCode = getSourceCode(context);\n          const equalToken = sourceCode.getTokenAfter(attrNode.name);\n          const spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken);\n          const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value);\n\n          if (config === 'never') {\n            if (spacedBefore) {\n              report(context, messages.noSpaceBefore, 'noSpaceBefore', {\n                node: attrNode,\n                loc: equalToken.loc.start,\n                fix(fixer) {\n                  return fixer.removeRange([attrNode.name.range[1], equalToken.range[0]]);\n                },\n              });\n            }\n            if (spacedAfter) {\n              report(context, messages.noSpaceAfter, 'noSpaceAfter', {\n                node: attrNode,\n                loc: equalToken.loc.start,\n                fix(fixer) {\n                  return fixer.removeRange([equalToken.range[1], attrNode.value.range[0]]);\n                },\n              });\n            }\n          } else if (config === 'always') {\n            if (!spacedBefore) {\n              report(context, messages.needSpaceBefore, 'needSpaceBefore', {\n                node: attrNode,\n                loc: equalToken.loc.start,\n                fix(fixer) {\n                  return fixer.insertTextBefore(equalToken, ' ');\n                },\n              });\n            }\n            if (!spacedAfter) {\n              report(context, messages.needSpaceAfter, 'needSpaceAfter', {\n                node: attrNode,\n                loc: equalToken.loc.start,\n                fix(fixer) {\n                  return fixer.insertTextAfter(equalToken, ' ');\n                },\n              });\n            }\n          }\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-filename-extension.js",
    "content": "/**\n * @fileoverview Restrict file extensions that may contain JSX\n * @author Joe Lencioni\n */\n\n'use strict';\n\nconst path = require('path');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = {\n  allow: 'always',\n  extensions: ['.jsx'],\n  ignoreFilesWithoutCode: false,\n};\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noJSXWithExtension: 'JSX not allowed in files with extension \\'{{ext}}\\'',\n  extensionOnlyForJSX: 'Only files containing JSX may use the extension \\'{{ext}}\\'',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow file extensions that may contain JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-filename-extension'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allow: {\n          enum: ['always', 'as-needed'],\n        },\n        extensions: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        ignoreFilesWithoutCode: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const filename = context.getFilename();\n\n    let jsxNode;\n\n    if (filename === '<text>') {\n      // No need to traverse any nodes.\n      return {};\n    }\n\n    const allow = (context.options[0] && context.options[0].allow) || DEFAULTS.allow;\n    const allowedExtensions = (context.options[0] && context.options[0].extensions) || DEFAULTS.extensions;\n    const ignoreFilesWithoutCode = (context.options[0] && context.options[0].ignoreFilesWithoutCode)\n      || DEFAULTS.ignoreFilesWithoutCode;\n    const isAllowedExtension = allowedExtensions.some((extension) => filename.slice(-extension.length) === extension);\n\n    function handleJSX(node) {\n      if (!jsxNode) {\n        jsxNode = node;\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXElement: handleJSX,\n      JSXFragment: handleJSX,\n\n      'Program:exit'(node) {\n        if (jsxNode) {\n          if (!isAllowedExtension) {\n            report(context, messages.noJSXWithExtension, 'noJSXWithExtension', {\n              node: jsxNode,\n              data: {\n                ext: path.extname(filename),\n              },\n            });\n          }\n          return;\n        }\n\n        if (isAllowedExtension && allow === 'as-needed') {\n          if (ignoreFilesWithoutCode && node.body.length === 0) {\n            return;\n          }\n          report(context, messages.extensionOnlyForJSX, 'extensionOnlyForJSX', {\n            node,\n            data: {\n              ext: path.extname(filename),\n            },\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-first-prop-new-line.js",
    "content": "/**\n * @fileoverview Ensure proper position of the first property in JSX\n * @author Joachim Seminck\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst propsUtil = require('../util/props');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  propOnNewLine: 'Property should be placed on a new line',\n  propOnSameLine: 'Property should be placed on the same line as the component declaration',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce proper position of the first property in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-first-prop-new-line'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      enum: ['always', 'never', 'multiline', 'multiline-multiprop', 'multiprop'],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || 'multiline-multiprop';\n\n    function isMultilineJSX(jsxNode) {\n      return jsxNode.loc.start.line < jsxNode.loc.end.line;\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        if (\n          (configuration === 'multiline' && isMultilineJSX(node))\n          || (configuration === 'multiline-multiprop' && isMultilineJSX(node) && node.attributes.length > 1)\n          || (configuration === 'multiprop' && node.attributes.length > 1)\n          || (configuration === 'always')\n        ) {\n          node.attributes.some((decl) => {\n            if (decl.loc.start.line === node.loc.start.line) {\n              report(context, messages.propOnNewLine, 'propOnNewLine', {\n                node: decl,\n                fix(fixer) {\n                  const nodeTypeArguments = propsUtil.getTypeArguments(node);\n                  return fixer.replaceTextRange([(nodeTypeArguments || node.name).range[1], decl.range[0]], '\\n');\n                },\n              });\n            }\n            return true;\n          });\n        } else if (\n          (configuration === 'never' && node.attributes.length > 0)\n          || (configuration === 'multiprop' && isMultilineJSX(node) && node.attributes.length <= 1)\n        ) {\n          const firstNode = node.attributes[0];\n          if (node.loc.start.line < firstNode.loc.start.line) {\n            report(context, messages.propOnSameLine, 'propOnSameLine', {\n              node: firstNode,\n              fix(fixer) {\n                return fixer.replaceTextRange([node.name.range[1], firstNode.range[0]], ' ');\n              },\n            });\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-fragments.js",
    "content": "/**\n * @fileoverview Enforce shorthand or standard form for React fragments.\n * @author Alex Zherdev\n */\n\n'use strict';\n\nconst elementType = require('jsx-ast-utils/elementType');\nconst pragmaUtil = require('../util/pragma');\nconst variableUtil = require('../util/variable');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction replaceNode(source, node, text) {\n  return `${source.slice(0, node.range[0])}${text}${source.slice(node.range[1])}`;\n}\n\nconst messages = {\n  fragmentsNotSupported: 'Fragments are only supported starting from React v16.2. Please disable the `react/jsx-fragments` rule in `eslint` settings or upgrade your version of React.',\n  preferPragma: 'Prefer {{react}}.{{fragment}} over fragment shorthand',\n  preferFragment: 'Prefer fragment shorthand over {{react}}.{{fragment}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce shorthand or standard form for React fragments',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-fragments'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      enum: ['syntax', 'element'],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || 'syntax';\n    const reactPragma = pragmaUtil.getFromContext(context);\n    const fragmentPragma = pragmaUtil.getFragmentFromContext(context);\n    const openFragShort = '<>';\n    const closeFragShort = '</>';\n    const openFragLong = `<${reactPragma}.${fragmentPragma}>`;\n    const closeFragLong = `</${reactPragma}.${fragmentPragma}>`;\n\n    function reportOnReactVersion(node) {\n      if (!testReactVersion(context, '>= 16.2.0')) {\n        report(context, messages.fragmentsNotSupported, 'fragmentsNotSupported', {\n          node,\n        });\n        return true;\n      }\n\n      return false;\n    }\n\n    function getFixerToLong(jsxFragment) {\n      if (!jsxFragment.closingFragment || !jsxFragment.openingFragment) {\n        // the old TS parser crashes here\n        // TODO: FIXME: can we fake these two descriptors?\n        return null;\n      }\n      return function fix(fixer) {\n        let source = getText(context);\n        source = replaceNode(source, jsxFragment.closingFragment, closeFragLong);\n        source = replaceNode(source, jsxFragment.openingFragment, openFragLong);\n        const lengthDiff = openFragLong.length - getText(context, jsxFragment.openingFragment).length\n          + closeFragLong.length - getText(context, jsxFragment.closingFragment).length;\n        const range = jsxFragment.range;\n        return fixer.replaceTextRange(range, source.slice(range[0], range[1] + lengthDiff));\n      };\n    }\n\n    function getFixerToShort(jsxElement) {\n      return function fix(fixer) {\n        let source = getText(context);\n        let lengthDiff;\n        if (jsxElement.closingElement) {\n          source = replaceNode(source, jsxElement.closingElement, closeFragShort);\n          source = replaceNode(source, jsxElement.openingElement, openFragShort);\n          lengthDiff = getText(context, jsxElement.openingElement).length - openFragShort.length\n            + getText(context, jsxElement.closingElement).length - closeFragShort.length;\n        } else {\n          source = replaceNode(source, jsxElement.openingElement, `${openFragShort}${closeFragShort}`);\n          lengthDiff = getText(context, jsxElement.openingElement).length - openFragShort.length\n            - closeFragShort.length;\n        }\n\n        const range = jsxElement.range;\n        return fixer.replaceTextRange(range, source.slice(range[0], range[1] - lengthDiff));\n      };\n    }\n\n    function refersToReactFragment(node, name) {\n      const variableInit = variableUtil.findVariableByName(context, node, name);\n      if (!variableInit) {\n        return false;\n      }\n\n      // const { Fragment } = React;\n      if (variableInit.type === 'Identifier' && variableInit.name === reactPragma) {\n        return true;\n      }\n\n      // const Fragment = React.Fragment;\n      if (\n        variableInit.type === 'MemberExpression'\n        && variableInit.object.type === 'Identifier'\n        && variableInit.object.name === reactPragma\n        && variableInit.property.type === 'Identifier'\n        && variableInit.property.name === fragmentPragma\n      ) {\n        return true;\n      }\n\n      // const { Fragment } = require('react');\n      if (\n        variableInit.callee\n        && variableInit.callee.name === 'require'\n        && variableInit.arguments\n        && variableInit.arguments[0]\n        && variableInit.arguments[0].value === 'react'\n      ) {\n        return true;\n      }\n\n      return false;\n    }\n\n    const jsxElements = [];\n    const fragmentNames = new Set([`${reactPragma}.${fragmentPragma}`]);\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXElement(node) {\n        jsxElements.push(node);\n      },\n\n      JSXFragment(node) {\n        if (reportOnReactVersion(node)) {\n          return;\n        }\n\n        if (configuration === 'element') {\n          report(context, messages.preferPragma, 'preferPragma', {\n            node,\n            data: {\n              react: reactPragma,\n              fragment: fragmentPragma,\n            },\n            fix: getFixerToLong(node),\n          });\n        }\n      },\n\n      ImportDeclaration(node) {\n        if (node.source && node.source.value === 'react') {\n          node.specifiers.forEach((spec) => {\n            if (\n              'imported' in spec\n              && spec.imported\n              && 'name' in spec.imported\n              && spec.imported.name === fragmentPragma\n            ) {\n              if (spec.local) {\n                fragmentNames.add(spec.local.name);\n              }\n            }\n          });\n        }\n      },\n\n      'Program:exit'() {\n        jsxElements.forEach((node) => {\n          const openingEl = node.openingElement;\n          const elName = elementType(openingEl);\n\n          if (fragmentNames.has(elName) || refersToReactFragment(node, elName)) {\n            if (reportOnReactVersion(node)) {\n              return;\n            }\n\n            const attrs = openingEl.attributes;\n            if (configuration === 'syntax' && !(attrs && attrs.length > 0)) {\n              report(context, messages.preferFragment, 'preferFragment', {\n                node,\n                data: {\n                  react: reactPragma,\n                  fragment: fragmentPragma,\n                },\n                fix: getFixerToShort(node),\n              });\n            }\n          }\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-handler-names.js",
    "content": "/**\n * @fileoverview Enforce event handler naming conventions in JSX\n * @author Jake Marsh\n */\n\n'use strict';\n\nconst minimatch = require('minimatch');\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  badHandlerName: 'Handler function for {{propKey}} prop key must be a camelCase name beginning with \\'{{handlerPrefix}}\\' only',\n  badPropKey: 'Prop key for {{propValue}} must begin with \\'{{handlerPropPrefix}}\\'',\n};\n\nfunction isPrefixDisabled(prefix) {\n  return prefix === false;\n}\n\nfunction isInlineHandler(node) {\n  return node.value.expression.type === 'ArrowFunctionExpression';\n}\n\nfunction getComponentName(node) {\n  if (node.type === 'JSXIdentifier') {\n    return node.name;\n  }\n  if (node.type === 'JSXMemberExpression') {\n    return `${getComponentName(node.object)}.${node.property.name}`;\n  }\n  if (node.type === 'JSXNamespacedName') {\n    return `${node.namespace.name}:${node.name.name}`;\n  }\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce event handler naming conventions in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-handler-names'),\n    },\n\n    messages,\n\n    schema: [{\n      anyOf: [\n        {\n          type: 'object',\n          properties: {\n            eventHandlerPrefix: { type: 'string' },\n            eventHandlerPropPrefix: { type: 'string' },\n            checkLocalVariables: { type: 'boolean' },\n            checkInlineFunction: { type: 'boolean' },\n            ignoreComponentNames: {\n              type: 'array',\n              uniqueItems: true,\n              items: { type: 'string' },\n            },\n          },\n          additionalProperties: false,\n        }, {\n          type: 'object',\n          properties: {\n            eventHandlerPrefix: { type: 'string' },\n            eventHandlerPropPrefix: {\n              type: 'boolean',\n              enum: [false],\n            },\n            checkLocalVariables: { type: 'boolean' },\n            checkInlineFunction: { type: 'boolean' },\n            ignoreComponentNames: {\n              type: 'array',\n              uniqueItems: true,\n              items: { type: 'string' },\n            },\n          },\n          additionalProperties: false,\n        }, {\n          type: 'object',\n          properties: {\n            eventHandlerPrefix: {\n              type: 'boolean',\n              enum: [false],\n            },\n            eventHandlerPropPrefix: { type: 'string' },\n            checkLocalVariables: { type: 'boolean' },\n            checkInlineFunction: { type: 'boolean' },\n            ignoreComponentNames: {\n              type: 'array',\n              uniqueItems: true,\n              items: { type: 'string' },\n            },\n          },\n          additionalProperties: false,\n        }, {\n          type: 'object',\n          properties: {\n            checkLocalVariables: { type: 'boolean' },\n          },\n          additionalProperties: false,\n        }, {\n          type: 'object',\n          properties: {\n            checkInlineFunction: { type: 'boolean' },\n          },\n          additionalProperties: false,\n        },\n        {\n          type: 'object',\n          properties: {\n            ignoreComponentNames: {\n              type: 'array',\n              uniqueItems: true,\n              items: { type: 'string' },\n            },\n          },\n        },\n      ],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n\n    const eventHandlerPrefix = isPrefixDisabled(configuration.eventHandlerPrefix)\n      ? null\n      : configuration.eventHandlerPrefix || 'handle';\n    const eventHandlerPropPrefix = isPrefixDisabled(configuration.eventHandlerPropPrefix)\n      ? null\n      : configuration.eventHandlerPropPrefix || 'on';\n\n    const EVENT_HANDLER_REGEX = !eventHandlerPrefix\n      ? null\n      : new RegExp(`^((props\\\\.${eventHandlerPropPrefix || ''})|((.*\\\\.)?${eventHandlerPrefix}))[0-9]*[A-Z].*$`);\n    const PROP_EVENT_HANDLER_REGEX = !eventHandlerPropPrefix\n      ? null\n      : new RegExp(`^(${eventHandlerPropPrefix}[A-Z].*|ref)$`);\n\n    const checkLocal = !!configuration.checkLocalVariables;\n\n    const checkInlineFunction = !!configuration.checkInlineFunction;\n\n    const ignoreComponentNames = configuration.ignoreComponentNames || [];\n\n    return {\n      JSXAttribute(node) {\n        const componentName = getComponentName(node.parent.name);\n\n        const isComponentNameIgnored = ignoreComponentNames.some((ignoredComponentNamePattern) => minimatch(\n          componentName,\n          ignoredComponentNamePattern\n        ));\n\n        if (\n          !node.value\n          || !node.value.expression\n          || (!checkInlineFunction && isInlineHandler(node))\n          || (\n            !checkLocal\n            && (isInlineHandler(node)\n              ? !node.value.expression.body.callee || !node.value.expression.body.callee.object\n              : !node.value.expression.object\n            )\n          )\n          || isComponentNameIgnored\n        ) {\n          return;\n        }\n\n        const propKey = typeof node.name === 'object' ? node.name.name : node.name;\n        const expression = node.value.expression;\n        const propValue = getText(\n          context,\n          checkInlineFunction && isInlineHandler(node) ? expression.body.callee : expression\n        ).replace(/\\s*/g, '').replace(/^this\\.|.*::/, '');\n\n        if (propKey === 'ref') {\n          return;\n        }\n\n        const propIsEventHandler = PROP_EVENT_HANDLER_REGEX && PROP_EVENT_HANDLER_REGEX.test(propKey);\n        const propFnIsNamedCorrectly = EVENT_HANDLER_REGEX && EVENT_HANDLER_REGEX.test(propValue);\n\n        if (\n          propIsEventHandler\n          && propFnIsNamedCorrectly !== null\n          && !propFnIsNamedCorrectly\n        ) {\n          report(context, messages.badHandlerName, 'badHandlerName', {\n            node,\n            data: {\n              propKey,\n              handlerPrefix: eventHandlerPrefix,\n            },\n          });\n        } else if (\n          propFnIsNamedCorrectly\n          && propIsEventHandler !== null\n          && !propIsEventHandler\n        ) {\n          report(context, messages.badPropKey, 'badPropKey', {\n            node,\n            data: {\n              propValue,\n              handlerPropPrefix: eventHandlerPropPrefix,\n            },\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-indent-props.js",
    "content": "/**\n * @fileoverview Validate props indentation in JSX\n * @author Yannick Croissant\n\n * This rule has been ported and modified from eslint and nodeca.\n * @author Vitaly Puzrin\n * @author Gyandeep Singh\n * @copyright 2015 Vitaly Puzrin. All rights reserved.\n * @copyright 2015 Gyandeep Singh. All rights reserved.\n Copyright (C) 2014 by Vitaly Puzrin\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the 'Software'), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n'use strict';\n\nconst repeat = require('string.prototype.repeat');\n\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst reportC = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  wrongIndent: 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce props indentation in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-indent-props'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      anyOf: [{\n        enum: ['tab', 'first'],\n      }, {\n        type: 'integer',\n      }, {\n        type: 'object',\n        properties: {\n          indentMode: {\n            anyOf: [{\n              enum: ['tab', 'first'],\n            }, {\n              type: 'integer',\n            }],\n          },\n          ignoreTernaryOperator: {\n            type: 'boolean',\n          },\n        },\n      }],\n    }],\n  },\n\n  create(context) {\n    const extraColumnStart = 0;\n    let indentType = 'space';\n    /** @type {number|'first'} */\n    let indentSize = 4;\n    const line = {\n      isUsingOperator: false,\n      currentOperator: false,\n    };\n    let ignoreTernaryOperator = false;\n\n    if (context.options.length) {\n      const isConfigObject = typeof context.options[0] === 'object';\n      const indentMode = isConfigObject\n        ? context.options[0].indentMode\n        : context.options[0];\n\n      if (indentMode === 'first') {\n        indentSize = 'first';\n        indentType = 'space';\n      } else if (indentMode === 'tab') {\n        indentSize = 1;\n        indentType = 'tab';\n      } else if (typeof indentMode === 'number') {\n        indentSize = indentMode;\n        indentType = 'space';\n      }\n\n      if (isConfigObject && context.options[0].ignoreTernaryOperator) {\n        ignoreTernaryOperator = true;\n      }\n    }\n\n    /**\n     * Reports a given indent violation and properly pluralizes the message\n     * @param {ASTNode} node Node violating the indent rule\n     * @param {number} needed Expected indentation character count\n     * @param {number} gotten Indentation character count in the actual node/code\n     */\n    function report(node, needed, gotten) {\n      const msgContext = {\n        needed,\n        type: indentType,\n        characters: needed === 1 ? 'character' : 'characters',\n        gotten,\n      };\n\n      reportC(context, messages.wrongIndent, 'wrongIndent', {\n        node,\n        data: msgContext,\n        fix(fixer) {\n          return fixer.replaceTextRange([node.range[0] - node.loc.start.column, node.range[0]],\n            repeat(indentType === 'space' ? ' ' : '\\t', needed)\n          );\n        },\n      });\n    }\n\n    /**\n     * Get node indent\n     * @param {ASTNode} node Node to examine\n     * @return {number} Indent\n     */\n    function getNodeIndent(node) {\n      let src = getText(context, node, node.loc.start.column + extraColumnStart);\n      const lines = src.split('\\n');\n      src = lines[0];\n\n      let regExp;\n      if (indentType === 'space') {\n        regExp = /^[ ]+/;\n      } else {\n        regExp = /^[\\t]+/;\n      }\n\n      const indent = regExp.exec(src);\n      const useOperator = /^([ ]|[\\t])*[:]/.test(src) || /^([ ]|[\\t])*[?]/.test(src);\n      const useBracket = /[<]/.test(src);\n\n      line.currentOperator = false;\n      if (useOperator) {\n        line.isUsingOperator = true;\n        line.currentOperator = true;\n      } else if (useBracket) {\n        line.isUsingOperator = false;\n      }\n\n      return indent ? indent[0].length : 0;\n    }\n\n    /**\n     * Check indent for nodes list\n     * @param {ASTNode[]} nodes list of node objects\n     * @param {number} indent needed indent\n     */\n    function checkNodesIndent(nodes, indent) {\n      let nestedIndent = indent;\n      nodes.forEach((node) => {\n        const nodeIndent = getNodeIndent(node);\n        if (\n          line.isUsingOperator\n          && !line.currentOperator\n          && indentSize !== 'first'\n          && !ignoreTernaryOperator\n        ) {\n          nestedIndent += indentSize;\n          line.isUsingOperator = false;\n        }\n        if (\n          node.type !== 'ArrayExpression' && node.type !== 'ObjectExpression'\n          && nodeIndent !== nestedIndent && astUtil.isNodeFirstInLine(context, node)\n        ) {\n          report(node, nestedIndent, nodeIndent);\n        }\n      });\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        if (!node.attributes.length) {\n          return;\n        }\n        let propIndent;\n        if (indentSize === 'first') {\n          const firstPropNode = node.attributes[0];\n          propIndent = firstPropNode.loc.start.column;\n        } else {\n          const elementIndent = getNodeIndent(node);\n          propIndent = elementIndent + indentSize;\n        }\n        checkNodesIndent(node.attributes, propIndent);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-indent.js",
    "content": "/**\n * @fileoverview Validate JSX indentation\n * @author Yannick Croissant\n\n * This rule has been ported and modified from eslint and nodeca.\n * @author Vitaly Puzrin\n * @author Gyandeep Singh\n * @copyright 2015 Vitaly Puzrin. All rights reserved.\n * @copyright 2015 Gyandeep Singh. All rights reserved.\n Copyright (C) 2014 by Vitaly Puzrin\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the 'Software'), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n */\n\n'use strict';\n\nconst matchAll = require('string.prototype.matchall');\nconst repeat = require('string.prototype.repeat');\n\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst reportC = require('../util/report');\nconst jsxUtil = require('../util/jsx');\nconst eslintUtil = require('../util/eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  wrongIndent: 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce JSX indentation',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-indent'),\n    },\n    fixable: 'whitespace',\n\n    messages,\n\n    schema: [{\n      anyOf: [{\n        enum: ['tab'],\n      }, {\n        type: 'integer',\n      }],\n    }, {\n      type: 'object',\n      properties: {\n        checkAttributes: {\n          type: 'boolean',\n        },\n        indentLogicalExpressions: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const extraColumnStart = 0;\n    let indentType = 'space';\n    let indentSize = 4;\n\n    if (context.options.length) {\n      if (context.options[0] === 'tab') {\n        indentSize = 1;\n        indentType = 'tab';\n      } else if (typeof context.options[0] === 'number') {\n        indentSize = context.options[0];\n        indentType = 'space';\n      }\n    }\n\n    const indentChar = indentType === 'space' ? ' ' : '\\t';\n    const options = context.options[1] || {};\n    const checkAttributes = options.checkAttributes || false;\n    const indentLogicalExpressions = options.indentLogicalExpressions || false;\n\n    /**\n     * Responsible for fixing the indentation issue fix\n     * @param {ASTNode} node Node violating the indent rule\n     * @param {number} needed Expected indentation character count\n     * @returns {Function} function to be executed by the fixer\n     * @private\n     */\n    function getFixerFunction(node, needed) {\n      const indent = repeat(indentChar, needed);\n\n      if (node.type === 'JSXText' || node.type === 'Literal') {\n        return function fix(fixer) {\n          const regExp = /\\n[\\t ]*(\\S)/g;\n          const fixedText = node.raw.replace(regExp, (match, p1) => `\\n${indent}${p1}`);\n          return fixer.replaceText(node, fixedText);\n        };\n      }\n\n      if (node.type === 'ReturnStatement') {\n        const raw = getText(context, node);\n        const lines = raw.split('\\n');\n        if (lines.length > 1) {\n          return function fix(fixer) {\n            const lastLineStart = raw.lastIndexOf('\\n');\n            const lastLine = raw.slice(lastLineStart).replace(/^\\n[\\t ]*(\\S)/, (match, p1) => `\\n${indent}${p1}`);\n            return fixer.replaceTextRange(\n              [node.range[0] + lastLineStart, node.range[1]],\n              lastLine\n            );\n          };\n        }\n      }\n\n      return function fix(fixer) {\n        return fixer.replaceTextRange(\n          [node.range[0] - node.loc.start.column, node.range[0]],\n          indent\n        );\n      };\n    }\n\n    /**\n     * Reports a given indent violation and properly pluralizes the message\n     * @param {ASTNode} node Node violating the indent rule\n     * @param {number} needed Expected indentation character count\n     * @param {number} gotten Indentation character count in the actual node/code\n     * @param {Object} [loc] Error line and column location\n     */\n    function report(node, needed, gotten, loc) {\n      const msgContext = {\n        needed,\n        type: indentType,\n        characters: needed === 1 ? 'character' : 'characters',\n        gotten,\n      };\n\n      reportC(context, messages.wrongIndent, 'wrongIndent', Object.assign({\n        node,\n        data: msgContext,\n        fix: getFixerFunction(node, needed),\n      }, loc && { loc }));\n    }\n\n    /**\n     * Get node indent\n     * @param {ASTNode} node Node to examine\n     * @param {boolean} [byLastLine] get indent of node's last line\n     * @param {boolean} [excludeCommas] skip comma on start of line\n     * @return {number} Indent\n     */\n    function getNodeIndent(node, byLastLine, excludeCommas) {\n      let src = getText(context, node, node.loc.start.column + extraColumnStart);\n      const lines = src.split('\\n');\n      if (byLastLine) {\n        src = lines[lines.length - 1];\n      } else {\n        src = lines[0];\n      }\n\n      const skip = excludeCommas ? ',' : '';\n\n      let regExp;\n      if (indentType === 'space') {\n        regExp = new RegExp(`^[ ${skip}]+`);\n      } else {\n        regExp = new RegExp(`^[\\t${skip}]+`);\n      }\n\n      const indent = regExp.exec(src);\n      return indent ? indent[0].length : 0;\n    }\n\n    /**\n     * Check if the node is the right member of a logical expression\n     * @param {ASTNode} node The node to check\n     * @return {boolean} true if its the case, false if not\n     */\n    function isRightInLogicalExp(node) {\n      return (\n        node.parent\n        && node.parent.parent\n        && node.parent.parent.type === 'LogicalExpression'\n        && node.parent.parent.right === node.parent\n        && !indentLogicalExpressions\n      );\n    }\n\n    /**\n     * Check if the node is the alternate member of a conditional expression\n     * @param {ASTNode} node The node to check\n     * @return {boolean} true if its the case, false if not\n     */\n    function isAlternateInConditionalExp(node) {\n      return (\n        node.parent\n        && node.parent.parent\n        && node.parent.parent.type === 'ConditionalExpression'\n        && node.parent.parent.alternate === node.parent\n        && getSourceCode(context).getTokenBefore(node).value !== '('\n      );\n    }\n\n    /**\n     * Check if the node is within a DoExpression block but not the first expression (which need to be indented)\n     * @param {ASTNode} node The node to check\n     * @return {boolean} true if its the case, false if not\n     */\n    function isSecondOrSubsequentExpWithinDoExp(node) {\n      /*\n        It returns true when node.parent.parent.parent.parent matches:\n\n        DoExpression({\n          ...,\n          body: BlockStatement({\n            ...,\n            body: [\n              ...,  // 1-n times\n              ExpressionStatement({\n                ...,\n                expression: JSXElement({\n                  ...,\n                  openingElement: JSXOpeningElement()  // the node\n                })\n              }),\n              ...  // 0-n times\n            ]\n          })\n        })\n\n        except:\n\n        DoExpression({\n          ...,\n          body: BlockStatement({\n            ...,\n            body: [\n              ExpressionStatement({\n                ...,\n                expression: JSXElement({\n                  ...,\n                  openingElement: JSXOpeningElement()  // the node\n                })\n              }),\n              ...  // 0-n times\n            ]\n          })\n        })\n      */\n      const isInExpStmt = (\n        node.parent\n        && node.parent.parent\n        && node.parent.parent.type === 'ExpressionStatement'\n      );\n      if (!isInExpStmt) {\n        return false;\n      }\n\n      const expStmt = node.parent.parent;\n      const isInBlockStmtWithinDoExp = (\n        expStmt.parent\n        && expStmt.parent.type === 'BlockStatement'\n        && expStmt.parent.parent\n        && expStmt.parent.parent.type === 'DoExpression'\n      );\n      if (!isInBlockStmtWithinDoExp) {\n        return false;\n      }\n\n      const blockStmt = expStmt.parent;\n      const blockStmtFirstExp = blockStmt.body[0];\n      return !(blockStmtFirstExp === expStmt);\n    }\n\n    /**\n     * Check indent for nodes list\n     * @param {ASTNode} node The node to check\n     * @param {number} indent needed indent\n     * @param {boolean} [excludeCommas] skip comma on start of line\n     */\n    function checkNodesIndent(node, indent, excludeCommas) {\n      const nodeIndent = getNodeIndent(node, false, excludeCommas);\n      const isCorrectRightInLogicalExp = isRightInLogicalExp(node) && (nodeIndent - indent) === indentSize;\n      const isCorrectAlternateInCondExp = isAlternateInConditionalExp(node) && (nodeIndent - indent) === 0;\n      if (\n        nodeIndent !== indent\n        && astUtil.isNodeFirstInLine(context, node)\n        && !isCorrectRightInLogicalExp\n        && !isCorrectAlternateInCondExp\n      ) {\n        report(node, indent, nodeIndent);\n      }\n    }\n\n    /**\n     * Check indent for Literal Node or JSXText Node\n     * @param {ASTNode} node The node to check\n     * @param {number} indent needed indent\n     */\n    function checkLiteralNodeIndent(node, indent) {\n      const value = node.value;\n      const regExp = indentType === 'space' ? /\\n( *)[\\t ]*\\S/g : /\\n(\\t*)[\\t ]*\\S/g;\n      const nodeIndentsPerLine = Array.from(\n        matchAll(String(value), regExp),\n        (match) => (match[1] ? match[1].length : 0)\n      );\n      const hasFirstInLineNode = nodeIndentsPerLine.length > 0;\n      if (\n        hasFirstInLineNode\n        && !nodeIndentsPerLine.every((actualIndent) => actualIndent === indent)\n      ) {\n        nodeIndentsPerLine.forEach((nodeIndent) => {\n          report(node, indent, nodeIndent);\n        });\n      }\n    }\n\n    function handleOpeningElement(node) {\n      const sourceCode = getSourceCode(context);\n      let prevToken = sourceCode.getTokenBefore(node);\n      if (!prevToken) {\n        return;\n      }\n      // Use the parent in a list or an array\n      if (prevToken.type === 'JSXText' || ((prevToken.type === 'Punctuator') && prevToken.value === ',')) {\n        prevToken = sourceCode.getNodeByRangeIndex(prevToken.range[0]);\n        prevToken = prevToken.type === 'Literal' || prevToken.type === 'JSXText' ? prevToken.parent : prevToken;\n      // Use the first non-punctuator token in a conditional expression\n      } else if (prevToken.type === 'Punctuator' && prevToken.value === ':') {\n        do {\n          prevToken = sourceCode.getTokenBefore(prevToken);\n        } while (prevToken.type === 'Punctuator' && prevToken.value !== '/');\n        prevToken = sourceCode.getNodeByRangeIndex(prevToken.range[0]);\n        while (prevToken.parent && prevToken.parent.type !== 'ConditionalExpression') {\n          prevToken = prevToken.parent;\n        }\n      }\n      prevToken = prevToken.type === 'JSXExpressionContainer' ? prevToken.expression : prevToken;\n      const parentElementIndent = getNodeIndent(prevToken);\n      const indent = (\n        prevToken.loc.start.line === node.loc.start.line\n        || isRightInLogicalExp(node)\n        || isAlternateInConditionalExp(node)\n        || isSecondOrSubsequentExpWithinDoExp(node)\n      ) ? 0 : indentSize;\n      checkNodesIndent(node, parentElementIndent + indent);\n    }\n\n    function handleClosingElement(node) {\n      if (!node.parent) {\n        return;\n      }\n      const peerElementIndent = getNodeIndent(node.parent.openingElement || node.parent.openingFragment);\n      checkNodesIndent(node, peerElementIndent);\n    }\n\n    function handleAttribute(node) {\n      if (!checkAttributes || (!node.value || node.value.type !== 'JSXExpressionContainer')) {\n        return;\n      }\n      const nameIndent = getNodeIndent(node.name);\n      const lastToken = getSourceCode(context).getLastToken(node.value);\n      const firstInLine = astUtil.getFirstNodeInLine(context, lastToken);\n      const indent = node.name.loc.start.line === firstInLine.loc.start.line ? 0 : nameIndent;\n      checkNodesIndent(firstInLine, indent);\n    }\n\n    function handleLiteral(node) {\n      if (!node.parent) {\n        return;\n      }\n      if (node.parent.type !== 'JSXElement' && node.parent.type !== 'JSXFragment') {\n        return;\n      }\n      const parentNodeIndent = getNodeIndent(node.parent);\n      checkLiteralNodeIndent(node, parentNodeIndent + indentSize);\n    }\n\n    return {\n      JSXOpeningElement: handleOpeningElement,\n      JSXOpeningFragment: handleOpeningElement,\n      JSXClosingElement: handleClosingElement,\n      JSXClosingFragment: handleClosingElement,\n      JSXAttribute: handleAttribute,\n      JSXExpressionContainer(node) {\n        if (!node.parent) {\n          return;\n        }\n        const parentNodeIndent = getNodeIndent(node.parent);\n        checkNodesIndent(node, parentNodeIndent + indentSize);\n      },\n      Literal: handleLiteral,\n      JSXText: handleLiteral,\n\n      ReturnStatement(node) {\n        if (\n          !node.parent\n          || !jsxUtil.isJSX(node.argument)\n        ) {\n          return;\n        }\n\n        let fn = node.parent;\n        while (fn && fn.type !== 'FunctionDeclaration' && fn.type !== 'FunctionExpression') {\n          fn = fn.parent;\n        }\n        if (\n          !fn\n          || !jsxUtil.isReturningJSX(context, node, true)\n        ) {\n          return;\n        }\n\n        const openingIndent = getNodeIndent(node);\n        const closingIndent = getNodeIndent(node, true);\n\n        if (openingIndent !== closingIndent) {\n          report(node, openingIndent, closingIndent);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-key.js",
    "content": "/**\n * @fileoverview Report missing `key` props in iterators/collection literals.\n * @author Ben Mosher\n */\n\n'use strict';\n\nconst hasProp = require('jsx-ast-utils/hasProp');\nconst propName = require('jsx-ast-utils/propName');\nconst values = require('object.values');\nconst docsUrl = require('../util/docsUrl');\nconst pragmaUtil = require('../util/pragma');\nconst report = require('../util/report');\nconst astUtil = require('../util/ast');\nconst getText = require('../util/eslint').getText;\nconst isJSX = require('../util/jsx').isJSX;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst defaultOptions = {\n  checkFragmentShorthand: false,\n  checkKeyMustBeforeSpread: false,\n  warnOnDuplicates: false,\n};\n\nconst messages = {\n  missingIterKey: 'Missing \"key\" prop for element in iterator',\n  missingIterKeyUsePrag: 'Missing \"key\" prop for element in iterator. Shorthand fragment syntax does not support providing keys. Use {{reactPrag}}.{{fragPrag}} instead',\n  missingArrayKey: 'Missing \"key\" prop for element in array',\n  missingArrayKeyUsePrag: 'Missing \"key\" prop for element in array. Shorthand fragment syntax does not support providing keys. Use {{reactPrag}}.{{fragPrag}} instead',\n  keyBeforeSpread: '`key` prop must be placed before any `{...spread}, to avoid conflicting with React’s new JSX transform: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html`',\n  nonUniqueKeys: '`key` prop must be unique',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow missing `key` props in iterators/collection literals',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('jsx-key'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        checkFragmentShorthand: {\n          type: 'boolean',\n          default: defaultOptions.checkFragmentShorthand,\n        },\n        checkKeyMustBeforeSpread: {\n          type: 'boolean',\n          default: defaultOptions.checkKeyMustBeforeSpread,\n        },\n        warnOnDuplicates: {\n          type: 'boolean',\n          default: defaultOptions.warnOnDuplicates,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const options = Object.assign({}, defaultOptions, context.options[0]);\n    const checkFragmentShorthand = options.checkFragmentShorthand;\n    const checkKeyMustBeforeSpread = options.checkKeyMustBeforeSpread;\n    const warnOnDuplicates = options.warnOnDuplicates;\n    const reactPragma = pragmaUtil.getFromContext(context);\n    const fragmentPragma = pragmaUtil.getFragmentFromContext(context);\n\n    function isKeyAfterSpread(attributes) {\n      let hasFoundSpread = false;\n      return attributes.some((attribute) => {\n        if (attribute.type === 'JSXSpreadAttribute') {\n          hasFoundSpread = true;\n          return false;\n        }\n        if (attribute.type !== 'JSXAttribute') {\n          return false;\n        }\n        return hasFoundSpread && propName(attribute) === 'key';\n      });\n    }\n\n    function checkIteratorElement(node) {\n      if (node.type === 'JSXElement') {\n        if (!hasProp(node.openingElement.attributes, 'key')) {\n          report(context, messages.missingIterKey, 'missingIterKey', { node });\n        } else {\n          const attrs = node.openingElement.attributes;\n\n          if (checkKeyMustBeforeSpread && isKeyAfterSpread(attrs)) {\n            report(context, messages.keyBeforeSpread, 'keyBeforeSpread', { node });\n          }\n        }\n      } else if (checkFragmentShorthand && node.type === 'JSXFragment') {\n        report(context, messages.missingIterKeyUsePrag, 'missingIterKeyUsePrag', {\n          node,\n          data: {\n            reactPrag: reactPragma,\n            fragPrag: fragmentPragma,\n          },\n        });\n      }\n    }\n\n    function getReturnStatements(node) {\n      const returnStatements = arguments[1] || [];\n      if (node.type === 'IfStatement') {\n        if (node.consequent) {\n          getReturnStatements(node.consequent, returnStatements);\n        }\n        if (node.alternate) {\n          getReturnStatements(node.alternate, returnStatements);\n        }\n      } else if (node.type === 'ReturnStatement') {\n        returnStatements.push(node);\n      } else if (Array.isArray(node.body)) {\n        node.body.forEach((item) => {\n          if (item.type === 'IfStatement') {\n            getReturnStatements(item, returnStatements);\n          }\n\n          if (item.type === 'ReturnStatement') {\n            returnStatements.push(item);\n          }\n        });\n      }\n\n      return returnStatements;\n    }\n\n    /**\n     * Checks if the given node is a function expression or arrow function,\n     * and checks if there is a missing key prop in return statement's arguments\n     * @param {ASTNode} node\n     */\n    function checkFunctionsBlockStatement(node) {\n      if (astUtil.isFunctionLikeExpression(node)) {\n        if (node.body.type === 'BlockStatement') {\n          getReturnStatements(node.body)\n            .filter((returnStatement) => returnStatement && returnStatement.argument)\n            .forEach((returnStatement) => {\n              const argument = returnStatement.argument;\n\n              if (argument.type === 'ConditionalExpression') {\n                if (isJSX(argument.consequent)) {\n                  checkIteratorElement(argument.consequent);\n                }\n                if (isJSX(argument.alternate)) {\n                  checkIteratorElement(argument.alternate);\n                }\n              } else if (argument.type === 'LogicalExpression' && isJSX(argument.right)) {\n                checkIteratorElement(argument.right);\n              } else {\n                checkIteratorElement(argument);\n              }\n            });\n        }\n      }\n    }\n\n    /**\n     * Checks if the given node is an arrow function that has an JSX Element or JSX Fragment in its body,\n     * and the JSX is missing a key prop\n     * @param {ASTNode} node\n     */\n    function checkArrowFunctionWithJSX(node) {\n      const isArrFn = node && node.type === 'ArrowFunctionExpression';\n      if (isArrFn && isJSX(node.body)) {\n        checkIteratorElement(node.body);\n      }\n      if (node.body.type === 'ConditionalExpression') {\n        if (isJSX(node.body.consequent)) {\n          checkIteratorElement(node.body.consequent);\n        }\n        if (isJSX(node.body.alternate)) {\n          checkIteratorElement(node.body.alternate);\n        }\n      } else if (node.body.type === 'LogicalExpression' && isJSX(node.body.right)) {\n        checkIteratorElement(node.body.right);\n      }\n    }\n\n    const childrenToArraySelector = `:matches(\n      CallExpression\n        [callee.object.object.name=${reactPragma}]\n        [callee.object.property.name=Children]\n        [callee.property.name=toArray],\n      CallExpression\n        [callee.object.name=Children]\n        [callee.property.name=toArray]\n    )`.replace(/\\s/g, '');\n    let isWithinChildrenToArray = false;\n\n    const seen = new WeakSet();\n\n    return {\n      [childrenToArraySelector]() {\n        isWithinChildrenToArray = true;\n      },\n\n      [`${childrenToArraySelector}:exit`]() {\n        isWithinChildrenToArray = false;\n      },\n\n      'ArrayExpression, JSXElement > JSXElement'(node) {\n        if (isWithinChildrenToArray) {\n          return;\n        }\n\n        const jsx = (node.type === 'ArrayExpression' ? node.elements : node.parent.children).filter((x) => x && x.type === 'JSXElement');\n        if (jsx.length === 0) {\n          return;\n        }\n\n        const map = {};\n        jsx.forEach((element) => {\n          const attrs = element.openingElement.attributes;\n          const keys = attrs.filter((x) => x.name && x.name.name === 'key');\n\n          if (keys.length === 0) {\n            if (node.type === 'ArrayExpression') {\n              report(context, messages.missingArrayKey, 'missingArrayKey', {\n                node: element,\n              });\n            }\n          } else {\n            keys.forEach((attr) => {\n              const value = getText(context, attr.value);\n              if (!map[value]) { map[value] = []; }\n              map[value].push(attr);\n\n              if (checkKeyMustBeforeSpread && isKeyAfterSpread(attrs)) {\n                report(context, messages.keyBeforeSpread, 'keyBeforeSpread', {\n                  node: node.type === 'ArrayExpression' ? node : node.parent,\n                });\n              }\n            });\n          }\n        });\n\n        if (warnOnDuplicates) {\n          values(map).filter((v) => v.length > 1).forEach((v) => {\n            v.forEach((n) => {\n              if (!seen.has(n)) {\n                seen.add(n);\n                report(context, messages.nonUniqueKeys, 'nonUniqueKeys', {\n                  node: n,\n                });\n              }\n            });\n          });\n        }\n      },\n\n      JSXFragment(node) {\n        if (!checkFragmentShorthand || isWithinChildrenToArray) {\n          return;\n        }\n\n        if (node.parent.type === 'ArrayExpression') {\n          report(context, messages.missingArrayKeyUsePrag, 'missingArrayKeyUsePrag', {\n            node,\n            data: {\n              reactPrag: reactPragma,\n              fragPrag: fragmentPragma,\n            },\n          });\n        }\n      },\n\n      // Array.prototype.map\n      // eslint-disable-next-line no-multi-str\n      'CallExpression[callee.type=\"MemberExpression\"][callee.property.name=\"map\"],\\\n       CallExpression[callee.type=\"OptionalMemberExpression\"][callee.property.name=\"map\"],\\\n       OptionalCallExpression[callee.type=\"MemberExpression\"][callee.property.name=\"map\"],\\\n       OptionalCallExpression[callee.type=\"OptionalMemberExpression\"][callee.property.name=\"map\"]'(node) {\n        if (isWithinChildrenToArray) {\n          return;\n        }\n\n        const fn = node.arguments.length > 0 && node.arguments[0];\n        if (!fn || !astUtil.isFunctionLikeExpression(fn)) {\n          return;\n        }\n\n        checkArrowFunctionWithJSX(fn);\n\n        checkFunctionsBlockStatement(fn);\n      },\n\n      // Array.from\n      'CallExpression[callee.type=\"MemberExpression\"][callee.property.name=\"from\"]'(node) {\n        if (isWithinChildrenToArray) {\n          return;\n        }\n\n        const fn = node.arguments.length > 1 && node.arguments[1];\n        if (!astUtil.isFunctionLikeExpression(fn)) {\n          return;\n        }\n\n        checkArrowFunctionWithJSX(fn);\n\n        checkFunctionsBlockStatement(fn);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-max-depth.js",
    "content": "/**\n * @fileoverview Validate JSX maximum depth\n * @author Chris<wfsr@foxmail.com>\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst includes = require('array-includes');\nconst variableUtil = require('../util/variable');\nconst jsxUtil = require('../util/jsx');\nconst docsUrl = require('../util/docsUrl');\nconst reportC = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  wrongDepth: 'Expected the depth of nested jsx elements to be <= {{needed}}, but found {{found}}.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce JSX maximum depth',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-max-depth'),\n    },\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          max: {\n            type: 'integer',\n            minimum: 0,\n          },\n        },\n        additionalProperties: false,\n      },\n    ],\n  },\n  create(context) {\n    const DEFAULT_DEPTH = 2;\n\n    const option = context.options[0] || {};\n    const maxDepth = has(option, 'max') ? option.max : DEFAULT_DEPTH;\n\n    function isExpression(node) {\n      return node.type === 'JSXExpressionContainer';\n    }\n\n    function hasJSX(node) {\n      return jsxUtil.isJSX(node) || (isExpression(node) && jsxUtil.isJSX(node.expression));\n    }\n\n    function isLeaf(node) {\n      const children = node.children;\n\n      return !children || children.length === 0 || !children.some(hasJSX);\n    }\n\n    function getDepth(node) {\n      let count = 0;\n\n      while (jsxUtil.isJSX(node.parent) || isExpression(node.parent)) {\n        node = node.parent;\n        if (jsxUtil.isJSX(node)) {\n          count += 1;\n        }\n      }\n\n      return count;\n    }\n\n    function report(node, depth) {\n      reportC(context, messages.wrongDepth, 'wrongDepth', {\n        node,\n        data: {\n          found: depth,\n          needed: maxDepth,\n        },\n      });\n    }\n\n    function findJSXElementOrFragment(startNode, name, previousReferences) {\n      function find(refs, prevRefs) {\n        for (let i = refs.length - 1; i >= 0; i--) {\n          if (typeof refs[i].writeExpr !== 'undefined') {\n            const writeExpr = refs[i].writeExpr;\n\n            return (jsxUtil.isJSX(writeExpr)\n              && writeExpr)\n              || ((writeExpr && writeExpr.type === 'Identifier')\n              && findJSXElementOrFragment(startNode, writeExpr.name, prevRefs));\n          }\n        }\n\n        return null;\n      }\n\n      const variable = variableUtil.getVariableFromContext(context, startNode, name);\n      if (variable && variable.references) {\n        const containDuplicates = previousReferences.some((ref) => includes(variable.references, ref));\n\n        // Prevent getting stuck in circular references\n        if (containDuplicates) {\n          return false;\n        }\n\n        return find(variable.references, previousReferences.concat(variable.references));\n      }\n\n      return false;\n    }\n\n    function checkDescendant(baseDepth, children) {\n      baseDepth += 1;\n      (children || []).filter((node) => hasJSX(node)).forEach((node) => {\n        if (baseDepth > maxDepth) {\n          report(node, baseDepth);\n        } else if (!isLeaf(node)) {\n          checkDescendant(baseDepth, node.children);\n        }\n      });\n    }\n\n    function handleJSX(node) {\n      if (!isLeaf(node)) {\n        return;\n      }\n\n      const depth = getDepth(node);\n      if (depth > maxDepth) {\n        report(node, depth);\n      }\n    }\n\n    return {\n      JSXElement: handleJSX,\n      JSXFragment: handleJSX,\n\n      JSXExpressionContainer(node) {\n        if (node.expression.type !== 'Identifier') {\n          return;\n        }\n\n        const element = findJSXElementOrFragment(node, node.expression.name, []);\n\n        if (element) {\n          const baseDepth = getDepth(node);\n          checkDescendant(baseDepth, element.children);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-max-props-per-line.js",
    "content": "/**\n * @fileoverview Limit maximum of props on a single line in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst report = require('../util/report');\n\nfunction getPropName(context, propNode) {\n  if (propNode.type === 'JSXSpreadAttribute') {\n    return getText(context, propNode.argument);\n  }\n  return propNode.name.name;\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  newLine: 'Prop `{{prop}}` must be placed on a new line',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce maximum of props on a single line in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-max-props-per-line'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      anyOf: [{\n        type: 'object',\n        properties: {\n          maximum: {\n            type: 'object',\n            properties: {\n              single: {\n                type: 'integer',\n                minimum: 1,\n              },\n              multi: {\n                type: 'integer',\n                minimum: 1,\n              },\n            },\n          },\n        },\n        additionalProperties: false,\n      }, {\n        type: 'object',\n        properties: {\n          maximum: {\n            type: 'number',\n            minimum: 1,\n          },\n          when: {\n            type: 'string',\n            enum: ['always', 'multiline'],\n          },\n        },\n        additionalProperties: false,\n      }],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const maximum = configuration.maximum || 1;\n\n    const maxConfig = typeof maximum === 'number'\n      ? {\n        single: configuration.when === 'multiline' ? Infinity : maximum,\n        multi: maximum,\n      }\n      : {\n        single: maximum.single || Infinity,\n        multi: maximum.multi || Infinity,\n      };\n\n    function generateFixFunction(line, max) {\n      const output = [];\n      const front = line[0].range[0];\n      const back = line[line.length - 1].range[1];\n\n      for (let i = 0; i < line.length; i += max) {\n        const nodes = line.slice(i, i + max);\n        output.push(nodes.reduce((prev, curr) => {\n          if (prev === '') {\n            return getText(context, curr);\n          }\n          return `${prev} ${getText(context, curr)}`;\n        }, ''));\n      }\n\n      const code = output.join('\\n');\n\n      return function fix(fixer) {\n        return fixer.replaceTextRange([front, back], code);\n      };\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        if (!node.attributes.length) {\n          return;\n        }\n\n        const isSingleLineTag = node.loc.start.line === node.loc.end.line;\n\n        if ((isSingleLineTag ? maxConfig.single : maxConfig.multi) === Infinity) {\n          return;\n        }\n\n        const firstProp = node.attributes[0];\n        const linePartitionedProps = [[firstProp]];\n\n        node.attributes.reduce((last, decl) => {\n          if (last.loc.end.line === decl.loc.start.line) {\n            linePartitionedProps[linePartitionedProps.length - 1].push(decl);\n          } else {\n            linePartitionedProps.push([decl]);\n          }\n          return decl;\n        });\n\n        linePartitionedProps.forEach((propsInLine) => {\n          const maxPropsCountPerLine = isSingleLineTag && propsInLine[0].loc.start.line === node.loc.start.line\n            ? maxConfig.single\n            : maxConfig.multi;\n\n          if (propsInLine.length > maxPropsCountPerLine) {\n            const name = getPropName(context, propsInLine[maxPropsCountPerLine]);\n            report(context, messages.newLine, 'newLine', {\n              node: propsInLine[maxPropsCountPerLine],\n              data: {\n                prop: name,\n              },\n              fix: generateFixFunction(propsInLine, maxPropsCountPerLine),\n            });\n          }\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-newline.js",
    "content": "/**\n * @fileoverview Require or prevent a new line after jsx elements and expressions.\n * @author Johnny Zabala\n * @author Joseph Stiles\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  require: 'JSX element should start in a new line',\n  prevent: 'JSX element should not start in a new line',\n  allowMultilines: 'Multiline JSX elements should start in a new line',\n};\n\nfunction isMultilined(node) {\n  return node && node.loc.start.line !== node.loc.end.line;\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Require or prevent a new line after jsx elements and expressions.',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-newline'),\n    },\n    fixable: 'code',\n\n    messages,\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          prevent: {\n            default: false,\n            type: 'boolean',\n          },\n          allowMultilines: {\n            default: false,\n            type: 'boolean',\n          },\n        },\n        additionalProperties: false,\n        if: {\n          properties: {\n            allowMultilines: {\n              const: true,\n            },\n          },\n        },\n        then: {\n          properties: {\n            prevent: {\n              const: true,\n            },\n          },\n          required: [\n            'prevent',\n          ],\n        },\n      },\n    ],\n  },\n  create(context) {\n    const jsxElementParents = new Set();\n\n    function isBlockCommentInCurlyBraces(element) {\n      const elementRawValue = getText(context, element);\n      return /^\\s*{\\/\\*/.test(elementRawValue);\n    }\n\n    function isNonBlockComment(element) {\n      return !isBlockCommentInCurlyBraces(element) && (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer');\n    }\n\n    return {\n      'Program:exit'() {\n        jsxElementParents.forEach((parent) => {\n          parent.children.forEach((element, index, elements) => {\n            if (element.type === 'JSXElement' || element.type === 'JSXExpressionContainer') {\n              const configuration = context.options[0] || {};\n              const prevent = configuration.prevent || false;\n              const allowMultilines = configuration.allowMultilines || false;\n\n              const firstAdjacentSibling = elements[index + 1];\n              const secondAdjacentSibling = elements[index + 2];\n\n              const hasSibling = firstAdjacentSibling\n              && secondAdjacentSibling\n              && (firstAdjacentSibling.type === 'Literal' || firstAdjacentSibling.type === 'JSXText');\n\n              if (!hasSibling) return;\n\n              // Check adjacent sibling has the proper amount of newlines\n              const isWithoutNewLine = !/\\n\\s*\\n/.test(firstAdjacentSibling.value);\n\n              if (isBlockCommentInCurlyBraces(element)) return;\n              if (\n                allowMultilines\n                && (\n                  isMultilined(element)\n                  || isMultilined(elements.slice(index + 2).find(isNonBlockComment))\n                )\n              ) {\n                if (!isWithoutNewLine) return;\n\n                const regex = /(\\n)(?!.*\\1)/g;\n                const replacement = '\\n\\n';\n                const messageId = 'allowMultilines';\n\n                report(context, messages[messageId], messageId, {\n                  node: secondAdjacentSibling,\n                  fix(fixer) {\n                    return fixer.replaceText(\n                      firstAdjacentSibling,\n                      getText(context, firstAdjacentSibling).replace(regex, replacement)\n                    );\n                  },\n                });\n\n                return;\n              }\n\n              if (isWithoutNewLine === prevent) return;\n\n              const messageId = prevent\n                ? 'prevent'\n                : 'require';\n\n              const regex = prevent\n                ? /(\\n\\n)(?!.*\\1)/g\n                : /(\\n)(?!.*\\1)/g;\n\n              const replacement = prevent\n                ? '\\n'\n                : '\\n\\n';\n\n              report(context, messages[messageId], messageId, {\n                node: secondAdjacentSibling,\n                fix(fixer) {\n                  return fixer.replaceText(\n                    firstAdjacentSibling,\n                    // double or remove the last newline\n                    getText(context, firstAdjacentSibling).replace(regex, replacement)\n                  );\n                },\n              });\n            }\n          });\n        });\n      },\n      ':matches(JSXElement, JSXFragment) > :matches(JSXElement, JSXExpressionContainer)': (node) => {\n        jsxElementParents.add(node.parent);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-bind.js",
    "content": "/**\n * @fileoverview Prevents usage of Function.prototype.bind and arrow functions\n *               in React component props.\n * @author Daniel Lo Nigro <dan.cx>\n * @author Jacky Ho\n */\n\n'use strict';\n\nconst propName = require('jsx-ast-utils/propName');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\nconst getAncestors = require('../util/eslint').getAncestors;\n\n// -----------------------------------------------------------------------------\n// Rule Definition\n// -----------------------------------------------------------------------------\n\nconst messages = {\n  bindCall: 'JSX props should not use .bind()',\n  arrowFunc: 'JSX props should not use arrow functions',\n  bindExpression: 'JSX props should not use ::',\n  func: 'JSX props should not use functions',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow `.bind()` or arrow functions in JSX props',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('jsx-no-bind'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowArrowFunctions: {\n          default: false,\n          type: 'boolean',\n        },\n        allowBind: {\n          default: false,\n          type: 'boolean',\n        },\n        allowFunctions: {\n          default: false,\n          type: 'boolean',\n        },\n        ignoreRefs: {\n          default: false,\n          type: 'boolean',\n        },\n        ignoreDOMComponents: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n\n    // Keep track of all the variable names pointing to a bind call,\n    // bind expression or an arrow function in different block statements\n    const blockVariableNameSets = {};\n\n    /**\n     * @param {string | number} blockStart\n     */\n    function setBlockVariableNameSet(blockStart) {\n      blockVariableNameSets[blockStart] = {\n        arrowFunc: new Set(),\n        bindCall: new Set(),\n        bindExpression: new Set(),\n        func: new Set(),\n      };\n    }\n\n    function getNodeViolationType(node) {\n      if (\n        !configuration.allowBind\n        && astUtil.isCallExpression(node)\n        && node.callee.type === 'MemberExpression'\n        && node.callee.property.type === 'Identifier'\n        && node.callee.property.name === 'bind'\n      ) {\n        return 'bindCall';\n      }\n      if (node.type === 'ConditionalExpression') {\n        return getNodeViolationType(node.test)\n               || getNodeViolationType(node.consequent)\n               || getNodeViolationType(node.alternate);\n      }\n      if (!configuration.allowArrowFunctions && node.type === 'ArrowFunctionExpression') {\n        return 'arrowFunc';\n      }\n      if (\n        !configuration.allowFunctions\n        && (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration')\n      ) {\n        return 'func';\n      }\n      if (!configuration.allowBind && node.type === 'BindExpression') {\n        return 'bindExpression';\n      }\n\n      return null;\n    }\n\n    /**\n     * @param {string | number} violationType\n     * @param {unknown} variableName\n     * @param {string | number} blockStart\n     */\n    function addVariableNameToSet(violationType, variableName, blockStart) {\n      blockVariableNameSets[blockStart][violationType].add(variableName);\n    }\n\n    function getBlockStatementAncestors(node) {\n      return getAncestors(context, node).filter(\n        (ancestor) => ancestor.type === 'BlockStatement'\n      ).reverse();\n    }\n\n    function reportVariableViolation(node, name, blockStart) {\n      const blockSets = blockVariableNameSets[blockStart];\n      const violationTypes = Object.keys(blockSets);\n\n      return violationTypes.find((type) => {\n        if (blockSets[type].has(name)) {\n          report(context, messages[type], type, {\n            node,\n          });\n          return true;\n        }\n\n        return false;\n      });\n    }\n\n    function findVariableViolation(node, name) {\n      getBlockStatementAncestors(node).find(\n        (block) => reportVariableViolation(node, name, block.range[0])\n      );\n    }\n\n    return {\n      BlockStatement(node) {\n        setBlockVariableNameSet(node.range[0]);\n      },\n\n      FunctionDeclaration(node) {\n        const blockAncestors = getBlockStatementAncestors(node);\n        const variableViolationType = getNodeViolationType(node);\n\n        if (blockAncestors.length > 0 && variableViolationType) {\n          addVariableNameToSet(variableViolationType, node.id.name, blockAncestors[0].range[0]);\n        }\n      },\n\n      VariableDeclarator(node) {\n        if (!node.init) {\n          return;\n        }\n        const blockAncestors = getBlockStatementAncestors(node);\n        const variableViolationType = getNodeViolationType(node.init);\n\n        if (\n          blockAncestors.length > 0\n          && variableViolationType\n          && 'kind' in node.parent\n          && node.parent.kind === 'const' // only support const right now\n        ) {\n          addVariableNameToSet(variableViolationType, 'name' in node.id ? node.id.name : undefined, blockAncestors[0].range[0]);\n        }\n      },\n\n      JSXAttribute(node) {\n        const isRef = configuration.ignoreRefs && propName(node) === 'ref';\n        if (isRef || !node.value || !node.value.expression) {\n          return;\n        }\n        const isDOMComponent = jsxUtil.isDOMComponent(node.parent);\n        if (configuration.ignoreDOMComponents && isDOMComponent) {\n          return;\n        }\n        const valueNode = node.value.expression;\n        const valueNodeType = valueNode.type;\n        const nodeViolationType = getNodeViolationType(valueNode);\n\n        if (valueNodeType === 'Identifier') {\n          findVariableViolation(node, valueNode.name);\n        } else if (nodeViolationType) {\n          report(context, messages[nodeViolationType], nodeViolationType, {\n            node,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-comment-textnodes.js",
    "content": "/**\n * @fileoverview Comments inside children section of tag should be placed inside braces.\n * @author Ben Vinegar\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  putCommentInBraces: 'Comments inside children section of tag should be placed inside braces',\n};\n\n/**\n * @param {Context} context\n * @param {ASTNode} node\n * @returns {void}\n */\nfunction checkText(context, node) {\n  // since babel-eslint has the wrong node.raw, we'll get the source text\n  const rawValue = getText(context, node);\n  if (/^\\s*\\/(\\/|\\*)/m.test(rawValue)) {\n    // inside component, e.g. <div>literal</div>\n    if (\n      node.parent.type !== 'JSXAttribute'\n      && node.parent.type !== 'JSXExpressionContainer'\n      && node.parent.type.indexOf('JSX') !== -1\n    ) {\n      report(context, messages.putCommentInBraces, 'putCommentInBraces', {\n        node,\n      });\n    }\n  }\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow comments from being inserted as text nodes',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('jsx-no-comment-textnodes'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      Literal(node) {\n        checkText(context, node);\n      },\n      JSXText(node) {\n        checkText(context, node);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-constructed-context-values.js",
    "content": "/**\n * @fileoverview Prevents jsx context provider values from taking values that\n *               will cause needless rerenders.\n * @author Dylan Oshima\n */\n\n'use strict';\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst getScope = require('../util/eslint').getScope;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n// Recursively checks if an element is a construction.\n// A construction is a variable that changes identity every render.\nfunction isConstruction(node, callScope) {\n  switch (node.type) {\n    case 'Literal':\n      if (node.regex != null) {\n        return { type: 'regular expression', node };\n      }\n      return null;\n    case 'Identifier': {\n      const variableScoping = callScope.set.get(node.name);\n\n      if (variableScoping == null || variableScoping.defs == null) {\n        // If it's not in scope, we don't care.\n        return null; // Handled\n      }\n\n      // Gets the last variable identity\n      const variableDefs = variableScoping.defs;\n      const def = variableDefs[variableDefs.length - 1];\n      if (def != null\n        && def.type !== 'Variable'\n        && def.type !== 'FunctionName'\n      ) {\n        // Parameter or an unusual pattern. Bail out.\n        return null; // Unhandled\n      }\n\n      if (def.node.type === 'FunctionDeclaration') {\n        return { type: 'function declaration', node: def.node, usage: node };\n      }\n\n      const init = def.node.init;\n      if (init == null) {\n        return null;\n      }\n\n      const initConstruction = isConstruction(init, callScope);\n      if (initConstruction == null) {\n        return null;\n      }\n\n      return {\n        type: initConstruction.type,\n        node: initConstruction.node,\n        usage: node,\n      };\n    }\n    case 'ObjectExpression':\n      // Any object initialized inline will create a new identity\n      return { type: 'object', node };\n    case 'ArrayExpression':\n      return { type: 'array', node };\n    case 'ArrowFunctionExpression':\n    case 'FunctionExpression':\n      // Functions that are initialized inline will have a new identity\n      return { type: 'function expression', node };\n    case 'ClassExpression':\n      return { type: 'class expression', node };\n    case 'NewExpression':\n      // `const a = new SomeClass();` is a construction\n      return { type: 'new expression', node };\n    case 'ConditionalExpression':\n      return (isConstruction(node.consequent, callScope)\n        || isConstruction(node.alternate, callScope)\n      );\n    case 'LogicalExpression':\n      return (isConstruction(node.left, callScope)\n        || isConstruction(node.right, callScope)\n      );\n    case 'MemberExpression': {\n      const objConstruction = isConstruction(node.object, callScope);\n      if (objConstruction == null) {\n        return null;\n      }\n      return {\n        type: objConstruction.type,\n        node: objConstruction.node,\n        usage: node.object,\n      };\n    }\n    case 'JSXFragment':\n      return { type: 'JSX fragment', node };\n    case 'JSXElement':\n      return { type: 'JSX element', node };\n    case 'AssignmentExpression': {\n      const construct = isConstruction(node.right, callScope);\n      if (construct != null) {\n        return {\n          type: 'assignment expression',\n          node: construct.node,\n          usage: node,\n        };\n      }\n      return null;\n    }\n    case 'TypeCastExpression':\n    case 'TSAsExpression':\n      return isConstruction(node.expression, callScope);\n    default:\n      return null;\n  }\n}\n\nfunction isReactContext(context, node) {\n  let scope = getScope(context, node);\n  let variableScoping = null;\n  const contextName = node.name;\n\n  while (scope && !variableScoping) { // Walk up the scope chain to find the variable\n    variableScoping = scope.set.get(contextName);\n    scope = scope.upper;\n  }\n\n  if (!variableScoping) { // Context was not found in scope\n    return false;\n  }\n\n  // Get the variable's definition\n  const def = variableScoping.defs[0];\n\n  if (!def || def.node.type !== 'VariableDeclarator') {\n    return false;\n  }\n\n  const init = def.node.init; // Variable initializer\n\n  const isCreateContext = init\n    && init.type === 'CallExpression'\n    && (\n      (\n        init.callee.type === 'Identifier'\n        && init.callee.name === 'createContext'\n      ) || (\n        init.callee.type === 'MemberExpression'\n        && init.callee.object.name === 'React'\n        && init.callee.property.name === 'createContext'\n      )\n    );\n\n  return isCreateContext;\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  withIdentifierMsg: \"The '{{variableName}}' {{type}} (at line {{nodeLine}}) passed as the value prop to the Context provider (at line {{usageLine}}) changes every render. To fix this consider wrapping it in a useMemo hook.\",\n  withIdentifierMsgFunc: \"The '{{variableName}}' {{type}} (at line {{nodeLine}}) passed as the value prop to the Context provider (at line {{usageLine}}) changes every render. To fix this consider wrapping it in a useCallback hook.\",\n  defaultMsg: 'The {{type}} passed as the value prop to the Context provider (at line {{nodeLine}}) changes every render. To fix this consider wrapping it in a useMemo hook.',\n  defaultMsgFunc: 'The {{type}} passed as the value prop to the Context provider (at line {{nodeLine}}) changes every render. To fix this consider wrapping it in a useCallback hook.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallows JSX context provider values from taking values that will cause needless rerenders',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('jsx-no-constructed-context-values'),\n    },\n    messages,\n    schema: false,\n  },\n\n  // eslint-disable-next-line arrow-body-style\n  create: Components.detect((context, components, utils) => {\n    return {\n      JSXOpeningElement(node) {\n        const openingElementName = node.name;\n\n        if (openingElementName.type === 'JSXMemberExpression') {\n          const isJSXContext = openingElementName.property.name === 'Provider';\n          if (!isJSXContext) {\n            // Member is not Provider\n            return;\n          }\n        } else if (openingElementName.type === 'JSXIdentifier') {\n          const isJSXContext = isReactContext(context, openingElementName);\n          if (!isJSXContext) {\n            // Member is not context\n            return;\n          }\n        } else {\n          return;\n        }\n\n        // Contexts can take in more than just a value prop\n        // so we need to iterate through all of them\n        const jsxValueAttribute = node.attributes.find(\n          (attribute) => attribute.type === 'JSXAttribute' && attribute.name.name === 'value'\n        );\n\n        if (jsxValueAttribute == null) {\n          // No value prop was passed\n          return;\n        }\n\n        const valueNode = jsxValueAttribute.value;\n        if (!valueNode) {\n          // attribute is a boolean shorthand\n          return;\n        }\n        if (valueNode.type !== 'JSXExpressionContainer') {\n          // value could be a literal\n          return;\n        }\n\n        const valueExpression = valueNode.expression;\n        const invocationScope = getScope(context, node);\n\n        // Check if the value prop is a construction\n        const constructInfo = isConstruction(valueExpression, invocationScope);\n        if (constructInfo == null) {\n          return;\n        }\n\n        if (!utils.getParentComponent(node)) {\n          return;\n        }\n\n        // Report found error\n        const constructType = constructInfo.type;\n        const constructNode = constructInfo.node;\n        const constructUsage = constructInfo.usage;\n        const data = {\n          type: constructType, nodeLine: constructNode.loc.start.line,\n        };\n        let messageId = 'defaultMsg';\n\n        // Variable passed to value prop\n        if (constructUsage != null) {\n          messageId = 'withIdentifierMsg';\n          data.usageLine = constructUsage.loc.start.line;\n          data.variableName = constructUsage.name;\n        }\n\n        // Type of expression\n        if (\n          constructType === 'function expression'\n          || constructType === 'function declaration'\n        ) {\n          messageId += 'Func';\n        }\n\n        report(context, messages[messageId], messageId, {\n          node: constructNode,\n          data,\n        });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-duplicate-props.js",
    "content": "/**\n * @fileoverview Enforce no duplicate props\n * @author Markus Ånöstam\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noDuplicateProps: 'No duplicate props allowed',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow duplicate properties in JSX',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('jsx-no-duplicate-props'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignoreCase: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const ignoreCase = configuration.ignoreCase || false;\n\n    return {\n      JSXOpeningElement(node) {\n        const props = {};\n\n        node.attributes.forEach((decl) => {\n          if (decl.type === 'JSXSpreadAttribute') {\n            return;\n          }\n\n          let name = decl.name.name;\n\n          if (typeof name !== 'string') {\n            return;\n          }\n\n          if (ignoreCase) {\n            name = name.toLowerCase();\n          }\n\n          if (has(props, name)) {\n            report(context, messages.noDuplicateProps, 'noDuplicateProps', {\n              node: decl,\n            });\n          } else {\n            props[name] = 1;\n          }\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-leaked-render.js",
    "content": "/**\n * @fileoverview Prevent problematic leaked values from being rendered\n * @author Mario Beltrán\n */\n\n'use strict';\n\nconst find = require('es-iterator-helpers/Iterator.prototype.find');\nconst from = require('es-iterator-helpers/Iterator.from');\n\nconst getText = require('../util/eslint').getText;\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst variableUtil = require('../util/variable');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst isParenthesized = require('../util/ast').isParenthesized;\n\n//------------------------------------------------------------------------------\n// Rule Definition\n//------------------------------------------------------------------------------\n\nconst messages = {\n  noPotentialLeakedRender: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n};\n\nconst COERCE_STRATEGY = 'coerce';\nconst TERNARY_STRATEGY = 'ternary';\nconst DEFAULT_VALID_STRATEGIES = [TERNARY_STRATEGY, COERCE_STRATEGY];\nconst COERCE_VALID_LEFT_SIDE_EXPRESSIONS = ['UnaryExpression', 'BinaryExpression', 'CallExpression'];\nconst TERNARY_INVALID_ALTERNATE_VALUES = [undefined, null, false];\n\nfunction trimLeftNode(node) {\n  // Remove double unary expression (boolean coercion), so we avoid trimming valid negations\n  if (node.type === 'UnaryExpression' && node.argument.type === 'UnaryExpression') {\n    return trimLeftNode(node.argument.argument);\n  }\n\n  return node;\n}\n\nfunction getIsCoerceValidNestedLogicalExpression(node) {\n  if (node.type === 'LogicalExpression') {\n    return getIsCoerceValidNestedLogicalExpression(node.left) && getIsCoerceValidNestedLogicalExpression(node.right);\n  }\n\n  return COERCE_VALID_LEFT_SIDE_EXPRESSIONS.some((validExpression) => validExpression === node.type);\n}\n\nfunction extractExpressionBetweenLogicalAnds(node) {\n  if (node.type !== 'LogicalExpression') return [node];\n  if (node.operator !== '&&') return [node];\n  return [].concat(\n    extractExpressionBetweenLogicalAnds(node.left),\n    extractExpressionBetweenLogicalAnds(node.right)\n  );\n}\n\nconst stopTypes = {\n  __proto__: null,\n  JSXElement: true,\n  JSXFragment: true,\n};\n\nfunction isWithinAttribute(node) {\n  let parent = node.parent;\n  while (!stopTypes[parent.type]) {\n    if (parent.type === 'JSXAttribute') return true;\n    parent = parent.parent;\n  }\n  return false;\n}\n\nfunction ruleFixer(context, fixStrategy, fixer, reportedNode, leftNode, rightNode) {\n  const rightSideText = getText(context, rightNode);\n\n  if (fixStrategy === COERCE_STRATEGY) {\n    const expressions = extractExpressionBetweenLogicalAnds(leftNode);\n    const newText = expressions.map((node) => {\n      let nodeText = getText(context, node);\n      if (isParenthesized(context, node)) {\n        nodeText = `(${nodeText})`;\n      }\n      if (node.parent && node.parent.type === 'ConditionalExpression' && node.parent.consequent.value === false) {\n        return `${getIsCoerceValidNestedLogicalExpression(node) ? '' : '!'}${nodeText}`;\n      }\n      return `${getIsCoerceValidNestedLogicalExpression(node) ? '' : '!!'}${nodeText}`;\n    }).join(' && ');\n\n    if (rightNode.parent && rightNode.parent.type === 'ConditionalExpression' && rightNode.parent.consequent.value === false) {\n      const consequentVal = rightNode.parent.consequent.raw || rightNode.parent.consequent.name;\n      const alternateVal = rightNode.parent.alternate.raw || rightNode.parent.alternate.name;\n      if (rightNode.parent.test && rightNode.parent.test.type === 'LogicalExpression') {\n        return fixer.replaceText(reportedNode, `${newText} ? ${consequentVal} : ${alternateVal}`);\n      }\n      return fixer.replaceText(reportedNode, `${newText} && ${alternateVal}`);\n    }\n\n    if (rightNode.type === 'ConditionalExpression' || rightNode.type === 'LogicalExpression') {\n      return fixer.replaceText(reportedNode, `${newText} && (${rightSideText})`);\n    }\n    if (rightNode.type === 'JSXElement') {\n      const rightSideTextLines = rightSideText.split('\\n');\n      if (rightSideTextLines.length > 1) {\n        const rightSideTextLastLine = rightSideTextLines[rightSideTextLines.length - 1];\n        const indentSpacesStart = ' '.repeat(rightSideTextLastLine.search(/\\S/));\n        const indentSpacesClose = ' '.repeat(rightSideTextLastLine.search(/\\S/) - 2);\n        return fixer.replaceText(reportedNode, `${newText} && (\\n${indentSpacesStart}${rightSideText}\\n${indentSpacesClose})`);\n      }\n    }\n    if (rightNode.type === 'Literal') {\n      return null;\n    }\n    return fixer.replaceText(reportedNode, `${newText} && ${rightSideText}`);\n  }\n\n  if (fixStrategy === TERNARY_STRATEGY) {\n    let leftSideText = getText(context, trimLeftNode(leftNode));\n    if (isParenthesized(context, leftNode)) {\n      leftSideText = `(${leftSideText})`;\n    }\n    return fixer.replaceText(reportedNode, `${leftSideText} ? ${rightSideText} : null`);\n  }\n\n  throw new TypeError('Invalid value for \"validStrategies\" option');\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow problematic leaked values from being rendered',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('jsx-no-leaked-render'),\n    },\n\n    messages,\n\n    fixable: 'code',\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          validStrategies: {\n            type: 'array',\n            items: {\n              enum: [\n                TERNARY_STRATEGY,\n                COERCE_STRATEGY,\n              ],\n            },\n            uniqueItems: true,\n            default: DEFAULT_VALID_STRATEGIES,\n          },\n          ignoreAttributes: {\n            type: 'boolean',\n            default: false,\n          },\n        },\n        additionalProperties: false,\n      },\n    ],\n  },\n\n  create(context) {\n    const config = context.options[0] || {};\n    const validStrategies = new Set(config.validStrategies || DEFAULT_VALID_STRATEGIES);\n    const fixStrategy = find(from(validStrategies), () => true);\n\n    return {\n      'JSXExpressionContainer > LogicalExpression[operator=\"&&\"]'(node) {\n        if (config.ignoreAttributes && isWithinAttribute(node)) {\n          return;\n        }\n        const leftSide = node.left;\n\n        const isCoerceValidLeftSide = COERCE_VALID_LEFT_SIDE_EXPRESSIONS\n          .some((validExpression) => validExpression === leftSide.type);\n        if (validStrategies.has(COERCE_STRATEGY)) {\n          if (isCoerceValidLeftSide || getIsCoerceValidNestedLogicalExpression(leftSide)) {\n            return;\n          }\n          const leftSideVar = variableUtil.getVariableFromContext(context, node, leftSide.name);\n          if (leftSideVar) {\n            const leftSideValue = leftSideVar.defs\n              && leftSideVar.defs.length\n              && leftSideVar.defs[0].node.init\n              && leftSideVar.defs[0].node.init.value;\n            if (typeof leftSideValue === 'boolean') {\n              return;\n            }\n          }\n        }\n\n        if (testReactVersion(context, '>= 18') && leftSide.type === 'Literal' && leftSide.value === '') {\n          return;\n        }\n        report(context, messages.noPotentialLeakedRender, 'noPotentialLeakedRender', {\n          node,\n          fix(fixer) {\n            return ruleFixer(context, fixStrategy, fixer, node, leftSide, node.right);\n          },\n        });\n      },\n\n      'JSXExpressionContainer > ConditionalExpression'(node) {\n        if (validStrategies.has(TERNARY_STRATEGY)) {\n          return;\n        }\n        if (config.ignoreAttributes && isWithinAttribute(node)) {\n          return;\n        }\n\n        const isValidTernaryAlternate = TERNARY_INVALID_ALTERNATE_VALUES.indexOf(node.alternate.value) === -1;\n        const isJSXElementAlternate = node.alternate.type === 'JSXElement';\n        if (isValidTernaryAlternate || isJSXElementAlternate) {\n          return;\n        }\n\n        report(context, messages.noPotentialLeakedRender, 'noPotentialLeakedRender', {\n          node,\n          fix(fixer) {\n            return ruleFixer(context, fixStrategy, fixer, node, node.test, node.consequent);\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-literals.js",
    "content": "/**\n * @fileoverview Prevent using string literals in React component definition\n * @author Caleb Morris\n * @author David Buchan-Swanson\n */\n\n'use strict';\n\nconst iterFrom = require('es-iterator-helpers/Iterator.from');\nconst map = require('es-iterator-helpers/Iterator.prototype.map');\nconst some = require('es-iterator-helpers/Iterator.prototype.some');\nconst flatMap = require('es-iterator-helpers/Iterator.prototype.flatMap');\nconst fromEntries = require('object.fromentries');\nconst entries = require('object.entries');\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\n/** @typedef {import('eslint').Rule.RuleModule} RuleModule */\n\n/** @typedef {import('../../types/rules/jsx-no-literals').Config} Config */\n/** @typedef {import('../../types/rules/jsx-no-literals').RawConfig} RawConfig */\n/** @typedef {import('../../types/rules/jsx-no-literals').ResolvedConfig} ResolvedConfig */\n/** @typedef {import('../../types/rules/jsx-no-literals').OverrideConfig} OverrideConfig */\n/** @typedef {import('../../types/rules/jsx-no-literals').ElementConfig} ElementConfig */\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n/**\n * @param {unknown} value\n * @returns {string | unknown}\n */\nfunction trimIfString(value) {\n  return typeof value === 'string' ? value.trim() : value;\n}\n\nconst reOverridableElement = /^[A-Z][\\w.]*$/;\nconst reIsWhiteSpace = /^[\\s]+$/;\nconst jsxElementTypes = new Set(['JSXElement', 'JSXFragment']);\nconst standardJSXNodeParentTypes = new Set(['JSXAttribute', 'JSXElement', 'JSXExpressionContainer', 'JSXFragment']);\n\nconst messages = {\n  invalidPropValue: 'Invalid prop value: \"{{text}}\"',\n  invalidPropValueInElement: 'Invalid prop value: \"{{text}}\" in {{element}}',\n  noStringsInAttributes: 'Strings not allowed in attributes: \"{{text}}\"',\n  noStringsInAttributesInElement: 'Strings not allowed in attributes: \"{{text}}\" in {{element}}',\n  noStringsInJSX: 'Strings not allowed in JSX files: \"{{text}}\"',\n  noStringsInJSXInElement: 'Strings not allowed in JSX files: \"{{text}}\" in {{element}}',\n  literalNotInJSXExpression: 'Missing JSX expression container around literal string: \"{{text}}\"',\n  literalNotInJSXExpressionInElement: 'Missing JSX expression container around literal string: \"{{text}}\" in {{element}}',\n  restrictedAttributeString: 'Restricted attribute string: \"{{text}}\" in {{attribute}}',\n  restrictedAttributeStringInElement: 'Restricted attribute string: \"{{text}}\" in {{attribute}} of {{element}}',\n};\n\n/** @type {Exclude<RuleModule['meta']['schema'], unknown[] | false>['properties']} */\nconst commonPropertiesSchema = {\n  noStrings: {\n    type: 'boolean',\n  },\n  allowedStrings: {\n    type: 'array',\n    uniqueItems: true,\n    items: {\n      type: 'string',\n    },\n  },\n  ignoreProps: {\n    type: 'boolean',\n  },\n  noAttributeStrings: {\n    type: 'boolean',\n  },\n  restrictedAttributes: {\n    type: 'array',\n    uniqueItems: true,\n    items: {\n      type: 'string',\n    },\n  },\n};\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Normalizes the element portion of the config\n * @param {RawConfig} config\n * @returns {ElementConfig}\n */\nfunction normalizeElementConfig(config) {\n  return {\n    type: 'element',\n    noStrings: !!config.noStrings,\n    allowedStrings: config.allowedStrings\n      ? new Set(map(iterFrom(config.allowedStrings), trimIfString))\n      : new Set(),\n    ignoreProps: !!config.ignoreProps,\n    noAttributeStrings: !!config.noAttributeStrings,\n    restrictedAttributes: config.restrictedAttributes\n      ? new Set(map(iterFrom(config.restrictedAttributes), trimIfString))\n      : new Set(),\n  };\n}\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Normalizes the config and applies default values to all config options\n * @param {RawConfig} config\n * @returns {Config}\n */\nfunction normalizeConfig(config) {\n  /** @type {Config} */\n  const normalizedConfig = Object.assign(normalizeElementConfig(config), {\n    elementOverrides: {},\n  });\n\n  if (config.elementOverrides) {\n    normalizedConfig.elementOverrides = fromEntries(\n      flatMap(\n        iterFrom(entries(config.elementOverrides)),\n        (entry) => {\n          const elementName = entry[0];\n          const rawElementConfig = entry[1];\n\n          if (!reOverridableElement.test(elementName)) {\n            return [];\n          }\n\n          return [[\n            elementName,\n            Object.assign(normalizeElementConfig(rawElementConfig), {\n              type: 'override',\n              name: elementName,\n              allowElement: !!rawElementConfig.allowElement,\n              applyToNestedElements: typeof rawElementConfig.applyToNestedElements === 'undefined' || !!rawElementConfig.applyToNestedElements,\n            }),\n          ]];\n        }\n      )\n    );\n  }\n\n  return normalizedConfig;\n}\n\nconst elementOverrides = {\n  type: 'object',\n  patternProperties: {\n    [reOverridableElement.source]: {\n      type: 'object',\n      properties: Object.assign(\n        { applyToNestedElements: { type: 'boolean' } },\n        commonPropertiesSchema\n      ),\n\n    },\n  },\n};\n\n/** @type {RuleModule} */\nmodule.exports = {\n  meta: /** @type {RuleModule['meta']} */ ({\n    docs: {\n      description: 'Disallow usage of string literals in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-no-literals'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: Object.assign(\n        { elementOverrides },\n        commonPropertiesSchema\n      ),\n      additionalProperties: false,\n    }],\n  }),\n\n  create(context) {\n    /** @type {RawConfig} */\n    const rawConfig = (context.options.length && context.options[0]) || {};\n    const config = normalizeConfig(rawConfig);\n\n    const hasElementOverrides = Object.keys(config.elementOverrides).length > 0;\n\n    /** @type {Map<string, string>} */\n    const renamedImportMap = new Map();\n\n    /**\n     * Determines if the given expression is a require statement. Supports\n     * nested MemberExpresions. ie `require('foo').nested.property`\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    function isRequireStatement(node) {\n      if (node.type === 'CallExpression') {\n        if (node.callee.type === 'Identifier') {\n          return node.callee.name === 'require';\n        }\n      }\n      if (node.type === 'MemberExpression') {\n        return isRequireStatement(node.object);\n      }\n\n      return false;\n    }\n\n    /** @typedef {{ name: string, compoundName?: string }} ElementNameFragment */\n\n    /**\n     * Gets the name of the given JSX element. Supports nested\n     * JSXMemeberExpressions. ie `<Namesapce.Component.SubComponent />`\n     * @param {ASTNode} node\n     * @returns {ElementNameFragment | undefined}\n     */\n    function getJSXElementName(node) {\n      if (node.openingElement.name.type === 'JSXIdentifier') {\n        const name = node.openingElement.name.name;\n        return {\n          name: renamedImportMap.get(name) || name,\n          compoundName: undefined,\n        };\n      }\n\n      /** @type {string[]} */\n      const nameFragments = [];\n\n      if (node.openingElement.name.type === 'JSXMemberExpression') {\n        /** @type {ASTNode} */\n        let current = node.openingElement.name;\n        while (current.type === 'JSXMemberExpression') {\n          if (current.property.type === 'JSXIdentifier') {\n            nameFragments.unshift(current.property.name);\n          }\n\n          current = current.object;\n        }\n\n        if (current.type === 'JSXIdentifier') {\n          nameFragments.unshift(current.name);\n\n          const rootFragment = nameFragments[0];\n          if (rootFragment) {\n            const rootFragmentRenamed = renamedImportMap.get(rootFragment);\n            if (rootFragmentRenamed) {\n              nameFragments[0] = rootFragmentRenamed;\n            }\n          }\n\n          const nameFragment = nameFragments[nameFragments.length - 1];\n          if (nameFragment) {\n            return {\n              name: nameFragment,\n              compoundName: nameFragments.join('.'),\n            };\n          }\n        }\n      }\n    }\n\n    /**\n     * Gets all JSXElement ancestor nodes for the given node\n     * @param {ASTNode} node\n     * @returns {ASTNode[]}\n     */\n    function getJSXElementAncestors(node) {\n      /** @type {ASTNode[]} */\n      const ancestors = [];\n\n      let current = node;\n      while (current) {\n        if (current.type === 'JSXElement') {\n          ancestors.push(current);\n        }\n\n        current = current.parent;\n      }\n\n      return ancestors;\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {ASTNode}\n     */\n    function getParentIgnoringBinaryExpressions(node) {\n      let current = node;\n      while (current.parent.type === 'BinaryExpression') {\n        current = current.parent;\n      }\n      return current.parent;\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {{ parent: ASTNode, grandParent: ASTNode }}\n     */\n    function getParentAndGrandParent(node) {\n      const parent = getParentIgnoringBinaryExpressions(node);\n      return {\n        parent,\n        grandParent: parent.parent,\n      };\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    function hasJSXElementParentOrGrandParent(node) {\n      const ancestors = getParentAndGrandParent(node);\n      return some(iterFrom([ancestors.parent, ancestors.grandParent]), (parent) => jsxElementTypes.has(parent.type));\n    }\n\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * Determines whether a given node's value and its immediate parent are\n     * viable text nodes that can/should be reported on\n     * @param {ASTNode} node\n     * @param {ResolvedConfig} resolvedConfig\n     * @returns {boolean}\n     */\n    function isViableTextNode(node, resolvedConfig) {\n      const textValues = iterFrom([trimIfString(node.raw), trimIfString(node.value)]);\n      if (some(textValues, (value) => resolvedConfig.allowedStrings.has(value))) {\n        return false;\n      }\n\n      const parent = getParentIgnoringBinaryExpressions(node);\n\n      let isStandardJSXNode = false;\n      if (typeof node.value === 'string' && !reIsWhiteSpace.test(node.value) && standardJSXNodeParentTypes.has(parent.type)) {\n        if (resolvedConfig.noAttributeStrings) {\n          isStandardJSXNode = parent.type === 'JSXAttribute' || parent.type === 'JSXElement';\n        } else {\n          isStandardJSXNode = parent.type !== 'JSXAttribute';\n        }\n      }\n\n      if (resolvedConfig.noStrings) {\n        return isStandardJSXNode;\n      }\n\n      return isStandardJSXNode && parent.type !== 'JSXExpressionContainer';\n    }\n\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * Gets an override config for a given node. For any given node, we also\n     * need to traverse the ancestor tree to determine if an ancestor's config\n     * will also apply to the current node.\n     * @param {ASTNode} node\n     * @returns {OverrideConfig | undefined}\n     */\n    function getOverrideConfig(node) {\n      if (!hasElementOverrides) {\n        return;\n      }\n\n      const allAncestorElements = getJSXElementAncestors(node);\n      if (!allAncestorElements.length) {\n        return;\n      }\n\n      for (const ancestorElement of allAncestorElements) {\n        const isClosestJSXAncestor = ancestorElement === allAncestorElements[0];\n\n        const ancestor = getJSXElementName(ancestorElement);\n        if (ancestor) {\n          if (ancestor.name) {\n            const ancestorElements = config.elementOverrides[ancestor.name];\n            const ancestorConfig = ancestor.compoundName\n              ? config.elementOverrides[ancestor.compoundName] || ancestorElements\n              : ancestorElements;\n\n            if (ancestorConfig) {\n              if (isClosestJSXAncestor || ancestorConfig.applyToNestedElements) {\n                return ancestorConfig;\n              }\n            }\n          }\n        }\n      }\n    }\n\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * @param {ResolvedConfig} resolvedConfig\n     * @returns {boolean}\n     */\n    function shouldAllowElement(resolvedConfig) {\n      return resolvedConfig.type === 'override' && 'allowElement' in resolvedConfig && !!resolvedConfig.allowElement;\n    }\n\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * @param {boolean} ancestorIsJSXElement\n     * @param {ResolvedConfig} resolvedConfig\n     * @returns {string}\n     */\n    function defaultMessageId(ancestorIsJSXElement, resolvedConfig) {\n      if (resolvedConfig.noAttributeStrings && !ancestorIsJSXElement) {\n        return resolvedConfig.type === 'override' ? 'noStringsInAttributesInElement' : 'noStringsInAttributes';\n      }\n\n      if (resolvedConfig.noStrings) {\n        return resolvedConfig.type === 'override' ? 'noStringsInJSXInElement' : 'noStringsInJSX';\n      }\n\n      return resolvedConfig.type === 'override' ? 'literalNotInJSXExpressionInElement' : 'literalNotInJSXExpression';\n    }\n\n    // eslint-disable-next-line valid-jsdoc\n    /**\n     * @param {ASTNode} node\n     * @param {string} messageId\n     * @param {ResolvedConfig} resolvedConfig\n     */\n    function reportLiteralNode(node, messageId, resolvedConfig) {\n      report(context, messages[messageId], messageId, {\n        node,\n        data: {\n          text: getText(context, node).trim(),\n          element: resolvedConfig.type === 'override' && 'name' in resolvedConfig ? resolvedConfig.name : undefined,\n        },\n      });\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return Object.assign(hasElementOverrides ? {\n      // Get renamed import local names mapped to their imported name\n      ImportDeclaration(node) {\n        node.specifiers\n          .filter((s) => s.type === 'ImportSpecifier')\n          .forEach((specifier) => {\n            renamedImportMap.set(\n              (specifier.local || specifier.imported).name,\n              specifier.imported.name\n            );\n          });\n      },\n\n      // Get renamed destructured local names mapped to their imported name\n      VariableDeclaration(node) {\n        node.declarations\n          .filter((d) => (\n            d.type === 'VariableDeclarator'\n            && isRequireStatement(d.init)\n            && d.id.type === 'ObjectPattern'\n          ))\n          .forEach((declaration) => {\n            declaration.id.properties\n              .filter((property) => (\n                property.type === 'Property'\n                && property.key.type === 'Identifier'\n                && property.value.type === 'Identifier'\n              ))\n              .forEach((property) => {\n                renamedImportMap.set(property.value.name, property.key.name);\n              });\n          });\n      },\n    } : false, {\n      Literal(node) {\n        const resolvedConfig = getOverrideConfig(node) || config;\n\n        const hasJSXParentOrGrandParent = hasJSXElementParentOrGrandParent(node);\n        if (hasJSXParentOrGrandParent && shouldAllowElement(resolvedConfig)) {\n          return;\n        }\n\n        if (isViableTextNode(node, resolvedConfig)) {\n          if (hasJSXParentOrGrandParent || !config.ignoreProps) {\n            reportLiteralNode(node, defaultMessageId(hasJSXParentOrGrandParent, resolvedConfig), resolvedConfig);\n          }\n        }\n      },\n\n      JSXAttribute(node) {\n        const isLiteralString = node.value && node.value.type === 'Literal'\n          && typeof node.value.value === 'string';\n        const isStringLiteral = node.value && node.value.type === 'StringLiteral';\n\n        if (isLiteralString || isStringLiteral) {\n          const resolvedConfig = getOverrideConfig(node) || config;\n          const restrictedAttributes = resolvedConfig.restrictedAttributes;\n\n          if (restrictedAttributes.size > 0 && node.name && node.name.type === 'JSXIdentifier') {\n            const attributeName = node.name.name;\n\n            if (restrictedAttributes.has(attributeName)) {\n              if (!resolvedConfig.allowedStrings.has(String(trimIfString(node.value.value)))) {\n                const messageId = resolvedConfig.type === 'override' ? 'restrictedAttributeStringInElement' : 'restrictedAttributeString';\n                report(context, messages[messageId], messageId, {\n                  node,\n                  data: {\n                    text: getText(context, node.value).trim(),\n                    attribute: attributeName,\n                    element: resolvedConfig.type === 'override' && 'name' in resolvedConfig ? resolvedConfig.name : undefined,\n                  },\n                });\n              }\n              return;\n            }\n          }\n\n          if (\n            resolvedConfig.noStrings\n            && !resolvedConfig.ignoreProps\n            && !resolvedConfig.allowedStrings.has(node.value.value)\n          ) {\n            const messageId = resolvedConfig.type === 'override' ? 'invalidPropValueInElement' : 'invalidPropValue';\n            reportLiteralNode(node, messageId, resolvedConfig);\n          }\n        }\n      },\n\n      JSXText(node) {\n        const resolvedConfig = getOverrideConfig(node) || config;\n\n        if (shouldAllowElement(resolvedConfig)) {\n          return;\n        }\n\n        if (isViableTextNode(node, resolvedConfig)) {\n          const hasJSXParendOrGrantParent = hasJSXElementParentOrGrandParent(node);\n          reportLiteralNode(node, defaultMessageId(hasJSXParendOrGrantParent, resolvedConfig), resolvedConfig);\n        }\n      },\n\n      TemplateLiteral(node) {\n        const ancestors = getParentAndGrandParent(node);\n        const isParentJSXExpressionCont = ancestors.parent.type === 'JSXExpressionContainer';\n        const isParentJSXElement = ancestors.grandParent.type === 'JSXElement';\n\n        if (isParentJSXExpressionCont) {\n          const resolvedConfig = getOverrideConfig(node) || config;\n\n          if (\n            resolvedConfig.noStrings\n            && (isParentJSXElement || !resolvedConfig.ignoreProps)\n          ) {\n            reportLiteralNode(node, defaultMessageId(isParentJSXElement, resolvedConfig), resolvedConfig);\n          }\n        }\n      },\n    });\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-script-url.js",
    "content": "/**\n * @fileoverview Prevent usage of `javascript:` URLs\n * @author Sergei Startsev\n */\n\n'use strict';\n\nconst includes = require('array-includes');\nconst docsUrl = require('../util/docsUrl');\nconst linkComponentsUtil = require('../util/linkComponents');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n// https://github.com/facebook/react/blob/d0ebde77f6d1232cefc0da184d731943d78e86f2/packages/react-dom/src/shared/sanitizeURL.js#L30\n/* eslint-disable-next-line max-len, no-control-regex */\nconst isJavaScriptProtocol = /^[\\u0000-\\u001F ]*j[\\r\\n\\t]*a[\\r\\n\\t]*v[\\r\\n\\t]*a[\\r\\n\\t]*s[\\r\\n\\t]*c[\\r\\n\\t]*r[\\r\\n\\t]*i[\\r\\n\\t]*p[\\r\\n\\t]*t[\\r\\n\\t]*:/i;\n\nfunction hasJavaScriptProtocol(attr) {\n  return attr.value && attr.value.type === 'Literal'\n    && isJavaScriptProtocol.test(attr.value.value);\n}\n\nfunction shouldVerifyProp(node, config) {\n  const name = node.name && node.name.name;\n  const parentName = node.parent.name && node.parent.name.name;\n\n  if (!name || !parentName || !config.has(parentName)) return false;\n\n  const attributes = config.get(parentName);\n  return includes(attributes, name);\n}\n\nfunction parseLegacyOption(config, option) {\n  option.forEach((opt) => {\n    config.set(opt.name, opt.props);\n  });\n}\n\nconst messages = {\n  noScriptURL: 'A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML, try using dangerouslySetInnerHTML instead.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of `javascript:` URLs',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('jsx-no-script-url'),\n    },\n\n    messages,\n\n    schema: {\n      anyOf: [\n        {\n          type: 'array',\n          items: [\n            {\n              type: 'array',\n              uniqueItems: true,\n              items: {\n                type: 'object',\n                properties: {\n                  name: {\n                    type: 'string',\n                  },\n                  props: {\n                    type: 'array',\n                    items: {\n                      type: 'string',\n                      uniqueItems: true,\n                    },\n                  },\n                },\n                required: ['name', 'props'],\n                additionalProperties: false,\n              },\n            },\n            {\n              type: 'object',\n              properties: {\n                includeFromSettings: {\n                  type: 'boolean',\n                },\n              },\n              additionalItems: false,\n            },\n          ],\n          additionalItems: false,\n        },\n        {\n          type: 'array',\n          items: [\n            {\n              type: 'object',\n              properties: {\n                includeFromSettings: {\n                  type: 'boolean',\n                },\n              },\n              additionalItems: false,\n            },\n          ],\n          additionalItems: false,\n        },\n      ],\n    },\n  },\n\n  create(context) {\n    const options = context.options;\n    const hasLegacyOption = Array.isArray(options[0]);\n    const legacyOptions = hasLegacyOption ? options[0] : [];\n    // eslint-disable-next-line no-nested-ternary\n    const objectOption = (hasLegacyOption && options.length > 1)\n      ? options[1]\n      : (options.length > 0\n        ? options[0]\n        : {\n          includeFromSettings: false,\n        }\n      );\n    const includeFromSettings = objectOption.includeFromSettings;\n\n    const linkComponents = linkComponentsUtil.getLinkComponents(includeFromSettings ? context : {});\n    parseLegacyOption(linkComponents, legacyOptions);\n\n    return {\n      JSXAttribute(node) {\n        if (shouldVerifyProp(node, linkComponents) && hasJavaScriptProtocol(node)) {\n          report(context, messages.noScriptURL, 'noScriptURL', {\n            node,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-target-blank.js",
    "content": "/**\n * @fileoverview Forbid target='_blank' attribute\n * @author Kevin Miller\n */\n\n'use strict';\n\nconst includes = require('array-includes');\nconst docsUrl = require('../util/docsUrl');\nconst linkComponentsUtil = require('../util/linkComponents');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction findLastIndex(arr, condition) {\n  for (let i = arr.length - 1; i >= 0; i -= 1) {\n    if (condition(arr[i])) {\n      return i;\n    }\n  }\n\n  return -1;\n}\n\nfunction attributeValuePossiblyBlank(attribute) {\n  if (!attribute || !attribute.value) {\n    return false;\n  }\n  const value = attribute.value;\n  if (value.type === 'Literal') {\n    return typeof value.value === 'string' && value.value.toLowerCase() === '_blank';\n  }\n  if (value.type === 'JSXExpressionContainer') {\n    const expr = value.expression;\n    if (expr.type === 'Literal') {\n      return typeof expr.value === 'string' && expr.value.toLowerCase() === '_blank';\n    }\n    if (expr.type === 'ConditionalExpression') {\n      if (expr.alternate.type === 'Literal' && expr.alternate.value && expr.alternate.value.toLowerCase() === '_blank') {\n        return true;\n      }\n      if (expr.consequent.type === 'Literal' && expr.consequent.value && expr.consequent.value.toLowerCase() === '_blank') {\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\nfunction hasExternalLink(node, linkAttributes, warnOnSpreadAttributes, spreadAttributeIndex) {\n  const linkIndex = findLastIndex(node.attributes, (attr) => attr.name && includes(linkAttributes, attr.name.name));\n  const foundExternalLink = linkIndex !== -1 && ((attr) => attr.value && attr.value.type === 'Literal' && /^(?:\\w+:|\\/\\/)/.test(attr.value.value))(\n    node.attributes[linkIndex]);\n  return foundExternalLink || (warnOnSpreadAttributes && linkIndex < spreadAttributeIndex);\n}\n\nfunction hasDynamicLink(node, linkAttributes) {\n  const dynamicLinkIndex = findLastIndex(node.attributes, (attr) => attr.name\n    && includes(linkAttributes, attr.name.name)\n    && attr.value\n    && attr.value.type === 'JSXExpressionContainer');\n  if (dynamicLinkIndex !== -1) {\n    return true;\n  }\n}\n\n/**\n * Get the string(s) from a value\n * @param {ASTNode} value The AST node being checked.\n * @param {ASTNode} targetValue The AST node being checked.\n * @returns {string | string[] | null} The string value, or null if not a string.\n */\nfunction getStringFromValue(value, targetValue) {\n  if (value) {\n    if (value.type === 'Literal') {\n      return value.value;\n    }\n    if (value.type === 'JSXExpressionContainer') {\n      if (value.expression.type === 'TemplateLiteral') {\n        return value.expression.quasis[0].value.cooked;\n      }\n      const expr = value.expression;\n      if (expr && expr.type === 'ConditionalExpression') {\n        const relValues = [expr.consequent.value, expr.alternate.value];\n        if (targetValue.type === 'JSXExpressionContainer' && targetValue.expression && targetValue.expression.type === 'ConditionalExpression') {\n          const targetTestCond = targetValue.expression.test.name;\n          const relTestCond = value.expression.test.name;\n          if (targetTestCond === relTestCond) {\n            const targetBlankIndex = [targetValue.expression.consequent.value, targetValue.expression.alternate.value].indexOf('_blank');\n            return relValues[targetBlankIndex];\n          }\n        }\n        return relValues;\n      }\n      return expr.value;\n    }\n  }\n  return null;\n}\n\nfunction hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttributeIndex) {\n  const relIndex = findLastIndex(node.attributes, (attr) => (attr.type === 'JSXAttribute' && attr.name.name === 'rel'));\n  const targetIndex = findLastIndex(node.attributes, (attr) => (attr.type === 'JSXAttribute' && attr.name.name === 'target'));\n  if (relIndex === -1 || (warnOnSpreadAttributes && relIndex < spreadAttributeIndex)) {\n    return false;\n  }\n\n  const relAttribute = node.attributes[relIndex];\n  const targetAttributeValue = node.attributes[targetIndex] && node.attributes[targetIndex].value;\n  const value = getStringFromValue(relAttribute.value, targetAttributeValue);\n  return [].concat(value).every((item) => {\n    const tags = typeof item === 'string' ? item.toLowerCase().split(' ') : false;\n    const noreferrer = tags && tags.indexOf('noreferrer') >= 0;\n    if (noreferrer) {\n      return true;\n    }\n    const noopener = tags && tags.indexOf('noopener') >= 0;\n    return allowReferrer && noopener;\n  });\n}\n\nconst messages = {\n  noTargetBlankWithoutNoreferrer: 'Using target=\"_blank\" without rel=\"noreferrer\" (which implies rel=\"noopener\") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations',\n  noTargetBlankWithoutNoopener: 'Using target=\"_blank\" without rel=\"noreferrer\" or rel=\"noopener\" (the former implies the latter and is preferred due to wider support) is a security risk: see https://mathiasbynens.github.io/rel-noopener/#recommendations',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    fixable: 'code',\n    docs: {\n      description: 'Disallow `target=\"_blank\"` attribute without `rel=\"noreferrer\"`',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('jsx-no-target-blank'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowReferrer: {\n          type: 'boolean',\n        },\n        enforceDynamicLinks: {\n          enum: ['always', 'never'],\n        },\n        warnOnSpreadAttributes: {\n          type: 'boolean',\n        },\n        links: {\n          type: 'boolean',\n          default: true,\n        },\n        forms: {\n          type: 'boolean',\n          default: false,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = Object.assign(\n      {\n        allowReferrer: false,\n        warnOnSpreadAttributes: false,\n        links: true,\n        forms: false,\n      },\n      context.options[0]\n    );\n    const allowReferrer = configuration.allowReferrer;\n    const warnOnSpreadAttributes = configuration.warnOnSpreadAttributes;\n    const enforceDynamicLinks = configuration.enforceDynamicLinks || 'always';\n    const linkComponents = linkComponentsUtil.getLinkComponents(context);\n    const formComponents = linkComponentsUtil.getFormComponents(context);\n\n    return {\n      JSXOpeningElement(node) {\n        const targetIndex = findLastIndex(node.attributes, (attr) => attr.name && attr.name.name === 'target');\n        const spreadAttributeIndex = findLastIndex(node.attributes, (attr) => (attr.type === 'JSXSpreadAttribute'));\n\n        if (linkComponents.has(node.name.name)) {\n          if (!attributeValuePossiblyBlank(node.attributes[targetIndex])) {\n            const hasSpread = spreadAttributeIndex >= 0;\n\n            if (warnOnSpreadAttributes && hasSpread) {\n              // continue to check below\n            } else if ((hasSpread && targetIndex < spreadAttributeIndex) || !hasSpread || !warnOnSpreadAttributes) {\n              return;\n            }\n          }\n\n          const linkAttributes = linkComponents.get(node.name.name);\n          const hasDangerousLink = hasExternalLink(node, linkAttributes, warnOnSpreadAttributes, spreadAttributeIndex)\n            || (enforceDynamicLinks === 'always' && hasDynamicLink(node, linkAttributes));\n          if (hasDangerousLink && !hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttributeIndex)) {\n            const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer';\n            const relValue = allowReferrer ? 'noopener' : 'noreferrer';\n            report(context, messages[messageId], messageId, {\n              node,\n              fix(fixer) {\n                // eslint 5 uses `node.attributes`; eslint 6+ uses `node.parent.attributes`\n                const nodeWithAttrs = node.parent.attributes ? node.parent : node;\n                // eslint 5 does not provide a `name` property on JSXSpreadElements\n                const relAttribute = nodeWithAttrs.attributes.find((attr) => attr.name && attr.name.name === 'rel');\n\n                if (targetIndex < spreadAttributeIndex || (spreadAttributeIndex >= 0 && !relAttribute)) {\n                  return null;\n                }\n\n                if (!relAttribute) {\n                  return fixer.insertTextAfter(nodeWithAttrs.attributes.slice(-1)[0], ` rel=\"${relValue}\"`);\n                }\n\n                if (!relAttribute.value) {\n                  return fixer.insertTextAfter(relAttribute, `=\"${relValue}\"`);\n                }\n\n                if (relAttribute.value.type === 'Literal') {\n                  const parts = relAttribute.value.value\n                    .split('noreferrer')\n                    .filter(Boolean);\n                  return fixer.replaceText(relAttribute.value, `\"${parts.concat('noreferrer').join(' ')}\"`);\n                }\n\n                if (relAttribute.value.type === 'JSXExpressionContainer') {\n                  if (relAttribute.value.expression.type === 'Literal') {\n                    if (typeof relAttribute.value.expression.value === 'string') {\n                      const parts = relAttribute.value.expression.value\n                        .split('noreferrer')\n                        .filter(Boolean);\n                      return fixer.replaceText(relAttribute.value.expression, `\"${parts.concat('noreferrer').join(' ')}\"`);\n                    }\n\n                    // for undefined, boolean, number, symbol, bigint, and null\n                    return fixer.replaceText(relAttribute.value, '\"noreferrer\"');\n                  }\n                }\n\n                return null;\n              },\n            });\n          }\n        }\n        if (formComponents.has(node.name.name)) {\n          if (!attributeValuePossiblyBlank(node.attributes[targetIndex])) {\n            const hasSpread = spreadAttributeIndex >= 0;\n\n            if (warnOnSpreadAttributes && hasSpread) {\n              // continue to check below\n            } else if (\n              (hasSpread && targetIndex < spreadAttributeIndex)\n              || !hasSpread\n              || !warnOnSpreadAttributes\n            ) {\n              return;\n            }\n          }\n\n          if (!configuration.forms || hasSecureRel(node)) {\n            return;\n          }\n\n          const formAttributes = formComponents.get(node.name.name);\n\n          if (\n            hasExternalLink(node, formAttributes)\n            || (enforceDynamicLinks === 'always' && hasDynamicLink(node, formAttributes))\n          ) {\n            const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer';\n            report(context, messages[messageId], messageId, {\n              node,\n            });\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-undef.js",
    "content": "/**\n * @fileoverview Disallow undeclared variables in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  undefined: '\\'{{identifier}}\\' is not defined.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow undeclared variables in JSX',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('jsx-no-undef'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowGlobals: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const config = context.options[0] || {};\n    const allowGlobals = config.allowGlobals || false;\n\n    /**\n     * Compare an identifier with the variables declared in the scope\n     * @param {ASTNode} node - Identifier or JSXIdentifier node\n     * @returns {void}\n     */\n    function checkIdentifierInJSX(node) {\n      let scope = eslintUtil.getScope(context, node);\n      const sourceCode = eslintUtil.getSourceCode(context);\n      const sourceType = sourceCode.ast.sourceType;\n      const scopeUpperBound = !allowGlobals && sourceType === 'module' ? 'module' : 'global';\n      let variables = scope.variables;\n      let i;\n      let len;\n\n      // Ignore 'this' keyword (also maked as JSXIdentifier when used in JSX)\n      if (node.name === 'this') {\n        return;\n      }\n\n      while (scope.type !== scopeUpperBound && scope.type !== 'global') {\n        scope = scope.upper;\n        variables = scope.variables.concat(variables);\n      }\n      if (scope.childScopes.length) {\n        variables = scope.childScopes[0].variables.concat(variables);\n        // Temporary fix for babel-eslint\n        if (scope.childScopes[0].childScopes.length) {\n          variables = scope.childScopes[0].childScopes[0].variables.concat(variables);\n        }\n      }\n\n      for (i = 0, len = variables.length; i < len; i++) {\n        if (variables[i].name === node.name) {\n          return;\n        }\n      }\n\n      report(context, messages.undefined, 'undefined', {\n        node,\n        data: {\n          identifier: node.name,\n        },\n      });\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        switch (node.name.type) {\n          case 'JSXIdentifier':\n            if (jsxUtil.isDOMComponent(node)) {\n              return;\n            }\n            node = node.name;\n            break;\n          case 'JSXMemberExpression':\n            node = node.name;\n            do {\n              node = node.object;\n            } while (node && node.type !== 'JSXIdentifier');\n            break;\n          case 'JSXNamespacedName':\n            return;\n          default:\n            break;\n        }\n        checkIdentifierInJSX(node);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-no-useless-fragment.js",
    "content": "/**\n * @fileoverview Disallow useless fragments\n */\n\n'use strict';\n\nconst arrayIncludes = require('array-includes');\n\nconst pragmaUtil = require('../util/pragma');\nconst astUtil = require('../util/ast');\nconst jsxUtil = require('../util/jsx');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\nfunction isJSXText(node) {\n  return !!node && (node.type === 'JSXText' || node.type === 'Literal');\n}\n\n/**\n * @param {string} text\n * @returns {boolean}\n */\nfunction isOnlyWhitespace(text) {\n  return text.trim().length === 0;\n}\n\n/**\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isNonspaceJSXTextOrJSXCurly(node) {\n  return (isJSXText(node) && !isOnlyWhitespace(node.raw)) || node.type === 'JSXExpressionContainer';\n}\n\n/**\n * Somehow fragment like this is useful: <Foo content={<>ee eeee eeee ...</>} />\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isFragmentWithOnlyTextAndIsNotChild(node) {\n  return node.children.length === 1\n    && isJSXText(node.children[0])\n    && !(node.parent.type === 'JSXElement' || node.parent.type === 'JSXFragment');\n}\n\n/**\n * @param {string} text\n * @returns {string}\n */\nfunction trimLikeReact(text) {\n  const leadingSpaces = /^\\s*/.exec(text)[0];\n  const trailingSpaces = /\\s*$/.exec(text)[0];\n\n  const start = arrayIncludes(leadingSpaces, '\\n') ? leadingSpaces.length : 0;\n  const end = arrayIncludes(trailingSpaces, '\\n') ? text.length - trailingSpaces.length : text.length;\n\n  return text.slice(start, end);\n}\n\n/**\n * Test if node is like `<Fragment key={_}>_</Fragment>`\n * @param {JSXElement} node\n * @returns {boolean}\n */\nfunction isKeyedElement(node) {\n  return node.type === 'JSXElement'\n    && node.openingElement.attributes\n    && node.openingElement.attributes.some(jsxUtil.isJSXAttributeKey);\n}\n\n/**\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction containsCallExpression(node) {\n  return node\n    && node.type === 'JSXExpressionContainer'\n    && astUtil.isCallExpression(node.expression);\n}\n\nconst messages = {\n  NeedsMoreChildren: 'Fragments should contain more than one child - otherwise, there’s no need for a Fragment at all.',\n  ChildOfHtmlElement: 'Passing a fragment to an HTML element is useless.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    type: 'suggestion',\n    fixable: 'code',\n    docs: {\n      description: 'Disallow unnecessary fragments',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('jsx-no-useless-fragment'),\n    },\n    messages,\n    schema: [{\n      type: 'object',\n      properties: {\n        allowExpressions: {\n          type: 'boolean',\n        },\n      },\n    }],\n  },\n\n  create(context) {\n    const config = context.options[0] || {};\n    const allowExpressions = config.allowExpressions || false;\n\n    const reactPragma = pragmaUtil.getFromContext(context);\n    const fragmentPragma = pragmaUtil.getFragmentFromContext(context);\n\n    /**\n     * Test whether a node is an padding spaces trimmed by react runtime.\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    function isPaddingSpaces(node) {\n      return isJSXText(node)\n        && isOnlyWhitespace(node.raw)\n        && arrayIncludes(node.raw, '\\n');\n    }\n\n    function isFragmentWithSingleExpression(node) {\n      const children = node && node.children.filter((child) => !isPaddingSpaces(child));\n      return (\n        children\n        && children.length === 1\n        && children[0].type === 'JSXExpressionContainer'\n      );\n    }\n\n    /**\n     * Test whether a JSXElement has less than two children, excluding paddings spaces.\n     * @param {JSXElement|JSXFragment} node\n     * @returns {boolean}\n     */\n    function hasLessThanTwoChildren(node) {\n      if (!node || !node.children) {\n        return true;\n      }\n\n      /** @type {ASTNode[]} */\n      const nonPaddingChildren = node.children.filter(\n        (child) => !isPaddingSpaces(child)\n      );\n\n      if (nonPaddingChildren.length < 2) {\n        return !containsCallExpression(nonPaddingChildren[0]);\n      }\n    }\n\n    /**\n     * @param {JSXElement|JSXFragment} node\n     * @returns {boolean}\n     */\n    function isChildOfHtmlElement(node) {\n      return node.parent.type === 'JSXElement'\n        && node.parent.openingElement.name.type === 'JSXIdentifier'\n        && /^[a-z]+$/.test(node.parent.openingElement.name.name);\n    }\n\n    /**\n     * @param {JSXElement|JSXFragment} node\n     * @return {boolean}\n     */\n    function isChildOfComponentElement(node) {\n      return node.parent.type === 'JSXElement'\n        && !isChildOfHtmlElement(node)\n        && !jsxUtil.isFragment(node.parent, reactPragma, fragmentPragma);\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    function canFix(node) {\n      // Not safe to fix fragments without a jsx parent.\n      if (!(node.parent.type === 'JSXElement' || node.parent.type === 'JSXFragment')) {\n        // const a = <></>\n        if (node.children.length === 0) {\n          return false;\n        }\n\n        // const a = <>cat {meow}</>\n        if (node.children.some(isNonspaceJSXTextOrJSXCurly)) {\n          return false;\n        }\n      }\n\n      // Not safe to fix `<Eeee><>foo</></Eeee>` because `Eeee` might require its children be a ReactElement.\n      if (isChildOfComponentElement(node)) {\n        return false;\n      }\n\n      // old TS parser can't handle this one\n      if (node.type === 'JSXFragment' && (!node.openingFragment || !node.closingFragment)) {\n        return false;\n      }\n\n      return true;\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {Function | undefined}\n     */\n    function getFix(node) {\n      if (!canFix(node)) {\n        return undefined;\n      }\n\n      return function fix(fixer) {\n        const opener = node.type === 'JSXFragment' ? node.openingFragment : node.openingElement;\n        const closer = node.type === 'JSXFragment' ? node.closingFragment : node.closingElement;\n\n        const childrenText = opener.selfClosing ? '' : getText(context).slice(opener.range[1], closer.range[0]);\n\n        return fixer.replaceText(node, trimLikeReact(childrenText));\n      };\n    }\n\n    function checkNode(node) {\n      if (isKeyedElement(node)) {\n        return;\n      }\n\n      if (\n        hasLessThanTwoChildren(node)\n        && !isFragmentWithOnlyTextAndIsNotChild(node)\n        && !(allowExpressions && isFragmentWithSingleExpression(node))\n      ) {\n        report(context, messages.NeedsMoreChildren, 'NeedsMoreChildren', {\n          node,\n          fix: getFix(node),\n        });\n      }\n\n      if (isChildOfHtmlElement(node)) {\n        report(context, messages.ChildOfHtmlElement, 'ChildOfHtmlElement', {\n          node,\n          fix: getFix(node),\n        });\n      }\n    }\n\n    return {\n      JSXElement(node) {\n        if (jsxUtil.isFragment(node, reactPragma, fragmentPragma)) {\n          checkNode(node);\n        }\n      },\n      JSXFragment: checkNode,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-one-expression-per-line.js",
    "content": "/**\n * @fileoverview Limit to one expression per line in JSX\n * @author Mark Ivan Allen <Vydia.com>\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst optionDefaults = {\n  allow: 'none',\n};\n\nconst messages = {\n  moveToNewLine: '`{{descriptor}}` must be placed on a new line',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Require one JSX element per line',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-one-expression-per-line'),\n    },\n    fixable: 'whitespace',\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          allow: {\n            enum: ['none', 'literal', 'single-child', 'non-jsx'],\n          },\n        },\n        default: optionDefaults,\n        additionalProperties: false,\n      },\n    ],\n  },\n\n  create(context) {\n    const options = Object.assign({}, optionDefaults, context.options[0]);\n\n    function nodeKey(node) {\n      return `${node.loc.start.line},${node.loc.start.column}`;\n    }\n\n    /**\n     * @param {ASTNode} n\n     * @returns {string}\n     */\n    function nodeDescriptor(n) {\n      return n.openingElement ? n.openingElement.name.name : getText(context, n).replace(/\\n/g, '');\n    }\n\n    function handleJSX(node) {\n      const children = node.children;\n\n      if (!children || !children.length) {\n        return;\n      }\n\n      if (\n        options.allow === 'non-jsx'\n        && !children.find((child) => (child.type === 'JSXFragment' || child.type === 'JSXElement'))\n      ) {\n        return;\n      }\n\n      const openingElement = node.openingElement || node.openingFragment;\n      const closingElement = node.closingElement || node.closingFragment;\n      const openingElementStartLine = openingElement.loc.start.line;\n      const openingElementEndLine = openingElement.loc.end.line;\n      const closingElementStartLine = closingElement.loc.start.line;\n      const closingElementEndLine = closingElement.loc.end.line;\n\n      if (children.length === 1) {\n        const child = children[0];\n        if (\n          openingElementStartLine === openingElementEndLine\n          && openingElementEndLine === closingElementStartLine\n          && closingElementStartLine === closingElementEndLine\n          && closingElementEndLine === child.loc.start.line\n          && child.loc.start.line === child.loc.end.line\n        ) {\n          if (\n            options.allow === 'single-child'\n            || (options.allow === 'literal' && (child.type === 'Literal' || child.type === 'JSXText'))\n          ) {\n            return;\n          }\n        }\n      }\n\n      const childrenGroupedByLine = {};\n      const fixDetailsByNode = {};\n\n      children.forEach((child) => {\n        let countNewLinesBeforeContent = 0;\n        let countNewLinesAfterContent = 0;\n\n        if (child.type === 'Literal' || child.type === 'JSXText') {\n          if (jsxUtil.isWhiteSpaces(child.raw)) {\n            return;\n          }\n\n          countNewLinesBeforeContent = (child.raw.match(/^\\s*\\n/g) || []).length;\n          countNewLinesAfterContent = (child.raw.match(/\\n\\s*$/g) || []).length;\n        }\n\n        const startLine = child.loc.start.line + countNewLinesBeforeContent;\n        const endLine = child.loc.end.line - countNewLinesAfterContent;\n\n        if (startLine === endLine) {\n          if (!childrenGroupedByLine[startLine]) {\n            childrenGroupedByLine[startLine] = [];\n          }\n          childrenGroupedByLine[startLine].push(child);\n        } else {\n          if (!childrenGroupedByLine[startLine]) {\n            childrenGroupedByLine[startLine] = [];\n          }\n          childrenGroupedByLine[startLine].push(child);\n          if (!childrenGroupedByLine[endLine]) {\n            childrenGroupedByLine[endLine] = [];\n          }\n          childrenGroupedByLine[endLine].push(child);\n        }\n      });\n\n      Object.keys(childrenGroupedByLine).forEach((_line) => {\n        const line = parseInt(_line, 10);\n        const firstIndex = 0;\n        const lastIndex = childrenGroupedByLine[line].length - 1;\n\n        childrenGroupedByLine[line].forEach((child, i) => {\n          let prevChild;\n          let nextChild;\n\n          if (i === firstIndex) {\n            if (line === openingElementEndLine) {\n              prevChild = openingElement;\n            }\n          } else {\n            prevChild = childrenGroupedByLine[line][i - 1];\n          }\n\n          if (i === lastIndex) {\n            if (line === closingElementStartLine) {\n              nextChild = closingElement;\n            }\n          } else {\n            // We don't need to append a trailing because the next child will prepend a leading.\n            // nextChild = childrenGroupedByLine[line][i + 1];\n          }\n\n          function spaceBetweenPrev() {\n            return ((prevChild.type === 'Literal' || prevChild.type === 'JSXText') && / $/.test(prevChild.raw))\n              || ((child.type === 'Literal' || child.type === 'JSXText') && /^ /.test(child.raw))\n              || getSourceCode(context).isSpaceBetweenTokens(prevChild, child);\n          }\n\n          function spaceBetweenNext() {\n            return ((nextChild.type === 'Literal' || nextChild.type === 'JSXText') && /^ /.test(nextChild.raw))\n              || ((child.type === 'Literal' || child.type === 'JSXText') && / $/.test(child.raw))\n              || getSourceCode(context).isSpaceBetweenTokens(child, nextChild);\n          }\n\n          if (!prevChild && !nextChild) {\n            return;\n          }\n\n          const source = getText(context, child);\n          const leadingSpace = !!(prevChild && spaceBetweenPrev());\n          const trailingSpace = !!(nextChild && spaceBetweenNext());\n          const leadingNewLine = !!prevChild;\n          const trailingNewLine = !!nextChild;\n\n          const key = nodeKey(child);\n\n          if (!fixDetailsByNode[key]) {\n            fixDetailsByNode[key] = {\n              node: child,\n              source,\n              descriptor: nodeDescriptor(child),\n            };\n          }\n\n          if (leadingSpace) {\n            fixDetailsByNode[key].leadingSpace = true;\n          }\n          if (leadingNewLine) {\n            fixDetailsByNode[key].leadingNewLine = true;\n          }\n          if (trailingNewLine) {\n            fixDetailsByNode[key].trailingNewLine = true;\n          }\n          if (trailingSpace) {\n            fixDetailsByNode[key].trailingSpace = true;\n          }\n        });\n      });\n\n      Object.keys(fixDetailsByNode).forEach((key) => {\n        const details = fixDetailsByNode[key];\n\n        const nodeToReport = details.node;\n        const descriptor = details.descriptor;\n        const source = details.source.replace(/(^ +| +(?=\\n)*$)/g, '');\n\n        const leadingSpaceString = details.leadingSpace ? '\\n{\\' \\'}' : '';\n        const trailingSpaceString = details.trailingSpace ? '{\\' \\'}\\n' : '';\n        const leadingNewLineString = details.leadingNewLine ? '\\n' : '';\n        const trailingNewLineString = details.trailingNewLine ? '\\n' : '';\n\n        const replaceText = `${leadingSpaceString}${leadingNewLineString}${source}${trailingNewLineString}${trailingSpaceString}`;\n\n        report(context, messages.moveToNewLine, 'moveToNewLine', {\n          node: nodeToReport,\n          data: {\n            descriptor,\n          },\n          fix(fixer) {\n            return fixer.replaceText(nodeToReport, replaceText);\n          },\n        });\n      });\n    }\n\n    return {\n      JSXElement: handleJSX,\n      JSXFragment: handleJSX,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-pascal-case.js",
    "content": "/**\n * @fileoverview Enforce PascalCase for user-defined JSX components\n * @author Jake Marsh\n */\n\n'use strict';\n\nconst elementType = require('jsx-ast-utils/elementType');\nconst minimatch = require('minimatch');\nconst docsUrl = require('../util/docsUrl');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\n\nfunction testDigit(char) {\n  const charCode = char.charCodeAt(0);\n  return charCode >= 48 && charCode <= 57;\n}\n\nfunction testUpperCase(char) {\n  const upperCase = char.toUpperCase();\n  return char === upperCase && upperCase !== char.toLowerCase();\n}\n\nfunction testLowerCase(char) {\n  const lowerCase = char.toLowerCase();\n  return char === lowerCase && lowerCase !== char.toUpperCase();\n}\n\nfunction testPascalCase(name) {\n  if (!testUpperCase(name.charAt(0))) {\n    return false;\n  }\n  const anyNonAlphaNumeric = Array.prototype.some.call(\n    name.slice(1),\n    (char) => char.toLowerCase() === char.toUpperCase() && !testDigit(char)\n  );\n  if (anyNonAlphaNumeric) {\n    return false;\n  }\n  return Array.prototype.some.call(\n    name.slice(1),\n    (char) => testLowerCase(char) || testDigit(char)\n  );\n}\n\nfunction testAllCaps(name) {\n  const firstChar = name.charAt(0);\n  if (!(testUpperCase(firstChar) || testDigit(firstChar))) {\n    return false;\n  }\n  for (let i = 1; i < name.length - 1; i += 1) {\n    const char = name.charAt(i);\n    if (!(testUpperCase(char) || testDigit(char) || char === '_')) {\n      return false;\n    }\n  }\n  const lastChar = name.charAt(name.length - 1);\n  if (!(testUpperCase(lastChar) || testDigit(lastChar))) {\n    return false;\n  }\n  return true;\n}\n\nfunction ignoreCheck(ignore, name) {\n  return ignore.some(\n    (entry) => name === entry || minimatch(name, entry, { noglobstar: true })\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  usePascalCase: 'Imported JSX component {{name}} must be in PascalCase',\n  usePascalOrSnakeCase: 'Imported JSX component {{name}} must be in PascalCase or SCREAMING_SNAKE_CASE',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce PascalCase for user-defined JSX components',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-pascal-case'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowAllCaps: {\n          type: 'boolean',\n        },\n        allowLeadingUnderscore: {\n          type: 'boolean',\n        },\n        allowNamespace: {\n          type: 'boolean',\n        },\n        ignore: {\n          items: [\n            {\n              type: 'string',\n            },\n          ],\n          minItems: 0,\n          type: 'array',\n          uniqueItems: true,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const allowAllCaps = configuration.allowAllCaps || false;\n    const allowLeadingUnderscore = configuration.allowLeadingUnderscore || false;\n    const allowNamespace = configuration.allowNamespace || false;\n    const ignore = configuration.ignore || [];\n\n    return {\n      JSXOpeningElement(node) {\n        const isCompatTag = jsxUtil.isDOMComponent(node);\n        if (isCompatTag) return undefined;\n\n        const name = elementType(node);\n        let checkNames = [name];\n        let index = 0;\n\n        if (name.lastIndexOf(':') > -1) {\n          checkNames = name.split(':');\n        } else if (name.lastIndexOf('.') > -1) {\n          checkNames = name.split('.');\n        }\n\n        do {\n          const splitName = checkNames[index];\n          if (splitName.length === 1) return undefined;\n          const isIgnored = ignoreCheck(ignore, splitName);\n\n          const checkName = allowLeadingUnderscore && splitName.startsWith('_') ? splitName.slice(1) : splitName;\n          const isPascalCase = testPascalCase(checkName);\n          const isAllowedAllCaps = allowAllCaps && testAllCaps(checkName);\n\n          if (!isPascalCase && !isAllowedAllCaps && !isIgnored) {\n            const messageId = allowAllCaps ? 'usePascalOrSnakeCase' : 'usePascalCase';\n            report(context, messages[messageId], messageId, {\n              node,\n              data: {\n                name: splitName,\n              },\n            });\n            break;\n          }\n          index += 1;\n        } while (index < checkNames.length && !allowNamespace);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-props-no-multi-spaces.js",
    "content": "/**\n * @fileoverview Disallow multiple spaces between inline JSX props\n * @author Adrian Moennich\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst report = require('../util/report');\nconst propsUtil = require('../util/props');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noLineGap: 'Expected no line gap between “{{prop1}}” and “{{prop2}}”',\n  onlyOneSpace: 'Expected only one space between “{{prop1}}” and “{{prop2}}”',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow multiple spaces between inline JSX props',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-props-no-multi-spaces'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    const sourceCode = getSourceCode(context);\n\n    function getPropName(propNode) {\n      switch (propNode.type) {\n        case 'JSXSpreadAttribute':\n          return getText(context, propNode.argument);\n        case 'JSXIdentifier':\n          return propNode.name;\n        case 'JSXMemberExpression':\n          return `${getPropName(propNode.object)}.${propNode.property.name}`;\n        default:\n          return propNode.name\n            ? propNode.name.name\n            : `${getText(context, propNode.object)}.${propNode.property.name}`; // needed for typescript-eslint parser\n      }\n    }\n\n    // First and second must be adjacent nodes\n    function hasEmptyLines(first, second) {\n      const comments = sourceCode.getCommentsBefore ? sourceCode.getCommentsBefore(second) : [];\n      const nodes = [].concat(first, comments, second);\n\n      for (let i = 1; i < nodes.length; i += 1) {\n        const prev = nodes[i - 1];\n        const curr = nodes[i];\n        if (curr.loc.start.line - prev.loc.end.line >= 2) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    function checkSpacing(prev, node) {\n      if (hasEmptyLines(prev, node)) {\n        report(context, messages.noLineGap, 'noLineGap', {\n          node,\n          data: {\n            prop1: getPropName(prev),\n            prop2: getPropName(node),\n          },\n          fix(fixer) {\n            const comments = sourceCode.getCommentsBefore ? sourceCode.getCommentsBefore(node) : [];\n            const nodes = [].concat(prev, comments, node);\n            const fixes = [];\n\n            for (let i = 1; i < nodes.length; i += 1) {\n              const prevNode = nodes[i - 1];\n              const currNode = nodes[i];\n              if (currNode.loc.start.line - prevNode.loc.end.line >= 2) {\n                const indent = ' '.repeat(currNode.loc.start.column);\n                fixes.push(fixer.replaceTextRange([prevNode.range[1], currNode.range[0]], `\\n${indent}`));\n              }\n            }\n\n            return fixes;\n          },\n        });\n      }\n\n      if (prev.loc.end.line !== node.loc.end.line) {\n        return;\n      }\n\n      const between = getSourceCode(context).text.slice(prev.range[1], node.range[0]);\n\n      if (between !== ' ') {\n        report(context, messages.onlyOneSpace, 'onlyOneSpace', {\n          node,\n          data: {\n            prop1: getPropName(prev),\n            prop2: getPropName(node),\n          },\n          fix(fixer) {\n            return fixer.replaceTextRange([prev.range[1], node.range[0]], ' ');\n          },\n        });\n      }\n    }\n\n    function containsGenericType(node) {\n      const nodeTypeArguments = propsUtil.getTypeArguments(node);\n      if (typeof nodeTypeArguments === 'undefined') {\n        return false;\n      }\n\n      return nodeTypeArguments.type === 'TSTypeParameterInstantiation';\n    }\n\n    function getGenericNode(node) {\n      const name = node.name;\n      if (containsGenericType(node)) {\n        const nodeTypeArguments = propsUtil.getTypeArguments(node);\n\n        return Object.assign(\n          {},\n          node,\n          {\n            range: [\n              name.range[0],\n              nodeTypeArguments.range[1],\n            ],\n          }\n        );\n      }\n\n      return name;\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        node.attributes.reduce((prev, prop) => {\n          checkSpacing(prev, prop);\n          return prop;\n        }, getGenericNode(node));\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-props-no-spread-multi.js",
    "content": "/**\n * @fileoverview Prevent JSX prop spreading the same expression multiple times\n * @author Simon Schick\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noMultiSpreading: 'Spreading the same expression multiple times is forbidden',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow JSX prop spreading the same identifier multiple times',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('jsx-props-no-spread-multi'),\n    },\n    messages,\n  },\n\n  create(context) {\n    return {\n      JSXOpeningElement(node) {\n        const spreads = node.attributes.filter(\n          (attr) => attr.type === 'JSXSpreadAttribute'\n          && attr.argument.type === 'Identifier'\n        );\n        if (spreads.length < 2) {\n          return;\n        }\n        // We detect duplicate expressions by their identifier\n        const identifierNames = new Set();\n        spreads.forEach((spread) => {\n          if (identifierNames.has(spread.argument.name)) {\n            report(context, messages.noMultiSpreading, 'noMultiSpreading', {\n              node: spread,\n            });\n          }\n          identifierNames.add(spread.argument.name);\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-props-no-spreading.js",
    "content": "/**\n * @fileoverview Prevent JSX prop spreading\n * @author Ashish Gambhir\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst OPTIONS = { ignore: 'ignore', enforce: 'enforce' };\nconst DEFAULTS = {\n  html: OPTIONS.enforce,\n  custom: OPTIONS.enforce,\n  explicitSpread: OPTIONS.enforce,\n  exceptions: [],\n};\n\nconst isException = (tag, allExceptions) => allExceptions.indexOf(tag) !== -1;\nconst isProperty = (property) => property.type === 'Property';\nconst getTagNameFromMemberExpression = (node) => {\n  if (node.property.parent) {\n    return `${node.property.parent.object.name}.${node.property.name}`;\n  }\n  // for eslint 3\n  return `${node.object.name}.${node.property.name}`;\n};\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noSpreading: 'Prop spreading is forbidden',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow JSX prop spreading',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('jsx-props-no-spreading'),\n    },\n\n    messages,\n\n    schema: [{\n      allOf: [{\n        type: 'object',\n        properties: {\n          html: {\n            enum: [OPTIONS.enforce, OPTIONS.ignore],\n          },\n          custom: {\n            enum: [OPTIONS.enforce, OPTIONS.ignore],\n          },\n          explicitSpread: {\n            enum: [OPTIONS.enforce, OPTIONS.ignore],\n          },\n          exceptions: {\n            type: 'array',\n            items: {\n              type: 'string',\n              uniqueItems: true,\n            },\n          },\n        },\n      }, {\n        not: {\n          type: 'object',\n          required: ['html', 'custom'],\n          properties: {\n            html: {\n              enum: [OPTIONS.ignore],\n            },\n            custom: {\n              enum: [OPTIONS.ignore],\n            },\n            exceptions: {\n              type: 'array',\n              minItems: 0,\n              maxItems: 0,\n            },\n          },\n        },\n      }],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const ignoreHtmlTags = (configuration.html || DEFAULTS.html) === OPTIONS.ignore;\n    const ignoreCustomTags = (configuration.custom || DEFAULTS.custom) === OPTIONS.ignore;\n    const ignoreExplicitSpread = (configuration.explicitSpread || DEFAULTS.explicitSpread) === OPTIONS.ignore;\n    const exceptions = configuration.exceptions || DEFAULTS.exceptions;\n    return {\n      JSXSpreadAttribute(node) {\n        const jsxOpeningElement = node.parent.name;\n        const type = jsxOpeningElement.type;\n\n        let tagName;\n        if (type === 'JSXIdentifier') {\n          tagName = jsxOpeningElement.name;\n        } else if (type === 'JSXMemberExpression') {\n          tagName = getTagNameFromMemberExpression(jsxOpeningElement);\n        } else {\n          tagName = undefined;\n        }\n\n        const isHTMLTag = tagName && tagName[0] !== tagName[0].toUpperCase();\n        const isCustomTag = tagName && (tagName[0] === tagName[0].toUpperCase() || tagName.includes('.'));\n        if (\n          isHTMLTag\n          && ((ignoreHtmlTags && !isException(tagName, exceptions))\n          || (!ignoreHtmlTags && isException(tagName, exceptions)))\n        ) {\n          return;\n        }\n        if (\n          isCustomTag\n          && ((ignoreCustomTags && !isException(tagName, exceptions))\n          || (!ignoreCustomTags && isException(tagName, exceptions)))\n        ) {\n          return;\n        }\n        if (\n          ignoreExplicitSpread\n          && node.argument.type === 'ObjectExpression'\n          && node.argument.properties.every(isProperty)\n        ) {\n          return;\n        }\n        report(context, messages.noSpreading, 'noSpreading', {\n          node,\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-sort-default-props.js",
    "content": "/**\n * @fileoverview Enforce default props alphabetical sorting\n * @author Vladimir Kattsov\n * @deprecated\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst log = require('../util/log');\nconst eslintUtil = require('../util/eslint');\n\nconst getFirstTokens = eslintUtil.getFirstTokens;\nconst getText = eslintUtil.getText;\n\nlet isWarnedForDeprecation = false;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  propsNotSorted: 'Default prop types declarations should be sorted alphabetically',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    deprecated: true,\n    replacedBy: ['sort-default-props'],\n    docs: {\n      description: 'Enforce defaultProps declarations alphabetical sorting',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-sort-default-props'),\n    },\n    // fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignoreCase: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const ignoreCase = configuration.ignoreCase || false;\n\n    /**\n     * Get properties name\n     * @param {Object} node - Property.\n     * @returns {string} Property name.\n     */\n    function getPropertyName(node) {\n      if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {\n        return node.key.name;\n      }\n      if (node.type === 'MemberExpression') {\n        return node.property.name;\n      // Special case for class properties\n      // (babel-eslint@5 does not expose property name so we have to rely on tokens)\n      }\n      if (node.type === 'ClassProperty') {\n        const tokens = getFirstTokens(context, node, 2);\n        return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;\n      }\n      return '';\n    }\n\n    /**\n     * Checks if the Identifier node passed in looks like a defaultProps declaration.\n     * @param   {ASTNode}  node The node to check. Must be an Identifier node.\n     * @returns {boolean}       `true` if the node is a defaultProps declaration, `false` if not\n     */\n    function isDefaultPropsDeclaration(node) {\n      const propName = getPropertyName(node);\n      return (propName === 'defaultProps' || propName === 'getDefaultProps');\n    }\n\n    function getKey(node) {\n      return getText(context, node.key || node.argument);\n    }\n\n    /**\n     * Find a variable by name in the current scope.\n     * @param  {ASTNode} node The node to look for.\n     * @param  {string} name Name of the variable to look for.\n     * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise.\n     */\n    function findVariableByName(node, name) {\n      const variable = variableUtil\n        .getVariableFromContext(context, node, name);\n\n      if (!variable || !variable.defs[0] || !variable.defs[0].node) {\n        return null;\n      }\n\n      if (variable.defs[0].node.type === 'TypeAlias') {\n        return variable.defs[0].node.right;\n      }\n\n      return variable.defs[0].node.init;\n    }\n\n    /**\n     * Checks if defaultProps declarations are sorted\n     * @param {Array} declarations The array of AST nodes being checked.\n     * @returns {void}\n     */\n    function checkSorted(declarations) {\n      // function fix(fixer) {\n      //   return propTypesSortUtil.fixPropTypesSort(context, fixer, declarations, ignoreCase);\n      // }\n\n      declarations.reduce((prev, curr, idx, decls) => {\n        if (/Spread(?:Property|Element)$/.test(curr.type)) {\n          return decls[idx + 1];\n        }\n\n        let prevPropName = getKey(prev);\n        let currentPropName = getKey(curr);\n\n        if (ignoreCase) {\n          prevPropName = prevPropName.toLowerCase();\n          currentPropName = currentPropName.toLowerCase();\n        }\n\n        if (currentPropName < prevPropName) {\n          report(context, messages.propsNotSorted, 'propsNotSorted', {\n            node: curr,\n            // fix\n          });\n\n          return prev;\n        }\n\n        return curr;\n      }, declarations[0]);\n    }\n\n    function checkNode(node) {\n      if (!node) {\n        return;\n      }\n      if (node.type === 'ObjectExpression') {\n        checkSorted(node.properties);\n      } else if (node.type === 'Identifier') {\n        const propTypesObject = findVariableByName(node, node.name);\n        if (propTypesObject && propTypesObject.properties) {\n          checkSorted(propTypesObject.properties);\n        }\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public API\n    // --------------------------------------------------------------------------\n\n    return {\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!isDefaultPropsDeclaration(node)) {\n          return;\n        }\n\n        checkNode(node.value);\n      },\n\n      MemberExpression(node) {\n        if (!isDefaultPropsDeclaration(node)) {\n          return;\n        }\n\n        checkNode('right' in node.parent && node.parent.right);\n      },\n\n      Program() {\n        if (isWarnedForDeprecation) {\n          return;\n        }\n\n        log('The react/jsx-sort-default-props rule is deprecated. It has been renamed to `react/sort-default-props`.');\n        isWarnedForDeprecation = true;\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-sort-props.js",
    "content": "/**\n * @fileoverview Enforce props alphabetical sorting\n * @author Ilya Volodin, Yannick Croissant\n */\n\n'use strict';\n\nconst propName = require('jsx-ast-utils/propName');\nconst includes = require('array-includes');\nconst toSorted = require('array.prototype.tosorted');\n\nconst docsUrl = require('../util/docsUrl');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\nconst propTypesSortUtil = require('../util/propTypesSort');\nconst eslintUtil = require('../util/eslint');\n\nconst getText = eslintUtil.getText;\nconst getSourceCode = eslintUtil.getSourceCode;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction isMultilineProp(node) {\n  return node.loc.start.line !== node.loc.end.line;\n}\n\nconst messages = {\n  noUnreservedProps: 'A customized reserved first list must only contain a subset of React reserved props. Remove: {{unreservedWords}}',\n  listIsEmpty: 'A customized reserved first list must not be empty',\n  listReservedPropsFirst: 'Reserved props must be listed before all other props',\n  listCallbacksLast: 'Callbacks must be listed after all other props',\n  listShorthandFirst: 'Shorthand props must be listed before all other props',\n  listShorthandLast: 'Shorthand props must be listed after all other props',\n  listMultilineFirst: 'Multiline props must be listed before all other props',\n  listMultilineLast: 'Multiline props must be listed after all other props',\n  listSortFirstPropsFirst: 'Props in sortFirst must be listed before all other props',\n  sortPropsByAlpha: 'Props should be sorted alphabetically',\n};\n\nconst RESERVED_PROPS_LIST = [\n  'children',\n  'dangerouslySetInnerHTML',\n  'key',\n  'ref',\n];\n\nfunction isReservedPropName(name, list) {\n  return list.indexOf(name) >= 0;\n}\n\nfunction getSortFirstIndex(name, sortFirstList, ignoreCase) {\n  const normalizedPropName = ignoreCase ? name.toLowerCase() : name;\n  for (let i = 0; i < sortFirstList.length; i++) {\n    const normalizedListName = ignoreCase ? sortFirstList[i].toLowerCase() : sortFirstList[i];\n    if (normalizedPropName === normalizedListName) {\n      return i;\n    }\n  }\n  return -1;\n}\n\nlet attributeMap;\n// attributeMap = { end: endrange, hasComment: true||false if comment in between nodes exists, it needs to be sorted to end }\n\nfunction shouldSortToEnd(node) {\n  const attr = attributeMap.get(node);\n  return !!attr && !!attr.hasComment;\n}\n\nfunction contextCompare(a, b, options) {\n  let aProp = propName(a);\n  let bProp = propName(b);\n\n  const aSortToEnd = shouldSortToEnd(a);\n  const bSortToEnd = shouldSortToEnd(b);\n  if (aSortToEnd && !bSortToEnd) {\n    return 1;\n  }\n  if (!aSortToEnd && bSortToEnd) {\n    return -1;\n  }\n\n  if (options.sortFirst && options.sortFirst.length > 0) {\n    const aSortFirstIndex = getSortFirstIndex(aProp, options.sortFirst, options.ignoreCase);\n    const bSortFirstIndex = getSortFirstIndex(bProp, options.sortFirst, options.ignoreCase);\n    if (aSortFirstIndex >= 0 && bSortFirstIndex >= 0) {\n      // Both are in sortFirst, maintain their exact order\n      if (aSortFirstIndex !== bSortFirstIndex) {\n        return aSortFirstIndex - bSortFirstIndex;\n      }\n      return 0;\n    }\n    if (aSortFirstIndex >= 0 && bSortFirstIndex < 0) {\n      return -1;\n    }\n    if (aSortFirstIndex < 0 && bSortFirstIndex >= 0) {\n      return 1;\n    }\n  }\n\n  if (options.reservedFirst) {\n    const aIsReserved = isReservedPropName(aProp, options.reservedList);\n    const bIsReserved = isReservedPropName(bProp, options.reservedList);\n    if (aIsReserved && !bIsReserved) {\n      return -1;\n    }\n    if (!aIsReserved && bIsReserved) {\n      return 1;\n    }\n  }\n\n  if (options.callbacksLast) {\n    const aIsCallback = propTypesSortUtil.isCallbackPropName(aProp);\n    const bIsCallback = propTypesSortUtil.isCallbackPropName(bProp);\n    if (aIsCallback && !bIsCallback) {\n      return 1;\n    }\n    if (!aIsCallback && bIsCallback) {\n      return -1;\n    }\n  }\n\n  if (options.shorthandFirst || options.shorthandLast) {\n    const shorthandSign = options.shorthandFirst ? -1 : 1;\n    if (!a.value && b.value) {\n      return shorthandSign;\n    }\n    if (a.value && !b.value) {\n      return -shorthandSign;\n    }\n  }\n\n  if (options.multiline !== 'ignore') {\n    const multilineSign = options.multiline === 'first' ? -1 : 1;\n    const aIsMultiline = isMultilineProp(a);\n    const bIsMultiline = isMultilineProp(b);\n    if (aIsMultiline && !bIsMultiline) {\n      return multilineSign;\n    }\n    if (!aIsMultiline && bIsMultiline) {\n      return -multilineSign;\n    }\n  }\n\n  if (options.noSortAlphabetically) {\n    return 0;\n  }\n\n  const actualLocale = options.locale === 'auto' ? undefined : options.locale;\n\n  if (options.ignoreCase) {\n    aProp = aProp.toLowerCase();\n    bProp = bProp.toLowerCase();\n    return aProp.localeCompare(bProp, actualLocale);\n  }\n  if (aProp === bProp) {\n    return 0;\n  }\n  if (options.locale === 'auto') {\n    return aProp < bProp ? -1 : 1;\n  }\n  return aProp.localeCompare(bProp, actualLocale);\n}\n\n/**\n * Create an array of arrays where each subarray is composed of attributes\n * that are considered sortable.\n * @param {Array<JSXSpreadAttribute|JSXAttribute>} attributes\n * @param {Object} context The context of the rule\n * @return {Array<Array<JSXAttribute>>}\n */\nfunction getGroupsOfSortableAttributes(attributes, context) {\n  const sourceCode = getSourceCode(context);\n\n  const sortableAttributeGroups = [];\n  let groupCount = 0;\n  function addtoSortableAttributeGroups(attribute) {\n    sortableAttributeGroups[groupCount - 1].push(attribute);\n  }\n\n  for (let i = 0; i < attributes.length; i++) {\n    const attribute = attributes[i];\n    const nextAttribute = attributes[i + 1];\n    const attributeline = attribute.loc.start.line;\n    let comment = [];\n    try {\n      comment = sourceCode.getCommentsAfter(attribute);\n    } catch (e) { /**/ }\n    const lastAttr = attributes[i - 1];\n    const attrIsSpread = attribute.type === 'JSXSpreadAttribute';\n\n    // If we have no groups or if the last attribute was JSXSpreadAttribute\n    // then we start a new group. Append attributes to the group until we\n    // come across another JSXSpreadAttribute or exhaust the array.\n    if (\n      !lastAttr\n      || (lastAttr.type === 'JSXSpreadAttribute' && !attrIsSpread)\n    ) {\n      groupCount += 1;\n      sortableAttributeGroups[groupCount - 1] = [];\n    }\n    if (!attrIsSpread) {\n      if (comment.length === 0) {\n        attributeMap.set(attribute, { end: attribute.range[1], hasComment: false });\n        addtoSortableAttributeGroups(attribute);\n      } else {\n        const firstComment = comment[0];\n        const commentline = firstComment.loc.start.line;\n        if (comment.length === 1) {\n          if (attributeline + 1 === commentline && nextAttribute) {\n            attributeMap.set(attribute, { end: nextAttribute.range[1], hasComment: true });\n            addtoSortableAttributeGroups(attribute);\n            i += 1;\n          } else if (attributeline === commentline) {\n            if (firstComment.type === 'Block' && nextAttribute) {\n              attributeMap.set(attribute, { end: nextAttribute.range[1], hasComment: true });\n              i += 1;\n            } else if (firstComment.type === 'Block') {\n              attributeMap.set(attribute, { end: firstComment.range[1], hasComment: true });\n            } else {\n              attributeMap.set(attribute, { end: firstComment.range[1], hasComment: false });\n            }\n            addtoSortableAttributeGroups(attribute);\n          }\n        } else if (comment.length > 1 && attributeline + 1 === comment[1].loc.start.line && nextAttribute) {\n          const commentNextAttribute = sourceCode.getCommentsAfter(nextAttribute);\n          attributeMap.set(attribute, { end: nextAttribute.range[1], hasComment: true });\n          if (\n            commentNextAttribute.length === 1\n            && nextAttribute.loc.start.line === commentNextAttribute[0].loc.start.line\n          ) {\n            attributeMap.set(attribute, { end: commentNextAttribute[0].range[1], hasComment: true });\n          }\n          addtoSortableAttributeGroups(attribute);\n          i += 1;\n        }\n      }\n    }\n  }\n  return sortableAttributeGroups;\n}\n\nfunction generateFixerFunction(node, context, reservedList) {\n  const attributes = node.attributes.slice(0);\n  const configuration = context.options[0] || {};\n  const ignoreCase = configuration.ignoreCase || false;\n  const callbacksLast = configuration.callbacksLast || false;\n  const shorthandFirst = configuration.shorthandFirst || false;\n  const shorthandLast = configuration.shorthandLast || false;\n  const multiline = configuration.multiline || 'ignore';\n  const noSortAlphabetically = configuration.noSortAlphabetically || false;\n  const reservedFirst = configuration.reservedFirst || false;\n  const sortFirst = configuration.sortFirst || [];\n  const locale = configuration.locale || 'auto';\n\n  // Sort props according to the context. Only supports ignoreCase.\n  // Since we cannot safely move JSXSpreadAttribute (due to potential variable overrides),\n  // we only consider groups of sortable attributes.\n  const options = {\n    ignoreCase,\n    callbacksLast,\n    shorthandFirst,\n    shorthandLast,\n    multiline,\n    noSortAlphabetically,\n    reservedFirst,\n    reservedList,\n    sortFirst,\n    locale,\n  };\n  const sortableAttributeGroups = getGroupsOfSortableAttributes(attributes, context);\n  const sortedAttributeGroups = sortableAttributeGroups\n    .slice(0)\n    .map((group) => toSorted(group, (a, b) => contextCompare(a, b, options)));\n\n  return function fixFunction(fixer) {\n    const fixers = [];\n    let source = getText(context);\n\n    sortableAttributeGroups.forEach((sortableGroup, ii) => {\n      sortableGroup.forEach((attr, jj) => {\n        const sortedAttr = sortedAttributeGroups[ii][jj];\n        const sortedAttrText = source.slice(sortedAttr.range[0], attributeMap.get(sortedAttr).end);\n        fixers.push({\n          range: [attr.range[0], attributeMap.get(attr).end],\n          text: sortedAttrText,\n        });\n      });\n    });\n\n    fixers.sort((a, b) => b.range[0] - a.range[0]);\n\n    const firstFixer = fixers[0];\n    const lastFixer = fixers[fixers.length - 1];\n    const rangeStart = lastFixer ? lastFixer.range[0] : 0;\n    const rangeEnd = firstFixer ? firstFixer.range[1] : -0;\n\n    fixers.forEach((fix) => {\n      source = `${source.slice(0, fix.range[0])}${fix.text}${source.slice(fix.range[1])}`;\n    });\n\n    return fixer.replaceTextRange([rangeStart, rangeEnd], source.slice(rangeStart, rangeEnd));\n  };\n}\n\n/**\n * Checks if the `reservedFirst` option is valid\n * @param {Object} context The context of the rule\n * @param {boolean | string[]} reservedFirst The `reservedFirst` option\n * @return {Function | undefined} If an error is detected, a function to generate the error message, otherwise, `undefined`\n */\n// eslint-disable-next-line consistent-return\nfunction validateReservedFirstConfig(context, reservedFirst) {\n  if (reservedFirst) {\n    if (Array.isArray(reservedFirst)) {\n      // Only allow a subset of reserved words in customized lists\n      const nonReservedWords = reservedFirst.filter((word) => !isReservedPropName(\n        word,\n        RESERVED_PROPS_LIST\n      ));\n\n      if (reservedFirst.length === 0) {\n        return function Report(decl) {\n          report(context, messages.listIsEmpty, 'listIsEmpty', {\n            node: decl,\n          });\n        };\n      }\n      if (nonReservedWords.length > 0) {\n        return function Report(decl) {\n          report(context, messages.noUnreservedProps, 'noUnreservedProps', {\n            node: decl,\n            data: {\n              unreservedWords: nonReservedWords.toString(),\n            },\n          });\n        };\n      }\n    }\n  }\n}\n\nconst reportedNodeAttributes = new WeakMap();\n/**\n * Check if the current node attribute has already been reported with the same error type\n * if that's the case then we don't report a new error\n * otherwise we report the error\n * @param {Object} nodeAttribute The node attribute to be reported\n * @param {string} errorType The error type to be reported\n * @param {Object} node The parent node for the node attribute\n * @param {Object} context The context of the rule\n * @param {Array<String>} reservedList The list of reserved props\n */\nfunction reportNodeAttribute(nodeAttribute, errorType, node, context, reservedList) {\n  const errors = reportedNodeAttributes.get(nodeAttribute) || [];\n\n  if (includes(errors, errorType)) {\n    return;\n  }\n\n  errors.push(errorType);\n\n  reportedNodeAttributes.set(nodeAttribute, errors);\n\n  report(context, messages[errorType], errorType, {\n    node: nodeAttribute.name,\n    fix: generateFixerFunction(node, context, reservedList),\n  });\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce props alphabetical sorting',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-sort-props'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        // Whether callbacks (prefixed with \"on\") should be listed at the very end,\n        // after all other props. Supersedes shorthandLast.\n        callbacksLast: {\n          type: 'boolean',\n        },\n        // Whether shorthand properties (without a value) should be listed first\n        shorthandFirst: {\n          type: 'boolean',\n        },\n        // Whether shorthand properties (without a value) should be listed last\n        shorthandLast: {\n          type: 'boolean',\n        },\n        // Whether multiline properties should be listed first or last\n        multiline: {\n          enum: ['ignore', 'first', 'last'],\n          default: 'ignore',\n        },\n        ignoreCase: {\n          type: 'boolean',\n        },\n        // Whether alphabetical sorting should be enforced\n        noSortAlphabetically: {\n          type: 'boolean',\n        },\n        reservedFirst: {\n          type: ['array', 'boolean'],\n        },\n        sortFirst: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n          uniqueItems: true,\n        },\n        locale: {\n          type: 'string',\n          default: 'auto',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const ignoreCase = configuration.ignoreCase || false;\n    const callbacksLast = configuration.callbacksLast || false;\n    const shorthandFirst = configuration.shorthandFirst || false;\n    const shorthandLast = configuration.shorthandLast || false;\n    const multiline = configuration.multiline || 'ignore';\n    const noSortAlphabetically = configuration.noSortAlphabetically || false;\n    const reservedFirst = configuration.reservedFirst || false;\n    const reservedFirstError = validateReservedFirstConfig(context, reservedFirst);\n    const reservedList = Array.isArray(reservedFirst) ? reservedFirst : RESERVED_PROPS_LIST;\n    const sortFirst = configuration.sortFirst || [];\n    const locale = configuration.locale || 'auto';\n\n    return {\n      Program() {\n        attributeMap = new WeakMap();\n      },\n\n      JSXOpeningElement(node) {\n        // `dangerouslySetInnerHTML` is only \"reserved\" on DOM components\n        const nodeReservedList = reservedFirst && !jsxUtil.isDOMComponent(node) ? reservedList.filter((prop) => prop !== 'dangerouslySetInnerHTML') : reservedList;\n\n        node.attributes.reduce((memo, decl, idx, attrs) => {\n          if (decl.type === 'JSXSpreadAttribute') {\n            return attrs[idx + 1];\n          }\n\n          let previousPropName = propName(memo);\n          let currentPropName = propName(decl);\n          const previousValue = memo.value;\n          const currentValue = decl.value;\n          const previousIsCallback = propTypesSortUtil.isCallbackPropName(previousPropName);\n          const currentIsCallback = propTypesSortUtil.isCallbackPropName(currentPropName);\n\n          if (sortFirst && sortFirst.length > 0) {\n            const previousSortFirstIndex = getSortFirstIndex(previousPropName, sortFirst, ignoreCase);\n            const currentSortFirstIndex = getSortFirstIndex(currentPropName, sortFirst, ignoreCase);\n\n            if (previousSortFirstIndex >= 0 && currentSortFirstIndex >= 0) {\n              // Both are in sortFirst, check their order\n              if (previousSortFirstIndex > currentSortFirstIndex) {\n                reportNodeAttribute(decl, 'listSortFirstPropsFirst', node, context, nodeReservedList);\n                return memo;\n              }\n              return decl;\n            }\n\n            if (previousSortFirstIndex >= 0 && currentSortFirstIndex < 0) {\n              // Previous is in sortFirst, current is not - this is correct, continue to next prop\n              return decl;\n            }\n\n            if (previousSortFirstIndex < 0 && currentSortFirstIndex >= 0) {\n              // Current is in sortFirst but previous is not - error\n              reportNodeAttribute(decl, 'listSortFirstPropsFirst', node, context, nodeReservedList);\n              return memo;\n            }\n          }\n\n          if (ignoreCase) {\n            previousPropName = previousPropName.toLowerCase();\n            currentPropName = currentPropName.toLowerCase();\n          }\n\n          if (reservedFirst) {\n            if (reservedFirstError) {\n              reservedFirstError(decl);\n              return memo;\n            }\n\n            const previousIsReserved = isReservedPropName(previousPropName, nodeReservedList);\n            const currentIsReserved = isReservedPropName(currentPropName, nodeReservedList);\n\n            if (previousIsReserved && !currentIsReserved) {\n              return decl;\n            }\n            if (!previousIsReserved && currentIsReserved) {\n              reportNodeAttribute(decl, 'listReservedPropsFirst', node, context, nodeReservedList);\n\n              return memo;\n            }\n          }\n\n          if (callbacksLast) {\n            if (!previousIsCallback && currentIsCallback) {\n              // Entering the callback prop section\n              return decl;\n            }\n            if (previousIsCallback && !currentIsCallback) {\n              // Encountered a non-callback prop after a callback prop\n              reportNodeAttribute(memo, 'listCallbacksLast', node, context, nodeReservedList);\n\n              return memo;\n            }\n          }\n\n          if (shorthandFirst) {\n            if (currentValue && !previousValue) {\n              return decl;\n            }\n            if (!currentValue && previousValue) {\n              reportNodeAttribute(decl, 'listShorthandFirst', node, context, nodeReservedList);\n\n              return memo;\n            }\n          }\n\n          if (shorthandLast) {\n            if (!currentValue && previousValue) {\n              return decl;\n            }\n            if (currentValue && !previousValue) {\n              reportNodeAttribute(memo, 'listShorthandLast', node, context, nodeReservedList);\n\n              return memo;\n            }\n          }\n\n          const previousIsMultiline = isMultilineProp(memo);\n          const currentIsMultiline = isMultilineProp(decl);\n          if (multiline === 'first') {\n            if (previousIsMultiline && !currentIsMultiline) {\n              // Exiting the multiline prop section\n              return decl;\n            }\n            if (!previousIsMultiline && currentIsMultiline) {\n              // Encountered a non-multiline prop before a multiline prop\n              reportNodeAttribute(decl, 'listMultilineFirst', node, context, nodeReservedList);\n\n              return memo;\n            }\n          } else if (multiline === 'last') {\n            if (!previousIsMultiline && currentIsMultiline) {\n              // Entering the multiline prop section\n              return decl;\n            }\n            if (previousIsMultiline && !currentIsMultiline) {\n              // Encountered a non-multiline prop after a multiline prop\n              reportNodeAttribute(memo, 'listMultilineLast', node, context, nodeReservedList);\n\n              return memo;\n            }\n          }\n\n          if (\n            !noSortAlphabetically\n            && (\n              (ignoreCase || locale !== 'auto')\n                ? previousPropName.localeCompare(currentPropName, locale === 'auto' ? undefined : locale) > 0\n                : previousPropName > currentPropName\n            )\n          ) {\n            reportNodeAttribute(decl, 'sortPropsByAlpha', node, context, nodeReservedList);\n\n            return memo;\n          }\n\n          return decl;\n        }, node.attributes[0]);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-space-before-closing.js",
    "content": "/**\n * @fileoverview Validate spacing before closing bracket in JSX.\n * @author ryym\n * @deprecated\n */\n\n'use strict';\n\nconst getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBracket');\nconst docsUrl = require('../util/docsUrl');\nconst log = require('../util/log');\nconst report = require('../util/report');\nconst getSourceCode = require('../util/eslint').getSourceCode;\n\nlet isWarnedForDeprecation = false;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noSpaceBeforeClose: 'A space is forbidden before closing bracket',\n  needSpaceBeforeClose: 'A space is required before closing bracket',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    deprecated: true,\n    replacedBy: ['jsx-tag-spacing'],\n    docs: {\n      description: 'Enforce spacing before closing bracket in JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-space-before-closing'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      enum: ['always', 'never'],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || 'always';\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXOpeningElement(node) {\n        if (!node.selfClosing) {\n          return;\n        }\n\n        const sourceCode = getSourceCode(context);\n\n        const leftToken = getTokenBeforeClosingBracket(node);\n        const closingSlash = /** @type {import('eslint').AST.Token} */ (sourceCode.getTokenAfter(leftToken));\n\n        if (leftToken.loc.end.line !== closingSlash.loc.start.line) {\n          return;\n        }\n\n        if (configuration === 'always' && !sourceCode.isSpaceBetweenTokens(leftToken, closingSlash)) {\n          report(context, messages.needSpaceBeforeClose, 'needSpaceBeforeClose', {\n            loc: closingSlash.loc.start,\n            fix(fixer) {\n              return fixer.insertTextBefore(closingSlash, ' ');\n            },\n          });\n        } else if (configuration === 'never' && sourceCode.isSpaceBetweenTokens(leftToken, closingSlash)) {\n          report(context, messages.noSpaceBeforeClose, 'noSpaceBeforeClose', {\n            loc: closingSlash.loc.start,\n            fix(fixer) {\n              const previousToken = sourceCode.getTokenBefore(closingSlash);\n              return fixer.removeRange([previousToken.range[1], closingSlash.range[0]]);\n            },\n          });\n        }\n      },\n\n      Program() {\n        if (isWarnedForDeprecation) {\n          return;\n        }\n\n        log('The react/jsx-space-before-closing rule is deprecated. '\n            + 'Please use the react/jsx-tag-spacing rule with the '\n            + '\"beforeSelfClosing\" option instead.');\n        isWarnedForDeprecation = true;\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-tag-spacing.js",
    "content": "/**\n * @fileoverview Validates whitespace in and around the JSX opening and closing brackets\n * @author Diogo Franco (Kovensky)\n */\n\n'use strict';\n\nconst getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBracket');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getFirstTokens = eslintUtil.getFirstTokens;\nconst getSourceCode = eslintUtil.getSourceCode;\n\nconst messages = {\n  selfCloseSlashNoSpace: 'Whitespace is forbidden between `/` and `>`; write `/>`',\n  selfCloseSlashNeedSpace: 'Whitespace is required between `/` and `>`; write `/ >`',\n  closeSlashNoSpace: 'Whitespace is forbidden between `<` and `/`; write `</`',\n  closeSlashNeedSpace: 'Whitespace is required between `<` and `/`; write `< /`',\n  beforeSelfCloseNoSpace: 'A space is forbidden before closing bracket',\n  beforeSelfCloseNeedSpace: 'A space is required before closing bracket',\n  beforeSelfCloseNeedNewline: 'A newline is required before closing bracket',\n  afterOpenNoSpace: 'A space is forbidden after opening bracket',\n  afterOpenNeedSpace: 'A space is required after opening bracket',\n  beforeCloseNoSpace: 'A space is forbidden before closing bracket',\n  beforeCloseNeedSpace: 'Whitespace is required before closing bracket',\n  beforeCloseNeedNewline: 'A newline is required before closing bracket',\n};\n\n// ------------------------------------------------------------------------------\n// Validators\n// ------------------------------------------------------------------------------\n\nfunction validateClosingSlash(context, node, option) {\n  const sourceCode = getSourceCode(context);\n\n  let adjacent;\n\n  if (node.selfClosing) {\n    const lastTokens = sourceCode.getLastTokens(node, 2);\n\n    adjacent = !sourceCode.isSpaceBetweenTokens(lastTokens[0], lastTokens[1]);\n\n    if (option === 'never') {\n      if (!adjacent) {\n        report(context, messages.selfCloseSlashNoSpace, 'selfCloseSlashNoSpace', {\n          node,\n          loc: {\n            start: lastTokens[0].loc.start,\n            end: lastTokens[1].loc.end,\n          },\n          fix(fixer) {\n            return fixer.removeRange([lastTokens[0].range[1], lastTokens[1].range[0]]);\n          },\n        });\n      }\n    } else if (option === 'always' && adjacent) {\n      report(context, messages.selfCloseSlashNeedSpace, 'selfCloseSlashNeedSpace', {\n        node,\n        loc: {\n          start: lastTokens[0].loc.start,\n          end: lastTokens[1].loc.end,\n        },\n        fix(fixer) {\n          return fixer.insertTextBefore(lastTokens[1], ' ');\n        },\n      });\n    }\n  } else {\n    const firstTokens = getFirstTokens(context, node, 2);\n\n    adjacent = !sourceCode.isSpaceBetweenTokens(firstTokens[0], firstTokens[1]);\n\n    if (option === 'never') {\n      if (!adjacent) {\n        report(context, messages.closeSlashNoSpace, 'closeSlashNoSpace', {\n          node,\n          loc: {\n            start: firstTokens[0].loc.start,\n            end: firstTokens[1].loc.end,\n          },\n          fix(fixer) {\n            return fixer.removeRange([firstTokens[0].range[1], firstTokens[1].range[0]]);\n          },\n        });\n      }\n    } else if (option === 'always' && adjacent) {\n      report(context, messages.closeSlashNeedSpace, 'closeSlashNeedSpace', {\n        node,\n        loc: {\n          start: firstTokens[0].loc.start,\n          end: firstTokens[1].loc.end,\n        },\n        fix(fixer) {\n          return fixer.insertTextBefore(firstTokens[1], ' ');\n        },\n      });\n    }\n  }\n}\n\nfunction validateBeforeSelfClosing(context, node, option) {\n  const sourceCode = getSourceCode(context);\n  const leftToken = getTokenBeforeClosingBracket(node);\n  const closingSlash = sourceCode.getTokenAfter(leftToken);\n\n  if (node.loc.start.line !== node.loc.end.line && option === 'proportional-always') {\n    if (leftToken.loc.end.line === closingSlash.loc.start.line) {\n      report(context, messages.beforeSelfCloseNeedNewline, 'beforeSelfCloseNeedNewline', {\n        node,\n        loc: leftToken.loc.end,\n        fix(fixer) {\n          return fixer.insertTextBefore(closingSlash, '\\n');\n        },\n      });\n      return;\n    }\n  }\n\n  if (leftToken.loc.end.line !== closingSlash.loc.start.line) {\n    return;\n  }\n\n  const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingSlash);\n\n  if ((option === 'always' || option === 'proportional-always') && adjacent) {\n    report(context, messages.beforeSelfCloseNeedSpace, 'beforeSelfCloseNeedSpace', {\n      node,\n      loc: closingSlash.loc.start,\n      fix(fixer) {\n        return fixer.insertTextBefore(closingSlash, ' ');\n      },\n    });\n  } else if (option === 'never' && !adjacent) {\n    report(context, messages.beforeSelfCloseNoSpace, 'beforeSelfCloseNoSpace', {\n      node,\n      loc: closingSlash.loc.start,\n      fix(fixer) {\n        const previousToken = sourceCode.getTokenBefore(closingSlash);\n        return fixer.removeRange([previousToken.range[1], closingSlash.range[0]]);\n      },\n    });\n  }\n}\n\nfunction validateAfterOpening(context, node, option) {\n  const sourceCode = getSourceCode(context);\n  const openingToken = sourceCode.getTokenBefore(node.name);\n\n  if (option === 'allow-multiline') {\n    if (openingToken.loc.start.line !== node.name.loc.start.line) {\n      return;\n    }\n  }\n\n  const adjacent = !sourceCode.isSpaceBetweenTokens(openingToken, node.name);\n\n  if (option === 'never' || option === 'allow-multiline') {\n    if (!adjacent) {\n      report(context, messages.afterOpenNoSpace, 'afterOpenNoSpace', {\n        node,\n        loc: {\n          start: openingToken.loc.start,\n          end: node.name.loc.start,\n        },\n        fix(fixer) {\n          return fixer.removeRange([openingToken.range[1], node.name.range[0]]);\n        },\n      });\n    }\n  } else if (option === 'always' && adjacent) {\n    report(context, messages.afterOpenNeedSpace, 'afterOpenNeedSpace', {\n      node,\n      loc: {\n        start: openingToken.loc.start,\n        end: node.name.loc.start,\n      },\n      fix(fixer) {\n        return fixer.insertTextBefore(node.name, ' ');\n      },\n    });\n  }\n}\n\nfunction validateBeforeClosing(context, node, option) {\n  // Don't enforce this rule for self closing tags\n  if (!node.selfClosing) {\n    const sourceCode = getSourceCode(context);\n    const leftToken = option === 'proportional-always'\n      ? getTokenBeforeClosingBracket(node)\n      : sourceCode.getLastTokens(node, 2)[0];\n    const closingToken = sourceCode.getTokenAfter(leftToken);\n\n    if (node.loc.start.line !== node.loc.end.line && option === 'proportional-always') {\n      if (leftToken.loc.end.line === closingToken.loc.start.line) {\n        report(context, messages.beforeCloseNeedNewline, 'beforeCloseNeedNewline', {\n          node,\n          loc: leftToken.loc.end,\n          fix(fixer) {\n            return fixer.insertTextBefore(closingToken, '\\n');\n          },\n        });\n        return;\n      }\n    }\n\n    if (leftToken.loc.start.line !== closingToken.loc.start.line) {\n      return;\n    }\n\n    const adjacent = !sourceCode.isSpaceBetweenTokens(leftToken, closingToken);\n\n    if (option === 'never' && !adjacent) {\n      report(context, messages.beforeCloseNoSpace, 'beforeCloseNoSpace', {\n        node,\n        loc: {\n          start: leftToken.loc.end,\n          end: closingToken.loc.start,\n        },\n        fix(fixer) {\n          return fixer.removeRange([leftToken.range[1], closingToken.range[0]]);\n        },\n      });\n    } else if (option === 'always' && adjacent) {\n      report(context, messages.beforeCloseNeedSpace, 'beforeCloseNeedSpace', {\n        node,\n        loc: {\n          start: leftToken.loc.end,\n          end: closingToken.loc.start,\n        },\n        fix(fixer) {\n          return fixer.insertTextBefore(closingToken, ' ');\n        },\n      });\n    } else if (option === 'proportional-always' && node.type === 'JSXOpeningElement' && adjacent !== (node.loc.start.line === node.loc.end.line)) {\n      report(context, messages.beforeCloseNeedSpace, 'beforeCloseNeedSpace', {\n        node,\n        loc: {\n          start: leftToken.loc.end,\n          end: closingToken.loc.start,\n        },\n        fix(fixer) {\n          return fixer.insertTextBefore(closingToken, ' ');\n        },\n      });\n    }\n  }\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst optionDefaults = {\n  closingSlash: 'never',\n  beforeSelfClosing: 'always',\n  afterOpening: 'never',\n  beforeClosing: 'allow',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce whitespace in and around the JSX opening and closing brackets',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-tag-spacing'),\n    },\n    fixable: 'whitespace',\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          closingSlash: {\n            enum: ['always', 'never', 'allow'],\n          },\n          beforeSelfClosing: {\n            enum: ['always', 'proportional-always', 'never', 'allow'],\n          },\n          afterOpening: {\n            enum: ['always', 'allow-multiline', 'never', 'allow'],\n          },\n          beforeClosing: {\n            enum: ['always', 'proportional-always', 'never', 'allow'],\n          },\n        },\n        default: optionDefaults,\n        additionalProperties: false,\n      },\n    ],\n  },\n  create(context) {\n    const options = Object.assign({}, optionDefaults, context.options[0]);\n\n    return {\n      JSXOpeningElement(node) {\n        if (options.closingSlash !== 'allow' && node.selfClosing) {\n          validateClosingSlash(context, node, options.closingSlash);\n        }\n        if (options.afterOpening !== 'allow') {\n          validateAfterOpening(context, node, options.afterOpening);\n        }\n        if (options.beforeSelfClosing !== 'allow' && node.selfClosing) {\n          validateBeforeSelfClosing(context, node, options.beforeSelfClosing);\n        }\n        if (options.beforeClosing !== 'allow') {\n          validateBeforeClosing(context, node, options.beforeClosing);\n        }\n      },\n      JSXClosingElement(node) {\n        if (options.afterOpening !== 'allow') {\n          validateAfterOpening(context, node, options.afterOpening);\n        }\n        if (options.closingSlash !== 'allow') {\n          validateClosingSlash(context, node, options.closingSlash);\n        }\n        if (options.beforeClosing !== 'allow') {\n          validateBeforeClosing(context, node, options.beforeClosing);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-uses-react.js",
    "content": "/**\n * @fileoverview Prevent React to be marked as unused\n * @author Glen Mailer\n */\n\n'use strict';\n\nconst pragmaUtil = require('../util/pragma');\nconst docsUrl = require('../util/docsUrl');\nconst markVariableAsUsed = require('../util/eslint').markVariableAsUsed;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  // eslint-disable-next-line eslint-plugin/prefer-message-ids -- https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/292\n  meta: {\n    docs: {\n      description: 'Disallow React to be incorrectly marked as unused',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('jsx-uses-react'),\n    },\n    schema: [],\n  },\n\n  create(context) {\n    const pragma = pragmaUtil.getFromContext(context);\n    const fragment = pragmaUtil.getFragmentFromContext(context);\n\n    /**\n     * @param {ASTNode} node\n     * @returns {void}\n     */\n    function handleOpeningElement(node) {\n      markVariableAsUsed(pragma, node, context);\n    }\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      JSXOpeningElement: handleOpeningElement,\n      JSXOpeningFragment: handleOpeningElement,\n      JSXFragment(node) {\n        markVariableAsUsed(fragment, node, context);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-uses-vars.js",
    "content": "/**\n * @fileoverview Prevent variables used in JSX to be marked as unused\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst markVariableAsUsed = require('../util/eslint').markVariableAsUsed;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst isTagNameRe = /^[a-z]/;\nconst isTagName = (name) => isTagNameRe.test(name);\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  // eslint-disable-next-line eslint-plugin/prefer-message-ids -- https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/292\n  meta: {\n    docs: {\n      description: 'Disallow variables used in JSX to be incorrectly marked as unused',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('jsx-uses-vars'),\n    },\n    schema: [],\n  },\n\n  create(context) {\n    return {\n      JSXOpeningElement(node) {\n        let name;\n        if (node.name.namespace) {\n          // <Foo:Bar>\n          return;\n        }\n        if (node.name.name) {\n          // <Foo>\n          name = node.name.name;\n          // Exclude lowercase tag names like <div>\n          if (isTagName(name)) {\n            return;\n          }\n        } else if (node.name.object) {\n          // <Foo...Bar>\n          let parent = node.name.object;\n          while (parent.object) {\n            parent = parent.object;\n          }\n          name = parent.name;\n        } else {\n          return;\n        }\n\n        markVariableAsUsed(name, node, context);\n      },\n\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/jsx-wrap-multilines.js",
    "content": "/**\n * @fileoverview Prevent missing parentheses around multilines JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst docsUrl = require('../util/docsUrl');\nconst eslintUtil = require('../util/eslint');\nconst jsxUtil = require('../util/jsx');\nconst reportC = require('../util/report');\nconst isParenthesized = require('../util/ast').isParenthesized;\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = {\n  declaration: 'parens',\n  assignment: 'parens',\n  return: 'parens',\n  arrow: 'parens',\n  condition: 'ignore',\n  logical: 'ignore',\n  prop: 'ignore',\n};\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  missingParens: 'Missing parentheses around multilines JSX',\n  extraParens: 'Expected no parentheses around multilines JSX',\n  parensOnNewLines: 'Parentheses around JSX should be on separate lines',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow missing parentheses around multiline JSX',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('jsx-wrap-multilines'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      // true/false are for backwards compatibility\n      properties: {\n        declaration: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        assignment: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        return: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        arrow: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        condition: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        logical: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n        prop: {\n          enum: [true, false, 'ignore', 'parens', 'parens-new-line', 'never'],\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    function getOption(type) {\n      const userOptions = context.options[0] || {};\n      if (has(userOptions, type)) {\n        return userOptions[type];\n      }\n      return DEFAULTS[type];\n    }\n\n    function isEnabled(type) {\n      const option = getOption(type);\n      return option && option !== 'ignore';\n    }\n\n    function needsOpeningNewLine(node) {\n      const previousToken = getSourceCode(context).getTokenBefore(node);\n\n      if (!isParenthesized(context, node)) {\n        return false;\n      }\n\n      if (previousToken.loc.end.line === node.loc.start.line) {\n        return true;\n      }\n\n      return false;\n    }\n\n    function needsClosingNewLine(node) {\n      const nextToken = getSourceCode(context).getTokenAfter(node);\n\n      if (!isParenthesized(context, node)) {\n        return false;\n      }\n\n      if (node.loc.end.line === nextToken.loc.end.line) {\n        return true;\n      }\n\n      return false;\n    }\n\n    function isMultilines(node) {\n      return node.loc.start.line !== node.loc.end.line;\n    }\n\n    function report(node, messageId, fix) {\n      reportC(context, messages[messageId], messageId, {\n        node,\n        fix,\n      });\n    }\n\n    function trimTokenBeforeNewline(node, tokenBefore) {\n      // if the token before the jsx is a bracket or curly brace\n      // we don't want a space between the opening parentheses and the multiline jsx\n      const isBracket = tokenBefore.value === '{' || tokenBefore.value === '[';\n      return `${tokenBefore.value.trim()}${isBracket ? '' : ' '}`;\n    }\n\n    function check(node, type) {\n      if (!node || !jsxUtil.isJSX(node)) {\n        return;\n      }\n\n      const sourceCode = getSourceCode(context);\n      const option = getOption(type);\n\n      if ((option === true || option === 'parens') && !isParenthesized(context, node) && isMultilines(node)) {\n        report(node, 'missingParens', (fixer) => fixer.replaceText(node, `(${getText(context, node)})`));\n      }\n\n      if (option === 'parens-new-line' && isMultilines(node)) {\n        if (!isParenthesized(context, node)) {\n          const tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true });\n          const tokenAfter = sourceCode.getTokenAfter(node, { includeComments: true });\n          const start = node.loc.start;\n          if (tokenBefore.loc.end.line < start.line) {\n            // Strip newline after operator if parens newline is specified\n            report(\n              node,\n              'missingParens',\n              (fixer) => fixer.replaceTextRange(\n                [tokenBefore.range[0], tokenAfter && (tokenAfter.value === ';' || tokenAfter.value === '}') ? tokenAfter.range[0] : node.range[1]],\n                `${trimTokenBeforeNewline(node, tokenBefore)}(\\n${start.column > 0 ? ' '.repeat(start.column) : ''}${getText(context, node)}\\n${start.column > 0 ? ' '.repeat(start.column - 2) : ''})`\n              )\n            );\n          } else {\n            report(node, 'missingParens', (fixer) => fixer.replaceText(node, `(\\n${getText(context, node)}\\n)`));\n          }\n        } else {\n          const needsOpening = needsOpeningNewLine(node);\n          const needsClosing = needsClosingNewLine(node);\n          if (needsOpening || needsClosing) {\n            report(node, 'parensOnNewLines', (fixer) => {\n              const text = getText(context, node);\n              let fixed = text;\n              if (needsOpening) {\n                fixed = `\\n${fixed}`;\n              }\n              if (needsClosing) {\n                fixed = `${fixed}\\n`;\n              }\n              return fixer.replaceText(node, fixed);\n            });\n          }\n        }\n      }\n\n      if (option === 'never' && isParenthesized(context, node)) {\n        const tokenBefore = sourceCode.getTokenBefore(node);\n        const tokenAfter = sourceCode.getTokenAfter(node);\n        report(node, 'extraParens', (fixer) => fixer.replaceTextRange(\n          [tokenBefore.range[0], tokenAfter.range[1]],\n          getText(context, node)\n        ));\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n\n      VariableDeclarator(node) {\n        const type = 'declaration';\n        if (!isEnabled(type)) {\n          return;\n        }\n        if (!isEnabled('condition') && node.init && node.init.type === 'ConditionalExpression') {\n          check(node.init.consequent, type);\n          check(node.init.alternate, type);\n          return;\n        }\n        check(node.init, type);\n      },\n\n      AssignmentExpression(node) {\n        const type = 'assignment';\n        if (!isEnabled(type)) {\n          return;\n        }\n        if (!isEnabled('condition') && node.right.type === 'ConditionalExpression') {\n          check(node.right.consequent, type);\n          check(node.right.alternate, type);\n          return;\n        }\n        check(node.right, type);\n      },\n\n      ReturnStatement(node) {\n        const type = 'return';\n        if (isEnabled(type)) {\n          check(node.argument, type);\n        }\n      },\n\n      'ArrowFunctionExpression:exit': (node) => {\n        const arrowBody = node.body;\n        const type = 'arrow';\n\n        if (isEnabled(type) && arrowBody.type !== 'BlockStatement') {\n          check(arrowBody, type);\n        }\n      },\n\n      ConditionalExpression(node) {\n        const type = 'condition';\n        if (isEnabled(type)) {\n          check(node.consequent, type);\n          check(node.alternate, type);\n        }\n      },\n\n      LogicalExpression(node) {\n        const type = 'logical';\n        if (isEnabled(type)) {\n          check(node.right, type);\n        }\n      },\n\n      JSXAttribute(node) {\n        const type = 'prop';\n        if (isEnabled(type) && node.value && node.value.type === 'JSXExpressionContainer') {\n          check(node.value.expression, type);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-access-state-in-setstate.js",
    "content": "/**\n * @fileoverview Prevent usage of this.state within setState\n * @author Rolf Erik Lekang, Jørgen Aaberg\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst report = require('../util/report');\nconst getScope = require('../util/eslint').getScope;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  useCallback: 'Use callback in setState when referencing the previous state.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow when this.state is accessed within setState',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('no-access-state-in-setstate'),\n    },\n\n    messages,\n  },\n\n  create(context) {\n    function isSetStateCall(node) {\n      return astUtil.isCallExpression(node)\n        && node.callee.property\n        && node.callee.property.name === 'setState'\n        && node.callee.object.type === 'ThisExpression';\n    }\n\n    function isFirstArgumentInSetStateCall(current, node) {\n      if (!isSetStateCall(current)) {\n        return false;\n      }\n      while (node && node.parent !== current) {\n        node = node.parent;\n      }\n      return current.arguments[0] === node;\n    }\n\n    /**\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    function isClassComponent(node) {\n      return !!(\n        componentUtil.getParentES6Component(context, node)\n        || componentUtil.getParentES5Component(context, node)\n      );\n    }\n\n    // The methods array contains all methods or functions that are using this.state\n    // or that are calling another method or function using this.state\n    const methods = [];\n    // The vars array contains all variables that contains this.state\n    const vars = [];\n    return {\n      CallExpression(node) {\n        if (!isClassComponent(node)) {\n          return;\n        }\n        // Appends all the methods that are calling another\n        // method containing this.state to the methods array\n        methods.forEach((method) => {\n          if ('name' in node.callee && node.callee.name === method.methodName) {\n            let current = node.parent;\n            while (current.type !== 'Program') {\n              if (current.type === 'MethodDefinition') {\n                methods.push({\n                  methodName: 'name' in current.key ? current.key.name : undefined,\n                  node: method.node,\n                });\n                break;\n              }\n              current = current.parent;\n            }\n          }\n        });\n\n        // Finding all CallExpressions that is inside a setState\n        // to further check if they contains this.state\n        let current = node.parent;\n        while (current.type !== 'Program') {\n          if (isFirstArgumentInSetStateCall(current, node)) {\n            const methodName = 'name' in node.callee ? node.callee.name : undefined;\n            methods.forEach((method) => {\n              if (method.methodName === methodName) {\n                report(context, messages.useCallback, 'useCallback', {\n                  node: method.node,\n                });\n              }\n            });\n\n            break;\n          }\n          current = current.parent;\n        }\n      },\n\n      MemberExpression(node) {\n        if (\n          'name' in node.property\n          && node.property.name === 'state'\n          && node.object.type === 'ThisExpression'\n          && isClassComponent(node)\n        ) {\n          /** @type {import('eslint').Rule.Node} */\n          let current = node;\n          while (current.type !== 'Program') {\n            // Reporting if this.state is directly within this.setState\n            if (isFirstArgumentInSetStateCall(current, node)) {\n              report(context, messages.useCallback, 'useCallback', {\n                node,\n              });\n              break;\n            }\n\n            // Storing all functions and methods that contains this.state\n            if (current.type === 'MethodDefinition') {\n              methods.push({\n                methodName: 'name' in current.key ? current.key.name : undefined,\n                node,\n              });\n              break;\n            } else if (\n              current.type === 'FunctionExpression'\n              && 'key' in current.parent\n              && current.parent.key\n            ) {\n              methods.push({\n                methodName: 'name' in current.parent.key ? current.parent.key.name : undefined,\n                node,\n              });\n              break;\n            }\n\n            // Storing all variables containing this.state\n            if (current.type === 'VariableDeclarator') {\n              vars.push({\n                node,\n                scope: getScope(context, node),\n                variableName: 'name' in current.id ? current.id.name : undefined,\n              });\n              break;\n            }\n\n            current = current.parent;\n          }\n        }\n      },\n\n      Identifier(node) {\n        // Checks if the identifier is a variable within an object\n        /** @type {import('eslint').Rule.Node} */\n        let current = node;\n        while (current.parent.type === 'BinaryExpression') {\n          current = current.parent;\n        }\n        if (\n          ('value' in current.parent && current.parent.value === current)\n          || ('object' in current.parent && current.parent.object === current)\n        ) {\n          while (current.type !== 'Program') {\n            if (isFirstArgumentInSetStateCall(current, node)) {\n              vars\n                .filter((v) => v.scope === getScope(context, node) && v.variableName === node.name)\n                .forEach((v) => {\n                  report(context, messages.useCallback, 'useCallback', {\n                    node: v.node,\n                  });\n                });\n            }\n            current = current.parent;\n          }\n        }\n      },\n\n      ObjectPattern(node) {\n        const isDerivedFromThis = 'init' in node.parent && node.parent.init && node.parent.init.type === 'ThisExpression';\n        node.properties.forEach((property) => {\n          if (\n            property\n            && 'key' in property\n            && property.key\n            && 'name' in property.key\n            && property.key.name === 'state'\n            && isDerivedFromThis\n          ) {\n            vars.push({\n              node: property.key,\n              scope: getScope(context, node),\n              variableName: property.key.name,\n            });\n          }\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-adjacent-inline-elements.js",
    "content": "/**\n * @fileoverview Prevent adjacent inline elements not separated by whitespace.\n * @author Sean Hayes\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\nconst astUtil = require('../util/ast');\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements\nconst inlineNames = [\n  'a',\n  'b',\n  'big',\n  'i',\n  'small',\n  'tt',\n  'abbr',\n  'acronym',\n  'cite',\n  'code',\n  'dfn',\n  'em',\n  'kbd',\n  'strong',\n  'samp',\n  'time',\n  'var',\n  'bdo',\n  'br',\n  'img',\n  'map',\n  'object',\n  'q',\n  'script',\n  'span',\n  'sub',\n  'sup',\n  'button',\n  'input',\n  'label',\n  'select',\n  'textarea',\n];\n// Note: raw &nbsp; will be transformed into \\u00a0.\nconst whitespaceRegex = /(?:^\\s|\\s$)/;\n\nfunction isInline(node) {\n  if (node.type === 'Literal') {\n    // Regular whitespace will be removed.\n    const value = node.value;\n    // To properly separate inline elements, each end of the literal will need\n    // whitespace.\n    return !whitespaceRegex.test(value);\n  }\n  if (node.type === 'JSXElement' && inlineNames.indexOf(node.openingElement.name.name) > -1) {\n    return true;\n  }\n  if (astUtil.isCallExpression(node) && inlineNames.indexOf(node.arguments[0].value) > -1) {\n    return true;\n  }\n  return false;\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  inlineElement: 'Child elements which render as inline HTML elements should be separated by a space or wrapped in block level elements.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow adjacent inline elements not separated by whitespace.',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-adjacent-inline-elements'),\n    },\n    schema: [],\n\n    messages,\n  },\n  create(context) {\n    function validate(node, children) {\n      let currentIsInline = false;\n      let previousIsInline = false;\n      if (!children) {\n        return;\n      }\n      for (let i = 0; i < children.length; i++) {\n        currentIsInline = isInline(children[i]);\n        if (previousIsInline && currentIsInline) {\n          report(context, messages.inlineElement, 'inlineElement', {\n            node,\n          });\n          return;\n        }\n        previousIsInline = currentIsInline;\n      }\n    }\n    return {\n      JSXElement(node) {\n        validate(node, node.children);\n      },\n      CallExpression(node) {\n        if (!isCreateElement(context, node)) {\n          return;\n        }\n        if (node.arguments.length < 2 || !node.arguments[2]) {\n          return;\n        }\n        const children = 'elements' in node.arguments[2] ? node.arguments[2].elements : undefined;\n        validate(node, children);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-array-index-key.js",
    "content": "/**\n * @fileoverview Prevent usage of Array index in keys\n * @author Joe Lencioni\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst pragma = require('../util/pragma');\nconst report = require('../util/report');\nconst variableUtil = require('../util/variable');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction isCreateCloneElement(node, context) {\n  if (!node) {\n    return false;\n  }\n\n  if (node.type === 'MemberExpression' || node.type === 'OptionalMemberExpression') {\n    return node.object\n      && node.object.name === pragma.getFromContext(context)\n      && ['createElement', 'cloneElement'].indexOf(node.property.name) !== -1;\n  }\n\n  if (node.type === 'Identifier') {\n    const variable = variableUtil.findVariableByName(context, node, node.name);\n    if (variable && variable.type === 'ImportSpecifier') {\n      return variable.parent.source.value === 'react';\n    }\n  }\n\n  return false;\n}\n\nconst messages = {\n  noArrayIndex: 'Do not use Array index in keys',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of Array index in keys',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-array-index-key'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n    const indexParamNames = [];\n    const iteratorFunctionsToIndexParamPosition = {\n      every: 1,\n      filter: 1,\n      find: 1,\n      findIndex: 1,\n      flatMap: 1,\n      forEach: 1,\n      map: 1,\n      reduce: 2,\n      reduceRight: 2,\n      some: 1,\n    };\n\n    function isArrayIndex(node) {\n      return node.type === 'Identifier'\n        && indexParamNames.indexOf(node.name) !== -1;\n    }\n\n    function isUsingReactChildren(node) {\n      const callee = node.callee;\n      if (\n        !callee\n        || !callee.property\n        || !callee.object\n      ) {\n        return null;\n      }\n\n      const isReactChildMethod = ['map', 'forEach'].indexOf(callee.property.name) > -1;\n      if (!isReactChildMethod) {\n        return null;\n      }\n\n      const obj = callee.object;\n      if (obj && obj.name === 'Children') {\n        return true;\n      }\n      if (obj && obj.object && obj.object.name === pragma.getFromContext(context)) {\n        return true;\n      }\n\n      return false;\n    }\n\n    function getMapIndexParamName(node) {\n      const callee = node.callee;\n      if (callee.type !== 'MemberExpression' && callee.type !== 'OptionalMemberExpression') {\n        return null;\n      }\n      if (callee.property.type !== 'Identifier') {\n        return null;\n      }\n      if (!has(iteratorFunctionsToIndexParamPosition, callee.property.name)) {\n        return null;\n      }\n\n      const name = /** @type {keyof iteratorFunctionsToIndexParamPosition} */ (callee.property.name);\n\n      const callbackArg = isUsingReactChildren(node)\n        ? node.arguments[1]\n        : node.arguments[0];\n\n      if (!callbackArg) {\n        return null;\n      }\n\n      if (!astUtil.isFunctionLikeExpression(callbackArg)) {\n        return null;\n      }\n\n      const params = callbackArg.params;\n\n      const indexParamPosition = iteratorFunctionsToIndexParamPosition[name];\n      if (params.length < indexParamPosition + 1) {\n        return null;\n      }\n\n      return params[indexParamPosition].name;\n    }\n\n    function getIdentifiersFromBinaryExpression(side) {\n      if (side.type === 'Identifier') {\n        return side;\n      }\n\n      if (side.type === 'BinaryExpression') {\n        // recurse\n        const left = getIdentifiersFromBinaryExpression(side.left);\n        const right = getIdentifiersFromBinaryExpression(side.right);\n        return [].concat(left, right).filter(Boolean);\n      }\n\n      return null;\n    }\n\n    function checkPropValue(node) {\n      if (isArrayIndex(node)) {\n        // key={bar}\n        report(context, messages.noArrayIndex, 'noArrayIndex', {\n          node,\n        });\n        return;\n      }\n\n      if (node.type === 'TemplateLiteral') {\n        // key={`foo-${bar}`}\n        node.expressions.filter(isArrayIndex).forEach(() => {\n          report(context, messages.noArrayIndex, 'noArrayIndex', {\n            node,\n          });\n        });\n\n        return;\n      }\n\n      if (node.type === 'BinaryExpression') {\n        // key={'foo' + bar}\n        const identifiers = getIdentifiersFromBinaryExpression(node);\n\n        identifiers.filter(isArrayIndex).forEach(() => {\n          report(context, messages.noArrayIndex, 'noArrayIndex', {\n            node,\n          });\n        });\n\n        return;\n      }\n\n      if (\n        astUtil.isCallExpression(node)\n        && node.callee\n        && node.callee.type === 'MemberExpression'\n        && node.callee.object\n        && isArrayIndex(node.callee.object)\n        && node.callee.property\n        && node.callee.property.type === 'Identifier'\n        && node.callee.property.name === 'toString'\n      ) {\n        // key={bar.toString()}\n        report(context, messages.noArrayIndex, 'noArrayIndex', {\n          node,\n        });\n        return;\n      }\n\n      if (\n        astUtil.isCallExpression(node)\n        && node.callee\n        && node.callee.type === 'Identifier'\n        && node.callee.name === 'String'\n        && Array.isArray(node.arguments)\n        && node.arguments.length > 0\n        && isArrayIndex(node.arguments[0])\n      ) {\n        // key={String(bar)}\n        report(context, messages.noArrayIndex, 'noArrayIndex', {\n          node: node.arguments[0],\n        });\n      }\n    }\n\n    function popIndex(node) {\n      const mapIndexParamName = getMapIndexParamName(node);\n      if (!mapIndexParamName) {\n        return;\n      }\n\n      indexParamNames.pop();\n    }\n\n    return {\n      'CallExpression, OptionalCallExpression'(node) {\n        if (isCreateCloneElement(node.callee, context) && node.arguments.length > 1) {\n          // React.createElement\n          if (!indexParamNames.length) {\n            return;\n          }\n\n          const props = node.arguments[1];\n\n          if (props.type !== 'ObjectExpression') {\n            return;\n          }\n\n          props.properties.forEach((prop) => {\n            if (!prop.key || prop.key.name !== 'key') {\n              // { ...foo }\n              // { foo: bar }\n              return;\n            }\n\n            checkPropValue(prop.value);\n          });\n\n          return;\n        }\n\n        const mapIndexParamName = getMapIndexParamName(node);\n        if (!mapIndexParamName) {\n          return;\n        }\n\n        indexParamNames.push(mapIndexParamName);\n      },\n\n      JSXAttribute(node) {\n        if (node.name.name !== 'key') {\n          // foo={bar}\n          return;\n        }\n\n        if (!indexParamNames.length) {\n          // Not inside a call expression that we think has an index param.\n          return;\n        }\n\n        const value = node.value;\n        if (!value || value.type !== 'JSXExpressionContainer') {\n          // key='foo' or just simply 'key'\n          return;\n        }\n\n        checkPropValue(value.expression);\n      },\n\n      'CallExpression:exit': popIndex,\n      'OptionalCallExpression:exit': popIndex,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-arrow-function-lifecycle.js",
    "content": "/**\n * @fileoverview Lifecycle methods should be methods on the prototype, not class fields\n * @author Tan Nguyen\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst lifecycleMethods = require('../util/lifecycleMethods');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\nfunction getRuleText(node) {\n  const params = node.value.params.map((p) => p.name);\n\n  if (node.type === 'Property') {\n    return `: function(${params.join(', ')}) `;\n  }\n\n  if (node.type === 'ClassProperty' || node.type === 'PropertyDefinition') {\n    return `(${params.join(', ')}) `;\n  }\n\n  return null;\n}\n\nconst messages = {\n  lifecycle: '{{propertyName}} is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Lifecycle methods should be methods on the prototype, not class fields',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-arrow-function-lifecycle'),\n    },\n    messages,\n    schema: [],\n    fixable: 'code',\n  },\n\n  create: Components.detect((context, components) => {\n    /**\n     * @param {Array} properties list of component properties\n     */\n    function reportNoArrowFunctionLifecycle(properties) {\n      properties.forEach((node) => {\n        if (!node || !node.value) {\n          return;\n        }\n\n        const propertyName = astUtil.getPropertyName(node);\n        const nodeType = node.value.type;\n        const isLifecycleMethod = (\n          node.static && !componentUtil.isES5Component(node, context)\n            ? lifecycleMethods.static\n            : lifecycleMethods.instance\n        ).indexOf(propertyName) > -1;\n\n        if (nodeType === 'ArrowFunctionExpression' && isLifecycleMethod) {\n          const body = node.value.body;\n          const isBlockBody = body.type === 'BlockStatement';\n          const sourceCode = getSourceCode(context);\n\n          let nextComment = [];\n          let previousComment = [];\n          let bodyRange;\n          if (!isBlockBody) {\n            const previousToken = sourceCode.getTokenBefore(body);\n\n            if (sourceCode.getCommentsBefore) {\n              // eslint >=4.x\n              previousComment = sourceCode.getCommentsBefore(body);\n            } else {\n              // eslint 3.x\n              const potentialComment = sourceCode.getTokenBefore(body, { includeComments: true });\n              previousComment = previousToken === potentialComment ? [] : [potentialComment];\n            }\n\n            if (sourceCode.getCommentsAfter) {\n              // eslint >=4.x\n              nextComment = sourceCode.getCommentsAfter(body);\n            } else {\n              // eslint 3.x\n              const potentialComment = sourceCode.getTokenAfter(body, { includeComments: true });\n              const nextToken = sourceCode.getTokenAfter(body);\n              nextComment = nextToken === potentialComment ? [] : [potentialComment];\n            }\n            bodyRange = [\n              (previousComment.length > 0 ? previousComment[0] : body).range[0],\n              (nextComment.length > 0 ? nextComment[nextComment.length - 1] : body).range[1]\n                + (node.value.body.type === 'ObjectExpression' ? 1 : 0), // to account for a wrapped end paren\n            ];\n          }\n          const headRange = [\n            node.key.range[1],\n            (previousComment.length > 0 ? previousComment[0] : body).range[0],\n          ];\n          const hasSemi = node.value.expression && getText(context, node).slice(node.value.range[1] - node.range[0]) === ';';\n\n          report(\n            context,\n            messages.lifecycle,\n            'lifecycle',\n            {\n              node,\n              data: {\n                propertyName,\n              },\n              fix(fixer) {\n                if (!sourceCode.getCommentsAfter) {\n                  // eslint 3.x\n                  return isBlockBody && fixer.replaceTextRange(headRange, getRuleText(node));\n                }\n                return [].concat(\n                  fixer.replaceTextRange(headRange, getRuleText(node)),\n                  isBlockBody ? [] : fixer.replaceTextRange(\n                    [bodyRange[0], bodyRange[1] + (hasSemi ? 1 : 0)],\n                    `{ return ${previousComment.map((x) => getText(context, x)).join('')}${getText(context, body)}${nextComment.map((x) => getText(context, x)).join('')}; }`\n                  )\n                );\n              },\n            }\n          );\n        }\n      });\n    }\n\n    return {\n      'Program:exit'() {\n        values(components.list()).forEach((component) => {\n          const properties = astUtil.getComponentProperties(component.node);\n          reportNoArrowFunctionLifecycle(properties);\n        });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-children-prop.js",
    "content": "/**\n * @fileoverview Prevent passing of children as props\n * @author Benjamin Stepp\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n/**\n * Checks if the node is a createElement call with a props literal.\n * @param {ASTNode} node - The AST node being checked.\n * @param {Context} context - The AST node being checked.\n * @returns {boolean} - True if node is a createElement call with a props\n * object literal, False if not.\n*/\nfunction isCreateElementWithProps(node, context) {\n  return isCreateElement(context, node)\n    && node.arguments.length > 1\n    && node.arguments[1].type === 'ObjectExpression';\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  nestChildren: 'Do not pass children as props. Instead, nest children between the opening and closing tags.',\n  passChildrenAsArgs: 'Do not pass children as props. Instead, pass them as additional arguments to React.createElement.',\n  nestFunction: 'Do not nest a function between the opening and closing tags. Instead, pass it as a prop.',\n  passFunctionAsArgs: 'Do not pass a function as an additional argument to React.createElement. Instead, pass it as a prop.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow passing of children as props',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-children-prop'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowFunctions: {\n          type: 'boolean',\n          default: false,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n  create(context) {\n    const configuration = context.options[0] || {};\n\n    function isFunction(node) {\n      return configuration.allowFunctions && (node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression');\n    }\n\n    return {\n      JSXAttribute(node) {\n        if (node.name.name !== 'children') {\n          return;\n        }\n\n        const value = node.value;\n        if (value && value.type === 'JSXExpressionContainer' && isFunction(value.expression)) {\n          return;\n        }\n\n        report(context, messages.nestChildren, 'nestChildren', {\n          node,\n        });\n      },\n      CallExpression(node) {\n        if (!isCreateElementWithProps(node, context)) {\n          return;\n        }\n\n        const props = 'properties' in node.arguments[1] ? node.arguments[1].properties : undefined;\n        const childrenProp = props.find((prop) => (\n          'key' in prop\n          && prop.key\n          && 'name' in prop.key\n          && prop.key.name === 'children'\n        ));\n\n        if (childrenProp) {\n          if ('value' in childrenProp && childrenProp.value && !isFunction(childrenProp.value)) {\n            report(context, messages.passChildrenAsArgs, 'passChildrenAsArgs', {\n              node,\n            });\n          }\n        } else if (node.arguments.length === 3) {\n          const children = node.arguments[2];\n          if (isFunction(children)) {\n            report(context, messages.passFunctionAsArgs, 'passFunctionAsArgs', {\n              node,\n            });\n          }\n        }\n      },\n      JSXElement(node) {\n        const children = node.children;\n        if (children && children.length === 1 && children[0].type === 'JSXExpressionContainer') {\n          if (isFunction(children[0].expression)) {\n            report(context, messages.nestFunction, 'nestFunction', {\n              node,\n            });\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-danger-with-children.js",
    "content": "/**\n * @fileoverview Report when a DOM element is using both children and dangerouslySetInnerHTML\n * @author David Petersen\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst jsxUtil = require('../util/jsx');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\nconst messages = {\n  dangerWithChildren: 'Only set one of `children` or `props.dangerouslySetInnerHTML`',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow when a DOM element is using both children and dangerouslySetInnerHTML',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('no-danger-with-children'),\n    },\n\n    messages,\n\n    schema: [], // no options\n  },\n  create(context) {\n    function findSpreadVariable(node, name) {\n      return variableUtil.getVariableFromContext(context, node, name);\n    }\n    /**\n     * Takes a ObjectExpression and returns the value of the prop if it has it\n     * @param {object} node - ObjectExpression node\n     * @param {string} propName - name of the prop to look for\n     * @param {string[]} seenProps\n     * @returns {object | boolean}\n     */\n    function findObjectProp(node, propName, seenProps) {\n      if (!node.properties) {\n        return false;\n      }\n      return node.properties.find((prop) => {\n        if (prop.type === 'Property') {\n          return prop.key.name === propName;\n        }\n        if (prop.type === 'ExperimentalSpreadProperty' || prop.type === 'SpreadElement') {\n          const variable = findSpreadVariable(node, prop.argument.name);\n          if (variable && variable.defs.length && variable.defs[0].node.init) {\n            if (seenProps.indexOf(prop.argument.name) > -1) {\n              return false;\n            }\n            const newSeenProps = seenProps.concat(prop.argument.name || []);\n            return findObjectProp(variable.defs[0].node.init, propName, newSeenProps);\n          }\n        }\n        return false;\n      });\n    }\n\n    /**\n     * Takes a JSXElement and returns the value of the prop if it has it\n     * @param {object} node - JSXElement node\n     * @param {string} propName - name of the prop to look for\n     * @returns {object | boolean}\n     */\n    function findJsxProp(node, propName) {\n      const attributes = node.openingElement.attributes;\n      return attributes.find((attribute) => {\n        if (attribute.type === 'JSXSpreadAttribute') {\n          const variable = findSpreadVariable(node, attribute.argument.name);\n          if (variable && variable.defs.length && variable.defs[0].node.init) {\n            return findObjectProp(variable.defs[0].node.init, propName, []);\n          }\n        }\n        return attribute.name && attribute.name.name === propName;\n      });\n    }\n\n    /**\n     * Checks to see if a node is a line break\n     * @param {ASTNode} node The AST node being checked\n     * @returns {boolean} True if node is a line break, false if not\n     */\n    function isLineBreak(node) {\n      const isLiteral = node.type === 'Literal' || node.type === 'JSXText';\n      const isMultiline = node.loc.start.line !== node.loc.end.line;\n      const isWhiteSpaces = jsxUtil.isWhiteSpaces(node.value);\n\n      return isLiteral && isMultiline && isWhiteSpaces;\n    }\n\n    return {\n      JSXElement(node) {\n        let hasChildren = false;\n\n        if (node.children.length && !isLineBreak(node.children[0])) {\n          hasChildren = true;\n        } else if (findJsxProp(node, 'children')) {\n          hasChildren = true;\n        }\n\n        if (\n          node.openingElement.attributes\n          && hasChildren\n          && findJsxProp(node, 'dangerouslySetInnerHTML')\n        ) {\n          report(context, messages.dangerWithChildren, 'dangerWithChildren', {\n            node,\n          });\n        }\n      },\n      CallExpression(node) {\n        if (\n          node.callee\n          && node.callee.type === 'MemberExpression'\n          && 'name' in node.callee.property\n          && node.callee.property.name === 'createElement'\n          && node.arguments.length > 1\n        ) {\n          let hasChildren = false;\n\n          let props = node.arguments[1];\n\n          if (props.type === 'Identifier') {\n            const variable = variableUtil.getVariableFromContext(context, node, props.name);\n            if (variable && variable.defs.length && variable.defs[0].node.init) {\n              props = variable.defs[0].node.init;\n            }\n          }\n\n          const dangerously = findObjectProp(props, 'dangerouslySetInnerHTML', []);\n\n          if (node.arguments.length === 2) {\n            if (findObjectProp(props, 'children', [])) {\n              hasChildren = true;\n            }\n          } else {\n            hasChildren = true;\n          }\n\n          if (dangerously && hasChildren) {\n            report(context, messages.dangerWithChildren, 'dangerWithChildren', {\n              node,\n            });\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-danger.js",
    "content": "/**\n * @fileoverview Prevent usage of dangerous JSX props\n * @author Scott Andrews\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst fromEntries = require('object.fromentries/polyfill')();\nconst minimatch = require('minimatch');\n\nconst docsUrl = require('../util/docsUrl');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DANGEROUS_PROPERTY_NAMES = [\n  'dangerouslySetInnerHTML',\n];\n\nconst DANGEROUS_PROPERTIES = fromEntries(DANGEROUS_PROPERTY_NAMES.map((prop) => [prop, prop]));\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n/**\n * Checks if a JSX attribute is dangerous.\n * @param {string} name - Name of the attribute to check.\n * @returns {boolean} Whether or not the attribute is dangerous.\n */\nfunction isDangerous(name) {\n  return has(DANGEROUS_PROPERTIES, name);\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  dangerousProp: 'Dangerous property \\'{{name}}\\' found',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of dangerous JSX properties',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-danger'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        customComponentNames: {\n          items: {\n            type: 'string',\n          },\n          minItems: 0,\n          type: 'array',\n          uniqueItems: true,\n        },\n      },\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const customComponentNames = configuration.customComponentNames || [];\n\n    return {\n      JSXAttribute(node) {\n        const nodeName = node.parent.name;\n        const functionName = nodeName.name || `${nodeName.object.name}.${nodeName.property.name}`;\n\n        const enableCheckingCustomComponent = customComponentNames.some((name) => minimatch(functionName, name));\n\n        if ((enableCheckingCustomComponent || jsxUtil.isDOMComponent(node.parent)) && isDangerous(node.name.name)) {\n          report(context, messages.dangerousProp, 'dangerousProp', {\n            node,\n            data: {\n              name: node.name.name,\n            },\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-deprecated.js",
    "content": "/**\n * @fileoverview Prevent usage of deprecated methods\n * @author Yannick Croissant\n * @author Scott Feeney\n * @author Sergei Startsev\n */\n\n'use strict';\n\nconst entries = require('object.entries');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst pragmaUtil = require('../util/pragma');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst MODULES = {\n  react: ['React'],\n  'react-addons-perf': ['ReactPerf', 'Perf'],\n  'react-dom': ['ReactDOM'],\n  'react-dom/server': ['ReactDOMServer'],\n};\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction getDeprecated(pragma) {\n  const deprecated = {};\n  // 0.12.0\n  deprecated[`${pragma}.renderComponent`] = ['0.12.0', `${pragma}.render`];\n  deprecated[`${pragma}.renderComponentToString`] = ['0.12.0', `${pragma}.renderToString`];\n  deprecated[`${pragma}.renderComponentToStaticMarkup`] = ['0.12.0', `${pragma}.renderToStaticMarkup`];\n  deprecated[`${pragma}.isValidComponent`] = ['0.12.0', `${pragma}.isValidElement`];\n  deprecated[`${pragma}.PropTypes.component`] = ['0.12.0', `${pragma}.PropTypes.element`];\n  deprecated[`${pragma}.PropTypes.renderable`] = ['0.12.0', `${pragma}.PropTypes.node`];\n  deprecated[`${pragma}.isValidClass`] = ['0.12.0'];\n  deprecated['this.transferPropsTo'] = ['0.12.0', 'spread operator ({...})'];\n  // 0.13.0\n  deprecated[`${pragma}.addons.classSet`] = ['0.13.0', 'the npm module classnames'];\n  deprecated[`${pragma}.addons.cloneWithProps`] = ['0.13.0', `${pragma}.cloneElement`];\n  // 0.14.0\n  deprecated[`${pragma}.render`] = ['0.14.0', 'ReactDOM.render'];\n  deprecated[`${pragma}.unmountComponentAtNode`] = ['0.14.0', 'ReactDOM.unmountComponentAtNode'];\n  deprecated[`${pragma}.findDOMNode`] = ['0.14.0', 'ReactDOM.findDOMNode'];\n  deprecated[`${pragma}.renderToString`] = ['0.14.0', 'ReactDOMServer.renderToString'];\n  deprecated[`${pragma}.renderToStaticMarkup`] = ['0.14.0', 'ReactDOMServer.renderToStaticMarkup'];\n  // 15.0.0\n  deprecated[`${pragma}.addons.LinkedStateMixin`] = ['15.0.0'];\n  deprecated['ReactPerf.printDOM'] = ['15.0.0', 'ReactPerf.printOperations'];\n  deprecated['Perf.printDOM'] = ['15.0.0', 'Perf.printOperations'];\n  deprecated['ReactPerf.getMeasurementsSummaryMap'] = ['15.0.0', 'ReactPerf.getWasted'];\n  deprecated['Perf.getMeasurementsSummaryMap'] = ['15.0.0', 'Perf.getWasted'];\n  // 15.5.0\n  deprecated[`${pragma}.createClass`] = ['15.5.0', 'the npm module create-react-class'];\n  deprecated[`${pragma}.addons.TestUtils`] = ['15.5.0', 'ReactDOM.TestUtils'];\n  deprecated[`${pragma}.PropTypes`] = ['15.5.0', 'the npm module prop-types'];\n  // 15.6.0\n  deprecated[`${pragma}.DOM`] = ['15.6.0', 'the npm module react-dom-factories'];\n  // 16.9.0\n  // For now the following life-cycle methods are just legacy, not deprecated:\n  // `componentWillMount`, `componentWillReceiveProps`, `componentWillUpdate`\n  // https://github.com/yannickcr/eslint-plugin-react/pull/1750#issuecomment-425975934\n  deprecated.componentWillMount = [\n    '16.9.0',\n    'UNSAFE_componentWillMount',\n    'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. '\n    + 'Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n  ];\n  deprecated.componentWillReceiveProps = [\n    '16.9.0',\n    'UNSAFE_componentWillReceiveProps',\n    'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. '\n    + 'Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n  ];\n  deprecated.componentWillUpdate = [\n    '16.9.0',\n    'UNSAFE_componentWillUpdate',\n    'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. '\n    + 'Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n  ];\n  // 18.0.0\n  // https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#deprecations\n  deprecated['ReactDOM.render'] = [\n    '18.0.0',\n    'createRoot',\n    'https://reactjs.org/link/switch-to-createroot',\n  ];\n  deprecated['ReactDOM.hydrate'] = [\n    '18.0.0',\n    'hydrateRoot',\n    'https://reactjs.org/link/switch-to-createroot',\n  ];\n  deprecated['ReactDOM.unmountComponentAtNode'] = [\n    '18.0.0',\n    'root.unmount',\n    'https://reactjs.org/link/switch-to-createroot',\n  ];\n  deprecated['ReactDOMServer.renderToNodeStream'] = [\n    '18.0.0',\n    'renderToPipeableStream',\n    'https://reactjs.org/docs/react-dom-server.html#rendertonodestream',\n  ];\n\n  return deprecated;\n}\n\nconst messages = {\n  deprecated: '{{oldMethod}} is deprecated since React {{version}}{{newMethod}}{{refs}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of deprecated methods',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-deprecated'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    const pragma = pragmaUtil.getFromContext(context);\n    const deprecated = getDeprecated(pragma);\n\n    function isDeprecated(method) {\n      return (\n        deprecated\n        && deprecated[method]\n        && deprecated[method][0]\n        && testReactVersion(context, `>= ${deprecated[method][0]}`)\n      );\n    }\n\n    function checkDeprecation(node, methodName, methodNode) {\n      if (!isDeprecated(methodName)) {\n        return;\n      }\n      const version = deprecated[methodName][0];\n      const newMethod = deprecated[methodName][1];\n      const refs = deprecated[methodName][2];\n      report(context, messages.deprecated, 'deprecated', {\n        node: methodNode || node,\n        data: {\n          oldMethod: methodName,\n          version,\n          newMethod: newMethod ? `, use ${newMethod} instead` : '',\n          refs: refs ? `, see ${refs}` : '',\n        },\n      });\n    }\n\n    function getReactModuleName(node) {\n      let moduleName = false;\n      if (!node.init) {\n        return false;\n      }\n\n      entries(MODULES).some((entry) => {\n        const key = entry[0];\n        const moduleNames = entry[1];\n        if (\n          node.init.arguments\n          && node.init.arguments.length > 0\n          && node.init.arguments[0]\n          && key === node.init.arguments[0].value\n        ) {\n          moduleName = MODULES[key][0];\n        } else {\n          moduleName = moduleNames.find((name) => name === node.init.name);\n        }\n        return moduleName;\n      });\n\n      return moduleName;\n    }\n\n    /**\n     * Returns life cycle methods if available\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {Array} The array of methods.\n     */\n    function getLifeCycleMethods(node) {\n      const properties = astUtil.getComponentProperties(node);\n      return properties.map((property) => ({\n        name: astUtil.getPropertyName(property),\n        node: astUtil.getPropertyNameNode(property),\n      }));\n    }\n\n    /**\n     * Checks life cycle methods\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function checkLifeCycleMethods(node) {\n      if (\n        componentUtil.isES5Component(node, context)\n     || componentUtil.isES6Component(node, context)\n      ) {\n        const methods = getLifeCycleMethods(node);\n        methods.forEach((method) => checkDeprecation(node, method.name, method.node));\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      MemberExpression(node) {\n        checkDeprecation(node, getText(context, node));\n      },\n\n      ImportDeclaration(node) {\n        const isReactImport = typeof MODULES[node.source.value] !== 'undefined';\n        if (!isReactImport) {\n          return;\n        }\n        node.specifiers.filter(((s) => 'imported' in s && s.imported)).forEach((specifier) => {\n          // TODO, semver-major: remove `in` check as part of jsdoc->tsdoc migration\n          checkDeprecation(node, 'imported' in specifier && 'name' in specifier.imported && `${MODULES[node.source.value][0]}.${specifier.imported.name}`, specifier);\n        });\n      },\n\n      VariableDeclarator(node) {\n        const reactModuleName = getReactModuleName(node);\n        const isRequire = node.init\n          && 'callee' in node.init\n          && node.init.callee\n          && 'name' in node.init.callee\n          && node.init.callee.name === 'require';\n        const isReactRequire = node.init\n          && 'arguments' in node.init\n          && node.init.arguments\n          && node.init.arguments.length\n          && typeof MODULES['value' in node.init.arguments[0] ? node.init.arguments[0].value : undefined] !== 'undefined';\n        const isDestructuring = node.id && node.id.type === 'ObjectPattern';\n\n        if (\n          !(isDestructuring && reactModuleName)\n          && !(isDestructuring && isRequire && isReactRequire)\n        ) {\n          return;\n        }\n\n        ('properties' in node.id ? node.id.properties : undefined).filter((p) => p.type !== 'RestElement' && p.key).forEach((property) => {\n          checkDeprecation(\n            node,\n            'key' in property && 'name' in property.key && `${reactModuleName || pragma}.${property.key.name}`,\n            property\n          );\n        });\n      },\n\n      ClassDeclaration: checkLifeCycleMethods,\n      ClassExpression: checkLifeCycleMethods,\n      ObjectExpression: checkLifeCycleMethods,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-did-mount-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentDidMount\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst makeNoMethodSetStateRule = require('../util/makeNoMethodSetStateRule');\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = makeNoMethodSetStateRule('componentDidMount');\n"
  },
  {
    "path": "lib/rules/no-did-update-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentDidUpdate\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst makeNoMethodSetStateRule = require('../util/makeNoMethodSetStateRule');\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = makeNoMethodSetStateRule('componentDidUpdate');\n"
  },
  {
    "path": "lib/rules/no-direct-mutation-state.js",
    "content": "/**\n * @fileoverview Prevent direct mutation of this.state\n * @author David Petersen\n * @author Nicolas Fernandez <@burabure>\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noDirectMutation: 'Do not mutate state directly. Use setState().',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow direct mutation of this.state',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('no-direct-mutation-state'),\n    },\n\n    messages,\n  },\n\n  create: Components.detect((context, components, utils) => {\n    /**\n     * Checks if the component is valid\n     * @param {Object} component The component to process\n     * @returns {boolean} True if the component is valid, false if not.\n     */\n    function isValid(component) {\n      return !!component && !component.mutateSetState;\n    }\n\n    /**\n     * Reports undeclared proptypes for a given component\n     * @param {Object} component The component to process\n     */\n    function reportMutations(component) {\n      let mutation;\n      for (let i = 0, j = component.mutations.length; i < j; i++) {\n        mutation = component.mutations[i];\n        report(context, messages.noDirectMutation, 'noDirectMutation', {\n          node: mutation,\n        });\n      }\n    }\n\n    /**\n     * Walks through the MemberExpression to the top-most property.\n     * @param {Object} node The node to process\n     * @returns {Object} The outer-most MemberExpression\n     */\n    function getOuterMemberExpression(node) {\n      while (node.object && node.object.property) {\n        node = node.object;\n      }\n      return node;\n    }\n\n    /**\n     * Determine if we should currently ignore assignments in this component.\n     * @param {?Object} component The component to process\n     * @returns {boolean} True if we should skip assignment checks.\n     */\n    function shouldIgnoreComponent(component) {\n      return !component || (component.inConstructor && !component.inCallExpression);\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n    return {\n      MethodDefinition(node) {\n        if (node.kind === 'constructor') {\n          components.set(node, {\n            inConstructor: true,\n          });\n        }\n      },\n\n      CallExpression(node) {\n        components.set(node, {\n          inCallExpression: true,\n        });\n      },\n\n      AssignmentExpression(node) {\n        const component = components.get(utils.getParentComponent(node));\n        if (shouldIgnoreComponent(component) || !node.left || !node.left.object) {\n          return;\n        }\n        const item = getOuterMemberExpression(node.left);\n        if (componentUtil.isStateMemberExpression(item)) {\n          const mutations = (component && component.mutations) || [];\n          mutations.push(node.left.object);\n          components.set(node, {\n            mutateSetState: true,\n            mutations,\n          });\n        }\n      },\n\n      UpdateExpression(node) {\n        const component = components.get(utils.getParentComponent(node));\n        if (shouldIgnoreComponent(component) || node.argument.type !== 'MemberExpression') {\n          return;\n        }\n        const item = getOuterMemberExpression(node.argument);\n        if (componentUtil.isStateMemberExpression(item)) {\n          const mutations = (component && component.mutations) || [];\n          mutations.push(item);\n          components.set(node, {\n            mutateSetState: true,\n            mutations,\n          });\n        }\n      },\n\n      'CallExpression:exit'(node) {\n        components.set(node, {\n          inCallExpression: false,\n        });\n      },\n\n      'MethodDefinition:exit'(node) {\n        if (node.kind === 'constructor') {\n          components.set(node, {\n            inConstructor: false,\n          });\n        }\n      },\n\n      'Program:exit'() {\n        values(components.list())\n          .filter((component) => !isValid(component))\n          .forEach((component) => {\n            reportMutations(component);\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-find-dom-node.js",
    "content": "/**\n * @fileoverview Prevent usage of findDOMNode\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noFindDOMNode: 'Do not use findDOMNode. It doesn’t work with function components and is deprecated in StrictMode. See https://reactjs.org/docs/react-dom.html#finddomnode',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of findDOMNode',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-find-dom-node'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    return {\n      CallExpression(node) {\n        const callee = node.callee;\n\n        const isFindDOMNode = ('name' in callee && callee.name === 'findDOMNode') || (\n          'property' in callee\n          && callee.property\n          && 'name' in callee.property\n          && callee.property.name === 'findDOMNode'\n        );\n\n        if (!isFindDOMNode) {\n          return;\n        }\n\n        report(context, messages.noFindDOMNode, 'noFindDOMNode', {\n          node: callee,\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-invalid-html-attribute.js",
    "content": "/**\n * @fileoverview Check if tag attributes to have non-valid value\n * @author Sebastian Malton\n */\n\n'use strict';\n\nconst matchAll = require('string.prototype.matchall');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst rel = new Map([\n  ['alternate', new Set(['link', 'area', 'a'])],\n  ['apple-touch-icon', new Set(['link'])],\n  ['apple-touch-startup-image', new Set(['link'])],\n  ['author', new Set(['link', 'area', 'a'])],\n  ['bookmark', new Set(['area', 'a'])],\n  ['canonical', new Set(['link'])],\n  ['dns-prefetch', new Set(['link'])],\n  ['external', new Set(['area', 'a', 'form'])],\n  ['help', new Set(['link', 'area', 'a', 'form'])],\n  ['icon', new Set(['link'])],\n  ['license', new Set(['link', 'area', 'a', 'form'])],\n  ['manifest', new Set(['link'])],\n  ['mask-icon', new Set(['link'])],\n  ['modulepreload', new Set(['link'])],\n  ['next', new Set(['link', 'area', 'a', 'form'])],\n  ['nofollow', new Set(['area', 'a', 'form'])],\n  ['noopener', new Set(['area', 'a', 'form'])],\n  ['noreferrer', new Set(['area', 'a', 'form'])],\n  ['opener', new Set(['area', 'a', 'form'])],\n  ['pingback', new Set(['link'])],\n  ['preconnect', new Set(['link'])],\n  ['prefetch', new Set(['link'])],\n  ['preload', new Set(['link'])],\n  ['prerender', new Set(['link'])],\n  ['prev', new Set(['link', 'area', 'a', 'form'])],\n  ['search', new Set(['link', 'area', 'a', 'form'])],\n  ['shortcut', new Set(['link'])], // generally allowed but needs pair with \"icon\"\n  ['shortcut\\u0020icon', new Set(['link'])],\n  ['stylesheet', new Set(['link'])],\n  ['tag', new Set(['area', 'a'])],\n]);\n\nconst pairs = new Map([\n  ['shortcut', new Set(['icon'])],\n]);\n\n/**\n * Map between attributes and a mapping between valid values and a set of tags they are valid on\n * @type {Map<string, Map<string, Set<string>>>}\n */\nconst VALID_VALUES = new Map([\n  ['rel', rel],\n]);\n\n/**\n * Map between attributes and a mapping between pair-values and a set of values they are valid with\n * @type {Map<string, Map<string, Set<string>>>}\n */\nconst VALID_PAIR_VALUES = new Map([\n  ['rel', pairs],\n]);\n\n/**\n * The set of all possible HTML elements. Used for skipping custom types\n * @type {Set<string>}\n */\nconst HTML_ELEMENTS = new Set([\n  'a',\n  'abbr',\n  'acronym',\n  'address',\n  'applet',\n  'area',\n  'article',\n  'aside',\n  'audio',\n  'b',\n  'base',\n  'basefont',\n  'bdi',\n  'bdo',\n  'bgsound',\n  'big',\n  'blink',\n  'blockquote',\n  'body',\n  'br',\n  'button',\n  'canvas',\n  'caption',\n  'center',\n  'cite',\n  'code',\n  'col',\n  'colgroup',\n  'content',\n  'data',\n  'datalist',\n  'dd',\n  'del',\n  'details',\n  'dfn',\n  'dialog',\n  'dir',\n  'div',\n  'dl',\n  'dt',\n  'em',\n  'embed',\n  'fieldset',\n  'figcaption',\n  'figure',\n  'font',\n  'footer',\n  'form',\n  'frame',\n  'frameset',\n  'h1',\n  'h2',\n  'h3',\n  'h4',\n  'h5',\n  'h6',\n  'head',\n  'header',\n  'hgroup',\n  'hr',\n  'html',\n  'i',\n  'iframe',\n  'image',\n  'img',\n  'input',\n  'ins',\n  'kbd',\n  'keygen',\n  'label',\n  'legend',\n  'li',\n  'link',\n  'main',\n  'map',\n  'mark',\n  'marquee',\n  'math',\n  'menu',\n  'menuitem',\n  'meta',\n  'meter',\n  'nav',\n  'nobr',\n  'noembed',\n  'noframes',\n  'noscript',\n  'object',\n  'ol',\n  'optgroup',\n  'option',\n  'output',\n  'p',\n  'param',\n  'picture',\n  'plaintext',\n  'portal',\n  'pre',\n  'progress',\n  'q',\n  'rb',\n  'rp',\n  'rt',\n  'rtc',\n  'ruby',\n  's',\n  'samp',\n  'script',\n  'section',\n  'select',\n  'shadow',\n  'slot',\n  'small',\n  'source',\n  'spacer',\n  'span',\n  'strike',\n  'strong',\n  'style',\n  'sub',\n  'summary',\n  'sup',\n  'svg',\n  'table',\n  'tbody',\n  'td',\n  'template',\n  'textarea',\n  'tfoot',\n  'th',\n  'thead',\n  'time',\n  'title',\n  'tr',\n  'track',\n  'tt',\n  'u',\n  'ul',\n  'var',\n  'video',\n  'wbr',\n  'xmp',\n]);\n\n/**\n* Map between attributes and set of tags that the attribute is valid on\n* @type {Map<string, Set<string>>}\n*/\nconst COMPONENT_ATTRIBUTE_MAP = new Map([\n  ['rel', new Set(['link', 'a', 'area', 'form'])],\n]);\n\n/* eslint-disable eslint-plugin/no-unused-message-ids -- false positives, these messageIds are used */\nconst messages = {\n  emptyIsMeaningless: 'An empty “{{attributeName}}” attribute is meaningless.',\n  neverValid: '“{{reportingValue}}” is never a valid “{{attributeName}}” attribute value.',\n  noEmpty: 'An empty “{{attributeName}}” attribute is meaningless.',\n  noMethod: 'The ”{{attributeName}}“ attribute cannot be a method.',\n  notAlone: '“{{reportingValue}}” must be directly followed by “{{missingValue}}”.',\n  notPaired: '“{{reportingValue}}” can not be directly followed by “{{secondValue}}” without “{{missingValue}}”.',\n  notValidFor: '“{{reportingValue}}” is not a valid “{{attributeName}}” attribute value for <{{elementName}}>.',\n  onlyMeaningfulFor: 'The ”{{attributeName}}“ attribute only has meaning on the tags: {{tagNames}}',\n  onlyStrings: '“{{attributeName}}” attribute only supports strings.',\n  spaceDelimited: '”{{attributeName}}“ attribute values should be space delimited.',\n  suggestRemoveDefault: '\"remove {{attributeName}}\"',\n  suggestRemoveEmpty: '\"remove empty attribute {{attributeName}}\"',\n  suggestRemoveInvalid: '“remove invalid attribute {{reportingValue}}”',\n  suggestRemoveWhitespaces: 'remove whitespaces in “{{attributeName}}”',\n  suggestRemoveNonString: 'remove non-string value in “{{attributeName}}”',\n};\n\nfunction splitIntoRangedParts(node, regex) {\n  const valueRangeStart = node.range[0] + 1; // the plus one is for the initial quote\n\n  return Array.from(matchAll(node.value, regex), (match) => {\n    const start = match.index + valueRangeStart;\n    const end = start + match[0].length;\n\n    return {\n      reportingValue: `${match[1]}`,\n      value: match[1],\n      range: [start, end],\n    };\n  });\n}\n\nfunction checkLiteralValueNode(context, attributeName, node, parentNode, parentNodeName) {\n  if (typeof node.value !== 'string') {\n    const data = { attributeName, reportingValue: node.value };\n\n    report(context, messages.onlyStrings, 'onlyStrings', {\n      node,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveNonString',\n        data,\n        fix(fixer) { return fixer.remove(parentNode); },\n      }],\n    });\n    return;\n  }\n\n  if (!node.value.trim()) {\n    const data = { attributeName, reportingValue: node.value };\n\n    report(context, messages.noEmpty, 'noEmpty', {\n      node,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveEmpty',\n        data,\n        fix(fixer) { return fixer.remove(node.parent); },\n      }],\n    });\n    return;\n  }\n\n  const singleAttributeParts = splitIntoRangedParts(node, /(\\S+)/g);\n  singleAttributeParts.forEach((singlePart) => {\n    const allowedTags = VALID_VALUES.get(attributeName).get(singlePart.value);\n    const reportingValue = singlePart.reportingValue;\n\n    if (!allowedTags) {\n      const data = {\n        attributeName,\n        reportingValue,\n      };\n\n      const suggest = [{\n        messageId: 'suggestRemoveInvalid',\n        data,\n        fix(fixer) { return fixer.removeRange(singlePart.range); },\n      }];\n\n      report(context, messages.neverValid, 'neverValid', {\n        node,\n        data,\n        suggest,\n      });\n    } else if (!allowedTags.has(parentNodeName)) {\n      const data = {\n        attributeName,\n        reportingValue,\n        elementName: parentNodeName,\n      };\n\n      const suggest = [{\n        messageId: 'suggestRemoveInvalid',\n        data,\n        fix(fixer) { return fixer.removeRange(singlePart.range); },\n      }];\n\n      report(context, messages.notValidFor, 'notValidFor', {\n        node,\n        data,\n        suggest,\n      });\n    }\n  });\n\n  const allowedPairsForAttribute = VALID_PAIR_VALUES.get(attributeName);\n  if (allowedPairsForAttribute) {\n    const pairAttributeParts = splitIntoRangedParts(node, /(?=(\\b\\S+\\s*\\S+))/g);\n    pairAttributeParts.forEach((pairPart) => {\n      allowedPairsForAttribute.forEach((siblings, pairing) => {\n        const attributes = pairPart.reportingValue.split('\\u0020');\n        const firstValue = attributes[0];\n        const secondValue = attributes[1];\n        if (firstValue === pairing) {\n          const lastValue = attributes[attributes.length - 1]; // in case of multiple white spaces\n          if (!siblings.has(lastValue)) {\n            const message = secondValue ? messages.notPaired : messages.notAlone;\n            const messageId = secondValue ? 'notPaired' : 'notAlone';\n            report(context, message, messageId, {\n              node,\n              data: {\n                reportingValue: firstValue,\n                secondValue,\n                missingValue: Array.from(siblings).join(', '),\n              },\n              suggest: false,\n            });\n          }\n        }\n      });\n    });\n  }\n\n  const whitespaceParts = splitIntoRangedParts(node, /(\\s+)/g);\n  whitespaceParts.forEach((whitespacePart) => {\n    const data = { attributeName };\n\n    if (whitespacePart.range[0] === (node.range[0] + 1) || whitespacePart.range[1] === (node.range[1] - 1)) {\n      report(context, messages.spaceDelimited, 'spaceDelimited', {\n        node,\n        data,\n        suggest: [{\n          messageId: 'suggestRemoveWhitespaces',\n          data,\n          fix(fixer) { return fixer.removeRange(whitespacePart.range); },\n        }],\n      });\n    } else if (whitespacePart.value !== '\\u0020') {\n      report(context, messages.spaceDelimited, 'spaceDelimited', {\n        node,\n        data,\n        suggest: [{\n          messageId: 'suggestRemoveWhitespaces',\n          data,\n          fix(fixer) { return fixer.replaceTextRange(whitespacePart.range, '\\u0020'); },\n        }],\n      });\n    }\n  });\n}\n\nconst DEFAULT_ATTRIBUTES = ['rel'];\n\nfunction checkAttribute(context, node) {\n  const attribute = node.name.name;\n\n  const parentNodeName = node.parent.name.name;\n  if (!COMPONENT_ATTRIBUTE_MAP.has(attribute) || !COMPONENT_ATTRIBUTE_MAP.get(attribute).has(parentNodeName)) {\n    const tagNames = Array.from(\n      COMPONENT_ATTRIBUTE_MAP.get(attribute).values(),\n      (tagName) => `\"<${tagName}>\"`\n    ).join(', ');\n    const data = {\n      attributeName: attribute,\n      tagNames,\n    };\n\n    report(context, messages.onlyMeaningfulFor, 'onlyMeaningfulFor', {\n      node: node.name,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveDefault',\n        data,\n        fix(fixer) { return fixer.remove(node); },\n      }],\n    });\n    return;\n  }\n\n  function fix(fixer) { return fixer.remove(node); }\n\n  if (!node.value) {\n    const data = { attributeName: attribute };\n\n    report(context, messages.emptyIsMeaningless, 'emptyIsMeaningless', {\n      node: node.name,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveEmpty',\n        data,\n        fix,\n      }],\n    });\n    return;\n  }\n\n  if (node.value.type === 'Literal') {\n    return checkLiteralValueNode(context, attribute, node.value, node, parentNodeName);\n  }\n\n  if (node.value.expression.type === 'Literal') {\n    return checkLiteralValueNode(context, attribute, node.value.expression, node, parentNodeName);\n  }\n\n  if (node.value.type !== 'JSXExpressionContainer') {\n    return;\n  }\n\n  if (node.value.expression.type === 'ObjectExpression') {\n    const data = { attributeName: attribute };\n\n    report(context, messages.onlyStrings, 'onlyStrings', {\n      node: node.value,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveDefault',\n        data,\n        fix,\n      }],\n    });\n  } else if (node.value.expression.type === 'Identifier' && node.value.expression.name === 'undefined') {\n    const data = { attributeName: attribute };\n\n    report(context, messages.onlyStrings, 'onlyStrings', {\n      node: node.value,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveDefault',\n        data,\n        fix,\n      }],\n    });\n  }\n}\n\nfunction isValidCreateElement(node) {\n  return node.callee\n    && node.callee.type === 'MemberExpression'\n    && node.callee.object.name === 'React'\n    && node.callee.property.name === 'createElement'\n    && node.arguments.length > 0;\n}\n\nfunction checkPropValidValue(context, node, value, attribute) {\n  const validTags = VALID_VALUES.get(attribute);\n\n  if (value.type !== 'Literal') {\n    return; // cannot check non-literals\n  }\n\n  const validTagSet = validTags.get(value.value);\n  if (!validTagSet) {\n    const data = {\n      attributeName: attribute,\n      reportingValue: value.value,\n    };\n\n    report(context, messages.neverValid, 'neverValid', {\n      node: value,\n      data,\n      suggest: [{\n        messageId: 'suggestRemoveInvalid',\n        data,\n        fix(fixer) { return fixer.replaceText(value, value.raw.replace(value.value, '')); },\n      }],\n    });\n  } else if (!validTagSet.has(node.arguments[0].value)) {\n    report(context, messages.notValidFor, 'notValidFor', {\n      node: value,\n      data: {\n        attributeName: attribute,\n        reportingValue: value.raw,\n        elementName: node.arguments[0].value,\n      },\n      suggest: false,\n    });\n  }\n}\n\n/**\n *\n * @param {*} context\n * @param {*} node\n * @param {string} attribute\n */\nfunction checkCreateProps(context, node, attribute) {\n  const propsArg = node.arguments[1];\n\n  if (!propsArg || propsArg.type !== 'ObjectExpression') {\n    return; // can't check variables, computed, or shorthands\n  }\n\n  for (const prop of propsArg.properties) {\n    if (!prop.key || prop.key.type !== 'Identifier') {\n      // eslint-disable-next-line no-continue\n      continue; // cannot check computed keys\n    }\n\n    if (prop.key.name !== attribute) {\n      // eslint-disable-next-line no-continue\n      continue; // ignore not this attribute\n    }\n\n    if (!COMPONENT_ATTRIBUTE_MAP.get(attribute).has(node.arguments[0].value)) {\n      const tagNames = Array.from(\n        COMPONENT_ATTRIBUTE_MAP.get(attribute).values(),\n        (tagName) => `\"<${tagName}>\"`\n      ).join(', ');\n\n      report(context, messages.onlyMeaningfulFor, 'onlyMeaningfulFor', {\n        node: prop.key,\n        data: {\n          attributeName: attribute,\n          tagNames,\n        },\n        suggest: false,\n      });\n\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n\n    if (prop.method) {\n      report(context, messages.noMethod, 'noMethod', {\n        node: prop,\n        data: {\n          attributeName: attribute,\n        },\n        suggest: false,\n      });\n\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n\n    if (prop.shorthand || prop.computed) {\n      // eslint-disable-next-line no-continue\n      continue; // cannot check these\n    }\n\n    if (prop.value.type === 'ArrayExpression') {\n      prop.value.elements.forEach((value) => {\n        checkPropValidValue(context, node, value, attribute);\n      });\n\n      // eslint-disable-next-line no-continue\n      continue;\n    }\n\n    checkPropValidValue(context, node, prop.value, attribute);\n  }\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of invalid attributes',\n      category: 'Possible Errors',\n      url: docsUrl('no-invalid-html-attribute'),\n    },\n    messages,\n    schema: [{\n      type: 'array',\n      uniqueItems: true,\n      items: {\n        enum: ['rel'],\n      },\n    }],\n    type: 'suggestion',\n    hasSuggestions: true, // eslint-disable-line eslint-plugin/require-meta-has-suggestions\n  },\n\n  create(context) {\n    return {\n      JSXAttribute(node) {\n        const attributes = new Set(context.options[0] || DEFAULT_ATTRIBUTES);\n\n        // ignore attributes that aren't configured to be checked\n        if (!attributes.has(node.name.name)) {\n          return;\n        }\n\n        // ignore non-HTML elements\n        if (!HTML_ELEMENTS.has(node.parent.name.name)) {\n          return;\n        }\n\n        checkAttribute(context, node);\n      },\n\n      CallExpression(node) {\n        if (!isValidCreateElement(node)) {\n          return;\n        }\n\n        const elemNameArg = node.arguments[0];\n\n        if (!elemNameArg || elemNameArg.type !== 'Literal') {\n          return; // can only check literals\n        }\n\n        // ignore non-HTML elements\n        if (typeof elemNameArg.value === 'string' && !HTML_ELEMENTS.has(elemNameArg.value)) {\n          return;\n        }\n\n        const attributes = new Set(context.options[0] || DEFAULT_ATTRIBUTES);\n\n        attributes.forEach((attribute) => {\n          checkCreateProps(context, node, attribute);\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-is-mounted.js",
    "content": "/**\n * @fileoverview Prevent usage of isMounted\n * @author Joe Lencioni\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getAncestors = require('../util/eslint').getAncestors;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noIsMounted: 'Do not use isMounted',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of isMounted',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-is-mounted'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    return {\n      CallExpression(node) {\n        const callee = node.callee;\n        if (callee.type !== 'MemberExpression') {\n          return;\n        }\n        if (\n          callee.object.type !== 'ThisExpression'\n          || !('name' in callee.property)\n          || callee.property.name !== 'isMounted'\n        ) {\n          return;\n        }\n        const ancestors = getAncestors(context, node);\n        for (let i = 0, j = ancestors.length; i < j; i++) {\n          if (ancestors[i].type === 'Property' || ancestors[i].type === 'MethodDefinition') {\n            report(context, messages.noIsMounted, 'noIsMounted', {\n              node: callee,\n            });\n            break;\n          }\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-multi-comp.js",
    "content": "/**\n * @fileoverview Prevent multiple component definition per file\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  onlyOneComponent: 'Declare only one React component per file',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow multiple component definition per file',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('no-multi-comp'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignoreStateless: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const configuration = context.options[0] || {};\n    const ignoreStateless = configuration.ignoreStateless || false;\n\n    /**\n     * Checks if the component is ignored\n     * @param {Object} component The component being checked.\n     * @returns {boolean} True if the component is ignored, false if not.\n     */\n    function isIgnored(component) {\n      return (\n        ignoreStateless && (\n          /Function/.test(component.node.type)\n          || utils.isPragmaComponentWrapper(component.node)\n        )\n      );\n    }\n\n    return {\n      'Program:exit'() {\n        if (components.length() <= 1) {\n          return;\n        }\n\n        values(components.list())\n          .filter((component) => !isIgnored(component))\n          .slice(1)\n          .forEach((component) => {\n            report(context, messages.onlyOneComponent, 'onlyOneComponent', {\n              node: component.node,\n            });\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-namespace.js",
    "content": "/**\n * @fileoverview Enforce that namespaces are not used in React elements\n * @author Yacine Hmito\n */\n\n'use strict';\n\nconst elementType = require('jsx-ast-utils/elementType');\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noNamespace: 'React component {{name}} must not be in a namespace, as React does not support them',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce that namespaces are not used in React elements',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('no-namespace'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    return {\n      CallExpression(node) {\n        if (isCreateElement(context, node) && node.arguments.length > 0 && node.arguments[0].type === 'Literal') {\n          const name = node.arguments[0].value;\n          if (typeof name !== 'string' || name.indexOf(':') === -1) return undefined;\n          report(context, messages.noNamespace, 'noNamespace', {\n            node,\n            data: {\n              name,\n            },\n          });\n        }\n      },\n      JSXOpeningElement(node) {\n        const name = elementType(node);\n        if (typeof name !== 'string' || name.indexOf(':') === -1) return undefined;\n        report(context, messages.noNamespace, 'noNamespace', {\n          node,\n          data: {\n            name,\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-object-type-as-default-prop.js",
    "content": "/**\n * @fileoverview Prevent usage of referential-type variables as default param in functional component\n * @author Chang Yan\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst report = require('../util/report');\n\nconst FORBIDDEN_TYPES_MAP = {\n  ArrowFunctionExpression: 'arrow function',\n  FunctionExpression: 'function expression',\n  ObjectExpression: 'object literal',\n  ArrayExpression: 'array literal',\n  ClassExpression: 'class expression',\n  NewExpression: 'construction expression',\n  JSXElement: 'JSX element',\n};\n\nconst FORBIDDEN_TYPES = new Set(Object.keys(FORBIDDEN_TYPES_MAP));\nconst MESSAGE_ID = 'forbiddenTypeDefaultParam';\n\nconst messages = {\n  [MESSAGE_ID]: '{{propName}} has a/an {{forbiddenType}} as default prop. This could lead to potential infinite render loop in React. Use a variable reference instead of {{forbiddenType}}.',\n};\nfunction hasUsedObjectDestructuringSyntax(params) {\n  return (\n    params != null\n    && params.length >= 1\n    && params[0].type === 'ObjectPattern'\n  );\n}\n\nfunction verifyDefaultPropsDestructuring(context, properties) {\n  // Loop through each of the default params\n  properties.filter((prop) => prop.type === 'Property' && prop.value.type === 'AssignmentPattern').forEach((prop) => {\n    const propName = prop.key.name;\n    const propDefaultValue = prop.value;\n\n    const propDefaultValueType = propDefaultValue.right.type;\n\n    if (\n      propDefaultValueType === 'Literal'\n      && propDefaultValue.right.regex != null\n    ) {\n      report(context, messages[MESSAGE_ID], MESSAGE_ID, {\n        node: propDefaultValue,\n        data: {\n          propName,\n          forbiddenType: 'regex literal',\n        },\n      });\n    } else if (\n      astUtil.isCallExpression(propDefaultValue.right)\n      && propDefaultValue.right.callee.type === 'Identifier'\n      && propDefaultValue.right.callee.name === 'Symbol'\n    ) {\n      report(context, messages[MESSAGE_ID], MESSAGE_ID, {\n        node: propDefaultValue,\n        data: {\n          propName,\n          forbiddenType: 'Symbol literal',\n        },\n      });\n    } else if (FORBIDDEN_TYPES.has(propDefaultValueType)) {\n      report(context, messages[MESSAGE_ID], MESSAGE_ID, {\n        node: propDefaultValue,\n        data: {\n          propName,\n          forbiddenType: FORBIDDEN_TYPES_MAP[propDefaultValueType],\n        },\n      });\n    }\n  });\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of referential-type variables as default param in functional component',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-object-type-as-default-prop'),\n    },\n    messages,\n  },\n  create: Components.detect((context, components) => ({\n    'Program:exit'() {\n      const list = components.list();\n      values(list)\n        .filter((component) => hasUsedObjectDestructuringSyntax(component.node.params))\n        .forEach((component) => {\n          const node = component.node;\n          const properties = node.params[0].properties;\n          verifyDefaultPropsDestructuring(context, properties);\n        });\n    },\n  })),\n};\n"
  },
  {
    "path": "lib/rules/no-redundant-should-component-update.js",
    "content": "/**\n * @fileoverview Flag shouldComponentUpdate when extending PureComponent\n */\n\n'use strict';\n\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noShouldCompUpdate: '{{component}} does not need shouldComponentUpdate when extending React.PureComponent.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of shouldComponentUpdate when extending React.PureComponent',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('no-redundant-should-component-update'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    /**\n     * Checks for shouldComponentUpdate property\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} Whether or not the property exists.\n     */\n    function hasShouldComponentUpdate(node) {\n      const properties = astUtil.getComponentProperties(node);\n      return properties.some((property) => {\n        const name = astUtil.getPropertyName(property);\n        return name === 'shouldComponentUpdate';\n      });\n    }\n\n    /**\n     * Get name of node if available\n     * @param {ASTNode} node The AST node being checked.\n     * @return {string} The name of the node\n     */\n    function getNodeName(node) {\n      if (node.id) {\n        return node.id.name;\n      }\n      if (node.parent && node.parent.id) {\n        return node.parent.id.name;\n      }\n      return '';\n    }\n\n    /**\n     * Checks for violation of rule\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function checkForViolation(node) {\n      if (componentUtil.isPureComponent(node, context)) {\n        const hasScu = hasShouldComponentUpdate(node);\n        if (hasScu) {\n          const className = getNodeName(node);\n          report(context, messages.noShouldCompUpdate, 'noShouldCompUpdate', {\n            node,\n            data: {\n              component: className,\n            },\n          });\n        }\n      }\n    }\n\n    return {\n      ClassDeclaration: checkForViolation,\n      ClassExpression: checkForViolation,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-render-return-value.js",
    "content": "/**\n * @fileoverview Prevent usage of the return value of React.render\n * @author Dustan Kasten\n */\n\n'use strict';\n\nconst testReactVersion = require('../util/version').testReactVersion;\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noReturnValue: 'Do not depend on the return value from {{node}}.render',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of the return value of ReactDOM.render',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-render-return-value'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    let calleeObjectName = /^ReactDOM$/;\n    if (testReactVersion(context, '>= 15.0.0')) {\n      calleeObjectName = /^ReactDOM$/;\n    } else if (testReactVersion(context, '^0.14.0')) {\n      calleeObjectName = /^React(DOM)?$/;\n    } else if (testReactVersion(context, '^0.13.0')) {\n      calleeObjectName = /^React$/;\n    }\n\n    return {\n      CallExpression(node) {\n        const callee = node.callee;\n        const parent = node.parent;\n        if (callee.type !== 'MemberExpression') {\n          return;\n        }\n\n        if (\n          callee.object.type !== 'Identifier'\n          || !calleeObjectName.test(callee.object.name)\n          || (!('name' in callee.property) || callee.property.name !== 'render')\n        ) {\n          return;\n        }\n\n        if (\n          parent.type === 'VariableDeclarator'\n          || parent.type === 'Property'\n          || parent.type === 'ReturnStatement'\n          || parent.type === 'ArrowFunctionExpression'\n          || parent.type === 'AssignmentExpression'\n        ) {\n          report(context, messages.noReturnValue, 'noReturnValue', {\n            node: callee,\n            data: {\n              node: callee.object.name,\n            },\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState\n * @author Mark Dalgleish\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noSetState: 'Do not use setState',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of setState',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('no-set-state'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    /**\n     * Checks if the component is valid\n     * @param {Object} component The component to process\n     * @returns {boolean} True if the component is valid, false if not.\n     */\n    function isValid(component) {\n      return !!component && !component.useSetState;\n    }\n\n    /**\n     * Reports usages of setState for a given component\n     * @param {Object} component The component to process\n     */\n    function reportSetStateUsages(component) {\n      for (let i = 0, j = component.setStateUsages.length; i < j; i++) {\n        const setStateUsage = component.setStateUsages[i];\n        report(context, messages.noSetState, 'noSetState', {\n          node: setStateUsage,\n        });\n      }\n    }\n\n    return {\n      CallExpression(node) {\n        const callee = node.callee;\n        if (\n          callee.type !== 'MemberExpression'\n          || callee.object.type !== 'ThisExpression'\n          || callee.property.name !== 'setState'\n        ) {\n          return;\n        }\n        const component = components.get(utils.getParentComponent(node));\n        const setStateUsages = (component && component.setStateUsages) || [];\n        setStateUsages.push(callee);\n        components.set(node, {\n          useSetState: true,\n          setStateUsages,\n        });\n      },\n\n      'Program:exit'() {\n        values(components.list())\n          .filter((component) => !isValid(component))\n          .forEach((component) => {\n            reportSetStateUsages(component);\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-string-refs.js",
    "content": "/**\n * @fileoverview Prevent string definitions for references and prevent referencing this.refs\n * @author Tom Hastjarjanto\n */\n\n'use strict';\n\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst testReactVersion = require('../util/version').testReactVersion;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  thisRefsDeprecated: 'Using this.refs is deprecated.',\n  stringInRefDeprecated: 'Using string literals in ref attributes is deprecated.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow using string references',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('no-string-refs'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        noTemplateLiterals: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const checkRefsUsage = testReactVersion(context, '< 18.3.0'); // `this.refs` is writable in React 18.3.0 and later, see https://github.com/facebook/react/pull/28867\n    const detectTemplateLiterals = context.options[0] ? context.options[0].noTemplateLiterals : false;\n    /**\n     * Checks if we are using refs\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if we are using refs, false if not.\n     */\n    function isRefsUsage(node) {\n      return !!(\n        (componentUtil.getParentES6Component(context, node) || componentUtil.getParentES5Component(context, node))\n        && node.object.type === 'ThisExpression'\n        && node.property.name === 'refs'\n      );\n    }\n\n    /**\n     * Checks if we are using a ref attribute\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if we are using a ref attribute, false if not.\n     */\n    function isRefAttribute(node) {\n      return node.type === 'JSXAttribute'\n        && !!node.name\n        && node.name.name === 'ref';\n    }\n\n    /**\n     * Checks if a node contains a string value\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if the node contains a string value, false if not.\n     */\n    function containsStringLiteral(node) {\n      return !!node.value\n        && node.value.type === 'Literal'\n        && typeof node.value.value === 'string';\n    }\n\n    /**\n     * Checks if a node contains a string value within a jsx expression\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if the node contains a string value within a jsx expression, false if not.\n     */\n    function containsStringExpressionContainer(node) {\n      return !!node.value\n        && node.value.type === 'JSXExpressionContainer'\n        && node.value.expression\n        && ((node.value.expression.type === 'Literal' && typeof node.value.expression.value === 'string')\n        || (node.value.expression.type === 'TemplateLiteral' && detectTemplateLiterals));\n    }\n\n    return {\n      MemberExpression(node) {\n        if (checkRefsUsage && isRefsUsage(node)) {\n          report(context, messages.thisRefsDeprecated, 'thisRefsDeprecated', {\n            node,\n          });\n        }\n      },\n\n      JSXAttribute(node) {\n        if (\n          isRefAttribute(node)\n          && (containsStringLiteral(node) || containsStringExpressionContainer(node))\n        ) {\n          report(context, messages.stringInRefDeprecated, 'stringInRefDeprecated', {\n            node,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-this-in-sfc.js",
    "content": "/**\n * @fileoverview Report \"this\" being used in stateless functional components.\n */\n\n'use strict';\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noThisInSFC: 'Stateless functional components should not use `this`',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow `this` from being used in stateless functional components',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('no-this-in-sfc'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create: Components.detect((context, components, utils) => ({\n    MemberExpression(node) {\n      if (node.object.type === 'ThisExpression') {\n        const component = components.get(utils.getParentStatelessComponent(node));\n        if (!component || (component.node && component.node.parent && component.node.parent.type === 'Property')) {\n          return;\n        }\n        report(context, messages.noThisInSFC, 'noThisInSFC', {\n          node,\n        });\n      }\n    },\n  })),\n};\n"
  },
  {
    "path": "lib/rules/no-typos.js",
    "content": "/**\n * @fileoverview Prevent common casing typos\n */\n\n'use strict';\n\nconst PROP_TYPES = Object.keys(require('prop-types'));\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst report = require('../util/report');\nconst lifecycleMethods = require('../util/lifecycleMethods');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst STATIC_CLASS_PROPERTIES = ['propTypes', 'contextTypes', 'childContextTypes', 'defaultProps'];\n\nconst messages = {\n  typoPropTypeChain: 'Typo in prop type chain qualifier: {{name}}',\n  typoPropType: 'Typo in declared prop type: {{name}}',\n  typoStaticClassProp: 'Typo in static class property declaration',\n  typoPropDeclaration: 'Typo in property declaration',\n  typoLifecycleMethod: 'Typo in component lifecycle method declaration: {{actual}} should be {{expected}}',\n  staticLifecycleMethod: 'Lifecycle method should be static: {{method}}',\n  noPropTypesBinding: '`\\'prop-types\\'` imported without a local `PropTypes` binding.',\n  noReactBinding: '`\\'react\\'` imported without a local `React` binding.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow common typos',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('no-typos'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    let propTypesPackageName = null;\n    let reactPackageName = null;\n\n    function checkValidPropTypeQualifier(node) {\n      if (node.name !== 'isRequired') {\n        report(context, messages.typoPropTypeChain, 'typoPropTypeChain', {\n          node,\n          data: { name: node.name },\n        });\n      }\n    }\n\n    function checkValidPropType(node) {\n      if (node.name && !PROP_TYPES.some((propTypeName) => propTypeName === node.name)) {\n        report(context, messages.typoPropType, 'typoPropType', {\n          node,\n          data: { name: node.name },\n        });\n      }\n    }\n\n    function isPropTypesPackage(node) {\n      return (\n        node.type === 'Identifier'\n        && node.name === propTypesPackageName\n      ) || (\n        node.type === 'MemberExpression'\n        && node.property.name === 'PropTypes'\n        && node.object.name === reactPackageName\n      );\n    }\n\n    /* eslint-disable no-use-before-define */\n\n    function checkValidCallExpression(node) {\n      const callee = node.callee;\n      if (callee.type === 'MemberExpression' && callee.property.name === 'shape') {\n        checkValidPropObject(node.arguments[0]);\n      } else if (callee.type === 'MemberExpression' && callee.property.name === 'oneOfType') {\n        const args = node.arguments[0];\n        if (args && args.type === 'ArrayExpression') {\n          args.elements.forEach((el) => {\n            checkValidProp(el);\n          });\n        }\n      }\n    }\n\n    function checkValidProp(node) {\n      if ((!propTypesPackageName && !reactPackageName) || !node) {\n        return;\n      }\n\n      if (node.type === 'MemberExpression') {\n        if (\n          node.object.type === 'MemberExpression'\n          && isPropTypesPackage(node.object.object)\n        ) { // PropTypes.myProp.isRequired\n          checkValidPropType(node.object.property);\n          checkValidPropTypeQualifier(node.property);\n        } else if (\n          isPropTypesPackage(node.object)\n          && node.property.name !== 'isRequired'\n        ) { // PropTypes.myProp\n          checkValidPropType(node.property);\n        } else if (astUtil.isCallExpression(node.object)) {\n          checkValidPropTypeQualifier(node.property);\n          checkValidCallExpression(node.object);\n        }\n      } else if (astUtil.isCallExpression(node)) {\n        checkValidCallExpression(node);\n      }\n    }\n\n    /* eslint-enable no-use-before-define */\n\n    function checkValidPropObject(node) {\n      if (node && node.type === 'ObjectExpression') {\n        node.properties.forEach((prop) => checkValidProp(prop.value));\n      }\n    }\n\n    function reportErrorIfPropertyCasingTypo(propertyValue, propertyKey, isClassProperty) {\n      const propertyName = propertyKey.name;\n      if (propertyName === 'propTypes' || propertyName === 'contextTypes' || propertyName === 'childContextTypes') {\n        checkValidPropObject(propertyValue);\n      }\n      STATIC_CLASS_PROPERTIES.forEach((CLASS_PROP) => {\n        if (propertyName && CLASS_PROP.toLowerCase() === propertyName.toLowerCase() && CLASS_PROP !== propertyName) {\n          const messageId = isClassProperty\n            ? 'typoStaticClassProp'\n            : 'typoPropDeclaration';\n          report(context, messages[messageId], messageId, {\n            node: propertyKey,\n          });\n        }\n      });\n    }\n\n    function reportErrorIfLifecycleMethodCasingTypo(node) {\n      const key = node.key;\n      let nodeKeyName = key.name;\n      if (key.type === 'Literal') {\n        nodeKeyName = key.value;\n      }\n      if (key.type === 'PrivateName' || (node.computed && typeof nodeKeyName !== 'string')) {\n        return;\n      }\n\n      lifecycleMethods.static.forEach((method) => {\n        if (!node.static && nodeKeyName && nodeKeyName.toLowerCase() === method.toLowerCase()) {\n          report(context, messages.staticLifecycleMethod, 'staticLifecycleMethod', {\n            node,\n            data: {\n              method: nodeKeyName,\n            },\n          });\n        }\n      });\n\n      lifecycleMethods.instance.concat(lifecycleMethods.static).forEach((method) => {\n        if (nodeKeyName && method.toLowerCase() === nodeKeyName.toLowerCase() && method !== nodeKeyName) {\n          report(context, messages.typoLifecycleMethod, 'typoLifecycleMethod', {\n            node,\n            data: { actual: nodeKeyName, expected: method },\n          });\n        }\n      });\n    }\n\n    return {\n      ImportDeclaration(node) {\n        if (node.source && node.source.value === 'prop-types') { // import PropType from \"prop-types\"\n          if (node.specifiers.length > 0) {\n            propTypesPackageName = node.specifiers[0].local.name;\n          } else {\n            report(context, messages.noPropTypesBinding, 'noPropTypesBinding', {\n              node,\n            });\n          }\n        } else if (node.source && node.source.value === 'react') { // import { PropTypes } from \"react\"\n          if (node.specifiers.length > 0) {\n            reactPackageName = node.specifiers[0].local.name; // guard against accidental anonymous `import \"react\"`\n          } else {\n            report(context, messages.noReactBinding, 'noReactBinding', {\n              node,\n            });\n          }\n          if (node.specifiers.length >= 1) {\n            const propTypesSpecifier = node.specifiers.find((specifier) => (\n              specifier.imported\n              && specifier.imported.name === 'PropTypes'\n            ));\n            if (propTypesSpecifier) {\n              propTypesPackageName = propTypesSpecifier.local.name;\n            }\n          }\n        }\n      },\n\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!node.static || !componentUtil.isES6Component(node.parent.parent, context)) {\n          return;\n        }\n\n        reportErrorIfPropertyCasingTypo(node.value, node.key, true);\n      },\n\n      MemberExpression(node) {\n        const propertyName = node.property.name;\n\n        if (\n          !propertyName\n          || STATIC_CLASS_PROPERTIES.map((prop) => prop.toLocaleLowerCase()).indexOf(propertyName.toLowerCase()) === -1\n        ) {\n          return;\n        }\n\n        const relatedComponent = utils.getRelatedComponent(node);\n\n        if (\n          relatedComponent\n            && (componentUtil.isES6Component(relatedComponent.node, context) || (\n              relatedComponent.node.type !== 'ClassDeclaration' && utils.isReturningJSX(relatedComponent.node)))\n            && (node.parent && node.parent.type === 'AssignmentExpression' && node.parent.right)\n        ) {\n          reportErrorIfPropertyCasingTypo(node.parent.right, node.property, true);\n        }\n      },\n\n      MethodDefinition(node) {\n        if (!componentUtil.isES6Component(node.parent.parent, context)) {\n          return;\n        }\n\n        reportErrorIfLifecycleMethodCasingTypo(node);\n      },\n\n      ObjectExpression(node) {\n        const component = componentUtil.isES5Component(node, context) && components.get(node);\n\n        if (!component) {\n          return;\n        }\n\n        node.properties.filter((property) => property.type !== 'SpreadElement').forEach((property) => {\n          reportErrorIfPropertyCasingTypo(property.value, property.key, false);\n          reportErrorIfLifecycleMethodCasingTypo(property);\n        });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-unescaped-entities.js",
    "content": "/**\n * @fileoverview HTML special characters should be escaped.\n * @author Patrick Hayes\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst getSourceCode = require('../util/eslint').getSourceCode;\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\nconst getMessageData = require('../util/message');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n// NOTE: '<' and '{' are also problematic characters, but they do not need\n// to be included here because it is a syntax error when these characters are\n// included accidentally.\nconst DEFAULTS = [{\n  char: '>',\n  alternatives: ['&gt;'],\n}, {\n  char: '\"',\n  alternatives: ['&quot;', '&ldquo;', '&#34;', '&rdquo;'],\n}, {\n  char: '\\'',\n  alternatives: ['&apos;', '&lsquo;', '&#39;', '&rsquo;'],\n}, {\n  char: '}',\n  alternatives: ['&#125;'],\n}];\n\nconst messages = {\n  unescapedEntity: 'HTML entity, `{{entity}}` , must be escaped.',\n  unescapedEntityAlts: '`{{entity}}` can be escaped with {{alts}}.',\n  replaceWithAlt: 'Replace with `{{alt}}`.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    hasSuggestions: true,\n    docs: {\n      description: 'Disallow unescaped HTML entities from appearing in markup',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('no-unescaped-entities'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbid: {\n          type: 'array',\n          items: {\n            anyOf: [{\n              type: 'string',\n            }, {\n              type: 'object',\n              properties: {\n                char: {\n                  type: 'string',\n                },\n                alternatives: {\n                  type: 'array',\n                  uniqueItems: true,\n                  items: {\n                    type: 'string',\n                  },\n                },\n              },\n            }],\n          },\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    function reportInvalidEntity(node) {\n      const configuration = context.options[0] || {};\n      const entities = configuration.forbid || DEFAULTS;\n\n      // HTML entities are already escaped in node.value (as well as node.raw),\n      // so pull the raw text from getSourceCode(context)\n      for (let i = node.loc.start.line; i <= node.loc.end.line; i++) {\n        let rawLine = getSourceCode(context).lines[i - 1];\n        let start = 0;\n        let end = rawLine.length;\n        if (i === node.loc.start.line) {\n          start = node.loc.start.column;\n        }\n        if (i === node.loc.end.line) {\n          end = node.loc.end.column;\n        }\n        rawLine = rawLine.slice(start, end);\n        for (let j = 0; j < entities.length; j++) {\n          for (let index = 0; index < rawLine.length; index++) {\n            const c = rawLine[index];\n            if (typeof entities[j] === 'string') {\n              if (c === entities[j]) {\n                report(context, messages.unescapedEntity, 'unescapedEntity', {\n                  node,\n                  loc: { line: i, column: start + index },\n                  data: {\n                    entity: entities[j],\n                  },\n                });\n              }\n            } else if (c === entities[j].char) {\n              report(context, messages.unescapedEntityAlts, 'unescapedEntityAlts', {\n                node,\n                loc: { line: i, column: start + index },\n                data: {\n                  entity: entities[j].char,\n                  alts: entities[j].alternatives.map((alt) => `\\`${alt}\\``).join(', '),\n                },\n                suggest: entities[j].alternatives.map((alt) => Object.assign(\n                  getMessageData('replaceWithAlt', messages.replaceWithAlt),\n                  {\n                    data: { alt },\n                    fix(fixer) {\n                      const lineToChange = i - node.loc.start.line;\n\n                      const newText = node.raw.split('\\n').map((line, idx) => {\n                        if (idx === lineToChange) {\n                          return line.slice(0, index) + alt + line.slice(index + 1);\n                        }\n\n                        return line;\n                      }).join('\\n');\n\n                      return fixer.replaceText(node, newText);\n                    },\n                  }\n                )),\n              });\n            }\n          }\n        }\n      }\n    }\n\n    return {\n      'Literal, JSXText'(node) {\n        if (jsxUtil.isJSX(node.parent)) {\n          reportInvalidEntity(node);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-unknown-property.js",
    "content": "/**\n * @fileoverview Prevent usage of unknown DOM property\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst docsUrl = require('../util/docsUrl');\nconst getText = require('../util/eslint').getText;\nconst testReactVersion = require('../util/version').testReactVersion;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst DEFAULTS = {\n  ignore: [],\n  requireDataLowercase: false,\n};\n\nconst DOM_ATTRIBUTE_NAMES = {\n  'accept-charset': 'acceptCharset',\n  class: 'className',\n  'http-equiv': 'httpEquiv',\n  crossorigin: 'crossOrigin',\n  for: 'htmlFor',\n  nomodule: 'noModule',\n};\n\nconst ATTRIBUTE_TAGS_MAP = {\n  abbr: ['th', 'td'],\n  charset: ['meta'],\n  checked: ['input'],\n  closedby: ['dialog'],\n  // image is required for SVG support, all other tags are HTML.\n  crossOrigin: ['script', 'img', 'video', 'audio', 'link', 'image'],\n  displaystyle: ['math'],\n  // https://html.spec.whatwg.org/multipage/links.html#downloading-resources\n  download: ['a', 'area'],\n  fill: [ // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill\n    // Fill color\n    'altGlyph',\n    'circle',\n    'ellipse',\n    'g',\n    'line',\n    'marker',\n    'mask',\n    'path',\n    'polygon',\n    'polyline',\n    'rect',\n    'svg',\n    'symbol',\n    'text',\n    'textPath',\n    'tref',\n    'tspan',\n    'use',\n    // Animation final state\n    'animate',\n    'animateColor',\n    'animateMotion',\n    'animateTransform',\n    'set',\n  ],\n  focusable: ['svg'],\n  imageSizes: ['link'],\n  imageSrcSet: ['link'],\n  property: ['meta'],\n  viewBox: ['marker', 'pattern', 'svg', 'symbol', 'view'],\n  as: ['link'],\n  align: ['applet', 'caption', 'col', 'colgroup', 'hr', 'iframe', 'img', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr'], // deprecated, but known\n  valign: ['tr', 'td', 'th', 'thead', 'tbody', 'tfoot', 'colgroup', 'col'], // deprecated, but known\n  noModule: ['script'],\n  // Media events allowed only on audio and video tags, see https://github.com/facebook/react/blob/256aefbea1449869620fb26f6ec695536ab453f5/CHANGELOG.md#notable-enhancements\n  onAbort: ['audio', 'video'],\n  onCancel: ['dialog'],\n  onCanPlay: ['audio', 'video'],\n  onCanPlayThrough: ['audio', 'video'],\n  onClose: ['dialog'],\n  onDurationChange: ['audio', 'video'],\n  onEmptied: ['audio', 'video'],\n  onEncrypted: ['audio', 'video'],\n  onEnded: ['audio', 'video'],\n  onError: ['audio', 'video', 'img', 'link', 'source', 'script', 'picture', 'iframe'],\n  onLoad: ['script', 'img', 'link', 'picture', 'iframe', 'object', 'source', 'body'],\n  onLoadedData: ['audio', 'video'],\n  onLoadedMetadata: ['audio', 'video'],\n  onLoadStart: ['audio', 'video'],\n  onPause: ['audio', 'video'],\n  onPlay: ['audio', 'video'],\n  onPlaying: ['audio', 'video'],\n  onProgress: ['audio', 'video'],\n  onRateChange: ['audio', 'video'],\n  onResize: ['audio', 'video'],\n  onSeeked: ['audio', 'video'],\n  onSeeking: ['audio', 'video'],\n  onStalled: ['audio', 'video'],\n  onSuspend: ['audio', 'video'],\n  onTimeUpdate: ['audio', 'video'],\n  onVolumeChange: ['audio', 'video'],\n  onWaiting: ['audio', 'video'],\n  autoPictureInPicture: ['video'],\n  controls: ['audio', 'video'],\n  controlsList: ['audio', 'video'],\n  disablePictureInPicture: ['video'],\n  disableRemotePlayback: ['audio', 'video'],\n  loop: ['audio', 'video'],\n  muted: ['audio', 'video'],\n  playsInline: ['video'],\n  allowFullScreen: ['iframe', 'video'],\n  webkitAllowFullScreen: ['iframe', 'video'],\n  mozAllowFullScreen: ['iframe', 'video'],\n  poster: ['video'],\n  preload: ['audio', 'video'],\n  scrolling: ['iframe'],\n  returnValue: ['dialog'],\n  webkitDirectory: ['input'],\n  shadowrootmode: ['template'],\n  shadowrootclonable: ['template'],\n  shadowrootdelegatesfocus: ['template'],\n  shadowrootserializable: ['template'],\n  'transform-origin': ['rect'],\n};\n\nconst SVGDOM_ATTRIBUTE_NAMES = {\n  'accent-height': 'accentHeight',\n  'alignment-baseline': 'alignmentBaseline',\n  'arabic-form': 'arabicForm',\n  'baseline-shift': 'baselineShift',\n  'cap-height': 'capHeight',\n  'clip-path': 'clipPath',\n  'clip-rule': 'clipRule',\n  'color-interpolation': 'colorInterpolation',\n  'color-interpolation-filters': 'colorInterpolationFilters',\n  'color-profile': 'colorProfile',\n  'color-rendering': 'colorRendering',\n  'dominant-baseline': 'dominantBaseline',\n  'enable-background': 'enableBackground',\n  'fill-opacity': 'fillOpacity',\n  'fill-rule': 'fillRule',\n  'flood-color': 'floodColor',\n  'flood-opacity': 'floodOpacity',\n  'font-family': 'fontFamily',\n  'font-size': 'fontSize',\n  'font-size-adjust': 'fontSizeAdjust',\n  'font-stretch': 'fontStretch',\n  'font-style': 'fontStyle',\n  'font-variant': 'fontVariant',\n  'font-weight': 'fontWeight',\n  'glyph-name': 'glyphName',\n  'glyph-orientation-horizontal': 'glyphOrientationHorizontal',\n  'glyph-orientation-vertical': 'glyphOrientationVertical',\n  'horiz-adv-x': 'horizAdvX',\n  'horiz-origin-x': 'horizOriginX',\n  'image-rendering': 'imageRendering',\n  'letter-spacing': 'letterSpacing',\n  'lighting-color': 'lightingColor',\n  'marker-end': 'markerEnd',\n  'marker-mid': 'markerMid',\n  'marker-start': 'markerStart',\n  'overline-position': 'overlinePosition',\n  'overline-thickness': 'overlineThickness',\n  'paint-order': 'paintOrder',\n  'panose-1': 'panose1',\n  'pointer-events': 'pointerEvents',\n  'rendering-intent': 'renderingIntent',\n  'shape-rendering': 'shapeRendering',\n  'stop-color': 'stopColor',\n  'stop-opacity': 'stopOpacity',\n  'strikethrough-position': 'strikethroughPosition',\n  'strikethrough-thickness': 'strikethroughThickness',\n  'stroke-dasharray': 'strokeDasharray',\n  'stroke-dashoffset': 'strokeDashoffset',\n  'stroke-linecap': 'strokeLinecap',\n  'stroke-linejoin': 'strokeLinejoin',\n  'stroke-miterlimit': 'strokeMiterlimit',\n  'stroke-opacity': 'strokeOpacity',\n  'stroke-width': 'strokeWidth',\n  'text-anchor': 'textAnchor',\n  'text-decoration': 'textDecoration',\n  'text-rendering': 'textRendering',\n  'underline-position': 'underlinePosition',\n  'underline-thickness': 'underlineThickness',\n  'unicode-bidi': 'unicodeBidi',\n  'unicode-range': 'unicodeRange',\n  'units-per-em': 'unitsPerEm',\n  'v-alphabetic': 'vAlphabetic',\n  'v-hanging': 'vHanging',\n  'v-ideographic': 'vIdeographic',\n  'v-mathematical': 'vMathematical',\n  'vector-effect': 'vectorEffect',\n  'vert-adv-y': 'vertAdvY',\n  'vert-origin-x': 'vertOriginX',\n  'vert-origin-y': 'vertOriginY',\n  'word-spacing': 'wordSpacing',\n  'writing-mode': 'writingMode',\n  'x-height': 'xHeight',\n  'xlink:actuate': 'xlinkActuate',\n  'xlink:arcrole': 'xlinkArcrole',\n  'xlink:href': 'xlinkHref',\n  'xlink:role': 'xlinkRole',\n  'xlink:show': 'xlinkShow',\n  'xlink:title': 'xlinkTitle',\n  'xlink:type': 'xlinkType',\n  'xml:base': 'xmlBase',\n  'xml:lang': 'xmlLang',\n  'xml:space': 'xmlSpace',\n};\n\nconst DOM_PROPERTY_NAMES_ONE_WORD = [\n  // Global attributes - can be used on any HTML/DOM element\n  // See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes\n  'dir', 'draggable', 'hidden', 'id', 'lang', 'nonce', 'part', 'slot', 'style', 'title', 'translate', 'inert',\n  // Element specific attributes\n  // See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes (includes global attributes too)\n  // To be considered if these should be added also to ATTRIBUTE_TAGS_MAP\n  'accept', 'action', 'allow', 'alt', 'as', 'async', 'buffered', 'capture', 'challenge', 'cite', 'code', 'cols',\n  'content', 'coords', 'csp', 'data', 'decoding', 'default', 'defer', 'disabled', 'form',\n  'headers', 'height', 'high', 'href', 'icon', 'importance', 'integrity', 'kind', 'label',\n  'language', 'loading', 'list', 'loop', 'low', 'manifest', 'max', 'media', 'method', 'min', 'multiple', 'muted',\n  'name', 'open', 'optimum', 'pattern', 'ping', 'placeholder', 'poster', 'preload', 'profile',\n  'rel', 'required', 'reversed', 'role', 'rows', 'sandbox', 'scope', 'seamless', 'selected', 'shape', 'size', 'sizes',\n  'span', 'src', 'start', 'step', 'summary', 'target', 'type', 'value', 'width', 'wmode', 'wrap',\n  // SVG attributes\n  // See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute\n  'accumulate', 'additive', 'alphabetic', 'amplitude', 'ascent', 'azimuth', 'bbox', 'begin',\n  'bias', 'by', 'clip', 'color', 'cursor', 'cx', 'cy', 'd', 'decelerate', 'descent', 'direction',\n  'display', 'divisor', 'dur', 'dx', 'dy', 'elevation', 'end', 'exponent', 'fill', 'filter',\n  'format', 'from', 'fr', 'fx', 'fy', 'g1', 'g2', 'hanging', 'height', 'hreflang', 'ideographic',\n  'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'local', 'mask', 'mode',\n  'offset', 'opacity', 'operator', 'order', 'orient', 'orientation', 'origin', 'overflow', 'path',\n  'ping', 'points', 'r', 'radius', 'rel', 'restart', 'result', 'rotate', 'rx', 'ry', 'scale',\n  'seed', 'slope', 'spacing', 'speed', 'stemh', 'stemv', 'string', 'stroke', 'to', 'transform',\n  'u1', 'u2', 'unicode', 'values', 'version', 'visibility', 'widths', 'x', 'x1', 'x2', 'xmlns',\n  'y', 'y1', 'y2', 'z',\n  // OpenGraph meta tag attributes\n  'property',\n  // React specific attributes\n  'ref', 'key', 'children',\n  // Non-standard\n  'results', 'security',\n  // Video specific\n  'controls',\n  // popovers\n  'popover', 'popovertarget', 'popovertargetaction',\n];\n\nconst DOM_PROPERTY_NAMES_TWO_WORDS = [\n  // Global attributes - can be used on any HTML/DOM element\n  // See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes\n  'accessKey', 'autoCapitalize', 'autoFocus', 'contentEditable', 'enterKeyHint', 'exportParts',\n  'inputMode', 'itemID', 'itemRef', 'itemProp', 'itemScope', 'itemType', 'spellCheck', 'tabIndex',\n  // Element specific attributes\n  // See https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes (includes global attributes too)\n  // To be considered if these should be added also to ATTRIBUTE_TAGS_MAP\n  'acceptCharset', 'autoComplete', 'autoPlay', 'border', 'cellPadding', 'cellSpacing', 'classID', 'codeBase',\n  'colSpan', 'contextMenu', 'dateTime', 'encType', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget',\n  'frameBorder', 'hrefLang', 'httpEquiv', 'imageSizes', 'imageSrcSet', 'isMap', 'keyParams', 'keyType', 'marginHeight', 'marginWidth',\n  'maxLength', 'mediaGroup', 'minLength', 'noValidate', 'onAnimationEnd', 'onAnimationIteration', 'onAnimationStart',\n  'onBlur', 'onChange', 'onClick', 'onContextMenu', 'onCopy', 'onCompositionEnd', 'onCompositionStart',\n  'onCompositionUpdate', 'onCut', 'onDoubleClick', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragExit', 'onDragLeave',\n  'onError', 'onFocus', 'onInput', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onLoad', 'onWheel', 'onDragOver',\n  'onDragStart', 'onDrop', 'onMouseDown', 'onMouseEnter', 'onMouseLeave', 'onMouseMove', 'onMouseOut', 'onMouseOver',\n  'onMouseUp', 'onPaste', 'onScroll', 'onScrollEnd', 'onSelect', 'onSubmit', 'onBeforeToggle', 'onToggle', 'onTransitionEnd', 'radioGroup',\n  'readOnly', 'referrerPolicy', 'rowSpan', 'srcDoc', 'srcLang', 'srcSet', 'useMap', 'fetchPriority',\n  // SVG attributes\n  // See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute\n  'crossOrigin', 'accentHeight', 'alignmentBaseline', 'arabicForm', 'attributeName',\n  'attributeType', 'baseFrequency', 'baselineShift', 'baseProfile', 'calcMode', 'capHeight',\n  'clipPathUnits', 'clipPath', 'clipRule', 'colorInterpolation', 'colorInterpolationFilters',\n  'colorProfile', 'colorRendering', 'contentScriptType', 'contentStyleType', 'diffuseConstant',\n  'dominantBaseline', 'edgeMode', 'enableBackground', 'fillOpacity', 'fillRule', 'filterRes',\n  'filterUnits', 'floodColor', 'floodOpacity', 'fontFamily', 'fontSize', 'fontSizeAdjust',\n  'fontStretch', 'fontStyle', 'fontVariant', 'fontWeight', 'glyphName',\n  'glyphOrientationHorizontal', 'glyphOrientationVertical', 'glyphRef', 'gradientTransform',\n  'gradientUnits', 'horizAdvX', 'horizOriginX', 'imageRendering', 'kernelMatrix',\n  'kernelUnitLength', 'keyPoints', 'keySplines', 'keyTimes', 'lengthAdjust', 'letterSpacing',\n  'lightingColor', 'limitingConeAngle', 'markerEnd', 'markerMid', 'markerStart', 'markerHeight',\n  'markerUnits', 'markerWidth', 'maskContentUnits', 'maskUnits', 'mathematical', 'numOctaves',\n  'overlinePosition', 'overlineThickness', 'panose1', 'paintOrder', 'pathLength',\n  'patternContentUnits', 'patternTransform', 'patternUnits', 'pointerEvents', 'pointsAtX',\n  'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits',\n  'referrerPolicy', 'refX', 'refY', 'rendering-intent', 'repeatCount', 'repeatDur',\n  'requiredExtensions', 'requiredFeatures', 'shapeRendering', 'specularConstant',\n  'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', 'stitchTiles', 'stopColor',\n  'stopOpacity', 'strikethroughPosition', 'strikethroughThickness', 'strokeDasharray',\n  'strokeDashoffset', 'strokeLinecap', 'strokeLinejoin', 'strokeMiterlimit', 'strokeOpacity',\n  'strokeWidth', 'surfaceScale', 'systemLanguage', 'tableValues', 'targetX', 'targetY',\n  'textAnchor', 'textDecoration', 'textRendering', 'textLength', 'transformOrigin',\n  'underlinePosition', 'underlineThickness', 'unicodeBidi', 'unicodeRange', 'unitsPerEm',\n  'vAlphabetic', 'vHanging', 'vIdeographic', 'vMathematical', 'vectorEffect', 'vertAdvY',\n  'vertOriginX', 'vertOriginY', 'viewBox', 'viewTarget', 'wordSpacing', 'writingMode', 'xHeight',\n  'xChannelSelector', 'xlinkActuate', 'xlinkArcrole', 'xlinkHref', 'xlinkRole', 'xlinkShow',\n  'xlinkTitle', 'xlinkType', 'xmlBase', 'xmlLang', 'xmlnsXlink', 'xmlSpace', 'yChannelSelector',\n  'zoomAndPan',\n  // Safari/Apple specific, no listing available\n  'autoCorrect', // https://stackoverflow.com/questions/47985384/html-autocorrect-for-text-input-is-not-working\n  'autoSave', // https://stackoverflow.com/questions/25456396/what-is-autosave-attribute-supposed-to-do-how-do-i-use-it\n  // React specific attributes https://reactjs.org/docs/dom-elements.html#differences-in-attributes\n  'className', 'dangerouslySetInnerHTML', 'defaultValue', 'defaultChecked', 'htmlFor',\n  // Events' capture events\n  'onBeforeInput', 'onChange',\n  'onInvalid', 'onReset', 'onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'suppressContentEditableWarning', 'suppressHydrationWarning',\n  'onAbort', 'onCanPlay', 'onCanPlayThrough', 'onDurationChange', 'onEmptied', 'onEncrypted', 'onEnded',\n  'onLoadedData', 'onLoadedMetadata', 'onLoadStart', 'onPause', 'onPlay', 'onPlaying', 'onProgress', 'onRateChange', 'onResize',\n  'onSeeked', 'onSeeking', 'onStalled', 'onSuspend', 'onTimeUpdate', 'onVolumeChange', 'onWaiting',\n  'onCopyCapture', 'onCutCapture', 'onPasteCapture', 'onCompositionEndCapture', 'onCompositionStartCapture', 'onCompositionUpdateCapture',\n  'onFocusCapture', 'onBlurCapture', 'onChangeCapture', 'onBeforeInputCapture', 'onInputCapture', 'onResetCapture', 'onSubmitCapture',\n  'onInvalidCapture', 'onLoadCapture', 'onErrorCapture', 'onKeyDownCapture', 'onKeyPressCapture', 'onKeyUpCapture',\n  'onAbortCapture', 'onCanPlayCapture', 'onCanPlayThroughCapture', 'onDurationChangeCapture', 'onEmptiedCapture', 'onEncryptedCapture',\n  'onEndedCapture', 'onLoadedDataCapture', 'onLoadedMetadataCapture', 'onLoadStartCapture', 'onPauseCapture', 'onPlayCapture',\n  'onPlayingCapture', 'onProgressCapture', 'onRateChangeCapture', 'onSeekedCapture', 'onSeekingCapture', 'onStalledCapture', 'onSuspendCapture',\n  'onTimeUpdateCapture', 'onVolumeChangeCapture', 'onWaitingCapture', 'onSelectCapture', 'onTouchCancelCapture', 'onTouchEndCapture',\n  'onTouchMoveCapture', 'onTouchStartCapture', 'onScrollCapture', 'onScrollEndCapture', 'onWheelCapture', 'onAnimationEndCapture', 'onAnimationIteration',\n  'onAnimationStartCapture', 'onTransitionEndCapture',\n  'onAuxClick', 'onAuxClickCapture', 'onClickCapture', 'onContextMenuCapture', 'onDoubleClickCapture',\n  'onDragCapture', 'onDragEndCapture', 'onDragEnterCapture', 'onDragExitCapture', 'onDragLeaveCapture',\n  'onDragOverCapture', 'onDragStartCapture', 'onDropCapture', 'onMouseDown', 'onMouseDownCapture',\n  'onMouseMoveCapture', 'onMouseOutCapture', 'onMouseOverCapture', 'onMouseUpCapture',\n  // Video specific\n  'autoPictureInPicture', 'controlsList', 'disablePictureInPicture', 'disableRemotePlayback',\n  // popovers\n  'popoverTarget', 'popoverTargetAction',\n];\n\nconst DOM_PROPERTIES_IGNORE_CASE = ['charset', 'allowFullScreen', 'webkitAllowFullScreen', 'mozAllowFullScreen', 'webkitDirectory', 'popoverTarget', 'popoverTargetAction'];\n\nconst ARIA_PROPERTIES = [\n  // See https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes\n  // Global attributes\n  'aria-atomic', 'aria-braillelabel', 'aria-brailleroledescription', 'aria-busy', 'aria-controls', 'aria-current',\n  'aria-describedby', 'aria-description', 'aria-details',\n  'aria-disabled', 'aria-dropeffect', 'aria-errormessage', 'aria-flowto', 'aria-grabbed', 'aria-haspopup',\n  'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live',\n  'aria-owns', 'aria-relevant', 'aria-roledescription',\n  // Widget attributes\n  'aria-autocomplete', 'aria-checked', 'aria-expanded', 'aria-level', 'aria-modal', 'aria-multiline', 'aria-multiselectable',\n  'aria-orientation', 'aria-placeholder', 'aria-pressed', 'aria-readonly', 'aria-required', 'aria-selected',\n  'aria-sort', 'aria-valuemax', 'aria-valuemin', 'aria-valuenow', 'aria-valuetext',\n  // Relationship attributes\n  'aria-activedescendant', 'aria-colcount', 'aria-colindex', 'aria-colindextext', 'aria-colspan',\n  'aria-posinset', 'aria-rowcount', 'aria-rowindex', 'aria-rowindextext', 'aria-rowspan', 'aria-setsize',\n];\n\nconst REACT_ON_PROPS = [\n  'onGotPointerCapture',\n  'onGotPointerCaptureCapture',\n  'onLostPointerCapture',\n  'onLostPointerCapture',\n  'onLostPointerCaptureCapture',\n  'onPointerCancel',\n  'onPointerCancelCapture',\n  'onPointerDown',\n  'onPointerDownCapture',\n  'onPointerEnter',\n  'onPointerEnterCapture',\n  'onPointerLeave',\n  'onPointerLeaveCapture',\n  'onPointerMove',\n  'onPointerMoveCapture',\n  'onPointerOut',\n  'onPointerOutCapture',\n  'onPointerOver',\n  'onPointerOverCapture',\n  'onPointerUp',\n  'onPointerUpCapture',\n];\n\nfunction getDOMPropertyNames(context) {\n  return [].concat(\n    DOM_PROPERTY_NAMES_TWO_WORDS,\n    DOM_PROPERTY_NAMES_ONE_WORD,\n\n    testReactVersion(context, '>= 16.1.0') ? [].concat(\n      testReactVersion(context, '>= 16.4.0') ? [].concat(\n        // these were added in React v16.4.0, see https://reactjs.org/blog/2018/05/23/react-v-16-4.html and https://github.com/facebook/react/pull/12507\n        REACT_ON_PROPS,\n        testReactVersion(context, '>= 19') ? [\n          // precedence was added in React v19, see https://react.dev/blog/2024/04/25/react-19#support-for-stylesheets\n          'precedence',\n        ] : []\n      ) : []\n    ) : [\n      // this was removed in React v16.1+, see https://github.com/facebook/react/pull/10823\n      'allowTransparency',\n    ]\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n/**\n * Checks if a node's parent is a JSX tag that is written with lowercase letters,\n * and is not a custom web component. Custom web components have a hyphen in tag name,\n * or have an `is=\"some-elem\"` attribute.\n *\n * Note: does not check if a tag's parent against a list of standard HTML/DOM tags. For example,\n * a `<fake>`'s child would return `true` because \"fake\" is written only with lowercase letters\n * without a hyphen and does not have a `is=\"some-elem\"` attribute.\n *\n * @param {Object} childNode - JSX element being tested.\n * @returns {boolean} Whether or not the node name match the JSX tag convention.\n */\nfunction isValidHTMLTagInJSX(childNode) {\n  const tagConvention = /^[a-z][^-]*$/;\n  if (tagConvention.test(childNode.parent.name.name)) {\n    return !childNode.parent.attributes.some((attrNode) => (\n      attrNode.type === 'JSXAttribute'\n        && attrNode.name.type === 'JSXIdentifier'\n        && attrNode.name.name === 'is'\n        // To learn more about custom web components and `is` attribute,\n        // see https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-customized-builtin-example\n\n    ));\n  }\n  return false;\n}\n\n/**\n * Checks if the attribute name is included in the attributes that are excluded\n * from the camel casing.\n *\n * // returns 'charSet'\n * @example normalizeAttributeCase('charset')\n *\n * Note - these exclusions are not made by React core team, but `eslint-plugin-react` community.\n *\n * @param {string} name - Attribute name to be normalized\n * @returns {string} Result\n */\nfunction normalizeAttributeCase(name) {\n  return DOM_PROPERTIES_IGNORE_CASE.find((element) => element.toLowerCase() === name.toLowerCase()) || name;\n}\n\n/**\n * Checks if an attribute name is a valid `data-*` attribute:\n * if the name starts with \"data-\" and has alphanumeric words (browsers require lowercase, but React and TS lowercase them),\n * not start with any casing of \"xml\", and separated by hyphens (-) (which is also called \"kebab case\" or \"dash case\"),\n * then the attribute is a valid data attribute.\n *\n * @param {string} name - Attribute name to be tested\n * @returns {boolean} Result\n */\nfunction isValidDataAttribute(name) {\n  return !/^data-xml/i.test(name) && /^data-[^:]*$/.test(name);\n}\n\n/**\n * Checks if an attribute name has at least one uppercase characters\n *\n * @param {string} name\n * @returns {boolean} Result\n */\nfunction hasUpperCaseCharacter(name) {\n  return name.toLowerCase() !== name;\n}\n\n/**\n * Checks if an attribute name is a standard aria attribute by compering it to a list\n * of standard aria property names\n *\n * @param {string} name - Attribute name to be tested\n * @returns {boolean} Result\n */\n\nfunction isValidAriaAttribute(name) {\n  return ARIA_PROPERTIES.some((element) => element === name);\n}\n\n/**\n * Extracts the tag name for the JSXAttribute\n * @param {JSXAttribute} node - JSXAttribute being tested.\n * @returns {string | null} tag name\n */\nfunction getTagName(node) {\n  if (\n    node\n    && node.parent\n    && node.parent.name\n  ) {\n    return node.parent.name.name;\n  }\n  return null;\n}\n\n/**\n * Test wether the tag name for the JSXAttribute is\n * something like <Foo.bar />\n * @param {JSXAttribute} node - JSXAttribute being tested.\n * @returns {boolean} result\n */\nfunction tagNameHasDot(node) {\n  return !!(\n    node.parent\n    && node.parent.name\n    && node.parent.name.type === 'JSXMemberExpression'\n  );\n}\n\n/**\n * Get the standard name of the attribute.\n * @param {string} name - Name of the attribute.\n * @param {object} context - eslint context\n * @returns {string | undefined} The standard name of the attribute, or undefined if no standard name was found.\n */\nfunction getStandardName(name, context) {\n  if (has(DOM_ATTRIBUTE_NAMES, name)) {\n    return DOM_ATTRIBUTE_NAMES[/** @type {keyof DOM_ATTRIBUTE_NAMES} */ (name)];\n  }\n  if (has(SVGDOM_ATTRIBUTE_NAMES, name)) {\n    return SVGDOM_ATTRIBUTE_NAMES[/** @type {keyof SVGDOM_ATTRIBUTE_NAMES} */ (name)];\n  }\n  const names = getDOMPropertyNames(context);\n\n  // Let's find a possible attribute match with a case-insensitive search.\n  return names.find((element) => element.toLowerCase() === name.toLowerCase());\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  invalidPropOnTag: 'Invalid property \\'{{name}}\\' found on tag \\'{{tagName}}\\', but it is only allowed on: {{allowedTags}}',\n  unknownPropWithStandardName: 'Unknown property \\'{{name}}\\' found, use \\'{{standardName}}\\' instead',\n  unknownProp: 'Unknown property \\'{{name}}\\' found',\n  dataLowercaseRequired: 'React does not recognize data-* props with uppercase characters on a DOM element. Found \\'{{name}}\\', use \\'{{lowerCaseName}}\\' instead',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of unknown DOM property',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('no-unknown-property'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignore: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        requireDataLowercase: {\n          type: 'boolean',\n          default: false,\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    function getIgnoreConfig() {\n      return (context.options[0] && context.options[0].ignore) || DEFAULTS.ignore;\n    }\n\n    function getRequireDataLowercase() {\n      return (context.options[0] && typeof context.options[0].requireDataLowercase !== 'undefined')\n        ? !!context.options[0].requireDataLowercase\n        : DEFAULTS.requireDataLowercase;\n    }\n\n    return {\n      JSXAttribute(node) {\n        const ignoreNames = getIgnoreConfig();\n        const actualName = getText(context, node.name);\n        if (ignoreNames.indexOf(actualName) >= 0) {\n          return;\n        }\n        const name = normalizeAttributeCase(actualName);\n\n        // Ignore tags like <Foo.bar />\n        if (tagNameHasDot(node)) {\n          return;\n        }\n\n        if (isValidDataAttribute(name)) {\n          if (getRequireDataLowercase() && hasUpperCaseCharacter(name)) {\n            report(context, messages.dataLowercaseRequired, 'dataLowercaseRequired', {\n              node,\n              data: {\n                name: actualName,\n                lowerCaseName: actualName.toLowerCase(),\n              },\n            });\n          }\n\n          return;\n        }\n\n        if (isValidAriaAttribute(name)) { return; }\n\n        const tagName = getTagName(node);\n\n        if (tagName === 'fbt' || tagName === 'fbs') { return; } // fbt/fbs nodes are bonkers, let's not go there\n\n        if (!isValidHTMLTagInJSX(node)) { return; }\n\n        // Let's dive deeper into tags that are HTML/DOM elements (`<button>`), and not React components (`<Button />`)\n\n        // Some attributes are allowed on some tags only\n        const allowedTags = has(ATTRIBUTE_TAGS_MAP, name)\n          ? ATTRIBUTE_TAGS_MAP[/** @type {keyof ATTRIBUTE_TAGS_MAP} */ (name)]\n          : null;\n        if (tagName && allowedTags) {\n          // Scenario 1A: Allowed attribute found where not supposed to, report it\n          if (allowedTags.indexOf(tagName) === -1) {\n            report(context, messages.invalidPropOnTag, 'invalidPropOnTag', {\n              node,\n              data: {\n                name: actualName,\n                tagName,\n                allowedTags: allowedTags.join(', '),\n              },\n            });\n          }\n          // Scenario 1B: There are allowed attributes on allowed tags, no need to report it\n          return;\n        }\n\n        // Let's see if the attribute is a close version to some standard property name\n        const standardName = getStandardName(name, context);\n\n        const hasStandardNameButIsNotUsed = standardName && standardName !== name;\n        const usesStandardName = standardName && standardName === name;\n\n        if (usesStandardName) {\n          // Scenario 2A: The attribute name is the standard name, no need to report it\n          return;\n        }\n\n        if (hasStandardNameButIsNotUsed) {\n          // Scenario 2B: The name of the attribute is close to a standard one, report it with the standard name\n          report(context, messages.unknownPropWithStandardName, 'unknownPropWithStandardName', {\n            node,\n            data: {\n              name: actualName,\n              standardName,\n            },\n            fix(fixer) {\n              return fixer.replaceText(node.name, standardName);\n            },\n          });\n          return;\n        }\n\n        // Scenario 3: We have an attribute that is unknown, report it\n        report(context, messages.unknownProp, 'unknownProp', {\n          node,\n          data: {\n            name: actualName,\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-unsafe.js",
    "content": "/**\n * @fileoverview Prevent usage of unsafe lifecycle methods\n * @author Sergei Startsev\n */\n\n'use strict';\n\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  unsafeMethod: '{{method}} is unsafe for use in async rendering. Update the component to use {{newMethod}} instead. {{details}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow usage of unsafe lifecycle methods',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-unsafe'),\n    },\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          checkAliases: {\n            default: false,\n            type: 'boolean',\n          },\n        },\n        additionalProperties: false,\n      },\n    ],\n  },\n\n  create(context) {\n    const config = context.options[0] || {};\n    const checkAliases = config.checkAliases || false;\n\n    const isApplicable = testReactVersion(context, '>= 16.3.0');\n    if (!isApplicable) {\n      return {};\n    }\n\n    const unsafe = {\n      UNSAFE_componentWillMount: {\n        newMethod: 'componentDidMount',\n        details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n      },\n      UNSAFE_componentWillReceiveProps: {\n        newMethod: 'getDerivedStateFromProps',\n        details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n      },\n      UNSAFE_componentWillUpdate: {\n        newMethod: 'componentDidUpdate',\n        details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n      },\n    };\n    if (checkAliases) {\n      unsafe.componentWillMount = unsafe.UNSAFE_componentWillMount;\n      unsafe.componentWillReceiveProps = unsafe.UNSAFE_componentWillReceiveProps;\n      unsafe.componentWillUpdate = unsafe.UNSAFE_componentWillUpdate;\n    }\n\n    /**\n     * Returns a list of unsafe methods\n     * @returns {Array} A list of unsafe methods\n     */\n    function getUnsafeMethods() {\n      return Object.keys(unsafe);\n    }\n\n    /**\n     * Checks if a passed method is unsafe\n     * @param {string} method Life cycle method\n     * @returns {boolean} Returns true for unsafe methods, otherwise returns false\n     */\n    function isUnsafe(method) {\n      const unsafeMethods = getUnsafeMethods();\n      return unsafeMethods.indexOf(method) !== -1;\n    }\n\n    /**\n     * Reports the error for an unsafe method\n     * @param {ASTNode} node The AST node being checked\n     * @param {string} method Life cycle method\n     */\n    function checkUnsafe(node, method) {\n      if (!isUnsafe(method)) {\n        return;\n      }\n\n      const meta = unsafe[method];\n      const newMethod = meta.newMethod;\n      const details = meta.details;\n\n      const propertyNode = astUtil.getComponentProperties(node)\n        .find((property) => astUtil.getPropertyName(property) === method);\n\n      report(context, messages.unsafeMethod, 'unsafeMethod', {\n        node: propertyNode,\n        data: {\n          method,\n          newMethod,\n          details,\n        },\n      });\n    }\n\n    /**\n     * Returns life cycle methods if available\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {Array} The array of methods.\n     */\n    function getLifeCycleMethods(node) {\n      const properties = astUtil.getComponentProperties(node);\n      return properties.map((property) => astUtil.getPropertyName(property));\n    }\n\n    /**\n     * Checks life cycle methods\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function checkLifeCycleMethods(node) {\n      if (componentUtil.isES5Component(node, context) || componentUtil.isES6Component(node, context)) {\n        const methods = getLifeCycleMethods(node);\n        methods\n          .sort((a, b) => a.localeCompare(b))\n          .forEach((method) => checkUnsafe(node, method));\n      }\n    }\n\n    return {\n      ClassDeclaration: checkLifeCycleMethods,\n      ClassExpression: checkLifeCycleMethods,\n      ObjectExpression: checkLifeCycleMethods,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-unstable-nested-components.js",
    "content": "/**\n * @fileoverview Prevent creating unstable components inside components\n * @author Ari Perkkiö\n */\n\n'use strict';\n\nconst minimatch = require('minimatch');\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst COMPONENT_AS_PROPS_INFO = ' If you want to allow component creation in props, set allowAsProps option to true.';\nconst HOOK_REGEXP = /^use[A-Z0-9].*$/;\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n/**\n * Generate error message with given parent component name\n * @param {string} parentName Name of the parent component, if known\n * @returns {string} Error message with parent component name\n */\nfunction generateErrorMessageWithParentName(parentName) {\n  return `Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component${parentName ? ` “${parentName}” ` : ' '}and pass data as props.`;\n}\n\n/**\n * Check whether given text matches the pattern passed in.\n * @param {string} text Text to validate\n * @param {string} pattern Pattern to match against\n * @returns {boolean}\n */\nfunction propMatchesRenderPropPattern(text, pattern) {\n  return typeof text === 'string' && minimatch(text, pattern);\n}\n\n/**\n * Get closest parent matching given matcher\n * @param {ASTNode} node The AST node\n * @param {Context} context eslint context\n * @param {Function} matcher Method used to match the parent\n * @returns {ASTNode} The matching parent node, if any\n */\nfunction getClosestMatchingParent(node, context, matcher) {\n  if (!node || !node.parent || node.parent.type === 'Program') {\n    return;\n  }\n\n  if (matcher(node.parent, context)) {\n    return node.parent;\n  }\n\n  return getClosestMatchingParent(node.parent, context, matcher);\n}\n\n/**\n * Matcher used to check whether given node is a `createElement` call\n * @param {ASTNode} node The AST node\n * @param {Context} context eslint context\n * @returns {boolean} True if node is a `createElement` call, false if not\n */\nfunction isCreateElementMatcher(node, context) {\n  return (\n    astUtil.isCallExpression(node)\n    && isCreateElement(context, node)\n  );\n}\n\n/**\n * Matcher used to check whether given node is a `ObjectExpression`\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is a `ObjectExpression`, false if not\n */\nfunction isObjectExpressionMatcher(node) {\n  return node && node.type === 'ObjectExpression';\n}\n\n/**\n * Matcher used to check whether given node is a `JSXExpressionContainer`\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is a `JSXExpressionContainer`, false if not\n */\nfunction isJSXExpressionContainerMatcher(node) {\n  return node && node.type === 'JSXExpressionContainer';\n}\n\n/**\n * Matcher used to check whether given node is a `JSXAttribute` of `JSXExpressionContainer`\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is a `JSXAttribute` of `JSXExpressionContainer`, false if not\n */\nfunction isJSXAttributeOfExpressionContainerMatcher(node) {\n  return (\n    node\n    && node.type === 'JSXAttribute'\n    && node.value\n    && node.value.type === 'JSXExpressionContainer'\n  );\n}\n\n/**\n * Matcher used to check whether given node is an object `Property`\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is a `Property`, false if not\n */\nfunction isPropertyOfObjectExpressionMatcher(node) {\n  return (\n    node\n    && node.parent\n    && node.parent.type === 'Property'\n  );\n}\n\n/**\n * Check whether given node or its parent is directly inside `map` call\n * ```jsx\n * {items.map(item => <li />)}\n * ```\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is directly inside `map` call, false if not\n */\nfunction isMapCall(node) {\n  return (\n    node\n    && node.callee\n    && node.callee.property\n    && node.callee.property.name === 'map'\n  );\n}\n\n/**\n * Check whether given node is `ReturnStatement` of a React hook\n * @param {ASTNode} node The AST node\n * @param {Context} context eslint context\n * @returns {boolean} True if node is a `ReturnStatement` of a React hook, false if not\n */\nfunction isReturnStatementOfHook(node, context) {\n  if (\n    !node\n    || !node.parent\n    || node.parent.type !== 'ReturnStatement'\n  ) {\n    return false;\n  }\n\n  const callExpression = getClosestMatchingParent(node, context, astUtil.isCallExpression);\n  return (\n    callExpression\n    && callExpression.callee\n    && HOOK_REGEXP.test(callExpression.callee.name)\n  );\n}\n\n/**\n * Check whether given node is declared inside a render prop\n * ```jsx\n * <Component renderFooter={() => <div />} />\n * <Component>{() => <div />}</Component>\n * ```\n * @param {ASTNode} node The AST node\n * @param {Context} context eslint context\n * @param {string} propNamePattern a pattern to match render props against\n * @returns {boolean} True if component is declared inside a render prop, false if not\n */\nfunction isComponentInRenderProp(node, context, propNamePattern) {\n  if (\n    node\n    && node.parent\n    && node.parent.type === 'Property'\n    && node.parent.key\n    && propMatchesRenderPropPattern(node.parent.key.name, propNamePattern)\n  ) {\n    return true;\n  }\n\n  // Check whether component is a render prop used as direct children, e.g. <Component>{() => <div />}</Component>\n  if (\n    node\n    && node.parent\n    && node.parent.type === 'JSXExpressionContainer'\n    && node.parent.parent\n    && node.parent.parent.type === 'JSXElement'\n  ) {\n    return true;\n  }\n\n  const jsxExpressionContainer = getClosestMatchingParent(node, context, isJSXExpressionContainerMatcher);\n\n  // Check whether prop name indicates accepted patterns\n  if (\n    jsxExpressionContainer\n    && jsxExpressionContainer.parent\n    && jsxExpressionContainer.parent.type === 'JSXAttribute'\n    && jsxExpressionContainer.parent.name\n    && jsxExpressionContainer.parent.name.type === 'JSXIdentifier'\n  ) {\n    const propName = jsxExpressionContainer.parent.name.name;\n\n    // Starts with render, e.g. <Component renderFooter={() => <div />} />\n    if (propMatchesRenderPropPattern(propName, propNamePattern)) {\n      return true;\n    }\n\n    // Uses children prop explicitly, e.g. <Component children={() => <div />} />\n    if (propName === 'children') {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Check whether given node is declared directly inside a render property\n * ```jsx\n * const rows = { render: () => <div /> }\n * <Component rows={ [{ render: () => <div /> }] } />\n *  ```\n * @param {ASTNode} node The AST node\n * @param {string} propNamePattern The pattern to match render props against\n * @returns {boolean} True if component is declared inside a render property, false if not\n */\nfunction isDirectValueOfRenderProperty(node, propNamePattern) {\n  return (\n    node\n    && node.parent\n    && node.parent.type === 'Property'\n    && node.parent.key\n    && node.parent.key.type === 'Identifier'\n    && propMatchesRenderPropPattern(node.parent.key.name, propNamePattern)\n  );\n}\n\n/**\n * Resolve the component name of given node\n * @param {ASTNode} node The AST node of the component\n * @returns {string} Name of the component, if any\n */\nfunction resolveComponentName(node) {\n  const parentName = node.id && node.id.name;\n  if (parentName) return parentName;\n\n  return (\n    node.type === 'ArrowFunctionExpression'\n    && node.parent\n    && node.parent.id\n    && node.parent.id.name\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow creating unstable components inside components',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('no-unstable-nested-components'),\n    },\n    schema: [{\n      type: 'object',\n      properties: {\n        customValidators: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        allowAsProps: {\n          type: 'boolean',\n        },\n        propNamePattern: {\n          type: 'string',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const allowAsProps = context.options.some((option) => option && option.allowAsProps);\n    const propNamePattern = (context.options[0] || {}).propNamePattern || 'render*';\n\n    /**\n     * Check whether given node is declared inside class component's render block\n     * ```jsx\n     * class Component extends React.Component {\n     *   render() {\n     *     class NestedClassComponent extends React.Component {\n     * ...\n     * ```\n     * @param {ASTNode} node The AST node being checked\n     * @returns {boolean} True if node is inside class component's render block, false if not\n     */\n    function isInsideRenderMethod(node) {\n      const parentComponent = utils.getParentComponent(node);\n\n      if (!parentComponent || parentComponent.type !== 'ClassDeclaration') {\n        return false;\n      }\n\n      return (\n        node\n        && node.parent\n        && node.parent.type === 'MethodDefinition'\n        && node.parent.key\n        && node.parent.key.name === 'render'\n      );\n    }\n\n    /**\n     * Check whether given node is a function component declared inside class component.\n     * Util's component detection fails to detect function components inside class components.\n     * ```jsx\n     * class Component extends React.Component {\n     *  render() {\n     *    const NestedComponent = () => <div />;\n     * ...\n     * ```\n     * @param {ASTNode} node The AST node being checked\n     * @returns {boolean} True if given node a function component declared inside class component, false if not\n     */\n    function isFunctionComponentInsideClassComponent(node) {\n      const parentComponent = utils.getParentComponent(node);\n      const parentStatelessComponent = utils.getParentStatelessComponent(node);\n\n      return (\n        parentComponent\n        && parentStatelessComponent\n        && parentComponent.type === 'ClassDeclaration'\n        && utils.getStatelessComponent(parentStatelessComponent)\n        && utils.isReturningJSX(node)\n      );\n    }\n\n    /**\n     * Check whether given node is declared inside `createElement` call's props\n     * ```js\n     * React.createElement(Component, {\n     *   footer: () => React.createElement(\"div\", null)\n     * })\n     * ```\n     * @param {ASTNode} node The AST node\n     * @returns {boolean} True if node is declare inside `createElement` call's props, false if not\n     */\n    function isComponentInsideCreateElementsProp(node) {\n      if (!components.get(node)) {\n        return false;\n      }\n\n      const createElementParent = getClosestMatchingParent(node, context, isCreateElementMatcher);\n\n      return (\n        createElementParent\n        && createElementParent.arguments\n        && createElementParent.arguments[1] === getClosestMatchingParent(node, context, isObjectExpressionMatcher)\n      );\n    }\n\n    /**\n     * Check whether given node is declared inside a component/object prop.\n     * ```jsx\n     * <Component footer={() => <div />} />\n     * { footer: () => <div /> }\n     * ```\n     * @param {ASTNode} node The AST node being checked\n     * @returns {boolean} True if node is a component declared inside prop, false if not\n     */\n    function isComponentInProp(node) {\n      if (isPropertyOfObjectExpressionMatcher(node)) {\n        return utils.isReturningJSX(node);\n      }\n\n      const jsxAttribute = getClosestMatchingParent(node, context, isJSXAttributeOfExpressionContainerMatcher);\n\n      if (!jsxAttribute) {\n        return isComponentInsideCreateElementsProp(node);\n      }\n\n      return utils.isReturningJSX(node);\n    }\n\n    /**\n     * Check whether given node is a stateless component returning non-JSX\n     * ```jsx\n     * {{ a: () => null }}\n     * ```\n     * @param {ASTNode} node The AST node being checked\n     * @returns {boolean} True if node is a stateless component returning non-JSX, false if not\n     */\n    function isStatelessComponentReturningNull(node) {\n      const component = utils.getStatelessComponent(node);\n\n      return component && !utils.isReturningJSX(component);\n    }\n\n    /**\n     * Check whether given node is a unstable nested component\n     * @param {ASTNode} node The AST node being checked\n     */\n    function validate(node) {\n      if (!node || !node.parent) {\n        return;\n      }\n\n      const isDeclaredInsideProps = isComponentInProp(node);\n\n      if (\n        !components.get(node)\n        && !isFunctionComponentInsideClassComponent(node)\n        && !isDeclaredInsideProps) {\n        return;\n      }\n\n      if (\n        // Support allowAsProps option\n        (isDeclaredInsideProps && (allowAsProps || isComponentInRenderProp(node, context, propNamePattern)))\n\n        // Prevent reporting components created inside Array.map calls\n        || isMapCall(node)\n        || isMapCall(node.parent)\n\n        // Do not mark components declared inside hooks (or falsy '() => null' clean-up methods)\n        || isReturnStatementOfHook(node, context)\n\n        // Do not mark objects containing render methods\n        || isDirectValueOfRenderProperty(node, propNamePattern)\n\n        // Prevent reporting nested class components twice\n        || isInsideRenderMethod(node)\n\n        // Prevent falsely reporting detected \"components\" which do not return JSX\n        || isStatelessComponentReturningNull(node)\n      ) {\n        return;\n      }\n\n      // Get the closest parent component\n      const parentComponent = getClosestMatchingParent(\n        node,\n        context,\n        (nodeToMatch) => components.get(nodeToMatch)\n      );\n\n      if (parentComponent) {\n        const parentName = resolveComponentName(parentComponent);\n\n        // Exclude lowercase parents, e.g. function createTestComponent()\n        // React-dom prevents creating lowercase components\n        if (parentName && parentName[0] === parentName[0].toLowerCase()) {\n          return;\n        }\n\n        let message = generateErrorMessageWithParentName(parentName);\n\n        // Add information about allowAsProps option when component is declared inside prop\n        if (isDeclaredInsideProps && !allowAsProps) {\n          message += COMPONENT_AS_PROPS_INFO;\n        }\n\n        report(context, message, null, {\n          node,\n        });\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      FunctionDeclaration(node) { validate(node); },\n      ArrowFunctionExpression(node) { validate(node); },\n      FunctionExpression(node) { validate(node); },\n      ClassDeclaration(node) { validate(node); },\n      CallExpression(node) { validate(node); },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-unused-class-component-methods.js",
    "content": "/**\n * @fileoverview Prevent declaring unused methods and properties of component class\n * @author Paweł Nowak, Berton Zhu\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst componentUtil = require('../util/componentUtil');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst LIFECYCLE_METHODS = new Set([\n  'constructor',\n  'componentDidCatch',\n  'componentDidMount',\n  'componentDidUpdate',\n  'componentWillMount',\n  'componentWillReceiveProps',\n  'componentWillUnmount',\n  'componentWillUpdate',\n  'getChildContext',\n  'getSnapshotBeforeUpdate',\n  'render',\n  'shouldComponentUpdate',\n  'UNSAFE_componentWillMount',\n  'UNSAFE_componentWillReceiveProps',\n  'UNSAFE_componentWillUpdate',\n]);\n\nconst ES6_LIFECYCLE = new Set([\n  'state',\n]);\n\nconst ES5_LIFECYCLE = new Set([\n  'getInitialState',\n  'getDefaultProps',\n  'mixins',\n]);\n\nfunction isKeyLiteralLike(node, property) {\n  return property.type === 'Literal'\n     || (property.type === 'TemplateLiteral' && property.expressions.length === 0)\n     || (node.computed === false && property.type === 'Identifier');\n}\n\n// Descend through all wrapping TypeCastExpressions and return the expression\n// that was cast.\nfunction uncast(node) {\n  while (node.type === 'TypeCastExpression') {\n    node = node.expression;\n  }\n  return node;\n}\n\n// Return the name of an identifier or the string value of a literal. Useful\n// anywhere that a literal may be used as a key (e.g., member expressions,\n// method definitions, ObjectExpression property keys).\nfunction getName(node) {\n  node = uncast(node);\n  const type = node.type;\n\n  if (type === 'Identifier') {\n    return node.name;\n  }\n  if (type === 'Literal') {\n    return String(node.value);\n  }\n  if (type === 'TemplateLiteral' && node.expressions.length === 0) {\n    return node.quasis[0].value.raw;\n  }\n  return null;\n}\n\nfunction isThisExpression(node) {\n  return uncast(node).type === 'ThisExpression';\n}\n\nfunction getInitialClassInfo(node, isClass) {\n  return {\n    classNode: node,\n    isClass,\n    // Set of nodes where properties were defined.\n    properties: new Set(),\n\n    // Set of names of properties that we've seen used.\n    usedProperties: new Set(),\n\n    inStatic: false,\n  };\n}\n\nconst messages = {\n  unused: 'Unused method or property \"{{name}}\"',\n  unusedWithClass: 'Unused method or property \"{{name}}\" of class \"{{className}}\"',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow declaring unused methods of component class',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-unused-class-component-methods'),\n    },\n    messages,\n    schema: [],\n  },\n\n  create: ((context) => {\n    let classInfo = null;\n\n    // Takes an ObjectExpression node and adds all named Property nodes to the\n    // current set of properties.\n    function addProperty(node) {\n      classInfo.properties.add(node);\n    }\n\n    // Adds the name of the given node as a used property if the node is an\n    // Identifier or a Literal. Other node types are ignored.\n    function addUsedProperty(node) {\n      const name = getName(node);\n      if (name) {\n        classInfo.usedProperties.add(name);\n      }\n    }\n\n    function reportUnusedProperties() {\n      // Report all unused properties.\n      for (const node of classInfo.properties) { // eslint-disable-line no-restricted-syntax\n        const name = getName(node);\n        if (\n          !classInfo.usedProperties.has(name)\n           && !LIFECYCLE_METHODS.has(name)\n           && (classInfo.isClass ? !ES6_LIFECYCLE.has(name) : !ES5_LIFECYCLE.has(name))\n        ) {\n          const className = (classInfo.classNode.id && classInfo.classNode.id.name) || '';\n\n          const messageID = className ? 'unusedWithClass' : 'unused';\n          report(\n            context,\n            messages[messageID],\n            messageID,\n            {\n              node,\n              data: {\n                name,\n                className,\n              },\n            }\n          );\n        }\n      }\n    }\n\n    function exitMethod() {\n      if (!classInfo || !classInfo.inStatic) {\n        return;\n      }\n\n      classInfo.inStatic = false;\n    }\n\n    return {\n      ClassDeclaration(node) {\n        if (componentUtil.isES6Component(node, context)) {\n          classInfo = getInitialClassInfo(node, true);\n        }\n      },\n\n      ObjectExpression(node) {\n        if (componentUtil.isES5Component(node, context)) {\n          classInfo = getInitialClassInfo(node, false);\n        }\n      },\n\n      'ClassDeclaration:exit'() {\n        if (!classInfo) {\n          return;\n        }\n        reportUnusedProperties();\n        classInfo = null;\n      },\n\n      'ObjectExpression:exit'(node) {\n        if (!classInfo || classInfo.classNode !== node) {\n          return;\n        }\n        reportUnusedProperties();\n        classInfo = null;\n      },\n\n      Property(node) {\n        if (!classInfo || classInfo.classNode !== node.parent) {\n          return;\n        }\n\n        if (isKeyLiteralLike(node, node.key)) {\n          addProperty(node.key);\n        }\n      },\n\n      'ClassProperty, MethodDefinition, PropertyDefinition'(node) {\n        if (!classInfo) {\n          return;\n        }\n\n        if (node.static) {\n          classInfo.inStatic = true;\n          return;\n        }\n\n        if (isKeyLiteralLike(node, node.key)) {\n          addProperty(node.key);\n        }\n      },\n\n      'ClassProperty:exit': exitMethod,\n      'MethodDefinition:exit': exitMethod,\n      'PropertyDefinition:exit': exitMethod,\n\n      MemberExpression(node) {\n        if (!classInfo || classInfo.inStatic) {\n          return;\n        }\n\n        if (isThisExpression(node.object) && isKeyLiteralLike(node, node.property)) {\n          if (node.parent.type === 'AssignmentExpression' && node.parent.left === node) {\n            // detect `this.property = xxx`\n            addProperty(node.property);\n          } else {\n            // detect `this.property()`, `x = this.property`, etc.\n            addUsedProperty(node.property);\n          }\n        }\n      },\n\n      VariableDeclarator(node) {\n        if (!classInfo || classInfo.inStatic) {\n          return;\n        }\n\n        // detect `{ foo, bar: baz } = this`\n        if (node.init && isThisExpression(node.init) && node.id.type === 'ObjectPattern') {\n          node.id.properties\n            .filter((prop) => prop.type === 'Property' && isKeyLiteralLike(prop, prop.key))\n            .forEach((prop) => {\n              addUsedProperty('key' in prop ? prop.key : undefined);\n            });\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-unused-prop-types.js",
    "content": "/**\n * @fileoverview Prevent definitions of unused prop types\n * @author Evgueni Naverniouk\n */\n\n'use strict';\n\nconst values = require('object.values');\n\n// As for exceptions for props.children or props.className (and alike) look at\n// https://github.com/jsx-eslint/eslint-plugin-react/issues/7\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n/**\n * Checks if the component must be validated\n * @param {Object} component The component to process\n * @returns {boolean} True if the component must be validated, false if not.\n */\nfunction mustBeValidated(component) {\n  return !!component && !component.ignoreUnusedPropTypesValidation;\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  unusedPropType: '\\'{{name}}\\' PropType is defined but prop is never used',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow definitions of unused propTypes',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-unused-prop-types'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignore: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n          uniqueItems: true,\n        },\n        customValidators: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        skipShapeProps: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    const defaults = { skipShapeProps: true, customValidators: [], ignore: [] };\n    const configuration = Object.assign({}, defaults, context.options[0] || {});\n\n    /**\n     * Checks if the prop is ignored\n     * @param {string} name Name of the prop to check.\n     * @returns {boolean} True if the prop is ignored, false if not.\n     */\n    function isIgnored(name) {\n      return configuration.ignore.indexOf(name) !== -1;\n    }\n\n    /**\n     * Checks if a prop is used\n     * @param {ASTNode} node The AST node being checked.\n     * @param {Object} prop Declared prop object\n     * @returns {boolean} True if the prop is used, false if not.\n     */\n    function isPropUsed(node, prop) {\n      const usedPropTypes = node.usedPropTypes || [];\n      for (let i = 0, l = usedPropTypes.length; i < l; i++) {\n        const usedProp = usedPropTypes[i];\n        if (\n          prop.type === 'shape'\n          || prop.type === 'exact'\n          || prop.name === '__ANY_KEY__'\n          || usedProp.name === prop.name\n        ) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    /**\n     * Used to recursively loop through each declared prop type\n     * @param {Object} component The component to process\n     * @param {ASTNode[]|true} props List of props to validate\n     */\n    function reportUnusedPropType(component, props) {\n      // Skip props that check instances\n      if (props === true) {\n        return;\n      }\n\n      Object.keys(props || {}).forEach((key) => {\n        const prop = props[key];\n        // Skip props that check instances\n        if (prop === true) {\n          return;\n        }\n\n        if ((prop.type === 'shape' || prop.type === 'exact') && configuration.skipShapeProps) {\n          return;\n        }\n\n        if (prop.node && prop.node.typeAnnotation && prop.node.typeAnnotation.typeAnnotation\n          && prop.node.typeAnnotation.typeAnnotation.type === 'TSNeverKeyword') {\n          return;\n        }\n\n        if (prop.node && !isIgnored(prop.fullName) && !isPropUsed(component, prop)) {\n          report(context, messages.unusedPropType, 'unusedPropType', {\n            node: prop.node.key || prop.node,\n            data: {\n              name: prop.fullName,\n            },\n          });\n        }\n\n        if (prop.children) {\n          reportUnusedPropType(component, prop.children);\n        }\n      });\n    }\n\n    /**\n     * Reports unused proptypes for a given component\n     * @param {Object} component The component to process\n     */\n    function reportUnusedPropTypes(component) {\n      reportUnusedPropType(component, component.declaredPropTypes);\n    }\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    return {\n      'Program:exit'() {\n        // Report undeclared proptypes for all classes\n        values(components.list())\n          .filter((component) => mustBeValidated(component))\n          .forEach((component) => {\n            reportUnusedPropTypes(component);\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/no-unused-state.js",
    "content": "/**\n * @fileoverview  Attempts to discover all state fields in a React component and\n * warn if any of them are never read.\n *\n * State field definitions are collected from `this.state = {}` assignments in\n * the constructor, objects passed to `this.setState()`, and `state = {}` class\n * property assignments.\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst report = require('../util/report');\nconst getScope = require('../util/eslint').getScope;\n\n// Descend through all wrapping TypeCastExpressions and return the expression\n// that was cast.\nfunction uncast(node) {\n  while (node.type === 'TypeCastExpression') {\n    node = node.expression;\n  }\n  return node;\n}\n\n// Return the name of an identifier or the string value of a literal. Useful\n// anywhere that a literal may be used as a key (e.g., member expressions,\n// method definitions, ObjectExpression property keys).\nfunction getName(node) {\n  node = uncast(node);\n  const type = node.type;\n\n  if (type === 'Identifier') {\n    return node.name;\n  }\n  if (type === 'Literal') {\n    return String(node.value);\n  }\n  if (type === 'TemplateLiteral' && node.expressions.length === 0) {\n    return node.quasis[0].value.raw;\n  }\n  return null;\n}\n\nfunction isThisExpression(node) {\n  return astUtil.unwrapTSAsExpression(uncast(node)).type === 'ThisExpression';\n}\n\nfunction getInitialClassInfo() {\n  return {\n    // Set of nodes where state fields were defined.\n    stateFields: new Set(),\n\n    // Set of names of state fields that we've seen used.\n    usedStateFields: new Set(),\n\n    // Names of local variables that may be pointing to this.state. To\n    // track this properly, we would need to keep track of all locals,\n    // shadowing, assignments, etc. To keep things simple, we only\n    // maintain one set of aliases per method and accept that it will\n    // produce some false negatives.\n    aliases: null,\n  };\n}\n\nfunction isSetStateCall(node) {\n  const unwrappedCalleeNode = astUtil.unwrapTSAsExpression(node.callee);\n\n  return (\n    unwrappedCalleeNode.type === 'MemberExpression'\n    && isThisExpression(unwrappedCalleeNode.object)\n    && getName(unwrappedCalleeNode.property) === 'setState'\n  );\n}\n\nconst messages = {\n  unusedStateField: 'Unused state field: \\'{{name}}\\'',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow definitions of unused state',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('no-unused-state'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    // Non-null when we are inside a React component ClassDeclaration and we have\n    // not yet encountered any use of this.state which we have chosen not to\n    // analyze. If we encounter any such usage (like this.state being spread as\n    // JSX attributes), then this is again set to null.\n    let classInfo = null;\n\n    function isStateParameterReference(node) {\n      const classMethods = [\n        'shouldComponentUpdate',\n        'componentWillUpdate',\n        'UNSAFE_componentWillUpdate',\n        'getSnapshotBeforeUpdate',\n        'componentDidUpdate',\n      ];\n\n      let scope = getScope(context, node);\n      while (scope) {\n        const parent = scope.block && scope.block.parent;\n        if (\n          parent\n          && parent.type === 'MethodDefinition' && (\n            (parent.static && parent.key.name === 'getDerivedStateFromProps')\n            || classMethods.indexOf(parent.key.name) !== -1\n          )\n          && parent.value.type === 'FunctionExpression'\n          && parent.value.params[1]\n          && parent.value.params[1].name === node.name\n        ) {\n          return true;\n        }\n        scope = scope.upper;\n      }\n\n      return false;\n    }\n\n    // Returns true if the given node is possibly a reference to `this.state` or the state parameter of\n    // a lifecycle method.\n    function isStateReference(node) {\n      node = uncast(node);\n\n      const isDirectStateReference = node.type === 'MemberExpression'\n        && isThisExpression(node.object)\n        && node.property.name === 'state';\n\n      const isAliasedStateReference = node.type === 'Identifier'\n        && classInfo.aliases\n        && classInfo.aliases.has(node.name);\n\n      return isDirectStateReference || isAliasedStateReference || isStateParameterReference(node);\n    }\n\n    // Takes an ObjectExpression node and adds all named Property nodes to the\n    // current set of state fields.\n    function addStateFields(node) {\n      node.properties.filter((prop) => (\n        prop.type === 'Property'\n          && (prop.key.type === 'Literal'\n          || (prop.key.type === 'TemplateLiteral' && prop.key.expressions.length === 0)\n          || (prop.computed === false && prop.key.type === 'Identifier'))\n          && getName(prop.key) !== null\n      )).forEach((prop) => {\n        classInfo.stateFields.add(prop);\n      });\n    }\n\n    // Adds the name of the given node as a used state field if the node is an\n    // Identifier or a Literal. Other node types are ignored.\n    function addUsedStateField(node) {\n      if (!classInfo) {\n        return;\n      }\n      const name = getName(node);\n      if (name) {\n        classInfo.usedStateFields.add(name);\n      }\n    }\n\n    // Records used state fields and new aliases for an ObjectPattern which\n    // destructures `this.state`.\n    function handleStateDestructuring(node) {\n      node.properties.forEach((prop) => {\n        if (prop.type === 'Property') {\n          addUsedStateField(prop.key);\n        } else if (\n          (prop.type === 'ExperimentalRestProperty' || prop.type === 'RestElement')\n          && classInfo.aliases\n        ) {\n          classInfo.aliases.add(getName(prop.argument));\n        }\n      });\n    }\n\n    // Used to record used state fields and new aliases for both\n    // AssignmentExpressions and VariableDeclarators.\n    function handleAssignment(left, right) {\n      const unwrappedRight = astUtil.unwrapTSAsExpression(right);\n\n      switch (left.type) {\n        case 'Identifier':\n          if (isStateReference(unwrappedRight) && classInfo.aliases) {\n            classInfo.aliases.add(left.name);\n          }\n          break;\n        case 'ObjectPattern':\n          if (isStateReference(unwrappedRight)) {\n            handleStateDestructuring(left);\n          } else if (isThisExpression(unwrappedRight) && classInfo.aliases) {\n            left.properties.forEach((prop) => {\n              if (prop.type === 'Property' && getName(prop.key) === 'state') {\n                const name = getName(prop.value);\n                if (name) {\n                  classInfo.aliases.add(name);\n                } else if (prop.value.type === 'ObjectPattern') {\n                  handleStateDestructuring(prop.value);\n                }\n              }\n            });\n          }\n          break;\n        default:\n        // pass\n      }\n    }\n\n    function reportUnusedFields() {\n      // Report all unused state fields.\n      classInfo.stateFields.forEach((node) => {\n        const name = getName(node.key);\n        if (!classInfo.usedStateFields.has(name)) {\n          report(context, messages.unusedStateField, 'unusedStateField', {\n            node,\n            data: {\n              name,\n            },\n          });\n        }\n      });\n    }\n\n    function handleES6ComponentEnter(node) {\n      if (componentUtil.isES6Component(node, context)) {\n        classInfo = getInitialClassInfo();\n      }\n    }\n\n    function handleES6ComponentExit() {\n      if (!classInfo) {\n        return;\n      }\n      reportUnusedFields();\n      classInfo = null;\n    }\n\n    function isGDSFP(node) {\n      const name = getName(node.key);\n      if (\n        !node.static\n        || name !== 'getDerivedStateFromProps'\n        || !node.value\n        || !node.value.params\n        || node.value.params.length < 2 // no `state` argument\n      ) {\n        return false;\n      }\n      return true;\n    }\n\n    return {\n      ClassDeclaration: handleES6ComponentEnter,\n\n      'ClassDeclaration:exit': handleES6ComponentExit,\n\n      ClassExpression: handleES6ComponentEnter,\n\n      'ClassExpression:exit': handleES6ComponentExit,\n\n      ObjectExpression(node) {\n        if (componentUtil.isES5Component(node, context)) {\n          classInfo = getInitialClassInfo();\n        }\n      },\n\n      'ObjectExpression:exit'(node) {\n        if (!classInfo) {\n          return;\n        }\n\n        if (componentUtil.isES5Component(node, context)) {\n          reportUnusedFields();\n          classInfo = null;\n        }\n      },\n\n      CallExpression(node) {\n        if (!classInfo) {\n          return;\n        }\n\n        const unwrappedNode = astUtil.unwrapTSAsExpression(node);\n        const unwrappedArgumentNode = astUtil.unwrapTSAsExpression(unwrappedNode.arguments[0]);\n\n        // If we're looking at a `this.setState({})` invocation, record all the\n        // properties as state fields.\n        if (\n          isSetStateCall(unwrappedNode)\n          && unwrappedNode.arguments.length > 0\n          && unwrappedArgumentNode.type === 'ObjectExpression'\n        ) {\n          addStateFields(unwrappedArgumentNode);\n        } else if (\n          isSetStateCall(unwrappedNode)\n          && unwrappedNode.arguments.length > 0\n          && unwrappedArgumentNode.type === 'ArrowFunctionExpression'\n        ) {\n          const unwrappedBodyNode = astUtil.unwrapTSAsExpression(unwrappedArgumentNode.body);\n\n          if (unwrappedBodyNode.type === 'ObjectExpression') {\n            addStateFields(unwrappedBodyNode);\n          }\n          if (unwrappedArgumentNode.params.length > 0 && classInfo.aliases) {\n            const firstParam = unwrappedArgumentNode.params[0];\n            if (firstParam.type === 'ObjectPattern') {\n              handleStateDestructuring(firstParam);\n            } else {\n              classInfo.aliases.add(getName(firstParam));\n            }\n          }\n        }\n      },\n\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!classInfo) {\n          return;\n        }\n        // If we see state being assigned as a class property using an object\n        // expression, record all the fields of that object as state fields.\n        const unwrappedValueNode = astUtil.unwrapTSAsExpression(node.value);\n\n        const name = getName(node.key);\n        if (\n          name === 'state'\n          && !node.static\n          && unwrappedValueNode\n          && unwrappedValueNode.type === 'ObjectExpression'\n        ) {\n          addStateFields(unwrappedValueNode);\n        }\n\n        if (\n          !node.static\n          && unwrappedValueNode\n          && unwrappedValueNode.type === 'ArrowFunctionExpression'\n        ) {\n          // Create a new set for this.state aliases local to this method.\n          classInfo.aliases = new Set();\n        }\n      },\n\n      'ClassProperty:exit'(node) {\n        if (\n          classInfo\n          && !node.static\n          && node.value\n          && node.value.type === 'ArrowFunctionExpression'\n        ) {\n          // Forget our set of local aliases.\n          classInfo.aliases = null;\n        }\n      },\n\n      'PropertyDefinition, ClassProperty'(node) {\n        if (!isGDSFP(node)) {\n          return;\n        }\n\n        const childScope = getScope(context, node).childScopes.find((x) => x.block === node.value);\n        if (!childScope) {\n          return;\n        }\n        const scope = childScope.variableScope.childScopes.find((x) => x.block === node.value);\n        const stateArg = node.value.params[1]; // probably \"state\"\n        if (!scope || !scope.variables) {\n          return;\n        }\n        const argVar = scope.variables.find((x) => x.name === stateArg.name);\n\n        if (argVar) {\n          const stateRefs = argVar.references;\n\n          stateRefs.forEach((ref) => {\n            const identifier = ref.identifier;\n            if (identifier && identifier.parent && identifier.parent.type === 'MemberExpression') {\n              addUsedStateField(identifier.parent.property);\n            }\n          });\n        }\n      },\n\n      'PropertyDefinition:exit'(node) {\n        if (\n          classInfo\n          && !node.static\n          && node.value\n          && node.value.type === 'ArrowFunctionExpression'\n          && !isGDSFP(node)\n        ) {\n          // Forget our set of local aliases.\n          classInfo.aliases = null;\n        }\n      },\n\n      MethodDefinition() {\n        if (!classInfo) {\n          return;\n        }\n        // Create a new set for this.state aliases local to this method.\n        classInfo.aliases = new Set();\n      },\n\n      'MethodDefinition:exit'() {\n        if (!classInfo) {\n          return;\n        }\n        // Forget our set of local aliases.\n        classInfo.aliases = null;\n      },\n\n      FunctionExpression(node) {\n        if (!classInfo) {\n          return;\n        }\n\n        const parent = node.parent;\n        if (!componentUtil.isES5Component(parent.parent, context)) {\n          return;\n        }\n\n        if (\n          'key' in parent\n          && 'name' in parent.key\n          && parent.key.name === 'getInitialState'\n        ) {\n          const body = node.body.body;\n          const lastBodyNode = body[body.length - 1];\n\n          if (\n            lastBodyNode.type === 'ReturnStatement'\n            && lastBodyNode.argument.type === 'ObjectExpression'\n          ) {\n            addStateFields(lastBodyNode.argument);\n          }\n        } else {\n          // Create a new set for this.state aliases local to this method.\n          classInfo.aliases = new Set();\n        }\n      },\n\n      AssignmentExpression(node) {\n        if (!classInfo) {\n          return;\n        }\n\n        const unwrappedLeft = astUtil.unwrapTSAsExpression(node.left);\n        const unwrappedRight = astUtil.unwrapTSAsExpression(node.right);\n\n        // Check for assignments like `this.state = {}`\n        if (\n          unwrappedLeft.type === 'MemberExpression'\n          && isThisExpression(unwrappedLeft.object)\n          && getName(unwrappedLeft.property) === 'state'\n          && unwrappedRight.type === 'ObjectExpression'\n        ) {\n          // Find the nearest function expression containing this assignment.\n          /** @type {import('eslint').Rule.Node} */\n          let fn = node;\n          while (fn.type !== 'FunctionExpression' && fn.parent) {\n            fn = fn.parent;\n          }\n          // If the nearest containing function is the constructor, then we want\n          // to record all the assigned properties as state fields.\n          if (\n            fn.parent\n            && fn.parent.type === 'MethodDefinition'\n            && fn.parent.kind === 'constructor'\n          ) {\n            addStateFields(unwrappedRight);\n          }\n        } else {\n          // Check for assignments like `alias = this.state` and record the alias.\n          handleAssignment(unwrappedLeft, unwrappedRight);\n        }\n      },\n\n      VariableDeclarator(node) {\n        if (!classInfo || !node.init) {\n          return;\n        }\n        handleAssignment(node.id, node.init);\n      },\n\n      'MemberExpression, OptionalMemberExpression'(node) {\n        if (!classInfo) {\n          return;\n        }\n        if (isStateReference(astUtil.unwrapTSAsExpression(node.object))) {\n          // If we see this.state[foo] access, give up.\n          if (node.computed && node.property.type !== 'Literal') {\n            classInfo = null;\n            return;\n          }\n          // Otherwise, record that we saw this property being accessed.\n          addUsedStateField(node.property);\n        // If we see a `this.state` access in a CallExpression, give up.\n        } else if (isStateReference(node) && astUtil.isCallExpression(node.parent)) {\n          classInfo = null;\n        }\n      },\n\n      JSXSpreadAttribute(node) {\n        if (classInfo && isStateReference(node.argument)) {\n          classInfo = null;\n        }\n      },\n\n      'ExperimentalSpreadProperty, SpreadElement'(node) {\n        if (classInfo && isStateReference(node.argument)) {\n          classInfo = null;\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/no-will-update-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentWillUpdate\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst makeNoMethodSetStateRule = require('../util/makeNoMethodSetStateRule');\nconst testReactVersion = require('../util/version').testReactVersion;\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = makeNoMethodSetStateRule(\n  'componentWillUpdate',\n  (context) => testReactVersion(context, '>= 16.3.0')\n);\n"
  },
  {
    "path": "lib/rules/prefer-es6-class.js",
    "content": "/**\n * @fileoverview Enforce ES5 or ES6 class for React Components\n * @author Dan Hamilton\n */\n\n'use strict';\n\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  shouldUseES6Class: 'Component should use es6 class instead of createClass',\n  shouldUseCreateClass: 'Component should use createClass instead of es6 class',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce ES5 or ES6 class for React Components',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('prefer-es6-class'),\n    },\n\n    messages,\n\n    schema: [{\n      enum: ['always', 'never'],\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || 'always';\n\n    return {\n      ObjectExpression(node) {\n        if (componentUtil.isES5Component(node, context) && configuration === 'always') {\n          report(context, messages.shouldUseES6Class, 'shouldUseES6Class', {\n            node,\n          });\n        }\n      },\n      ClassDeclaration(node) {\n        if (componentUtil.isES6Component(node, context) && configuration === 'never') {\n          report(context, messages.shouldUseCreateClass, 'shouldUseCreateClass', {\n            node,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/prefer-exact-props.js",
    "content": "/**\n * @fileoverview Prefer exact proptype definitions\n */\n\n'use strict';\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst propsUtil = require('../util/props');\nconst propWrapperUtil = require('../util/propWrapper');\nconst variableUtil = require('../util/variable');\nconst report = require('../util/report');\nconst getText = require('../util/eslint').getText;\n\n// -----------------------------------------------------------------------------\n// Rule Definition\n// -----------------------------------------------------------------------------\n\nconst messages = {\n  propTypes: 'Component propTypes should be exact by using {{exactPropWrappers}}.',\n  flow: 'Component flow props should be set with exact objects.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Prefer exact proptype definitions',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('prefer-exact-props'),\n    },\n    messages,\n    schema: [],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const typeAliases = {};\n    const exactWrappers = propWrapperUtil.getExactPropWrapperFunctions(context);\n\n    function getPropTypesErrorMessage() {\n      const formattedWrappers = propWrapperUtil.formatPropWrapperFunctions(exactWrappers);\n      const message = exactWrappers.size > 1 ? `one of ${formattedWrappers}` : formattedWrappers;\n      return { exactPropWrappers: message };\n    }\n\n    function isNonExactObjectTypeAnnotation(node) {\n      return (\n        node\n        && node.type === 'ObjectTypeAnnotation'\n        && node.properties.length > 0\n        && !node.exact\n      );\n    }\n\n    function hasNonExactObjectTypeAnnotation(node) {\n      const typeAnnotation = node.typeAnnotation;\n      return (\n        typeAnnotation\n        && typeAnnotation.typeAnnotation\n        && isNonExactObjectTypeAnnotation(typeAnnotation.typeAnnotation)\n      );\n    }\n\n    function hasGenericTypeAnnotation(node) {\n      const typeAnnotation = node.typeAnnotation;\n      return (\n        typeAnnotation\n        && typeAnnotation.typeAnnotation\n        && typeAnnotation.typeAnnotation.type === 'GenericTypeAnnotation'\n      );\n    }\n\n    function isNonEmptyObjectExpression(node) {\n      return (\n        node\n        && node.type === 'ObjectExpression'\n        && node.properties.length > 0\n      );\n    }\n\n    function isNonExactPropWrapperFunction(node) {\n      return (\n        astUtil.isCallExpression(node)\n        && !propWrapperUtil.isExactPropWrapperFunction(context, getText(context, node.callee))\n      );\n    }\n\n    function reportPropTypesError(node) {\n      report(context, messages.propTypes, 'propTypes', {\n        node,\n        data: getPropTypesErrorMessage(),\n      });\n    }\n\n    function reportFlowError(node) {\n      report(context, messages.flow, 'flow', {\n        node,\n      });\n    }\n\n    return {\n      TypeAlias(node) {\n        // working around an issue with eslint@3 and babel-eslint not finding the TypeAlias in scope\n        typeAliases[node.id.name] = node;\n      },\n\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!propsUtil.isPropTypesDeclaration(node)) {\n          return;\n        }\n\n        if (hasNonExactObjectTypeAnnotation(node)) {\n          reportFlowError(node);\n        } else if (exactWrappers.size > 0 && isNonEmptyObjectExpression(node.value)) {\n          reportPropTypesError(node);\n        } else if (exactWrappers.size > 0 && isNonExactPropWrapperFunction(node.value)) {\n          reportPropTypesError(node);\n        }\n      },\n\n      Identifier(node) {\n        if (!utils.getStatelessComponent(node.parent)) {\n          return;\n        }\n\n        if (hasNonExactObjectTypeAnnotation(node)) {\n          reportFlowError(node);\n        } else if (hasGenericTypeAnnotation(node)) {\n          const identifier = node.typeAnnotation.typeAnnotation.id.name;\n          const typeAlias = typeAliases[identifier];\n          const propsDefinition = typeAlias ? typeAlias.right : null;\n          if (isNonExactObjectTypeAnnotation(propsDefinition)) {\n            reportFlowError(node);\n          }\n        }\n      },\n\n      MemberExpression(node) {\n        if (!propsUtil.isPropTypesDeclaration(node) || exactWrappers.size === 0) {\n          return;\n        }\n\n        const right = node.parent.right;\n        if (isNonEmptyObjectExpression(right)) {\n          reportPropTypesError(node);\n        } else if (isNonExactPropWrapperFunction(right)) {\n          reportPropTypesError(node);\n        } else if (right.type === 'Identifier') {\n          const identifier = right.name;\n          const propsDefinition = variableUtil.findVariableByName(context, node, identifier);\n          if (isNonEmptyObjectExpression(propsDefinition)) {\n            reportPropTypesError(node);\n          } else if (isNonExactPropWrapperFunction(propsDefinition)) {\n            reportPropTypesError(node);\n          }\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/prefer-read-only-props.js",
    "content": "/**\n * @fileoverview Require component props to be typed as read-only.\n * @author Luke Zapart\n */\n\n'use strict';\n\nconst flatMap = require('array.prototype.flatmap');\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\nfunction isFlowPropertyType(node) {\n  return node.type === 'ObjectTypeProperty';\n}\n\nfunction isTypescriptPropertyType(node) {\n  return node.type === 'TSPropertySignature';\n}\n\nfunction isCovariant(node) {\n  return (node.variance && node.variance.kind === 'plus')\n    || (\n      node.parent\n      && node.parent.parent\n      && node.parent.parent.parent\n      && node.parent.parent.parent.id\n      && node.parent.parent.parent.id.name === '$ReadOnly'\n    );\n}\n\nfunction isReadonly(node) {\n  return (\n    node.typeAnnotation\n    && node.typeAnnotation.parent\n    && node.typeAnnotation.parent.readonly\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  readOnlyProp: 'Prop \\'{{name}}\\' should be read-only.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce that props are read-only',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('prefer-read-only-props'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [],\n  },\n\n  create: Components.detect((context, components) => {\n    function reportReadOnlyProp(prop, propName, fixer) {\n      report(context, messages.readOnlyProp, 'readOnlyProp', {\n        node: prop.node,\n        data: {\n          name: propName,\n        },\n        fix: fixer,\n      });\n    }\n\n    return {\n      'Program:exit'() {\n        flatMap(\n          values(components.list()),\n          (component) => component.declaredPropTypes || []\n        ).forEach((declaredPropTypes) => {\n          Object.keys(declaredPropTypes).forEach((propName) => {\n            const prop = declaredPropTypes[propName];\n            if (!prop.node) {\n              return;\n            }\n\n            if (isFlowPropertyType(prop.node)) {\n              if (!isCovariant(prop.node)) {\n                reportReadOnlyProp(prop, propName, (fixer) => {\n                  if (!prop.node.variance) {\n                    // Insert covariance\n                    return fixer.insertTextBefore(prop.node, '+');\n                  }\n\n                  // Replace contravariance with covariance\n                  return fixer.replaceText(prop.node.variance, '+');\n                });\n              }\n\n              return;\n            }\n\n            if (isTypescriptPropertyType(prop.node)) {\n              if (!isReadonly(prop.node)) {\n                reportReadOnlyProp(prop, propName, (fixer) => (\n                  fixer.insertTextBefore(prop.node, 'readonly ')\n                ));\n              }\n            }\n          });\n        });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/prefer-stateless-function.js",
    "content": "/**\n * @fileoverview Enforce stateless components to be written as a pure function\n * @author Yannick Croissant\n * @author Alberto Rodríguez\n * @copyright 2015 Alberto Rodríguez. All rights reserved.\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst testReactVersion = require('../util/version').testReactVersion;\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getScope = eslintUtil.getScope;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  componentShouldBePure: 'Component should be written as a pure function',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce stateless components to be written as a pure function',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('prefer-stateless-function'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignorePureComponents: {\n          default: false,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    const configuration = context.options[0] || {};\n    const ignorePureComponents = configuration.ignorePureComponents || false;\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    /**\n     * Checks whether a given array of statements is a single call of `super`.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode[]} body - An array of statements to check.\n     * @returns {boolean} `true` if the body is a single call of `super`.\n     */\n    function isSingleSuperCall(body) {\n      return (\n        body.length === 1\n        && body[0].type === 'ExpressionStatement'\n        && astUtil.isCallExpression(body[0].expression)\n        && body[0].expression.callee.type === 'Super'\n      );\n    }\n\n    /**\n     * Checks whether a given node is a pattern which doesn't have any side effects.\n     * Default parameters and Destructuring parameters can have side effects.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode} node - A pattern node.\n     * @returns {boolean} `true` if the node doesn't have any side effects.\n     */\n    function isSimple(node) {\n      return node.type === 'Identifier' || node.type === 'RestElement';\n    }\n\n    /**\n     * Checks whether a given array of expressions is `...arguments` or not.\n     * `super(...arguments)` passes all arguments through.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode[]} superArgs - An array of expressions to check.\n     * @returns {boolean} `true` if the superArgs is `...arguments`.\n     */\n    function isSpreadArguments(superArgs) {\n      return (\n        superArgs.length === 1\n        && superArgs[0].type === 'SpreadElement'\n        && superArgs[0].argument.type === 'Identifier'\n        && superArgs[0].argument.name === 'arguments'\n      );\n    }\n\n    /**\n     * Checks whether given 2 nodes are identifiers which have the same name or not.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode} ctorParam - A node to check.\n     * @param {ASTNode} superArg - A node to check.\n     * @returns {boolean} `true` if the nodes are identifiers which have the same\n     *      name.\n     */\n    function isValidIdentifierPair(ctorParam, superArg) {\n      return (\n        ctorParam.type === 'Identifier'\n        && superArg.type === 'Identifier'\n        && ctorParam.name === superArg.name\n      );\n    }\n\n    /**\n     * Checks whether given 2 nodes are a rest/spread pair which has the same values.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode} ctorParam - A node to check.\n     * @param {ASTNode} superArg - A node to check.\n     * @returns {boolean} `true` if the nodes are a rest/spread pair which has the\n     *      same values.\n     */\n    function isValidRestSpreadPair(ctorParam, superArg) {\n      return (\n        ctorParam.type === 'RestElement'\n        && superArg.type === 'SpreadElement'\n        && isValidIdentifierPair(ctorParam.argument, superArg.argument)\n      );\n    }\n\n    /**\n     * Checks whether given 2 nodes have the same value or not.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode} ctorParam - A node to check.\n     * @param {ASTNode} superArg - A node to check.\n     * @returns {boolean} `true` if the nodes have the same value or not.\n     */\n    function isValidPair(ctorParam, superArg) {\n      return (\n        isValidIdentifierPair(ctorParam, superArg)\n        || isValidRestSpreadPair(ctorParam, superArg)\n      );\n    }\n\n    /**\n     * Checks whether the parameters of a constructor and the arguments of `super()`\n     * have the same values or not.\n     * @see eslint no-useless-constructor rule\n     * @param {ASTNode[]} ctorParams - The parameters of a constructor to check.\n     * @param {ASTNode} superArgs - The arguments of `super()` to check.\n     * @returns {boolean} `true` if those have the same values.\n     */\n    function isPassingThrough(ctorParams, superArgs) {\n      if (ctorParams.length !== superArgs.length) {\n        return false;\n      }\n\n      for (let i = 0; i < ctorParams.length; ++i) {\n        if (!isValidPair(ctorParams[i], superArgs[i])) {\n          return false;\n        }\n      }\n\n      return true;\n    }\n\n    /**\n     * Checks whether the constructor body is a redundant super call.\n     * @see eslint no-useless-constructor rule\n     * @param {Array} body - constructor body content.\n     * @param {Array} ctorParams - The params to check against super call.\n     * @returns {boolean} true if the constructor body is redundant\n     */\n    function isRedundantSuperCall(body, ctorParams) {\n      return (\n        isSingleSuperCall(body)\n        && ctorParams.every(isSimple)\n        && (\n          isSpreadArguments(body[0].expression.arguments)\n          || isPassingThrough(ctorParams, body[0].expression.arguments)\n        )\n      );\n    }\n\n    /**\n     * Check if a given AST node have any other properties the ones available in stateless components\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if the node has at least one other property, false if not.\n     */\n    function hasOtherProperties(node) {\n      const properties = astUtil.getComponentProperties(node);\n      return properties.some((property) => {\n        const name = astUtil.getPropertyName(property);\n        const isDisplayName = name === 'displayName';\n        const isPropTypes = name === 'propTypes' || ((name === 'props') && property.typeAnnotation);\n        const contextTypes = name === 'contextTypes';\n        const defaultProps = name === 'defaultProps';\n        const isUselessConstructor = property.kind === 'constructor'\n          && !!property.value.body\n          && isRedundantSuperCall(property.value.body.body, property.value.params);\n        const isRender = name === 'render';\n        return !isDisplayName && !isPropTypes && !contextTypes && !defaultProps && !isUselessConstructor && !isRender;\n      });\n    }\n\n    /**\n     * Mark component as pure as declared\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markSCUAsDeclared(node) {\n      components.set(node, {\n        hasSCU: true,\n      });\n    }\n\n    /**\n     * Mark childContextTypes as declared\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markChildContextTypesAsDeclared(node) {\n      components.set(node, {\n        hasChildContextTypes: true,\n      });\n    }\n\n    /**\n     * Mark a setState as used\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markThisAsUsed(node) {\n      components.set(node, {\n        useThis: true,\n      });\n    }\n\n    /**\n     * Mark a props or context as used\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markPropsOrContextAsUsed(node) {\n      components.set(node, {\n        usePropsOrContext: true,\n      });\n    }\n\n    /**\n     * Mark a ref as used\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markRefAsUsed(node) {\n      components.set(node, {\n        useRef: true,\n      });\n    }\n\n    /**\n     * Mark return as invalid\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markReturnAsInvalid(node) {\n      components.set(node, {\n        invalidReturn: true,\n      });\n    }\n\n    /**\n     * Mark a ClassDeclaration as having used decorators\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markDecoratorsAsUsed(node) {\n      components.set(node, {\n        useDecorators: true,\n      });\n    }\n\n    function visitClass(node) {\n      if (ignorePureComponents && componentUtil.isPureComponent(node, context)) {\n        markSCUAsDeclared(node);\n      }\n\n      if (node.decorators && node.decorators.length) {\n        markDecoratorsAsUsed(node);\n      }\n    }\n\n    return {\n      ClassDeclaration: visitClass,\n      ClassExpression: visitClass,\n\n      // Mark `this` destructuring as a usage of `this`\n      VariableDeclarator(node) {\n        // Ignore destructuring on other than `this`\n        if (!node.id || node.id.type !== 'ObjectPattern' || !node.init || node.init.type !== 'ThisExpression') {\n          return;\n        }\n        // Ignore `props` and `context`\n        const useThis = node.id.properties.some((property) => {\n          const name = astUtil.getPropertyName(property);\n          return name !== 'props' && name !== 'context';\n        });\n        if (!useThis) {\n          markPropsOrContextAsUsed(node);\n          return;\n        }\n        markThisAsUsed(node);\n      },\n\n      // Mark `this` usage\n      MemberExpression(node) {\n        if (node.object.type !== 'ThisExpression') {\n          if (node.property && node.property.name === 'childContextTypes') {\n            const component = utils.getRelatedComponent(node);\n            if (!component) {\n              return;\n            }\n            markChildContextTypesAsDeclared(component.node);\n          }\n          return;\n        // Ignore calls to `this.props` and `this.context`\n        }\n        if (\n          (node.property.name || node.property.value) === 'props'\n          || (node.property.name || node.property.value) === 'context'\n        ) {\n          markPropsOrContextAsUsed(node);\n          return;\n        }\n        markThisAsUsed(node);\n      },\n\n      // Mark `ref` usage\n      JSXAttribute(node) {\n        const name = getText(context, node.name);\n        if (name !== 'ref') {\n          return;\n        }\n        markRefAsUsed(node);\n      },\n\n      // Mark `render` that do not return some JSX\n      ReturnStatement(node) {\n        let blockNode;\n        let scope = getScope(context, node);\n        while (scope) {\n          blockNode = scope.block && scope.block.parent;\n          if (blockNode && (blockNode.type === 'MethodDefinition' || blockNode.type === 'Property')) {\n            break;\n          }\n          scope = scope.upper;\n        }\n        const isRender = blockNode\n          && blockNode.key\n          && blockNode.key.name === 'render';\n        const allowNull = testReactVersion(context, '>= 15.0.0'); // Stateless components can return null since React 15\n        const isReturningJSX = utils.isReturningJSX(node, !allowNull);\n        const isReturningNull = node.argument && (node.argument.value === null || node.argument.value === false);\n        if (\n          !isRender\n          || (allowNull && (isReturningJSX || isReturningNull))\n          || (!allowNull && isReturningJSX)\n        ) {\n          return;\n        }\n        markReturnAsInvalid(node);\n      },\n\n      'Program:exit'() {\n        const list = components.list();\n        values(list)\n          .filter((component) => (\n            !hasOtherProperties(component.node)\n            && !component.useThis\n            && !component.useRef\n            && !component.invalidReturn\n            && !component.hasChildContextTypes\n            && !component.useDecorators\n            && !component.hasSCU\n            && (\n              componentUtil.isES5Component(component.node, context)\n              || componentUtil.isES6Component(component.node, context)\n            )\n          ))\n          .forEach((component) => {\n            report(context, messages.componentShouldBePure, 'componentShouldBePure', {\n              node: component.node,\n            });\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/prop-types.js",
    "content": "/**\n * @fileoverview Prevent missing props validation in a React component definition\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// As for exceptions for props.children or props.className (and alike) look at\n// https://github.com/jsx-eslint/eslint-plugin-react/issues/7\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  missingPropType: '\\'{{name}}\\' is missing in props validation',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow missing props validation in a React component definition',\n      category: 'Best Practices',\n      recommended: true,\n      url: docsUrl('prop-types'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignore: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        customValidators: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        skipUndeclared: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    const configuration = context.options[0] || {};\n    const ignored = configuration.ignore || [];\n    const skipUndeclared = configuration.skipUndeclared || false;\n\n    /**\n     * Checks if the prop is ignored\n     * @param {string} name Name of the prop to check.\n     * @returns {boolean} True if the prop is ignored, false if not.\n     */\n    function isIgnored(name) {\n      return ignored.indexOf(name) !== -1;\n    }\n\n    /**\n     * Checks if the component must be validated\n     * @param {Object} component The component to process\n     * @returns {boolean} True if the component must be validated, false if not.\n     */\n    function mustBeValidated(component) {\n      const isSkippedByConfig = skipUndeclared && typeof component.declaredPropTypes === 'undefined';\n      return !!(\n        component\n        && component.usedPropTypes\n        && !component.ignorePropsValidation\n        && !isSkippedByConfig\n      );\n    }\n\n    /**\n     * Internal: Checks if the prop is declared\n     * @param {Object} declaredPropTypes Description of propTypes declared in the current component\n     * @param {string[]} keyList Dot separated name of the prop to check.\n     * @returns {boolean} True if the prop is declared, false if not.\n     */\n    function internalIsDeclaredInComponent(declaredPropTypes, keyList) {\n      for (let i = 0, j = keyList.length; i < j; i++) {\n        const key = keyList[i];\n        const propType = (\n          declaredPropTypes && (\n            // Check if this key is declared\n            (declaredPropTypes[key] // If not, check if this type accepts any key\n            || declaredPropTypes.__ANY_KEY__) // eslint-disable-line no-underscore-dangle\n          )\n        );\n\n        if (!propType) {\n          // If it's a computed property, we can't make any further analysis, but is valid\n          return key === '__COMPUTED_PROP__';\n        }\n        if (typeof propType === 'object' && !propType.type) {\n          return true;\n        }\n        // Consider every children as declared\n        if (propType.children === true || propType.containsUnresolvedSpread || propType.containsIndexers) {\n          return true;\n        }\n        if (propType.acceptedProperties) {\n          return key in propType.acceptedProperties;\n        }\n        if (propType.type === 'union') {\n          // If we fall in this case, we know there is at least one complex type in the union\n          if (i + 1 >= j) {\n            // this is the last key, accept everything\n            return true;\n          }\n          // non trivial, check all of them\n          const unionTypes = propType.children;\n          const unionPropType = {};\n          for (let k = 0, z = unionTypes.length; k < z; k++) {\n            unionPropType[key] = unionTypes[k];\n            const isValid = internalIsDeclaredInComponent(\n              unionPropType,\n              keyList.slice(i)\n            );\n            if (isValid) {\n              return true;\n            }\n          }\n\n          // every possible union were invalid\n          return false;\n        }\n        declaredPropTypes = propType.children;\n      }\n      return true;\n    }\n\n    /**\n     * Checks if the prop is declared\n     * @param {ASTNode} node The AST node being checked.\n     * @param {string[]} names List of names of the prop to check.\n     * @returns {boolean} True if the prop is declared, false if not.\n     */\n    function isDeclaredInComponent(node, names) {\n      while (node) {\n        const component = components.get(node);\n\n        const isDeclared = component && component.confidence >= 2\n          && internalIsDeclaredInComponent(component.declaredPropTypes || {}, names);\n\n        if (isDeclared) {\n          return true;\n        }\n\n        node = node.parent;\n      }\n      return false;\n    }\n\n    /**\n     * Reports undeclared proptypes for a given component\n     * @param {Object} component The component to process\n     */\n    function reportUndeclaredPropTypes(component) {\n      const undeclareds = component.usedPropTypes.filter((propType) => (\n        propType.node\n        && !isIgnored(propType.allNames[0])\n        && !isDeclaredInComponent(component.node, propType.allNames)\n      ));\n      undeclareds.forEach((propType) => {\n        report(context, messages.missingPropType, 'missingPropType', {\n          node: propType.node,\n          data: {\n            name: propType.allNames.join('.').replace(/\\.__COMPUTED_PROP__/g, '[]'),\n          },\n        });\n      });\n    }\n\n    /**\n     * @param {Object} component The current component to process\n     * @param {Array} list The all components to process\n     * @returns {boolean} True if the component is nested False if not.\n     */\n    function checkNestedComponent(component, list) {\n      const componentIsMemo = component.node.callee && component.node.callee.name === 'memo';\n      const argumentIsForwardRef = component.node.arguments && component.node.arguments[0].callee && component.node.arguments[0].callee.name === 'forwardRef';\n      if (componentIsMemo && argumentIsForwardRef) {\n        const forwardComponent = list.find(\n          (innerComponent) => (\n            innerComponent.node.range[0] === component.node.arguments[0].range[0]\n            && innerComponent.node.range[0] === component.node.arguments[0].range[0]\n          ));\n\n        const isValidated = mustBeValidated(forwardComponent);\n        const isIgnorePropsValidation = forwardComponent.ignorePropsValidation;\n\n        return isIgnorePropsValidation || isValidated;\n      }\n    }\n\n    return {\n      'Program:exit'() {\n        const list = components.list();\n        // Report undeclared proptypes for all classes\n        values(list)\n          .filter((component) => mustBeValidated(component))\n          .forEach((component) => {\n            if (checkNestedComponent(component, values(list))) return;\n            reportUndeclaredPropTypes(component);\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/react-in-jsx-scope.js",
    "content": "/**\n * @fileoverview Prevent missing React when using JSX\n * @author Glen Mailer\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst pragmaUtil = require('../util/pragma');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// -----------------------------------------------------------------------------\n// Rule Definition\n// -----------------------------------------------------------------------------\n\nconst messages = {\n  notInScope: '\\'{{name}}\\' must be in scope when using JSX',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow missing React when using JSX',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('react-in-jsx-scope'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create(context) {\n    const pragma = pragmaUtil.getFromContext(context);\n\n    function checkIfReactIsInScope(node) {\n      if (variableUtil.getVariableFromContext(context, node, pragma)) {\n        return;\n      }\n      report(context, messages.notInScope, 'notInScope', {\n        node,\n        data: {\n          name: pragma,\n        },\n      });\n    }\n\n    return {\n      JSXOpeningElement: checkIfReactIsInScope,\n      JSXOpeningFragment: checkIfReactIsInScope,\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/require-default-props.js",
    "content": "/**\n * @fileOverview Enforce a defaultProps definition for every prop that is not a required prop.\n * @author Vitor Balocco\n */\n\n'use strict';\n\nconst entries = require('object.entries');\nconst values = require('object.values');\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noDefaultWithRequired: 'propType \"{{name}}\" is required and should not have a defaultProps declaration.',\n  shouldHaveDefault: 'propType \"{{name}}\" is not required, but has no corresponding defaultProps declaration.',\n  noDefaultPropsWithFunction: 'Don’t use defaultProps with function components.',\n  shouldAssignObjectDefault: 'propType \"{{name}}\" is not required, but has no corresponding default argument value.',\n  destructureInSignature: 'Must destructure props in the function signature to initialize an optional prop.',\n};\n\nfunction isPropWithNoDefaulVal(prop) {\n  if (prop.type === 'RestElement' || prop.type === 'ExperimentalRestProperty') {\n    return false;\n  }\n  return prop.value.type !== 'AssignmentPattern';\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce a defaultProps definition for every prop that is not a required prop',\n      category: 'Best Practices',\n      url: docsUrl('require-default-props'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        forbidDefaultForRequired: {\n          type: 'boolean',\n        },\n        classes: {\n          enum: ['defaultProps', 'ignore'],\n        },\n        functions: {\n          enum: ['defaultArguments', 'defaultProps', 'ignore'],\n        },\n        /**\n         * @deprecated\n         */\n        ignoreFunctionalComponents: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    const configuration = context.options[0] || {};\n    const forbidDefaultForRequired = configuration.forbidDefaultForRequired || false;\n    const classes = configuration.classes || 'defaultProps';\n    /**\n     * @todo\n     * - Remove ignoreFunctionalComponents\n     * - Change default to 'defaultArguments'\n     */\n    const functions = configuration.ignoreFunctionalComponents\n      ? 'ignore'\n      : configuration.functions || 'defaultProps';\n\n    /**\n     * Reports all propTypes passed in that don't have a defaultProps counterpart.\n     * @param  {Object[]} propTypes    List of propTypes to check.\n     * @param  {Object}   defaultProps Object of defaultProps to check. Keys are the props names.\n     * @return {void}\n     */\n    function reportPropTypesWithoutDefault(propTypes, defaultProps) {\n      entries(propTypes).forEach((propType) => {\n        const propName = propType[0];\n        const prop = propType[1];\n\n        if (!prop.node) {\n          return;\n        }\n        if (prop.isRequired) {\n          if (forbidDefaultForRequired && defaultProps[propName]) {\n            report(context, messages.noDefaultWithRequired, 'noDefaultWithRequired', {\n              node: prop.node,\n              data: { name: propName },\n            });\n          }\n          return;\n        }\n\n        if (defaultProps[propName]) {\n          return;\n        }\n\n        report(context, messages.shouldHaveDefault, 'shouldHaveDefault', {\n          node: prop.node,\n          data: { name: propName },\n        });\n      });\n    }\n\n    /**\n     * If functions option is 'defaultArguments', reports defaultProps is used and all params that doesn't initialized.\n     * @param {Object} componentNode Node of component.\n     * @param {Object[]} declaredPropTypes List of propTypes to check `isRequired`.\n     * @param {Object} defaultProps Object of defaultProps to check used.\n     */\n    function reportFunctionComponent(componentNode, declaredPropTypes, defaultProps) {\n      if (defaultProps) {\n        report(context, messages.noDefaultPropsWithFunction, 'noDefaultPropsWithFunction', {\n          node: componentNode,\n        });\n      }\n\n      const props = componentNode.params[0];\n      const propTypes = declaredPropTypes;\n\n      if (!props) {\n        return;\n      }\n\n      if (props.type === 'Identifier') {\n        const hasOptionalProp = values(propTypes).some((propType) => !propType.isRequired);\n        if (hasOptionalProp) {\n          report(context, messages.destructureInSignature, 'destructureInSignature', {\n            node: props,\n          });\n        }\n      } else if (props.type === 'ObjectPattern') {\n        // Filter required props with default value and report error\n        props.properties.filter((prop) => {\n          const propName = prop && prop.key && prop.key.name;\n          const isPropRequired = propTypes[propName] && propTypes[propName].isRequired;\n          return propTypes[propName] && isPropRequired && !isPropWithNoDefaulVal(prop);\n        }).forEach((prop) => {\n          report(context, messages.noDefaultWithRequired, 'noDefaultWithRequired', {\n            node: prop,\n            data: { name: prop.key.name },\n          });\n        });\n\n        // Filter non required props with no default value and report error\n        props.properties.filter((prop) => {\n          const propName = prop && prop.key && prop.key.name;\n          const isPropRequired = propTypes[propName] && propTypes[propName].isRequired;\n          return propTypes[propName] && !isPropRequired && isPropWithNoDefaulVal(prop);\n        }).forEach((prop) => {\n          report(context, messages.shouldAssignObjectDefault, 'shouldAssignObjectDefault', {\n            node: prop,\n            data: { name: prop.key.name },\n          });\n        });\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public API\n    // --------------------------------------------------------------------------\n\n    return {\n      'Program:exit'() {\n        const list = components.list();\n\n        values(list).filter((component) => {\n          if (functions === 'ignore' && astUtil.isFunctionLike(component.node)) {\n            return false;\n          }\n          if (classes === 'ignore' && astUtil.isClass(component.node)) {\n            return false;\n          }\n\n          // If this defaultProps is \"unresolved\", then we should ignore this component and not report\n          // any errors for it, to avoid false-positives with e.g. external defaultProps declarations or spread operators.\n          if (component.defaultProps === 'unresolved') {\n            return false;\n          }\n          return component.declaredPropTypes !== undefined;\n        }).forEach((component) => {\n          if (functions === 'defaultArguments' && astUtil.isFunctionLike(component.node)) {\n            reportFunctionComponent(\n              component.node,\n              component.declaredPropTypes,\n              component.defaultProps\n            );\n          } else {\n            reportPropTypesWithoutDefault(\n              component.declaredPropTypes,\n              component.defaultProps || {}\n            );\n          }\n        });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/require-optimization.js",
    "content": "/**\n * @fileoverview Enforce React components to have a shouldComponentUpdate method\n * @author Evgueni Naverniouk\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getScope = require('../util/eslint').getScope;\n\nconst messages = {\n  noShouldComponentUpdate: 'Component is not optimized. Please add a shouldComponentUpdate method.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce React components to have a shouldComponentUpdate method',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('require-optimization'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        allowDecorators: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    const configuration = context.options[0] || {};\n    const allowDecorators = configuration.allowDecorators || [];\n\n    /**\n     * Checks to see if our component is decorated by PureRenderMixin via reactMixin\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if node is decorated with a PureRenderMixin, false if not.\n     */\n    function hasPureRenderDecorator(node) {\n      if (node.decorators && node.decorators.length) {\n        for (let i = 0, l = node.decorators.length; i < l; i++) {\n          if (\n            node.decorators[i].expression\n            && node.decorators[i].expression.callee\n            && node.decorators[i].expression.callee.object\n            && node.decorators[i].expression.callee.object.name === 'reactMixin'\n            && node.decorators[i].expression.callee.property\n            && node.decorators[i].expression.callee.property.name === 'decorate'\n            && node.decorators[i].expression.arguments\n            && node.decorators[i].expression.arguments.length\n            && node.decorators[i].expression.arguments[0].name === 'PureRenderMixin'\n          ) {\n            return true;\n          }\n        }\n      }\n\n      return false;\n    }\n\n    /**\n     * Checks to see if our component is custom decorated\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if node is decorated name with a custom decorated, false if not.\n     */\n    function hasCustomDecorator(node) {\n      const allowLength = allowDecorators.length;\n\n      if (allowLength && node.decorators && node.decorators.length) {\n        for (let i = 0; i < allowLength; i++) {\n          for (let j = 0, l = node.decorators.length; j < l; j++) {\n            const expression = node.decorators[j].expression;\n            if (\n              expression\n              && expression.name === allowDecorators[i]\n            ) {\n              return true;\n            }\n          }\n        }\n      }\n\n      return false;\n    }\n\n    /**\n     * Checks if we are declaring a shouldComponentUpdate method\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if we are declaring a shouldComponentUpdate method, false if not.\n     */\n    function isSCUDeclared(node) {\n      return !!node && node.name === 'shouldComponentUpdate';\n    }\n\n    /**\n     * Checks if we are declaring a PureRenderMixin mixin\n     * @param {ASTNode} node The AST node being checked.\n     * @returns {boolean} True if we are declaring a PureRenderMixin method, false if not.\n     */\n    function isPureRenderDeclared(node) {\n      let hasPR = false;\n      if (node.value && node.value.elements) {\n        for (let i = 0, l = node.value.elements.length; i < l; i++) {\n          if (node.value.elements[i] && node.value.elements[i].name === 'PureRenderMixin') {\n            hasPR = true;\n            break;\n          }\n        }\n      }\n\n      return (\n        !!node\n        && node.key.name === 'mixins'\n        && hasPR\n      );\n    }\n\n    /**\n     * Mark shouldComponentUpdate as declared\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markSCUAsDeclared(node) {\n      components.set(node, {\n        hasSCU: true,\n      });\n    }\n\n    /**\n     * Reports missing optimization for a given component\n     * @param {Object} component The component to process\n     */\n    function reportMissingOptimization(component) {\n      report(context, messages.noShouldComponentUpdate, 'noShouldComponentUpdate', {\n        node: component.node,\n      });\n    }\n\n    /**\n     * Checks if we are declaring function in class\n     * @param {ASTNode} node\n     * @returns {boolean} True if we are declaring function in class, false if not.\n     */\n    function isFunctionInClass(node) {\n      let blockNode;\n      let scope = getScope(context, node);\n      while (scope) {\n        blockNode = scope.block;\n        if (blockNode && blockNode.type === 'ClassDeclaration') {\n          return true;\n        }\n        scope = scope.upper;\n      }\n\n      return false;\n    }\n\n    return {\n      ArrowFunctionExpression(node) {\n        // Skip if the function is declared in the class\n        if (isFunctionInClass(node)) {\n          return;\n        }\n        // Stateless Functional Components cannot be optimized (yet)\n        markSCUAsDeclared(node);\n      },\n\n      ClassDeclaration(node) {\n        if (!(\n          hasPureRenderDecorator(node)\n          || hasCustomDecorator(node)\n          || componentUtil.isPureComponent(node, context)\n        )) {\n          return;\n        }\n        markSCUAsDeclared(node);\n      },\n\n      FunctionDeclaration(node) {\n        // Skip if the function is declared in the class\n        if (isFunctionInClass(node)) {\n          return;\n        }\n        // Stateless Functional Components cannot be optimized (yet)\n        markSCUAsDeclared(node);\n      },\n\n      FunctionExpression(node) {\n        // Skip if the function is declared in the class\n        if (isFunctionInClass(node)) {\n          return;\n        }\n        // Stateless Functional Components cannot be optimized (yet)\n        markSCUAsDeclared(node);\n      },\n\n      MethodDefinition(node) {\n        if (!isSCUDeclared(node.key)) {\n          return;\n        }\n        markSCUAsDeclared(node);\n      },\n\n      ObjectExpression(node) {\n        // Search for the shouldComponentUpdate declaration\n        const found = node.properties.some((property) => (\n          property.key\n          && (isSCUDeclared(property.key) || isPureRenderDeclared(property))\n        ));\n        if (found) {\n          markSCUAsDeclared(node);\n        }\n      },\n\n      'Program:exit'() {\n        // Report missing shouldComponentUpdate for all components\n        values(components.list())\n          .filter((component) => !component.hasSCU)\n          .forEach((component) => {\n            reportMissingOptimization(component);\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/require-render-return.js",
    "content": "/**\n * @fileoverview Enforce ES5 or ES6 class for returning value in render function.\n * @author Mark Orel\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst Components = require('../util/Components');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst getAncestors = require('../util/eslint').getAncestors;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  noRenderReturn: 'Your render method should have a return statement',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce ES5 or ES6 class for returning value in render function',\n      category: 'Possible Errors',\n      recommended: true,\n      url: docsUrl('require-render-return'),\n    },\n\n    messages,\n\n    schema: [],\n  },\n\n  create: Components.detect((context, components) => {\n    /**\n     * Mark a return statement as present\n     * @param {ASTNode} node The AST node being checked.\n     */\n    function markReturnStatementPresent(node) {\n      components.set(node, {\n        hasReturnStatement: true,\n      });\n    }\n\n    /**\n     * Find render method in a given AST node\n     * @param {ASTNode} node The component to find render method.\n     * @returns {ASTNode} Method node if found, undefined if not.\n     */\n    function findRenderMethod(node) {\n      const properties = astUtil.getComponentProperties(node);\n      return properties\n        .filter((property) => astUtil.getPropertyName(property) === 'render' && property.value)\n        .find((property) => astUtil.isFunctionLikeExpression(property.value));\n    }\n\n    return {\n      ReturnStatement(node) {\n        const ancestors = getAncestors(context, node).reverse();\n        let depth = 0;\n        ancestors.forEach((ancestor) => {\n          if (/Function(Expression|Declaration)$/.test(ancestor.type)) {\n            depth += 1;\n          }\n          if (\n            /(MethodDefinition|Property|ClassProperty|PropertyDefinition)$/.test(ancestor.type)\n            && astUtil.getPropertyName(ancestor) === 'render'\n            && depth <= 1\n          ) {\n            markReturnStatementPresent(node);\n          }\n        });\n      },\n\n      ArrowFunctionExpression(node) {\n        if (node.expression === false || astUtil.getPropertyName(node.parent) !== 'render') {\n          return;\n        }\n        markReturnStatementPresent(node);\n      },\n\n      'Program:exit'() {\n        values(components.list())\n          .filter((component) => (\n            findRenderMethod(component.node)\n            && !component.hasReturnStatement\n            && (\n              componentUtil.isES5Component(component.node, context)\n              || componentUtil.isES6Component(component.node, context)\n            )\n          ))\n          .forEach((component) => {\n            report(context, messages.noRenderReturn, 'noRenderReturn', {\n              node: findRenderMethod(component.node),\n            });\n          });\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/self-closing-comp.js",
    "content": "/**\n * @fileoverview Prevent extra closing tags for components without children\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst docsUrl = require('../util/docsUrl');\nconst jsxUtil = require('../util/jsx');\nconst report = require('../util/report');\n\nconst optionDefaults = { component: true, html: true };\n\nfunction isComponent(node) {\n  return (\n    node.name\n    && (node.name.type === 'JSXIdentifier' || node.name.type === 'JSXMemberExpression')\n    && !jsxUtil.isDOMComponent(node)\n  );\n}\n\nfunction childrenIsEmpty(node) {\n  return node.parent.children.length === 0;\n}\n\nfunction childrenIsMultilineSpaces(node) {\n  const childrens = node.parent.children;\n\n  return (\n    childrens.length === 1\n    && (childrens[0].type === 'Literal' || childrens[0].type === 'JSXText')\n    && childrens[0].value.indexOf('\\n') !== -1\n    && childrens[0].value.replace(/(?!\\xA0)\\s/g, '') === ''\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  notSelfClosing: 'Empty components are self-closing',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow extra closing tags for components without children',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('self-closing-comp'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        component: {\n          default: optionDefaults.component,\n          type: 'boolean',\n        },\n        html: {\n          default: optionDefaults.html,\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    function isShouldBeSelfClosed(node) {\n      const configuration = Object.assign({}, optionDefaults, context.options[0]);\n      return (\n        (configuration.component && isComponent(node))\n        || (configuration.html && jsxUtil.isDOMComponent(node))\n      ) && !node.selfClosing && (childrenIsEmpty(node) || childrenIsMultilineSpaces(node));\n    }\n\n    return {\n      JSXOpeningElement(node) {\n        if (!isShouldBeSelfClosed(node)) {\n          return;\n        }\n        report(context, messages.notSelfClosing, 'notSelfClosing', {\n          node,\n          fix(fixer) {\n            // Represents the last character of the JSXOpeningElement, the '>' character\n            const openingElementEnding = node.range[1] - 1;\n            // Represents the last character of the JSXClosingElement, the '>' character\n            const closingElementEnding = node.parent.closingElement.range[1];\n\n            // Replace />.*<\\/.*>/ with '/>'\n            const range = [openingElementEnding, closingElementEnding];\n            return fixer.replaceTextRange(range, ' />');\n          },\n        });\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/sort-comp.js",
    "content": "/**\n * @fileoverview Enforce component methods order\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst has = require('hasown');\nconst entries = require('object.entries');\nconst values = require('object.values');\nconst arrayIncludes = require('array-includes');\n\nconst Components = require('../util/Components');\nconst astUtil = require('../util/ast');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\nconst defaultConfig = {\n  order: [\n    'static-methods',\n    'lifecycle',\n    'everything-else',\n    'render',\n  ],\n  groups: {\n    lifecycle: [\n      'displayName',\n      'propTypes',\n      'contextTypes',\n      'childContextTypes',\n      'mixins',\n      'statics',\n      'defaultProps',\n      'constructor',\n      'getDefaultProps',\n      'state',\n      'getInitialState',\n      'getChildContext',\n      'getDerivedStateFromProps',\n      'componentWillMount',\n      'UNSAFE_componentWillMount',\n      'componentDidMount',\n      'componentWillReceiveProps',\n      'UNSAFE_componentWillReceiveProps',\n      'shouldComponentUpdate',\n      'componentWillUpdate',\n      'UNSAFE_componentWillUpdate',\n      'getSnapshotBeforeUpdate',\n      'componentDidUpdate',\n      'componentDidCatch',\n      'componentWillUnmount',\n    ],\n  },\n};\n\n/**\n * Get the methods order from the default config and the user config\n * @param {Object} userConfig The user configuration.\n * @returns {Array} Methods order\n */\nfunction getMethodsOrder(userConfig) {\n  userConfig = userConfig || {};\n\n  const groups = Object.assign({}, defaultConfig.groups, userConfig.groups);\n  const order = userConfig.order || defaultConfig.order;\n\n  let config = [];\n  let entry;\n  for (let i = 0, j = order.length; i < j; i++) {\n    entry = order[i];\n    if (has(groups, entry)) {\n      config = config.concat(groups[entry]);\n    } else {\n      config.push(entry);\n    }\n  }\n\n  return config;\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  unsortedProps: '{{propA}} should be placed {{position}} {{propB}}',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce component methods order',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('sort-comp'),\n    },\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        order: {\n          type: 'array',\n          items: {\n            type: 'string',\n          },\n        },\n        groups: {\n          type: 'object',\n          patternProperties: {\n            '^.*$': {\n              type: 'array',\n              items: {\n                type: 'string',\n              },\n            },\n          },\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create: Components.detect((context, components) => {\n    /** @satisfies {Record<string, { node: ASTNode, score: number, closest: { distance: number, ref: { node: null | ASTNode, index: number } } }>} */\n    const errors = {};\n    const methodsOrder = getMethodsOrder(context.options[0]);\n\n    // --------------------------------------------------------------------------\n    // Public\n    // --------------------------------------------------------------------------\n\n    const regExpRegExp = /\\/(.*)\\/([gimsuy]*)/;\n\n    /**\n     * Get indexes of the matching patterns in methods order configuration\n     * @param {Object} method - Method metadata.\n     * @returns {Array} The matching patterns indexes. Return [Infinity] if there is no match.\n     */\n    function getRefPropIndexes(method) {\n      const methodGroupIndexes = [];\n\n      methodsOrder.forEach((currentGroup, groupIndex) => {\n        if (currentGroup === 'getters') {\n          if (method.getter) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'setters') {\n          if (method.setter) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'type-annotations') {\n          if (method.typeAnnotation) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'static-variables') {\n          if (method.staticVariable) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'static-methods') {\n          if (method.staticMethod) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'instance-variables') {\n          if (method.instanceVariable) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (currentGroup === 'instance-methods') {\n          if (method.instanceMethod) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else if (arrayIncludes([\n          'displayName',\n          'propTypes',\n          'contextTypes',\n          'childContextTypes',\n          'mixins',\n          'statics',\n          'defaultProps',\n          'constructor',\n          'getDefaultProps',\n          'state',\n          'getInitialState',\n          'getChildContext',\n          'getDerivedStateFromProps',\n          'componentWillMount',\n          'UNSAFE_componentWillMount',\n          'componentDidMount',\n          'componentWillReceiveProps',\n          'UNSAFE_componentWillReceiveProps',\n          'shouldComponentUpdate',\n          'componentWillUpdate',\n          'UNSAFE_componentWillUpdate',\n          'getSnapshotBeforeUpdate',\n          'componentDidUpdate',\n          'componentDidCatch',\n          'componentWillUnmount',\n          'render',\n        ], currentGroup)) {\n          if (currentGroup === method.name) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        } else {\n          // Is the group a regex?\n          const isRegExp = currentGroup.match(regExpRegExp);\n          if (isRegExp) {\n            const isMatching = new RegExp(isRegExp[1], isRegExp[2]).test(method.name);\n            if (isMatching) {\n              methodGroupIndexes.push(groupIndex);\n            }\n          } else if (currentGroup === method.name) {\n            methodGroupIndexes.push(groupIndex);\n          }\n        }\n      });\n\n      // No matching pattern, return 'everything-else' index\n      if (methodGroupIndexes.length === 0) {\n        const everythingElseIndex = methodsOrder.indexOf('everything-else');\n\n        if (everythingElseIndex !== -1) {\n          methodGroupIndexes.push(everythingElseIndex);\n        } else {\n          // No matching pattern and no 'everything-else' group\n          methodGroupIndexes.push(Infinity);\n        }\n      }\n\n      return methodGroupIndexes;\n    }\n\n    /**\n     * Get properties name\n     * @param {Object} node - Property.\n     * @returns {string} Property name.\n     */\n    function getPropertyName(node) {\n      if (node.kind === 'get') {\n        return 'getter functions';\n      }\n\n      if (node.kind === 'set') {\n        return 'setter functions';\n      }\n\n      return astUtil.getPropertyName(node);\n    }\n\n    /**\n     * Store a new error in the error list\n     * @param {Object} propA - Mispositioned property.\n     * @param {Object} propB - Reference property.\n     */\n    function storeError(propA, propB) {\n      // Initialize the error object if needed\n      if (!errors[propA.index]) {\n        errors[propA.index] = {\n          node: propA.node,\n          score: 0,\n          closest: {\n            distance: Infinity,\n            ref: {\n              node: null,\n              index: 0,\n            },\n          },\n        };\n      }\n      // Increment the prop score\n      errors[propA.index].score += 1;\n      // Stop here if we already have pushed another node at this position\n      if (getPropertyName(errors[propA.index].node) !== getPropertyName(propA.node)) {\n        return;\n      }\n      // Stop here if we already have a closer reference\n      if (Math.abs(propA.index - propB.index) > errors[propA.index].closest.distance) {\n        return;\n      }\n      // Update the closest reference\n      errors[propA.index].closest.distance = Math.abs(propA.index - propB.index);\n      errors[propA.index].closest.ref.node = propB.node;\n      errors[propA.index].closest.ref.index = propB.index;\n    }\n\n    /**\n     * Dedupe errors, only keep the ones with the highest score and delete the others\n     */\n    function dedupeErrors() {\n      entries(errors).forEach((entry) => {\n        const i = entry[0];\n        const error = entry[1];\n\n        const index = error.closest.ref.index;\n        if (errors[index]) {\n          if (error.score > errors[index].score) {\n            delete errors[index];\n          } else {\n            delete errors[i];\n          }\n        }\n      });\n    }\n\n    /**\n     * Report errors\n     */\n    function reportErrors() {\n      dedupeErrors();\n\n      entries(errors).forEach((entry) => {\n        const nodeA = entry[1].node;\n        const nodeB = entry[1].closest.ref.node;\n        const indexA = entry[0];\n        const indexB = entry[1].closest.ref.index;\n\n        report(context, messages.unsortedProps, 'unsortedProps', {\n          node: nodeA,\n          data: {\n            propA: getPropertyName(nodeA),\n            propB: getPropertyName(nodeB),\n            position: indexA < indexB ? 'before' : 'after',\n          },\n        });\n      });\n    }\n\n    /**\n     * Compare two properties and find out if they are in the right order\n     * @param {Array} propertiesInfos Array containing all the properties metadata.\n     * @param {Object} propA First property name and metadata\n     * @param {Object} propB Second property name.\n     * @returns {Object} Object containing a correct true/false flag and the correct indexes for the two properties.\n     */\n    function comparePropsOrder(propertiesInfos, propA, propB) {\n      let i;\n      let j;\n      let k;\n      let l;\n      let refIndexA;\n      let refIndexB;\n\n      // Get references indexes (the correct position) for given properties\n      const refIndexesA = getRefPropIndexes(propA);\n      const refIndexesB = getRefPropIndexes(propB);\n\n      // Get current indexes for given properties\n      const classIndexA = propertiesInfos.indexOf(propA);\n      const classIndexB = propertiesInfos.indexOf(propB);\n\n      // Loop around the references indexes for the 1st property\n      for (i = 0, j = refIndexesA.length; i < j; i++) {\n        refIndexA = refIndexesA[i];\n\n        // Loop around the properties for the 2nd property (for comparison)\n        for (k = 0, l = refIndexesB.length; k < l; k++) {\n          refIndexB = refIndexesB[k];\n\n          if (\n            // Comparing the same properties\n            refIndexA === refIndexB\n            // 1st property is placed before the 2nd one in reference and in current component\n            || ((refIndexA < refIndexB) && (classIndexA < classIndexB))\n            // 1st property is placed after the 2nd one in reference and in current component\n            || ((refIndexA > refIndexB) && (classIndexA > classIndexB))\n          ) {\n            return {\n              correct: true,\n              indexA: classIndexA,\n              indexB: classIndexB,\n            };\n          }\n        }\n      }\n\n      // We did not find any correct match between reference and current component\n      return {\n        correct: false,\n        indexA: refIndexA,\n        indexB: refIndexB,\n      };\n    }\n\n    /**\n     * Check properties order from a properties list and store the eventual errors\n     * @param {Array} properties Array containing all the properties.\n     */\n    function checkPropsOrder(properties) {\n      const propertiesInfos = properties.map((node) => ({\n        name: getPropertyName(node),\n        getter: node.kind === 'get',\n        setter: node.kind === 'set',\n        staticVariable: node.static\n          && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')\n          && (!node.value || !astUtil.isFunctionLikeExpression(node.value)),\n        staticMethod: node.static\n          && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition' || node.type === 'MethodDefinition')\n          && node.value\n          && (astUtil.isFunctionLikeExpression(node.value)),\n        instanceVariable: !node.static\n          && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')\n          && (!node.value || !astUtil.isFunctionLikeExpression(node.value)),\n        instanceMethod: !node.static\n          && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')\n          && node.value\n          && (astUtil.isFunctionLikeExpression(node.value)),\n        typeAnnotation: !!node.typeAnnotation && node.value === null,\n      }));\n\n      // Loop around the properties\n      propertiesInfos.forEach((propA, i) => {\n        // Loop around the properties a second time (for comparison)\n        propertiesInfos.forEach((propB, k) => {\n          if (i === k) {\n            return;\n          }\n\n          // Compare the properties order\n          const order = comparePropsOrder(propertiesInfos, propA, propB);\n\n          if (!order.correct) {\n            // Store an error if the order is incorrect\n            storeError({\n              node: properties[i],\n              index: order.indexA,\n            }, {\n              node: properties[k],\n              index: order.indexB,\n            });\n          }\n        });\n      });\n    }\n\n    return {\n      'Program:exit'() {\n        values(components.list()).forEach((component) => {\n          const properties = astUtil.getComponentProperties(component.node);\n          checkPropsOrder(properties);\n        });\n\n        reportErrors();\n      },\n    };\n  }),\n\n  defaultConfig,\n};\n"
  },
  {
    "path": "lib/rules/sort-default-props.js",
    "content": "/**\n * @fileoverview Enforce default props alphabetical sorting\n * @author Vladimir Kattsov\n * @deprecated\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getFirstTokens = eslintUtil.getFirstTokens;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  propsNotSorted: 'Default prop types declarations should be sorted alphabetically',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce defaultProps declarations alphabetical sorting',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('sort-default-props'),\n    },\n    // fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        ignoreCase: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const ignoreCase = configuration.ignoreCase || false;\n\n    /**\n     * Get properties name\n     * @param {Object} node - Property.\n     * @returns {string} Property name.\n     */\n    function getPropertyName(node) {\n      if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {\n        return node.key.name;\n      }\n      if (node.type === 'MemberExpression') {\n        return node.property.name;\n      // Special case for class properties\n      // (babel-eslint@5 does not expose property name so we have to rely on tokens)\n      }\n      if (node.type === 'ClassProperty') {\n        const tokens = getFirstTokens(context, node, 2);\n        return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;\n      }\n      return '';\n    }\n\n    /**\n     * Checks if the Identifier node passed in looks like a defaultProps declaration.\n     * @param   {ASTNode}  node The node to check. Must be an Identifier node.\n     * @returns {boolean}       `true` if the node is a defaultProps declaration, `false` if not\n     */\n    function isDefaultPropsDeclaration(node) {\n      const propName = getPropertyName(node);\n      return (propName === 'defaultProps' || propName === 'getDefaultProps');\n    }\n\n    function getKey(node) {\n      return getText(context, node.key || node.argument);\n    }\n\n    /**\n     * Find a variable by name in the current scope.\n     * @param  {ASTNode} node The node to look for.\n     * @param  {string} name Name of the variable to look for.\n     * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise.\n     */\n    function findVariableByName(node, name) {\n      const variable = variableUtil.getVariableFromContext(context, node, name);\n\n      if (!variable || !variable.defs[0] || !variable.defs[0].node) {\n        return null;\n      }\n\n      if (variable.defs[0].node.type === 'TypeAlias') {\n        return variable.defs[0].node.right;\n      }\n\n      return variable.defs[0].node.init;\n    }\n\n    /**\n     * Checks if defaultProps declarations are sorted\n     * @param {Array} declarations The array of AST nodes being checked.\n     * @returns {void}\n     */\n    function checkSorted(declarations) {\n      // function fix(fixer) {\n      //   return propTypesSortUtil.fixPropTypesSort(context, fixer, declarations, ignoreCase);\n      // }\n\n      declarations.reduce((prev, curr, idx, decls) => {\n        if (/Spread(?:Property|Element)$/.test(curr.type)) {\n          return decls[idx + 1];\n        }\n\n        let prevPropName = getKey(prev);\n        let currentPropName = getKey(curr);\n\n        if (ignoreCase) {\n          prevPropName = prevPropName.toLowerCase();\n          currentPropName = currentPropName.toLowerCase();\n        }\n\n        if (currentPropName < prevPropName) {\n          report(context, messages.propsNotSorted, 'propsNotSorted', {\n            node: curr,\n            // fix\n          });\n\n          return prev;\n        }\n\n        return curr;\n      }, declarations[0]);\n    }\n\n    function checkNode(node) {\n      if (!node) {\n        return;\n      }\n      if (node.type === 'ObjectExpression') {\n        checkSorted(node.properties);\n      } else if (node.type === 'Identifier') {\n        const propTypesObject = findVariableByName(node, node.name);\n        if (propTypesObject && propTypesObject.properties) {\n          checkSorted(propTypesObject.properties);\n        }\n      }\n    }\n\n    // --------------------------------------------------------------------------\n    // Public API\n    // --------------------------------------------------------------------------\n\n    return {\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!isDefaultPropsDeclaration(node)) {\n          return;\n        }\n\n        checkNode(node.value);\n      },\n\n      MemberExpression(node) {\n        if (!isDefaultPropsDeclaration(node)) {\n          return;\n        }\n\n        checkNode('right' in node.parent && node.parent.right);\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/sort-prop-types.js",
    "content": "/**\n * @fileoverview Enforce propTypes declarations alphabetical sorting\n */\n\n'use strict';\n\nconst astUtil = require('../util/ast');\nconst variableUtil = require('../util/variable');\nconst propsUtil = require('../util/props');\nconst docsUrl = require('../util/docsUrl');\nconst propWrapperUtil = require('../util/propWrapper');\nconst propTypesSortUtil = require('../util/propTypesSort');\nconst report = require('../util/report');\nconst eslintUtil = require('../util/eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  requiredPropsFirst: 'Required prop types must be listed before all other prop types',\n  callbackPropsLast: 'Callback prop types must be listed after all other prop types',\n  propsNotSorted: 'Prop types declarations should be sorted alphabetically',\n};\n\nfunction getKey(context, node) {\n  if (node.type === 'ObjectTypeProperty') {\n    return getSourceCode(context).getFirstToken(node).value;\n  }\n  if (node.key && node.key.value) {\n    return node.key.value;\n  }\n  return getText(context, node.key || node.argument);\n}\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce propTypes declarations alphabetical sorting',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('sort-prop-types'),\n    },\n    fixable: 'code',\n\n    messages,\n\n    schema: [{\n      type: 'object',\n      properties: {\n        requiredFirst: {\n          type: 'boolean',\n        },\n        callbacksLast: {\n          type: 'boolean',\n        },\n        ignoreCase: {\n          type: 'boolean',\n        },\n        // Whether alphabetical sorting should be enforced\n        noSortAlphabetically: {\n          type: 'boolean',\n        },\n        sortShapeProp: {\n          type: 'boolean',\n        },\n        checkTypes: {\n          type: 'boolean',\n        },\n      },\n      additionalProperties: false,\n    }],\n  },\n\n  create(context) {\n    const configuration = context.options[0] || {};\n    const requiredFirst = configuration.requiredFirst || false;\n    const callbacksLast = configuration.callbacksLast || false;\n    const ignoreCase = configuration.ignoreCase || false;\n    const noSortAlphabetically = configuration.noSortAlphabetically || false;\n    const sortShapeProp = configuration.sortShapeProp || false;\n    const checkTypes = configuration.checkTypes || false;\n\n    const typeAnnotations = new Map();\n\n    /**\n     * Checks if propTypes declarations are sorted\n     * @param {Array} declarations The array of AST nodes being checked.\n     * @returns {void}\n     */\n    function checkSorted(declarations) {\n      // Declarations will be `undefined` if the `shape` is not a literal. For\n      // example, if it is a propType imported from another file.\n      if (!declarations) {\n        return;\n      }\n\n      function fix(fixer) {\n        return propTypesSortUtil.fixPropTypesSort(\n          context,\n          fixer,\n          declarations,\n          ignoreCase,\n          requiredFirst,\n          callbacksLast,\n          noSortAlphabetically,\n          sortShapeProp,\n          checkTypes\n        );\n      }\n\n      const callbackPropsLastSeen = new WeakSet();\n      const requiredPropsFirstSeen = new WeakSet();\n      const propsNotSortedSeen = new WeakSet();\n\n      declarations.reduce((prev, curr, idx, decls) => {\n        if (curr.type === 'ExperimentalSpreadProperty' || curr.type === 'SpreadElement') {\n          return decls[idx + 1];\n        }\n\n        let prevPropName = getKey(context, prev);\n        let currentPropName = getKey(context, curr);\n        const previousIsRequired = propTypesSortUtil.isRequiredProp(prev);\n        const currentIsRequired = propTypesSortUtil.isRequiredProp(curr);\n        const previousIsCallback = propTypesSortUtil.isCallbackPropName(prevPropName);\n        const currentIsCallback = propTypesSortUtil.isCallbackPropName(currentPropName);\n\n        if (ignoreCase) {\n          prevPropName = String(prevPropName).toLowerCase();\n          currentPropName = String(currentPropName).toLowerCase();\n        }\n\n        if (requiredFirst) {\n          if (previousIsRequired && !currentIsRequired) {\n            // Transition between required and non-required. Don't compare for alphabetical.\n            return curr;\n          }\n          if (!previousIsRequired && currentIsRequired) {\n            // Encountered a non-required prop after a required prop\n            if (!requiredPropsFirstSeen.has(curr)) {\n              requiredPropsFirstSeen.add(curr);\n              report(context, messages.requiredPropsFirst, 'requiredPropsFirst', {\n                node: curr,\n                fix,\n              });\n            }\n            return curr;\n          }\n        }\n\n        if (callbacksLast) {\n          if (!previousIsCallback && currentIsCallback) {\n            // Entering the callback prop section\n            return curr;\n          }\n          if (previousIsCallback && !currentIsCallback) {\n            // Encountered a non-callback prop after a callback prop\n            if (!callbackPropsLastSeen.has(prev)) {\n              callbackPropsLastSeen.add(prev);\n              report(context, messages.callbackPropsLast, 'callbackPropsLast', {\n                node: prev,\n                fix,\n              });\n            }\n            return prev;\n          }\n        }\n\n        if (!noSortAlphabetically && currentPropName < prevPropName) {\n          if (!propsNotSortedSeen.has(curr)) {\n            propsNotSortedSeen.add(curr);\n            report(context, messages.propsNotSorted, 'propsNotSorted', {\n              node: curr,\n              fix,\n            });\n          }\n          return prev;\n        }\n\n        return curr;\n      }, declarations[0]);\n    }\n\n    function checkNode(node) {\n      if (!node) {\n        return;\n      }\n\n      if (node.type === 'ObjectExpression') {\n        checkSorted(node.properties);\n      } else if (node.type === 'Identifier') {\n        const propTypesObject = variableUtil.findVariableByName(context, node, node.name);\n        if (propTypesObject && propTypesObject.properties) {\n          checkSorted(propTypesObject.properties);\n        }\n      } else if (astUtil.isCallExpression(node)) {\n        const innerNode = node.arguments && node.arguments[0];\n        if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {\n          checkNode(innerNode);\n        }\n      }\n    }\n\n    function handleFunctionComponent(node) {\n      const firstArg = node.params\n        && node.params.length > 0\n        && node.params[0].typeAnnotation\n        && node.params[0].typeAnnotation.typeAnnotation;\n      if (firstArg && firstArg.type === 'TSTypeReference') {\n        const propType = typeAnnotations.get(firstArg.typeName.name)\n          && typeAnnotations.get(firstArg.typeName.name)[0];\n        if (propType && propType.members) {\n          checkSorted(propType.members);\n        }\n      } else if (firstArg && firstArg.type === 'TSTypeLiteral') {\n        if (firstArg.members) {\n          checkSorted(firstArg.members);\n        }\n      } else if (firstArg && firstArg.type === 'GenericTypeAnnotation') {\n        const propType = typeAnnotations.get(firstArg.id.name)\n          && typeAnnotations.get(firstArg.id.name)[0];\n        if (propType && propType.properties) {\n          checkSorted(propType.properties);\n        }\n      } else if (firstArg && firstArg.type === 'ObjectTypeAnnotation') {\n        if (firstArg.properties) {\n          checkSorted(firstArg.properties);\n        }\n      }\n    }\n\n    return Object.assign({\n      CallExpression(node) {\n        if (!sortShapeProp || !propTypesSortUtil.isShapeProp(node) || !(node.arguments && node.arguments[0])) {\n          return;\n        }\n\n        const firstArg = node.arguments[0];\n        if (firstArg.properties) {\n          checkSorted(firstArg.properties);\n        } else if (firstArg.type === 'Identifier') {\n          const variable = variableUtil.findVariableByName(context, node, firstArg.name);\n          if (variable && variable.properties) {\n            checkSorted(variable.properties);\n          }\n        }\n      },\n\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!propsUtil.isPropTypesDeclaration(node)) {\n          return;\n        }\n        checkNode(node.value);\n      },\n\n      MemberExpression(node) {\n        if (!propsUtil.isPropTypesDeclaration(node)) {\n          return;\n        }\n\n        checkNode(node.parent.right);\n      },\n\n      ObjectExpression(node) {\n        node.properties.forEach((property) => {\n          if (!property.key) {\n            return;\n          }\n\n          if (!propsUtil.isPropTypesDeclaration(property)) {\n            return;\n          }\n          if (property.value.type === 'ObjectExpression') {\n            checkSorted(property.value.properties);\n          }\n        });\n      },\n    }, checkTypes ? {\n      TSTypeLiteral(node) {\n        if (node && node.parent.id) {\n          const currentNode = [].concat(\n            typeAnnotations.get(node.parent.id.name) || [],\n            node\n          );\n          typeAnnotations.set(node.parent.id.name, currentNode);\n        }\n      },\n\n      TypeAlias(node) {\n        if (node.right.type === 'ObjectTypeAnnotation') {\n          const currentNode = [].concat(\n            typeAnnotations.get(node.id.name) || [],\n            node.right\n          );\n          typeAnnotations.set(node.id.name, currentNode);\n        }\n      },\n\n      TSTypeAliasDeclaration(node) {\n        if (node.typeAnnotation.type === 'TSTypeLiteral' || node.typeAnnotation.type === 'ObjectTypeAnnotation') {\n          const currentNode = [].concat(\n            typeAnnotations.get(node.id.name) || [],\n            node.typeAnnotation\n          );\n          typeAnnotations.set(node.id.name, currentNode);\n        }\n      },\n      FunctionDeclaration: handleFunctionComponent,\n      ArrowFunctionExpression: handleFunctionComponent,\n    } : null);\n  },\n};\n"
  },
  {
    "path": "lib/rules/state-in-constructor.js",
    "content": "/**\n * @fileoverview Enforce the state initialization style to be either in a constructor or with a class property\n * @author Kanitkorn Sujautra\n */\n\n'use strict';\n\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst docsUrl = require('../util/docsUrl');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  stateInitConstructor: 'State initialization should be in a constructor',\n  stateInitClassProp: 'State initialization should be in a class property',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce class component state initialization style',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('state-in-constructor'),\n    },\n\n    messages,\n\n    schema: [{\n      enum: ['always', 'never'],\n    }],\n  },\n\n  create(context) {\n    const option = context.options[0] || 'always';\n    return {\n      'ClassProperty, PropertyDefinition'(node) {\n        if (\n          option === 'always'\n          && !node.static\n          && node.key.name === 'state'\n          && componentUtil.getParentES6Component(context, node)\n        ) {\n          report(context, messages.stateInitConstructor, 'stateInitConstructor', {\n            node,\n          });\n        }\n      },\n      AssignmentExpression(node) {\n        if (\n          option === 'never'\n          && componentUtil.isStateMemberExpression(node.left)\n          && astUtil.inConstructor(context, node)\n          && componentUtil.getParentES6Component(context, node)\n        ) {\n          report(context, messages.stateInitClassProp, 'stateInitClassProp', {\n            node,\n          });\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/static-property-placement.js",
    "content": "/**\n * @fileoverview Defines where React component static properties should be positioned.\n * @author Daniel Mason\n */\n\n'use strict';\n\nconst fromEntries = require('object.fromentries');\nconst Components = require('../util/Components');\nconst docsUrl = require('../util/docsUrl');\nconst astUtil = require('../util/ast');\nconst componentUtil = require('../util/componentUtil');\nconst propsUtil = require('../util/props');\nconst report = require('../util/report');\nconst getScope = require('../util/eslint').getScope;\n\n// ------------------------------------------------------------------------------\n// Positioning Options\n// ------------------------------------------------------------------------------\nconst STATIC_PUBLIC_FIELD = 'static public field';\nconst STATIC_GETTER = 'static getter';\nconst PROPERTY_ASSIGNMENT = 'property assignment';\nconst POSITION_SETTINGS = [STATIC_PUBLIC_FIELD, STATIC_GETTER, PROPERTY_ASSIGNMENT];\n\n// ------------------------------------------------------------------------------\n// Rule messages\n// ------------------------------------------------------------------------------\nconst ERROR_MESSAGES = {\n  [STATIC_PUBLIC_FIELD]: 'notStaticClassProp',\n  [STATIC_GETTER]: 'notGetterClassFunc',\n  [PROPERTY_ASSIGNMENT]: 'declareOutsideClass',\n};\n\n// ------------------------------------------------------------------------------\n// Properties to check\n// ------------------------------------------------------------------------------\nconst propertiesToCheck = {\n  propTypes: propsUtil.isPropTypesDeclaration,\n  defaultProps: propsUtil.isDefaultPropsDeclaration,\n  childContextTypes: propsUtil.isChildContextTypesDeclaration,\n  contextTypes: propsUtil.isContextTypesDeclaration,\n  contextType: propsUtil.isContextTypeDeclaration,\n  displayName: (node) => propsUtil.isDisplayNameDeclaration(astUtil.getPropertyNameNode(node)),\n};\n\nconst classProperties = Object.keys(propertiesToCheck);\nconst schemaProperties = fromEntries(classProperties.map((property) => [property, { enum: POSITION_SETTINGS }]));\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  notStaticClassProp: '\\'{{name}}\\' should be declared as a static class property.',\n  notGetterClassFunc: '\\'{{name}}\\' should be declared as a static getter class function.',\n  declareOutsideClass: '\\'{{name}}\\' should be declared outside the class body.',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforces where React component static properties should be positioned.',\n      category: 'Stylistic Issues',\n      recommended: false,\n      url: docsUrl('static-property-placement'),\n    },\n    fixable: null, // or 'code' or 'whitespace'\n\n    messages,\n\n    schema: [\n      { enum: POSITION_SETTINGS },\n      {\n        type: 'object',\n        properties: schemaProperties,\n        additionalProperties: false,\n      },\n    ],\n  },\n\n  create: Components.detect((context, components, utils) => {\n    // variables should be defined here\n    const options = context.options;\n    const defaultCheckType = options[0] || STATIC_PUBLIC_FIELD;\n    const hasAdditionalConfig = options.length > 1;\n    const additionalConfig = hasAdditionalConfig ? options[1] : {};\n\n    // Set config\n    const config = fromEntries(classProperties.map((property) => [\n      property,\n      additionalConfig[property] || defaultCheckType,\n    ]));\n\n    // ----------------------------------------------------------------------\n    // Helpers\n    // ----------------------------------------------------------------------\n\n    /**\n      * Checks if we are declaring context in class\n      * @param {ASTNode} node\n      * @returns {boolean} True if we are declaring context in class, false if not.\n     */\n    function isContextInClass(node) {\n      let blockNode;\n      let scope = getScope(context, node);\n      while (scope) {\n        blockNode = scope.block;\n        if (blockNode && blockNode.type === 'ClassDeclaration') {\n          return true;\n        }\n        scope = scope.upper;\n      }\n\n      return false;\n    }\n\n    /**\n     * Check if we should report this property node\n     * @param {ASTNode} node\n     * @param {string} expectedRule\n     */\n    function reportNodeIncorrectlyPositioned(node, expectedRule) {\n      // Detect if this node is an expected property declaration adn return the property name\n      const name = classProperties.find((propertyName) => {\n        if (propertiesToCheck[propertyName](node)) {\n          return !!propertyName;\n        }\n\n        return false;\n      });\n\n      // If name is set but the configured rule does not match expected then report error\n      if (\n        name\n        && (\n          config[name] !== expectedRule\n          || (!node.static && (config[name] === STATIC_PUBLIC_FIELD || config[name] === STATIC_GETTER))\n        )\n      ) {\n        const messageId = ERROR_MESSAGES[config[name]];\n        report(context, messages[messageId], messageId, {\n          node,\n          data: { name },\n        });\n      }\n    }\n\n    // ----------------------------------------------------------------------\n    // Public\n    // ----------------------------------------------------------------------\n    return {\n      'ClassProperty, PropertyDefinition'(node) {\n        if (!componentUtil.getParentES6Component(context, node)) {\n          return;\n        }\n\n        reportNodeIncorrectlyPositioned(node, STATIC_PUBLIC_FIELD);\n      },\n\n      MemberExpression(node) {\n        // If definition type is undefined then it must not be a defining expression or if the definition is inside a\n        // class body then skip this node.\n        const right = node.parent.right;\n        if (!right || right.type === 'undefined' || isContextInClass(node)) {\n          return;\n        }\n\n        // Get the related component\n        const relatedComponent = utils.getRelatedComponent(node);\n\n        // If the related component is not an ES6 component then skip this node\n        if (!relatedComponent || !componentUtil.isES6Component(relatedComponent.node, context)) {\n          return;\n        }\n\n        // Report if needed\n        reportNodeIncorrectlyPositioned(node, PROPERTY_ASSIGNMENT);\n      },\n\n      MethodDefinition(node) {\n        // If the function is inside a class and is static getter then check if correctly positioned\n        if (\n          componentUtil.getParentES6Component(context, node)\n          && node.static\n          && node.kind === 'get'\n        ) {\n          // Report error if needed\n          reportNodeIncorrectlyPositioned(node, STATIC_GETTER);\n        }\n      },\n    };\n  }),\n};\n"
  },
  {
    "path": "lib/rules/style-prop-object.js",
    "content": "/**\n * @fileoverview Enforce style prop value is an object\n * @author David Petersen\n */\n\n'use strict';\n\nconst variableUtil = require('../util/variable');\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst messages = {\n  stylePropNotObject: 'Style prop value must be an object',\n};\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Enforce style prop value is an object',\n      category: 'Possible Errors',\n      recommended: false,\n      url: docsUrl('style-prop-object'),\n    },\n\n    messages,\n\n    schema: [\n      {\n        type: 'object',\n        properties: {\n          allow: {\n            type: 'array',\n            items: {\n              type: 'string',\n            },\n            additionalItems: false,\n            uniqueItems: true,\n          },\n        },\n      },\n    ],\n  },\n\n  create(context) {\n    const allowed = new Set(((context.options.length > 0) && context.options[0].allow) || []);\n\n    /**\n     * @param {ASTNode} expression An Identifier node\n     * @returns {boolean}\n     */\n    function isNonNullaryLiteral(expression) {\n      return expression.type === 'Literal' && expression.value !== null;\n    }\n\n    /**\n     * @param {object} node A Identifier node\n     */\n    function checkIdentifiers(node) {\n      const variable = variableUtil.getVariableFromContext(context, node, node.name);\n\n      if (!variable || !variable.defs[0] || !variable.defs[0].node.init) {\n        return;\n      }\n\n      if (isNonNullaryLiteral(variable.defs[0].node.init)) {\n        report(context, messages.stylePropNotObject, 'stylePropNotObject', {\n          node,\n        });\n      }\n    }\n\n    return {\n      CallExpression(node) {\n        if (\n          isCreateElement(context, node)\n          && node.arguments.length > 1\n        ) {\n          if ('name' in node.arguments[0] && node.arguments[0].name) {\n            // store name of component\n            const componentName = node.arguments[0].name;\n\n            // allowed list contains the name\n            if (allowed.has(componentName)) {\n              // abort operation\n              return;\n            }\n          }\n          if (node.arguments[1].type === 'ObjectExpression') {\n            const style = node.arguments[1].properties.find((property) => (\n              'key' in property\n              && property.key\n              && 'name' in property.key\n              && property.key.name === 'style'\n              && !property.computed\n            ));\n\n            if (style && 'value' in style) {\n              if (style.value.type === 'Identifier') {\n                checkIdentifiers(style.value);\n              } else if (isNonNullaryLiteral(style.value)) {\n                report(context, messages.stylePropNotObject, 'stylePropNotObject', {\n                  node: style.value,\n                });\n              }\n            }\n          }\n        }\n      },\n\n      JSXAttribute(node) {\n        if (!node.value || node.name.name !== 'style') {\n          return;\n        }\n        // store parent element\n        const parentElement = node.parent;\n\n        // parent element is a JSXOpeningElement\n        if (parentElement && parentElement.type === 'JSXOpeningElement') {\n          // get the name of the JSX element\n          const name = parentElement.name && parentElement.name.name;\n\n          // allowed list contains the name\n          if (allowed.has(name)) {\n            // abort operation\n            return;\n          }\n        }\n\n        if (node.value.type !== 'JSXExpressionContainer' || isNonNullaryLiteral(node.value.expression)) {\n          report(context, messages.stylePropNotObject, 'stylePropNotObject', {\n            node,\n          });\n        } else if (node.value.expression.type === 'Identifier') {\n          checkIdentifiers(node.value.expression);\n        }\n      },\n    };\n  },\n};\n"
  },
  {
    "path": "lib/rules/void-dom-elements-no-children.js",
    "content": "/**\n * @fileoverview Prevent void elements (e.g. <img />, <br />) from receiving\n *   children\n * @author Joe Lencioni\n */\n\n'use strict';\n\nconst has = require('hasown');\n\nconst docsUrl = require('../util/docsUrl');\nconst isCreateElement = require('../util/isCreateElement');\nconst report = require('../util/report');\n\n// ------------------------------------------------------------------------------\n// Helpers\n// ------------------------------------------------------------------------------\n\n// Using an object here to avoid array scan. We should switch to Set once\n// support is good enough.\nconst VOID_DOM_ELEMENTS = {\n  area: true,\n  base: true,\n  br: true,\n  col: true,\n  embed: true,\n  hr: true,\n  img: true,\n  input: true,\n  keygen: true,\n  link: true,\n  menuitem: true,\n  meta: true,\n  param: true,\n  source: true,\n  track: true,\n  wbr: true,\n};\n\nfunction isVoidDOMElement(elementName) {\n  return has(VOID_DOM_ELEMENTS, elementName);\n}\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nconst noChildrenInVoidEl = 'Void DOM element <{{element}} /> cannot receive children.';\n\n/** @type {import('eslint').Rule.RuleModule} */\nmodule.exports = {\n  meta: {\n    docs: {\n      description: 'Disallow void DOM elements (e.g. `<img />`, `<br />`) from receiving children',\n      category: 'Best Practices',\n      recommended: false,\n      url: docsUrl('void-dom-elements-no-children'),\n    },\n\n    messages: {\n      noChildrenInVoidEl,\n    },\n\n    schema: [],\n  },\n\n  create: (context) => ({\n    JSXElement(node) {\n      const elementName = node.openingElement.name.name;\n\n      if (!isVoidDOMElement(elementName)) {\n        // e.g. <div />\n        return;\n      }\n\n      if (node.children.length > 0) {\n        // e.g. <br>Foo</br>\n        report(context, noChildrenInVoidEl, 'noChildrenInVoidEl', {\n          node,\n          data: {\n            element: elementName,\n          },\n        });\n      }\n\n      const attributes = node.openingElement.attributes;\n\n      const hasChildrenAttributeOrDanger = attributes.some((attribute) => {\n        if (!attribute.name) {\n          return false;\n        }\n\n        return attribute.name.name === 'children' || attribute.name.name === 'dangerouslySetInnerHTML';\n      });\n\n      if (hasChildrenAttributeOrDanger) {\n        // e.g. <br children=\"Foo\" />\n        report(context, noChildrenInVoidEl, 'noChildrenInVoidEl', {\n          node,\n          data: {\n            element: elementName,\n          },\n        });\n      }\n    },\n\n    CallExpression(node) {\n      if (node.callee.type !== 'MemberExpression' && node.callee.type !== 'Identifier') {\n        return;\n      }\n\n      if (!isCreateElement(context, node)) {\n        return;\n      }\n\n      const args = node.arguments;\n\n      if (args.length < 1) {\n        // React.createElement() should not crash linter\n        return;\n      }\n\n      const elementName = 'value' in args[0] ? args[0].value : undefined;\n\n      if (!isVoidDOMElement(elementName)) {\n        // e.g. React.createElement('div');\n        return;\n      }\n\n      if (args.length < 2 || args[1].type !== 'ObjectExpression') {\n        return;\n      }\n\n      const firstChild = args[2];\n      if (firstChild) {\n        // e.g. React.createElement('br', undefined, 'Foo')\n        report(context, noChildrenInVoidEl, 'noChildrenInVoidEl', {\n          node,\n          data: {\n            element: elementName,\n          },\n        });\n      }\n\n      const props = args[1].properties;\n\n      const hasChildrenPropOrDanger = props.some((prop) => {\n        if (!('key' in prop) || !prop.key || !('name' in prop.key)) {\n          return false;\n        }\n\n        return prop.key.name === 'children' || prop.key.name === 'dangerouslySetInnerHTML';\n      });\n\n      if (hasChildrenPropOrDanger) {\n        // e.g. React.createElement('br', { children: 'Foo' })\n        report(context, noChildrenInVoidEl, 'noChildrenInVoidEl', {\n          node,\n          data: {\n            element: elementName,\n          },\n        });\n      }\n    },\n  }),\n};\n"
  },
  {
    "path": "lib/types.d.ts",
    "content": "import eslint from 'eslint';\nimport estree from 'estree';\n\ndeclare global {\n  interface ASTNode extends estree.BaseNode {\n    [_: string]: any; // TODO: fixme\n  }\n  type Scope = eslint.Scope.Scope;\n  type Token = eslint.AST.Token;\n  type Fixer = eslint.Rule.RuleFixer;\n  type JSXAttribute = ASTNode;\n  type JSXElement = ASTNode;\n  type JSXFragment = ASTNode;\n  type JSXOpeningElement = ASTNode;\n  type JSXSpreadAttribute = ASTNode;\n\n  type Context = eslint.Rule.RuleContext;\n\n  type TypeDeclarationBuilder = (annotation: ASTNode, parentName: string, seen: Set<typeof annotation>) => object;\n\n  type TypeDeclarationBuilders = {\n    [k in string]: TypeDeclarationBuilder;\n  };\n\n  type UnionTypeDefinition = {\n    type: 'union' | 'shape';\n    children: unknown[];\n  };\n}\n"
  },
  {
    "path": "lib/util/Components.js",
    "content": "/**\n * @fileoverview Utility class and functions for React components detection\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst arrayIncludes = require('array-includes');\nconst fromEntries = require('object.fromentries');\nconst values = require('object.values');\nconst iterFrom = require('es-iterator-helpers/Iterator.from');\nconst map = require('es-iterator-helpers/Iterator.prototype.map');\n\nconst variableUtil = require('./variable');\nconst pragmaUtil = require('./pragma');\nconst astUtil = require('./ast');\nconst componentUtil = require('./componentUtil');\nconst propTypesUtil = require('./propTypes');\nconst jsxUtil = require('./jsx');\nconst usedPropTypesUtil = require('./usedPropTypes');\nconst defaultPropsUtil = require('./defaultProps');\nconst isFirstLetterCapitalized = require('./isFirstLetterCapitalized');\nconst isDestructuredFromPragmaImport = require('./isDestructuredFromPragmaImport');\nconst eslintUtil = require('./eslint');\n\nconst getScope = eslintUtil.getScope;\nconst getText = eslintUtil.getText;\n\nfunction getId(node) {\n  return node ? `${node.range[0]}:${node.range[1]}` : '';\n}\n\nfunction usedPropTypesAreEquivalent(propA, propB) {\n  if (propA.name === propB.name) {\n    if (!propA.allNames && !propB.allNames) {\n      return true;\n    }\n    if (Array.isArray(propA.allNames) && Array.isArray(propB.allNames) && propA.allNames.join('') === propB.allNames.join('')) {\n      return true;\n    }\n    return false;\n  }\n  return false;\n}\n\nfunction mergeUsedPropTypes(propsList, newPropsList) {\n  const propsToAdd = newPropsList.filter((newProp) => {\n    const newPropIsAlreadyInTheList = propsList.some((prop) => usedPropTypesAreEquivalent(prop, newProp));\n    return !newPropIsAlreadyInTheList;\n  });\n\n  return propsList.concat(propsToAdd);\n}\n\nconst USE_HOOK_PREFIX_REGEX = /^use[A-Z]/;\n\nconst Lists = new WeakMap();\nconst ReactImports = new WeakMap();\n\n/**\n * Components\n */\nclass Components {\n  constructor() {\n    Lists.set(this, {});\n    ReactImports.set(this, {});\n  }\n\n  /**\n   * Add a node to the components list, or update it if it's already in the list\n   *\n   * @param {ASTNode} node The AST node being added.\n   * @param {number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)\n   * @returns {Object} Added component object\n   */\n  add(node, confidence) {\n    const id = getId(node);\n    const list = Lists.get(this);\n    if (list[id]) {\n      if (confidence === 0 || list[id].confidence === 0) {\n        list[id].confidence = 0;\n      } else {\n        list[id].confidence = Math.max(list[id].confidence, confidence);\n      }\n      return list[id];\n    }\n    list[id] = {\n      node,\n      confidence,\n    };\n    return list[id];\n  }\n\n  /**\n   * Find a component in the list using its node\n   *\n   * @param {ASTNode} node The AST node being searched.\n   * @returns {Object} Component object, undefined if the component is not found or has confidence value of 0.\n   */\n  get(node) {\n    const id = getId(node);\n    const item = Lists.get(this)[id];\n    if (item && item.confidence >= 1) {\n      return item;\n    }\n    return null;\n  }\n\n  /**\n   * Update a component in the list\n   *\n   * @param {ASTNode} node The AST node being updated.\n   * @param {Object} props Additional properties to add to the component.\n   */\n  set(node, props) {\n    const list = Lists.get(this);\n    let component = list[getId(node)];\n    while (!component || component.confidence < 1) {\n      node = node.parent;\n      if (!node) {\n        return;\n      }\n      component = list[getId(node)];\n    }\n\n    Object.assign(\n      component,\n      props,\n      {\n        usedPropTypes: mergeUsedPropTypes(\n          component.usedPropTypes || [],\n          props.usedPropTypes || []\n        ),\n      }\n    );\n  }\n\n  /**\n   * Return the components list\n   * Components for which we are not confident are not returned\n   *\n   * @returns {Object} Components list\n   */\n  list() {\n    const thisList = Lists.get(this);\n    const list = {};\n    const usedPropTypes = {};\n\n    // Find props used in components for which we are not confident\n    Object.keys(thisList).filter((i) => thisList[i].confidence < 2).forEach((i) => {\n      let component = null;\n      let node = null;\n      node = thisList[i].node;\n      while (!component && node.parent) {\n        node = node.parent;\n        // Stop moving up if we reach a decorator\n        if (node.type === 'Decorator') {\n          break;\n        }\n        component = this.get(node);\n      }\n      if (component) {\n        const newUsedProps = (thisList[i].usedPropTypes || []).filter((propType) => !propType.node || propType.node.kind !== 'init');\n\n        const componentId = getId(component.node);\n\n        usedPropTypes[componentId] = mergeUsedPropTypes(usedPropTypes[componentId] || [], newUsedProps);\n      }\n    });\n\n    // Assign used props in not confident components to the parent component\n    Object.keys(thisList).filter((j) => thisList[j].confidence >= 2).forEach((j) => {\n      const id = getId(thisList[j].node);\n      list[j] = thisList[j];\n      if (usedPropTypes[id]) {\n        list[j].usedPropTypes = mergeUsedPropTypes(list[j].usedPropTypes || [], usedPropTypes[id]);\n      }\n    });\n    return list;\n  }\n\n  /**\n   * Return the length of the components list\n   * Components for which we are not confident are not counted\n   *\n   * @returns {number} Components list length\n   */\n  length() {\n    const list = Lists.get(this);\n    return values(list).filter((component) => component.confidence >= 2).length;\n  }\n\n  /**\n   * Return the node naming the default React import\n   * It can be used to determine the local name of import, even if it's imported\n   * with an unusual name.\n   *\n   * @returns {ASTNode} React default import node\n   */\n  getDefaultReactImports() {\n    return ReactImports.get(this).defaultReactImports;\n  }\n\n  /**\n   * Return the nodes of all React named imports\n   *\n   * @returns {Object} The list of React named imports\n   */\n  getNamedReactImports() {\n    return ReactImports.get(this).namedReactImports;\n  }\n\n  /**\n   * Add the default React import specifier to the scope\n   *\n   * @param {ASTNode} specifier The AST Node of the default React import\n   * @returns {void}\n   */\n  addDefaultReactImport(specifier) {\n    const info = ReactImports.get(this);\n    ReactImports.set(this, Object.assign({}, info, {\n      defaultReactImports: (info.defaultReactImports || []).concat(specifier),\n    }));\n  }\n\n  /**\n   * Add a named React import specifier to the scope\n   *\n   * @param {ASTNode} specifier The AST Node of a named React import\n   * @returns {void}\n   */\n  addNamedReactImport(specifier) {\n    const info = ReactImports.get(this);\n    ReactImports.set(this, Object.assign({}, info, {\n      namedReactImports: (info.namedReactImports || []).concat(specifier),\n    }));\n  }\n}\n\nfunction getWrapperFunctions(context, pragma) {\n  const componentWrapperFunctions = context.settings.componentWrapperFunctions || [];\n\n  // eslint-disable-next-line arrow-body-style\n  return componentWrapperFunctions.map((wrapperFunction) => {\n    return typeof wrapperFunction === 'string'\n      ? { property: wrapperFunction }\n      : Object.assign({}, wrapperFunction, {\n        object: wrapperFunction.object === '<pragma>' ? pragma : wrapperFunction.object,\n      });\n  }).concat([\n    { property: 'forwardRef', object: pragma },\n    { property: 'memo', object: pragma },\n  ]);\n}\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Merge many eslint rules into one\n * @param {{[_: string]: Function}[]} rules the returned values for eslint rule.create(context)\n * @returns {{[_: string]: Function}} merged rule\n */\nfunction mergeRules(rules) {\n  /** @type {Map<string, Function[]>} */\n  const handlersByKey = new Map();\n  rules.forEach((rule) => {\n    Object.keys(rule).forEach((key) => {\n      const fns = handlersByKey.get(key);\n      if (!fns) {\n        handlersByKey.set(key, [rule[key]]);\n      } else {\n        fns.push(rule[key]);\n      }\n    });\n  });\n\n  /** @type {{ [key: string]: Function }} */\n  return fromEntries(map(iterFrom(handlersByKey), (entry) => [\n    entry[0],\n    function mergedHandler(node) {\n      entry[1].forEach((fn) => {\n        fn(node);\n      });\n    },\n  ]));\n}\n\nfunction componentRule(rule, context) {\n  const pragma = pragmaUtil.getFromContext(context);\n  const components = new Components();\n  const wrapperFunctions = getWrapperFunctions(context, pragma);\n\n  // Utilities for component detection\n  const utils = {\n    /**\n     * Check if variable is destructured from pragma import\n     *\n     * @param {ASTNode} node The AST node to check\n     * @param {string} variable The variable name to check\n     * @returns {boolean} True if createElement is destructured from the pragma\n     */\n    isDestructuredFromPragmaImport(node, variable) {\n      return isDestructuredFromPragmaImport(context, node, variable);\n    },\n\n    /**\n     * @param {ASTNode} node\n     * @param {boolean=} strict\n     * @returns {boolean}\n     */\n    isReturningJSX(node, strict) {\n      return jsxUtil.isReturningJSX(context, node, strict, true);\n    },\n\n    isReturningJSXOrNull(node, strict) {\n      return jsxUtil.isReturningJSX(context, node, strict);\n    },\n\n    isReturningOnlyNull(node) {\n      return jsxUtil.isReturningOnlyNull(node, context);\n    },\n\n    getPragmaComponentWrapper(node) {\n      let isPragmaComponentWrapper;\n      let currentNode = node;\n      let prevNode;\n      do {\n        currentNode = currentNode.parent;\n        isPragmaComponentWrapper = this.isPragmaComponentWrapper(currentNode);\n        if (isPragmaComponentWrapper) {\n          prevNode = currentNode;\n        }\n      } while (isPragmaComponentWrapper);\n\n      return prevNode;\n    },\n\n    getComponentNameFromJSXElement(node) {\n      if (node.type !== 'JSXElement') {\n        return null;\n      }\n      if (node.openingElement && node.openingElement.name && node.openingElement.name.name) {\n        return node.openingElement.name.name;\n      }\n      return null;\n    },\n\n    /**\n     * Getting the first JSX element's name.\n     * @param {object} node\n     * @returns {string | null}\n     */\n    getNameOfWrappedComponent(node) {\n      if (node.length < 1) {\n        return null;\n      }\n      const body = node[0].body;\n      if (!body) {\n        return null;\n      }\n      if (body.type === 'JSXElement') {\n        return this.getComponentNameFromJSXElement(body);\n      }\n      if (body.type === 'BlockStatement') {\n        const jsxElement = body.body.find((item) => item.type === 'ReturnStatement');\n        return jsxElement\n          && jsxElement.argument\n          && this.getComponentNameFromJSXElement(jsxElement.argument);\n      }\n      return null;\n    },\n\n    /**\n     * Get the list of names of components created till now\n     * @returns {string | boolean}\n     */\n    getDetectedComponents() {\n      const list = components.list();\n      return values(list).filter((val) => {\n        if (val.node.type === 'ClassDeclaration') {\n          return true;\n        }\n        if (\n          val.node.type === 'ArrowFunctionExpression'\n          && val.node.parent\n          && val.node.parent.type === 'VariableDeclarator'\n          && val.node.parent.id\n        ) {\n          return true;\n        }\n        return false;\n      }).map((val) => {\n        if (val.node.type === 'ArrowFunctionExpression') return val.node.parent.id.name;\n        return val.node.id && val.node.id.name;\n      });\n    },\n\n    /**\n     * It will check whether memo/forwardRef is wrapping existing component or\n     * creating a new one.\n     * @param {object} node\n     * @returns {boolean}\n     */\n    nodeWrapsComponent(node) {\n      const childComponent = this.getNameOfWrappedComponent(node.arguments);\n      const componentList = this.getDetectedComponents();\n      return !!childComponent && arrayIncludes(componentList, childComponent);\n    },\n\n    isPragmaComponentWrapper(node) {\n      if (!astUtil.isCallExpression(node)) {\n        return false;\n      }\n\n      return wrapperFunctions.some((wrapperFunction) => {\n        if (node.callee.type === 'MemberExpression') {\n          return wrapperFunction.object\n            && wrapperFunction.object === node.callee.object.name\n            && wrapperFunction.property === node.callee.property.name\n            && !this.nodeWrapsComponent(node);\n        }\n        return wrapperFunction.property === node.callee.name\n          && (!wrapperFunction.object\n            // Functions coming from the current pragma need special handling\n            || (wrapperFunction.object === pragma && this.isDestructuredFromPragmaImport(node, node.callee.name))\n          );\n      });\n    },\n\n    /**\n     * Find a return statement in the current node\n     *\n     * @param {ASTNode} node The AST node being checked\n     */\n    findReturnStatement: astUtil.findReturnStatement,\n\n    /**\n     * Get the parent component node from the current scope\n     * @param {ASTNode} node\n     *\n     * @returns {ASTNode} component node, null if we are not in a component\n     */\n    getParentComponent(node) {\n      return (\n        componentUtil.getParentES6Component(context, node)\n        || componentUtil.getParentES5Component(context, node)\n        || utils.getParentStatelessComponent(node)\n      );\n    },\n\n    /**\n     * @param {ASTNode} node\n     * @returns {boolean}\n     */\n    isInAllowedPositionForComponent(node) {\n      switch (node.parent.type) {\n        case 'VariableDeclarator':\n        case 'AssignmentExpression':\n        case 'Property':\n        case 'ReturnStatement':\n        case 'ExportDefaultDeclaration':\n        case 'ArrowFunctionExpression': {\n          return true;\n        }\n        case 'SequenceExpression': {\n          return utils.isInAllowedPositionForComponent(node.parent)\n            && node === node.parent.expressions[node.parent.expressions.length - 1];\n        }\n        default:\n          return false;\n      }\n    },\n\n    /**\n     * Get node if node is a stateless component, or node.parent in cases like\n     * `React.memo` or `React.forwardRef`. Otherwise returns `undefined`.\n     * @param {ASTNode} node\n     * @returns {ASTNode | undefined}\n     */\n    getStatelessComponent(node) {\n      const parent = node.parent;\n      if (\n        node.type === 'FunctionDeclaration'\n        && (!node.id || isFirstLetterCapitalized(node.id.name))\n        && utils.isReturningJSXOrNull(node)\n      ) {\n        return node;\n      }\n\n      if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {\n        const isPropertyAssignment = parent.type === 'AssignmentExpression'\n          && parent.left.type === 'MemberExpression';\n        const isModuleExportsAssignment = isPropertyAssignment\n          && parent.left.object.name === 'module'\n          && parent.left.property.name === 'exports';\n\n        if (node.parent.type === 'ExportDefaultDeclaration') {\n          if (utils.isReturningJSX(node)) {\n            return node;\n          }\n          return undefined;\n        }\n\n        if (node.parent.type === 'VariableDeclarator' && utils.isReturningJSXOrNull(node)) {\n          if (isFirstLetterCapitalized(node.parent.id.name)) {\n            return node;\n          }\n          return undefined;\n        }\n\n        // case: const any = () => { return (props) => null }\n        // case: const any = () => (props) => null\n        if (\n          (node.parent.type === 'ReturnStatement' || (node.parent.type === 'ArrowFunctionExpression' && node.parent.expression))\n          && !utils.isReturningJSX(node)\n        ) {\n          return undefined;\n        }\n\n        // case: any = () => { return => null }\n        // case: any = () => null\n        if (node.parent.type === 'AssignmentExpression' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {\n          if (isFirstLetterCapitalized(node.parent.left.name)) {\n            return node;\n          }\n          return undefined;\n        }\n\n        // case: any = () => () => null\n        if (node.parent.type === 'ArrowFunctionExpression' && node.parent.parent.type === 'AssignmentExpression' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {\n          if (isFirstLetterCapitalized(node.parent.parent.left.name)) {\n            return node;\n          }\n          return undefined;\n        }\n\n        // case: { any: () => () => null }\n        if (node.parent.type === 'ArrowFunctionExpression' && node.parent.parent.type === 'Property' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {\n          if (isFirstLetterCapitalized(node.parent.parent.key.name)) {\n            return node;\n          }\n          return undefined;\n        }\n\n        // case: any = function() {return function() {return null;};}\n        if (node.parent.type === 'ReturnStatement') {\n          if (isFirstLetterCapitalized(node.id && node.id.name)) {\n            return node;\n          }\n          const functionExpr = node.parent.parent.parent;\n          if (functionExpr.parent.type === 'AssignmentExpression' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {\n            if (isFirstLetterCapitalized(functionExpr.parent.left.name)) {\n              return node;\n            }\n            return undefined;\n          }\n        }\n\n        // case: { any: function() {return function() {return null;};} }\n        if (node.parent.type === 'ReturnStatement') {\n          const functionExpr = node.parent.parent.parent;\n          if (functionExpr.parent.type === 'Property' && !isPropertyAssignment && utils.isReturningJSXOrNull(node)) {\n            if (isFirstLetterCapitalized(functionExpr.parent.key.name)) {\n              return node;\n            }\n            return undefined;\n          }\n        }\n\n        // for case abc = { [someobject.somekey]: props => { ... return not-jsx } }\n        if (\n          node.parent\n          && node.parent.key\n          && node.parent.key.type === 'MemberExpression'\n          && !utils.isReturningJSX(node)\n          && !utils.isReturningOnlyNull(node)\n        ) {\n          return undefined;\n        }\n\n        if (\n          node.parent.type === 'Property' && (\n            (node.parent.method && !node.parent.computed) // case: { f() { return ... } }\n            || (!node.id && !node.parent.computed) // case: { f: () => ... }\n          )\n        ) {\n          if (\n            isFirstLetterCapitalized(node.parent.key.name)\n            && utils.isReturningJSX(node)\n          ) {\n            return node;\n          }\n          return undefined;\n        }\n\n        // Case like `React.memo(() => <></>)` or `React.forwardRef(...)`\n        const pragmaComponentWrapper = utils.getPragmaComponentWrapper(node);\n        if (pragmaComponentWrapper && utils.isReturningJSXOrNull(node)) {\n          return pragmaComponentWrapper;\n        }\n\n        if (!(utils.isInAllowedPositionForComponent(node) && utils.isReturningJSXOrNull(node))) {\n          return undefined;\n        }\n\n        if (utils.isParentComponentNotStatelessComponent(node)) {\n          return undefined;\n        }\n\n        if (node.id) {\n          return isFirstLetterCapitalized(node.id.name) ? node : undefined;\n        }\n\n        if (\n          isPropertyAssignment\n          && !isModuleExportsAssignment\n          && !isFirstLetterCapitalized(parent.left.property.name)\n        ) {\n          return undefined;\n        }\n\n        if (parent.type === 'Property' && utils.isReturningOnlyNull(node)) {\n          return undefined;\n        }\n\n        return node;\n      }\n\n      return undefined;\n    },\n\n    /**\n     * Get the parent stateless component node from the current scope\n     *\n     * @param {ASTNode} node The AST node being checked\n     * @returns {ASTNode} component node, null if we are not in a component\n     */\n    getParentStatelessComponent(node) {\n      let scope = getScope(context, node);\n      while (scope) {\n        const statelessComponent = utils.getStatelessComponent(scope.block);\n        if (statelessComponent) {\n          return statelessComponent;\n        }\n        scope = scope.upper;\n      }\n      return null;\n    },\n\n    /**\n     * Get the related component from a node\n     *\n     * @param {ASTNode} node The AST node being checked (must be a MemberExpression).\n     * @returns {ASTNode | null} component node, null if we cannot find the component\n     */\n    getRelatedComponent(node) {\n      let i;\n      let j;\n      let k;\n      let l;\n      let componentNode;\n      // Get the component path\n      const componentPath = [];\n      let nodeTemp = node;\n      while (nodeTemp) {\n        if (nodeTemp.property && nodeTemp.property.type === 'Identifier') {\n          componentPath.push(nodeTemp.property.name);\n        }\n        if (nodeTemp.object && nodeTemp.object.type === 'Identifier') {\n          componentPath.push(nodeTemp.object.name);\n        }\n        nodeTemp = nodeTemp.object;\n      }\n      componentPath.reverse();\n      const componentName = componentPath.slice(0, componentPath.length - 1).join('.');\n\n      // Find the variable in the current scope\n      const variableName = componentPath.shift();\n      if (!variableName) {\n        return null;\n      }\n      const variableInScope = variableUtil.getVariableFromContext(context, node, variableName);\n      if (!variableInScope) {\n        return null;\n      }\n\n      // Try to find the component using variable references\n      variableInScope.references.some((ref) => {\n        let refId = ref.identifier;\n        if (refId.parent && refId.parent.type === 'MemberExpression') {\n          refId = refId.parent;\n        }\n        if (getText(context, refId) !== componentName) {\n          return false;\n        }\n        if (refId.type === 'MemberExpression') {\n          componentNode = refId.parent.right;\n        } else if (\n          refId.parent\n          && refId.parent.type === 'VariableDeclarator'\n          && refId.parent.init\n          && refId.parent.init.type !== 'Identifier'\n        ) {\n          componentNode = refId.parent.init;\n        }\n        return true;\n      });\n\n      if (componentNode) {\n        // Return the component\n        return components.add(componentNode, 1);\n      }\n\n      // Try to find the component using variable declarations\n      const defs = variableInScope.defs;\n      const defInScope = defs.find((def) => (\n        def.type === 'ClassName'\n        || def.type === 'FunctionName'\n        || def.type === 'Variable'\n      ));\n      if (!defInScope || !defInScope.node) {\n        return null;\n      }\n      componentNode = defInScope.node.init || defInScope.node;\n\n      // Traverse the node properties to the component declaration\n      for (i = 0, j = componentPath.length; i < j; i++) {\n        if (!componentNode.properties) {\n          continue; // eslint-disable-line no-continue\n        }\n        for (k = 0, l = componentNode.properties.length; k < l; k++) {\n          if (componentNode.properties[k].key && componentNode.properties[k].key.name === componentPath[i]) {\n            componentNode = componentNode.properties[k];\n            break;\n          }\n        }\n        if (!componentNode || !componentNode.value) {\n          return null;\n        }\n        componentNode = componentNode.value;\n      }\n\n      // Return the component\n      return components.add(componentNode, 1);\n    },\n\n    isParentComponentNotStatelessComponent(node) {\n      return !!(\n        node.parent\n        && node.parent.key\n        && node.parent.key.type === 'Identifier'\n        // custom component functions must start with a capital letter (returns false otherwise)\n        && node.parent.key.name.charAt(0) === node.parent.key.name.charAt(0).toLowerCase()\n        // react render function cannot have params\n        && !!(node.params || []).length\n      );\n    },\n\n    /**\n     * Identify whether a node (CallExpression) is a call to a React hook\n     *\n     * @param {ASTNode} node The AST node being searched. (expects CallExpression)\n     * @param {('useCallback'|'useContext'|'useDebugValue'|'useEffect'|'useImperativeHandle'|'useLayoutEffect'|'useMemo'|'useReducer'|'useRef'|'useState')[]} [expectedHookNames] React hook names to which search is limited.\n     * @returns {boolean} True if the node is a call to a React hook\n     */\n    isReactHookCall(node, expectedHookNames) {\n      if (!astUtil.isCallExpression(node)) {\n        return false;\n      }\n\n      const defaultReactImports = components.getDefaultReactImports();\n      const namedReactImports = components.getNamedReactImports();\n\n      const defaultReactImportName = defaultReactImports\n        && defaultReactImports[0]\n        && defaultReactImports[0].local.name;\n      const reactHookImportSpecifiers = namedReactImports\n        && namedReactImports.filter((specifier) => USE_HOOK_PREFIX_REGEX.test(specifier.imported.name));\n      const reactHookImportNames = reactHookImportSpecifiers\n        && fromEntries(reactHookImportSpecifiers.map((specifier) => [specifier.local.name, specifier.imported.name]));\n\n      const isPotentialReactHookCall = defaultReactImportName\n        && node.callee.type === 'MemberExpression'\n        && node.callee.object.type === 'Identifier'\n        && node.callee.object.name === defaultReactImportName\n        && node.callee.property.type === 'Identifier'\n        && node.callee.property.name.match(USE_HOOK_PREFIX_REGEX);\n\n      const isPotentialHookCall = reactHookImportNames\n        && node.callee.type === 'Identifier'\n        && node.callee.name.match(USE_HOOK_PREFIX_REGEX);\n\n      const scope = (isPotentialReactHookCall || isPotentialHookCall) && getScope(context, node);\n\n      const reactResolvedDefs = isPotentialReactHookCall\n        && scope.references\n        && scope.references.find(\n          (reference) => reference.identifier.name === defaultReactImportName\n        ).resolved.defs;\n\n      const isReactShadowed = isPotentialReactHookCall && reactResolvedDefs\n        && reactResolvedDefs.some((reactDef) => reactDef.type !== 'ImportBinding');\n\n      const potentialHookReference = isPotentialHookCall\n        && scope.references\n        && scope.references.find(\n          (reference) => reactHookImportNames[reference.identifier.name]\n        );\n\n      const hookResolvedDefs = potentialHookReference && potentialHookReference.resolved.defs;\n      const localHookName = (\n        isPotentialReactHookCall\n        && node.callee.property.name\n      ) || (\n        isPotentialHookCall\n        && potentialHookReference\n        && node.callee.name\n      );\n      const isHookShadowed = isPotentialHookCall\n        && hookResolvedDefs\n        && hookResolvedDefs.some(\n          (hookDef) => hookDef.name.name === localHookName\n          && hookDef.type !== 'ImportBinding'\n        );\n\n      const isHookCall = (isPotentialReactHookCall && !isReactShadowed)\n        || (isPotentialHookCall && localHookName && !isHookShadowed);\n\n      if (!isHookCall) {\n        return false;\n      }\n\n      if (!expectedHookNames) {\n        return true;\n      }\n\n      return arrayIncludes(\n        expectedHookNames,\n        (reactHookImportNames && reactHookImportNames[localHookName]) || localHookName\n      );\n    },\n  };\n\n  // Component detection instructions\n  const detectionInstructions = {\n    CallExpression(node) {\n      if (!utils.isPragmaComponentWrapper(node)) {\n        return;\n      }\n      if (node.arguments.length > 0 && astUtil.isFunctionLikeExpression(node.arguments[0])) {\n        components.add(node, 2);\n      }\n    },\n\n    ClassExpression(node) {\n      if (!componentUtil.isES6Component(node, context)) {\n        return;\n      }\n      components.add(node, 2);\n    },\n\n    ClassDeclaration(node) {\n      if (!componentUtil.isES6Component(node, context)) {\n        return;\n      }\n      components.add(node, 2);\n    },\n\n    ObjectExpression(node) {\n      if (!componentUtil.isES5Component(node, context)) {\n        return;\n      }\n      components.add(node, 2);\n    },\n\n    FunctionExpression(node) {\n      if (node.async && node.generator) {\n        components.add(node, 0);\n        return;\n      }\n\n      const component = utils.getStatelessComponent(node);\n      if (!component) {\n        return;\n      }\n      components.add(component, 2);\n    },\n\n    FunctionDeclaration(node) {\n      if (node.async && node.generator) {\n        components.add(node, 0);\n        return;\n      }\n\n      const cNode = utils.getStatelessComponent(node);\n      if (!cNode) {\n        return;\n      }\n      components.add(cNode, 2);\n    },\n\n    ArrowFunctionExpression(node) {\n      const component = utils.getStatelessComponent(node);\n      if (!component) {\n        return;\n      }\n      components.add(component, 2);\n    },\n\n    ThisExpression(node) {\n      const component = utils.getParentStatelessComponent(node);\n      if (!component || !/Function/.test(component.type) || !node.parent.property) {\n        return;\n      }\n      // Ban functions accessing a property on a ThisExpression\n      components.add(node, 0);\n    },\n  };\n\n  // Detect React import specifiers\n  const reactImportInstructions = {\n    ImportDeclaration(node) {\n      const isReactImported = node.source.type === 'Literal' && node.source.value === 'react';\n      if (!isReactImported) {\n        return;\n      }\n\n      node.specifiers.forEach((specifier) => {\n        if (specifier.type === 'ImportDefaultSpecifier') {\n          components.addDefaultReactImport(specifier);\n        }\n        if (specifier.type === 'ImportSpecifier') {\n          components.addNamedReactImport(specifier);\n        }\n      });\n    },\n  };\n\n  const ruleInstructions = rule(context, components, utils);\n  const propTypesInstructions = propTypesUtil(context, components, utils);\n  const usedPropTypesInstructions = usedPropTypesUtil(context, components, utils);\n  const defaultPropsInstructions = defaultPropsUtil(context, components, utils);\n\n  const mergedRule = mergeRules([\n    detectionInstructions,\n    propTypesInstructions,\n    usedPropTypesInstructions,\n    defaultPropsInstructions,\n    reactImportInstructions,\n    ruleInstructions,\n  ]);\n\n  return mergedRule;\n}\n\nmodule.exports = Object.assign(Components, {\n  detect(rule) {\n    return componentRule.bind(this, rule);\n  },\n});\n"
  },
  {
    "path": "lib/util/annotations.js",
    "content": "/**\n * @fileoverview Utility functions for type annotation detection.\n * @author Yannick Croissant\n * @author Vitor Balocco\n */\n\n'use strict';\n\nconst getFirstTokens = require('./eslint').getFirstTokens;\n\n/**\n * Checks if we are declaring a `props` argument with a flow type annotation.\n * @param {ASTNode} node The AST node being checked.\n * @param {Object} context\n * @returns {boolean} True if the node is a type annotated props declaration, false if not.\n */\nfunction isAnnotatedFunctionPropsDeclaration(node, context) {\n  if (!node || !node.params || !node.params.length) {\n    return false;\n  }\n\n  const typeNode = node.params[0].type === 'AssignmentPattern' ? node.params[0].left : node.params[0];\n\n  const tokens = getFirstTokens(context, typeNode, 2);\n  const isAnnotated = typeNode.typeAnnotation;\n  const isDestructuredProps = typeNode.type === 'ObjectPattern';\n  const isProps = tokens[0].value === 'props' || (tokens[1] && tokens[1].value === 'props');\n\n  return (isAnnotated && (isDestructuredProps || isProps));\n}\n\nmodule.exports = {\n  isAnnotatedFunctionPropsDeclaration,\n};\n"
  },
  {
    "path": "lib/util/ast.js",
    "content": "/**\n * @fileoverview Utility functions for AST\n */\n\n'use strict';\n\nconst estraverse = require('estraverse');\nconst eslintUtil = require('./eslint');\n\nconst getFirstTokens = eslintUtil.getFirstTokens;\nconst getScope = eslintUtil.getScope;\nconst getSourceCode = eslintUtil.getSourceCode;\n// const pragmaUtil = require('./pragma');\n\n/**\n * Wrapper for estraverse.traverse\n *\n * @param {ASTNode} ASTnode The AST node being checked\n * @param {Object} visitor Visitor Object for estraverse\n */\nfunction traverse(ASTnode, visitor) {\n  const opts = Object.assign({}, {\n    fallback(node) {\n      return Object.keys(node).filter((key) => key === 'children' || key === 'argument');\n    },\n  }, visitor);\n\n  opts.keys = Object.assign({}, visitor.keys, {\n    JSXElement: ['children'],\n    JSXFragment: ['children'],\n  });\n\n  estraverse.traverse(ASTnode, opts);\n}\n\nfunction loopNodes(nodes) {\n  for (let i = nodes.length - 1; i >= 0; i--) {\n    if (nodes[i].type === 'ReturnStatement') {\n      return nodes[i];\n    }\n    if (nodes[i].type === 'SwitchStatement') {\n      const j = nodes[i].cases.length - 1;\n      if (j >= 0) {\n        return loopNodes(nodes[i].cases[j].consequent);\n      }\n    }\n  }\n  return false;\n}\n\n/**\n * Find a return statement in the current node\n *\n * @param {ASTNode} node The AST node being checked\n * @returns {ASTNode | false}\n */\nfunction findReturnStatement(node) {\n  if (\n    (!node.value || !node.value.body || !node.value.body.body)\n    && (!node.body || !node.body.body)\n  ) {\n    return false;\n  }\n\n  const bodyNodes = node.value ? node.value.body.body : node.body.body;\n\n  return loopNodes(bodyNodes);\n}\n\n// eslint-disable-next-line valid-jsdoc -- valid-jsdoc cannot parse function types.\n/**\n * Helper function for traversing \"returns\" (return statements or the\n * returned expression in the case of an arrow function) of a function\n *\n * @param {ASTNode} ASTNode The AST node being checked\n * @param {Context} context The context of `ASTNode`.\n * @param {(returnValue: ASTNode, breakTraverse: () => void) => void} onReturn\n *   Function to execute for each returnStatement found\n * @returns {undefined}\n */\nfunction traverseReturns(ASTNode, context, onReturn) {\n  const nodeType = ASTNode.type;\n\n  if (nodeType === 'ReturnStatement') {\n    onReturn(ASTNode.argument, () => {});\n    return;\n  }\n\n  if (nodeType === 'ArrowFunctionExpression' && ASTNode.expression) {\n    onReturn(ASTNode.body, () => {});\n    return;\n  }\n\n  /* TODO: properly warn on React.forwardRefs having typo properties\n  if (astUtil.isCallExpression(ASTNode)) {\n    const callee = ASTNode.callee;\n    const pragma = pragmaUtil.getFromContext(context);\n    if (\n      callee.type === 'MemberExpression'\n      && callee.object.type === 'Identifier'\n      && callee.object.name === pragma\n      && callee.property.type === 'Identifier'\n      && callee.property.name === 'forwardRef'\n      && ASTNode.arguments.length > 0\n    ) {\n      return enterFunc(ASTNode.arguments[0]);\n    }\n    return;\n  }\n  */\n\n  if (\n    nodeType !== 'FunctionExpression'\n    && nodeType !== 'FunctionDeclaration'\n    && nodeType !== 'ArrowFunctionExpression'\n    && nodeType !== 'MethodDefinition'\n  ) {\n    return;\n  }\n\n  traverse(ASTNode.body, {\n    enter(node) {\n      const breakTraverse = () => {\n        this.break();\n      };\n      switch (node.type) {\n        case 'ReturnStatement':\n          this.skip();\n          onReturn(node.argument, breakTraverse);\n          return;\n        case 'BlockStatement':\n        case 'IfStatement':\n        case 'ForStatement':\n        case 'WhileStatement':\n        case 'SwitchStatement':\n        case 'SwitchCase':\n          return;\n        default:\n          this.skip();\n      }\n    },\n  });\n}\n\n/**\n * Get node with property's name\n * @param {Object} node - Property.\n * @returns {Object} Property name node.\n */\nfunction getPropertyNameNode(node) {\n  if (\n    node.key\n    || node.type === 'MethodDefinition'\n    || node.type === 'Property'\n  ) {\n    return node.key;\n  }\n  if (node.type === 'MemberExpression') {\n    return node.property;\n  }\n  return null;\n}\n\n/**\n * Get properties name\n * @param {Object} node - Property.\n * @returns {string} Property name.\n */\nfunction getPropertyName(node) {\n  const nameNode = getPropertyNameNode(node);\n  return nameNode ? nameNode.name : '';\n}\n\n/**\n * Get properties for a given AST node\n * @param {ASTNode} node The AST node being checked.\n * @returns {Array} Properties array.\n */\nfunction getComponentProperties(node) {\n  switch (node.type) {\n    case 'ClassDeclaration':\n    case 'ClassExpression':\n      return node.body.body;\n    case 'ObjectExpression':\n      return node.properties;\n    default:\n      return [];\n  }\n}\n\n/**\n * Gets the first node in a line from the initial node, excluding whitespace.\n * @param {Object} context The node to check\n * @param {ASTNode} node The node to check\n * @return {ASTNode} the first node in the line\n */\nfunction getFirstNodeInLine(context, node) {\n  const sourceCode = getSourceCode(context);\n  let token = node;\n  let lines;\n  do {\n    token = sourceCode.getTokenBefore(token);\n    lines = token.type === 'JSXText'\n      ? token.value.split('\\n')\n      : null;\n  } while (\n    token.type === 'JSXText'\n        && /^\\s*$/.test(lines[lines.length - 1])\n  );\n  return token;\n}\n\n/**\n * Checks if the node is the first in its line, excluding whitespace.\n * @param {Object} context The node to check\n * @param {ASTNode} node The node to check\n * @return {boolean} true if it's the first node in its line\n */\nfunction isNodeFirstInLine(context, node) {\n  const token = getFirstNodeInLine(context, node);\n  const startLine = node.loc.start.line;\n  const endLine = token ? token.loc.end.line : -1;\n  return startLine !== endLine;\n}\n\n/**\n * Checks if the node is a function or arrow function expression.\n * @param {ASTNode} node The node to check\n * @return {boolean} true if it's a function-like expression\n */\nfunction isFunctionLikeExpression(node) {\n  return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n/**\n * Checks if the node is a function.\n * @param {ASTNode} node The node to check\n * @return {boolean} true if it's a function\n */\nfunction isFunction(node) {\n  return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';\n}\n\n/**\n * Checks if node is a function declaration or expression or arrow function.\n * @param {ASTNode} node The node to check\n * @return {boolean} true if it's a function-like\n */\nfunction isFunctionLike(node) {\n  return node.type === 'FunctionDeclaration' || isFunctionLikeExpression(node);\n}\n\n/**\n * Checks if the node is a class.\n * @param {ASTNode} node The node to check\n * @return {boolean} true if it's a class\n */\nfunction isClass(node) {\n  return node.type === 'ClassDeclaration' || node.type === 'ClassExpression';\n}\n\n/**\n * Check if we are in a class constructor\n * @param {Context} context\n * @param {ASTNode} node The AST node being checked.\n * @return {boolean}\n */\nfunction inConstructor(context, node) {\n  let scope = getScope(context, node);\n  while (scope) {\n    // @ts-ignore\n    if (scope.block && scope.block.parent && scope.block.parent.kind === 'constructor') {\n      return true;\n    }\n    scope = scope.upper;\n  }\n  return false;\n}\n\n/**\n * Removes quotes from around an identifier.\n * @param {string} string the identifier to strip\n * @returns {string}\n */\nfunction stripQuotes(string) {\n  return string.replace(/^'|'$/g, '');\n}\n\n/**\n * Retrieve the name of a key node\n * @param {Context} context The AST node with the key.\n * @param {any} node The AST node with the key.\n * @return {string | undefined} the name of the key\n */\nfunction getKeyValue(context, node) {\n  if (node.type === 'ObjectTypeProperty') {\n    const tokens = getFirstTokens(context, node, 2);\n    return (tokens[0].value === '+' || tokens[0].value === '-'\n      ? tokens[1].value\n      : stripQuotes(tokens[0].value)\n    );\n  }\n  if (node.type === 'GenericTypeAnnotation') {\n    return node.id.name;\n  }\n  if (node.type === 'ObjectTypeAnnotation') {\n    return;\n  }\n  const key = node.key || node.argument;\n  if (!key) {\n    return;\n  }\n  return key.type === 'Identifier' ? key.name : key.value;\n}\n\n/**\n * Checks if a node is surrounded by parenthesis.\n *\n * @param {object} context - Context from the rule\n * @param {ASTNode} node - Node to be checked\n * @returns {boolean}\n */\nfunction isParenthesized(context, node) {\n  const sourceCode = getSourceCode(context);\n  const previousToken = sourceCode.getTokenBefore(node);\n  const nextToken = sourceCode.getTokenAfter(node);\n\n  return !!previousToken && !!nextToken\n    && previousToken.value === '(' && previousToken.range[1] <= node.range[0]\n    && nextToken.value === ')' && nextToken.range[0] >= node.range[1];\n}\n\n/**\n * Checks if a node is being assigned a value: props.bar = 'bar'\n * @param {ASTNode} node The AST node being checked.\n * @returns {boolean}\n */\nfunction isAssignmentLHS(node) {\n  return (\n    node.parent\n    && node.parent.type === 'AssignmentExpression'\n    && node.parent.left === node\n  );\n}\n\nfunction isTSAsExpression(node) {\n  return node && node.type === 'TSAsExpression';\n}\n\n/**\n * Matcher used to check whether given node is a `CallExpression`\n * @param {ASTNode} node The AST node\n * @returns {boolean} True if node is a `CallExpression`, false if not\n */\nfunction isCallExpression(node) {\n  return node && node.type === 'CallExpression';\n}\n\n/**\n * Extracts the expression node that is wrapped inside a TS type assertion\n *\n * @param {ASTNode} node - potential TS node\n * @returns {ASTNode} - unwrapped expression node\n */\nfunction unwrapTSAsExpression(node) {\n  return isTSAsExpression(node) ? node.expression : node;\n}\n\nfunction isTSTypeReference(node) {\n  if (!node) return false;\n\n  return node.type === 'TSTypeReference';\n}\n\nfunction isTSTypeAnnotation(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSTypeAnnotation';\n}\n\nfunction isTSTypeLiteral(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSTypeLiteral';\n}\n\nfunction isTSIntersectionType(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSIntersectionType';\n}\n\nfunction isTSInterfaceHeritage(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSInterfaceHeritage';\n}\n\nfunction isTSInterfaceDeclaration(node) {\n  if (!node) { return false; }\n\n  return (node.type === 'ExportNamedDeclaration' && node.declaration\n    ? node.declaration.type\n    : node.type\n  ) === 'TSInterfaceDeclaration';\n}\n\nfunction isTSTypeDeclaration(node) {\n  if (!node) { return false; }\n\n  const nodeToCheck = node.type === 'ExportNamedDeclaration' && node.declaration\n    ? node.declaration\n    : node;\n\n  return nodeToCheck.type === 'VariableDeclaration' && nodeToCheck.kind === 'type';\n}\n\nfunction isTSTypeAliasDeclaration(node) {\n  if (!node) { return false; }\n\n  if (node.type === 'ExportNamedDeclaration' && node.declaration) {\n    return node.declaration.type === 'TSTypeAliasDeclaration' && node.exportKind === 'type';\n  }\n  return node.type === 'TSTypeAliasDeclaration';\n}\n\nfunction isTSParenthesizedType(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSTypeAliasDeclaration';\n}\n\nfunction isTSFunctionType(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSFunctionType';\n}\n\nfunction isTSTypeQuery(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSTypeQuery';\n}\n\nfunction isTSTypeParameterInstantiation(node) {\n  if (!node) { return false; }\n\n  return node.type === 'TSTypeParameterInstantiation';\n}\n\nfunction isMemberExpression(node) {\n  if (!node) { return false; }\n\n  return node.type === 'MemberExpression' || node.type === 'OptionalMemberExpression';\n}\n\nfunction isObjectPattern(node) {\n  if (!node) { return false; }\n\n  return node.type === 'ObjectPattern';\n}\n\nfunction isVariableDeclarator(node) {\n  if (!node) { return false; }\n\n  return node.type === 'VariableDeclarator';\n}\n\nmodule.exports = {\n  findReturnStatement,\n  getComponentProperties,\n  getFirstNodeInLine,\n  getKeyValue,\n  getPropertyName,\n  getPropertyNameNode,\n  inConstructor,\n  isAssignmentLHS,\n  isCallExpression,\n  isClass,\n  isFunction,\n  isFunctionLike,\n  isFunctionLikeExpression,\n  isMemberExpression,\n  isNodeFirstInLine,\n  isObjectPattern,\n  isParenthesized,\n  isTSAsExpression,\n  isTSFunctionType,\n  isTSInterfaceDeclaration,\n  isTSInterfaceHeritage,\n  isTSIntersectionType,\n  isTSParenthesizedType,\n  isTSTypeAliasDeclaration,\n  isTSTypeAnnotation,\n  isTSTypeDeclaration,\n  isTSTypeLiteral,\n  isTSTypeParameterInstantiation,\n  isTSTypeQuery,\n  isTSTypeReference,\n  isVariableDeclarator,\n  traverse,\n  traverseReturns,\n  unwrapTSAsExpression,\n};\n"
  },
  {
    "path": "lib/util/componentUtil.js",
    "content": "'use strict';\n\nconst doctrine = require('doctrine');\nconst pragmaUtil = require('./pragma');\nconst eslintUtil = require('./eslint');\n\nconst getScope = eslintUtil.getScope;\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @template {(_: object) => any} T\n * @param {T} fn\n * @returns {T}\n */\nfunction memoize(fn) {\n  const cache = new WeakMap();\n  // @ts-ignore\n  return function memoizedFn(arg) {\n    const cachedValue = cache.get(arg);\n    if (cachedValue !== undefined) {\n      return cachedValue;\n    }\n    const v = fn(arg);\n    cache.set(arg, v);\n    return v;\n  };\n}\n\nconst getPragma = memoize(pragmaUtil.getFromContext);\nconst getCreateClass = memoize(pragmaUtil.getCreateClassFromContext);\n\n/**\n * @param {ASTNode} node\n * @param {Context} context\n * @returns {boolean}\n */\nfunction isES5Component(node, context) {\n  const pragma = getPragma(context);\n  const createClass = getCreateClass(context);\n\n  if (!node.parent || !node.parent.callee) {\n    return false;\n  }\n  const callee = node.parent.callee;\n  // React.createClass({})\n  if (callee.type === 'MemberExpression') {\n    return callee.object.name === pragma && callee.property.name === createClass;\n  }\n  // createClass({})\n  if (callee.type === 'Identifier') {\n    return callee.name === createClass;\n  }\n  return false;\n}\n\n/**\n * Check if the node is explicitly declared as a descendant of a React Component\n * @param {any} node\n * @param {Context} context\n * @returns {boolean}\n */\nfunction isExplicitComponent(node, context) {\n  const sourceCode = getSourceCode(context);\n  let comment;\n  // Sometimes the passed node may not have been parsed yet by eslint, and this function call crashes.\n  // Can be removed when eslint sets \"parent\" property for all nodes on initial AST traversal: https://github.com/eslint/eslint-scope/issues/27\n  // eslint-disable-next-line no-warning-comments\n  // FIXME: Remove try/catch when https://github.com/eslint/eslint-scope/issues/27 is implemented.\n  try {\n    comment = sourceCode.getJSDocComment(node);\n  } catch (e) {\n    comment = null;\n  }\n\n  if (comment === null) {\n    return false;\n  }\n\n  let commentAst;\n  try {\n    commentAst = doctrine.parse(comment.value, {\n      unwrap: true,\n      tags: ['extends', 'augments'],\n    });\n  } catch (e) {\n    // handle a bug in the archived `doctrine`, see #2596\n    return false;\n  }\n\n  const relevantTags = commentAst.tags.filter((tag) => tag.name === 'React.Component' || tag.name === 'React.PureComponent');\n\n  return relevantTags.length > 0;\n}\n\n/**\n * @param {ASTNode} node\n * @param {Context} context\n * @returns {boolean}\n */\nfunction isES6Component(node, context) {\n  const pragma = getPragma(context);\n  if (isExplicitComponent(node, context)) {\n    return true;\n  }\n\n  if (!node.superClass) {\n    return false;\n  }\n  if (node.superClass.type === 'MemberExpression') {\n    return node.superClass.object.name === pragma\n          && /^(Pure)?Component$/.test(node.superClass.property.name);\n  }\n  if (node.superClass.type === 'Identifier') {\n    return /^(Pure)?Component$/.test(node.superClass.name);\n  }\n  return false;\n}\n\n/**\n * Get the parent ES5 component node from the current scope\n * @param {Context} context\n * @param {ASTNode} node\n * @returns {ASTNode|null}\n */\nfunction getParentES5Component(context, node) {\n  let scope = getScope(context, node);\n  while (scope) {\n    // @ts-ignore\n    node = scope.block && scope.block.parent && scope.block.parent.parent;\n    if (node && isES5Component(node, context)) {\n      return node;\n    }\n    scope = scope.upper;\n  }\n  return null;\n}\n\n/**\n * Get the parent ES6 component node from the current scope\n * @param {Context} context\n * @param {ASTNode} node\n * @returns {ASTNode | null}\n */\nfunction getParentES6Component(context, node) {\n  let scope = getScope(context, node);\n  while (scope && scope.type !== 'class') {\n    scope = scope.upper;\n  }\n  node = scope && scope.block;\n  if (!node || !isES6Component(node, context)) {\n    return null;\n  }\n  return node;\n}\n\n/**\n * Checks if a component extends React.PureComponent\n * @param {ASTNode} node\n * @param {Context} context\n * @returns {boolean}\n */\nfunction isPureComponent(node, context) {\n  const pragma = getPragma(context);\n  if (node.superClass) {\n    return new RegExp(`^(${pragma}\\\\.)?PureComponent$`).test(getText(context, node.superClass));\n  }\n  return false;\n}\n\n/**\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isStateMemberExpression(node) {\n  return node.type === 'MemberExpression'\n    && node.object.type === 'ThisExpression'\n    && node.property.name === 'state';\n}\n\nmodule.exports = {\n  isES5Component,\n  isES6Component,\n  getParentES5Component,\n  getParentES6Component,\n  isExplicitComponent,\n  isPureComponent,\n  isStateMemberExpression,\n};\n"
  },
  {
    "path": "lib/util/defaultProps.js",
    "content": "/**\n * @fileoverview Common defaultProps detection functionality.\n */\n\n'use strict';\n\nconst fromEntries = require('object.fromentries');\nconst astUtil = require('./ast');\nconst componentUtil = require('./componentUtil');\nconst propsUtil = require('./props');\nconst variableUtil = require('./variable');\nconst propWrapperUtil = require('./propWrapper');\nconst getText = require('./eslint').getText;\n\nconst QUOTES_REGEX = /^[\"']|[\"']$/g;\n\nmodule.exports = function defaultPropsInstructions(context, components, utils) {\n  /**\n   * Try to resolve the node passed in to a variable in the current scope. If the node passed in is not\n   * an Identifier, then the node is simply returned.\n   * @param   {ASTNode} node The node to resolve.\n   * @returns {ASTNode|null} Return null if the value could not be resolved, ASTNode otherwise.\n   */\n  function resolveNodeValue(node) {\n    if (node.type === 'Identifier') {\n      return variableUtil.findVariableByName(context, node, node.name);\n    }\n    if (\n      astUtil.isCallExpression(node)\n      && propWrapperUtil.isPropWrapperFunction(context, node.callee.name)\n      && node.arguments && node.arguments[0]\n    ) {\n      return resolveNodeValue(node.arguments[0]);\n    }\n    return node;\n  }\n\n  /**\n   * Extracts a DefaultProp from an ObjectExpression node.\n   * @param   {ASTNode} objectExpression ObjectExpression node.\n   * @returns {Object|string}            Object representation of a defaultProp, to be consumed by\n   *                                     `addDefaultPropsToComponent`, or string \"unresolved\", if the defaultProps\n   *                                     from this ObjectExpression can't be resolved.\n   */\n  function getDefaultPropsFromObjectExpression(objectExpression) {\n    const hasSpread = objectExpression.properties.find((property) => property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement');\n\n    if (hasSpread) {\n      return 'unresolved';\n    }\n\n    return objectExpression.properties.map((defaultProp) => ({\n      name: getText(context, defaultProp.key).replace(QUOTES_REGEX, ''),\n      node: defaultProp,\n    }));\n  }\n\n  /**\n   * Marks a component's DefaultProps declaration as \"unresolved\". A component's DefaultProps is\n   * marked as \"unresolved\" if we cannot safely infer the values of its defaultProps declarations\n   * without risking false negatives.\n   * @param   {Object} component The component to mark.\n   * @returns {void}\n   */\n  function markDefaultPropsAsUnresolved(component) {\n    components.set(component.node, {\n      defaultProps: 'unresolved',\n    });\n  }\n\n  /**\n   * Adds defaultProps to the component passed in.\n   * @param   {ASTNode}         component    The component to add the defaultProps to.\n   * @param   {Object[]|'unresolved'} defaultProps defaultProps to add to the component or the string \"unresolved\"\n   *                                         if this component has defaultProps that can't be resolved.\n   * @returns {void}\n   */\n  function addDefaultPropsToComponent(component, defaultProps) {\n    // Early return if this component's defaultProps is already marked as \"unresolved\".\n    if (component.defaultProps === 'unresolved') {\n      return;\n    }\n\n    if (defaultProps === 'unresolved') {\n      markDefaultPropsAsUnresolved(component);\n      return;\n    }\n\n    const defaults = component.defaultProps || {};\n    const newDefaultProps = Object.assign(\n      {},\n      defaults,\n      fromEntries(defaultProps.map((prop) => [prop.name, prop]))\n    );\n\n    components.set(component.node, {\n      defaultProps: newDefaultProps,\n    });\n  }\n\n  return {\n    MemberExpression(node) {\n      const isDefaultProp = propsUtil.isDefaultPropsDeclaration(node);\n\n      if (!isDefaultProp) {\n        return;\n      }\n\n      // find component this defaultProps belongs to\n      const component = utils.getRelatedComponent(node);\n      if (!component) {\n        return;\n      }\n\n      // e.g.:\n      // MyComponent.propTypes = {\n      //   foo: React.PropTypes.string.isRequired,\n      //   bar: React.PropTypes.string\n      // };\n      //\n      // or:\n      //\n      // MyComponent.propTypes = myPropTypes;\n      if (node.parent.type === 'AssignmentExpression') {\n        const expression = resolveNodeValue(node.parent.right);\n        if (!expression || expression.type !== 'ObjectExpression') {\n          // If a value can't be found, we mark the defaultProps declaration as \"unresolved\", because\n          // we should ignore this component and not report any errors for it, to avoid false-positives\n          // with e.g. external defaultProps declarations.\n          if (isDefaultProp) {\n            markDefaultPropsAsUnresolved(component);\n          }\n\n          return;\n        }\n\n        addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));\n\n        return;\n      }\n\n      // e.g.:\n      // MyComponent.propTypes.baz = React.PropTypes.string;\n      if (node.parent.type === 'MemberExpression' && node.parent.parent\n        && node.parent.parent.type === 'AssignmentExpression') {\n        addDefaultPropsToComponent(component, [{\n          name: node.parent.property.name,\n          node: node.parent.parent,\n        }]);\n      }\n    },\n\n    // e.g.:\n    // class Hello extends React.Component {\n    //   static get defaultProps() {\n    //     return {\n    //       name: 'Dean'\n    //     };\n    //   }\n    //   render() {\n    //     return <div>Hello {this.props.name}</div>;\n    //   }\n    // }\n    MethodDefinition(node) {\n      if (!node.static || node.kind !== 'get') {\n        return;\n      }\n\n      if (!propsUtil.isDefaultPropsDeclaration(node)) {\n        return;\n      }\n\n      // find component this propTypes/defaultProps belongs to\n      const component = components.get(componentUtil.getParentES6Component(context, node));\n      if (!component) {\n        return;\n      }\n\n      const returnStatement = utils.findReturnStatement(node);\n      if (!returnStatement) {\n        return;\n      }\n\n      const expression = resolveNodeValue(returnStatement.argument);\n      if (!expression || expression.type !== 'ObjectExpression') {\n        return;\n      }\n\n      addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));\n    },\n\n    // e.g.:\n    // class Greeting extends React.Component {\n    //   render() {\n    //     return (\n    //       <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n    //     );\n    //   }\n    //   static defaultProps = {\n    //     foo: 'bar',\n    //     bar: 'baz'\n    //   };\n    // }\n    'ClassProperty, PropertyDefinition'(node) {\n      if (!(node.static && node.value)) {\n        return;\n      }\n\n      const propName = astUtil.getPropertyName(node);\n      const isDefaultProp = propName === 'defaultProps' || propName === 'getDefaultProps';\n\n      if (!isDefaultProp) {\n        return;\n      }\n\n      // find component this propTypes/defaultProps belongs to\n      const component = components.get(componentUtil.getParentES6Component(context, node));\n      if (!component) {\n        return;\n      }\n\n      const expression = resolveNodeValue(node.value);\n      if (!expression || expression.type !== 'ObjectExpression') {\n        return;\n      }\n\n      addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));\n    },\n\n    // e.g.:\n    // React.createClass({\n    //   render: function() {\n    //     return <div>{this.props.foo}</div>;\n    //   },\n    //   getDefaultProps: function() {\n    //     return {\n    //       foo: 'default'\n    //     };\n    //   }\n    // });\n    ObjectExpression(node) {\n      // find component this propTypes/defaultProps belongs to\n      const component = componentUtil.isES5Component(node, context) && components.get(node);\n      if (!component) {\n        return;\n      }\n\n      // Search for the proptypes declaration\n      node.properties.forEach((property) => {\n        if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {\n          return;\n        }\n\n        const isDefaultProp = propsUtil.isDefaultPropsDeclaration(property);\n\n        if (isDefaultProp && property.value.type === 'FunctionExpression') {\n          const returnStatement = utils.findReturnStatement(property);\n          if (!returnStatement || returnStatement.argument.type !== 'ObjectExpression') {\n            return;\n          }\n\n          addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(returnStatement.argument));\n        }\n      });\n    },\n  };\n};\n"
  },
  {
    "path": "lib/util/docsUrl.js",
    "content": "'use strict';\n\nfunction docsUrl(ruleName) {\n  return `https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules/${ruleName}.md`;\n}\n\nmodule.exports = docsUrl;\n"
  },
  {
    "path": "lib/util/error.js",
    "content": "'use strict';\n\n/**\n * Logs out a message if there is no format option set.\n * @param {string} message - Message to log.\n */\nfunction error(message) {\n  if (!/=-(f|-format)=/.test(process.argv.join('='))) {\n    // eslint-disable-next-line no-console\n    console.error(message);\n  }\n}\n\nmodule.exports = error;\n"
  },
  {
    "path": "lib/util/eslint.js",
    "content": "'use strict';\n\nfunction getSourceCode(context) {\n  return context.getSourceCode ? context.getSourceCode() : context.sourceCode;\n}\n\nfunction getAncestors(context, node) {\n  const sourceCode = getSourceCode(context);\n  return sourceCode.getAncestors ? sourceCode.getAncestors(node) : context.getAncestors();\n}\n\nfunction getScope(context, node) {\n  const sourceCode = getSourceCode(context);\n  if (sourceCode.getScope) {\n    return sourceCode.getScope(node);\n  }\n\n  return context.getScope();\n}\n\nfunction markVariableAsUsed(name, node, context) {\n  const sourceCode = getSourceCode(context);\n  return sourceCode.markVariableAsUsed\n    ? sourceCode.markVariableAsUsed(name, node)\n    : context.markVariableAsUsed(name);\n}\n\nfunction getFirstTokens(context, node, count) {\n  const sourceCode = getSourceCode(context);\n  return sourceCode.getFirstTokens ? sourceCode.getFirstTokens(node, count) : context.getFirstTokens(node, count);\n}\n\nfunction getText(context) {\n  const sourceCode = getSourceCode(context);\n  const args = Array.prototype.slice.call(arguments, 1);\n  return sourceCode.getText ? sourceCode.getText.apply(sourceCode, args) : context.getSource.apply(context, args);\n}\n\nmodule.exports = {\n  getAncestors,\n  getFirstTokens,\n  getScope,\n  getSourceCode,\n  getText,\n  markVariableAsUsed,\n};\n"
  },
  {
    "path": "lib/util/getTokenBeforeClosingBracket.js",
    "content": "'use strict';\n\n/**\n * Find the token before the closing bracket.\n * @param {ASTNode} node - The JSX element node.\n * @returns {Token} The token before the closing bracket.\n */\nfunction getTokenBeforeClosingBracket(node) {\n  const attributes = node.attributes;\n  if (!attributes || attributes.length === 0) {\n    return node.name;\n  }\n  return attributes[attributes.length - 1];\n}\n\nmodule.exports = getTokenBeforeClosingBracket;\n"
  },
  {
    "path": "lib/util/isCreateContext.js",
    "content": "'use strict';\n\nconst astUtil = require('./ast');\n\n/**\n * Checks if the node is a React.createContext call\n * @param {ASTNode} node - The AST node being checked.\n * @returns {boolean} - True if node is a React.createContext call, false if not.\n */\nmodule.exports = function isCreateContext(node) {\n  if (\n    node.init\n    && node.init.callee\n  ) {\n    if (\n      astUtil.isCallExpression(node.init)\n      && node.init.callee.name === 'createContext'\n    ) {\n      return true;\n    }\n\n    if (\n      node.init.callee.type === 'MemberExpression'\n      && node.init.callee.property\n      && node.init.callee.property.name === 'createContext'\n    ) {\n      return true;\n    }\n  }\n\n  if (\n    node.expression\n    && node.expression.type === 'AssignmentExpression'\n    && node.expression.operator === '='\n    && astUtil.isCallExpression(node.expression.right)\n    && node.expression.right.callee\n  ) {\n    const right = node.expression.right;\n\n    if (right.callee.name === 'createContext') {\n      return true;\n    }\n\n    if (\n      right.callee.type === 'MemberExpression'\n      && right.callee.property\n      && right.callee.property.name === 'createContext'\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n"
  },
  {
    "path": "lib/util/isCreateElement.js",
    "content": "'use strict';\n\nconst pragmaUtil = require('./pragma');\nconst isDestructuredFromPragmaImport = require('./isDestructuredFromPragmaImport');\n\n/**\n * Checks if the node is a createElement call\n * @param {Context} context - The AST node being checked.\n * @param {ASTNode} node - The AST node being checked.\n * @returns {boolean} - True if node is a createElement call object literal, False if not.\n*/\nmodule.exports = function isCreateElement(context, node) {\n  if (!node.callee) {\n    return false;\n  }\n\n  if (\n    node.callee.type === 'MemberExpression'\n    && node.callee.property.name === 'createElement'\n    && node.callee.object\n    && node.callee.object.name === pragmaUtil.getFromContext(context)\n  ) {\n    return true;\n  }\n\n  if (\n    node.callee.name === 'createElement'\n    && isDestructuredFromPragmaImport(context, node, 'createElement')\n  ) {\n    return true;\n  }\n\n  return false;\n};\n"
  },
  {
    "path": "lib/util/isDestructuredFromPragmaImport.js",
    "content": "'use strict';\n\nconst astUtil = require('./ast');\nconst pragmaUtil = require('./pragma');\nconst variableUtil = require('./variable');\n\n/**\n * Check if variable is destructured from pragma import\n *\n * @param {Context} context eslint context\n * @param {ASTNode} node The AST node to check\n * @param {string} variable The variable name to check\n * @returns {boolean} True if createElement is destructured from the pragma\n */\nmodule.exports = function isDestructuredFromPragmaImport(context, node, variable) {\n  const pragma = pragmaUtil.getFromContext(context);\n  const variableInScope = variableUtil.getVariableFromContext(context, node, variable);\n  if (variableInScope) {\n    const latestDef = variableUtil.getLatestVariableDefinition(variableInScope);\n    if (latestDef) {\n      // check if latest definition is a variable declaration: 'variable = value'\n      if (latestDef.node.type === 'VariableDeclarator' && latestDef.node.init) {\n        // check for: 'variable = pragma.variable'\n        if (\n          latestDef.node.init.type === 'MemberExpression'\n          && latestDef.node.init.object.type === 'Identifier'\n          && latestDef.node.init.object.name === pragma\n        ) {\n          return true;\n        }\n        // check for: '{variable} = pragma'\n        if (\n          latestDef.node.init.type === 'Identifier'\n          && latestDef.node.init.name === pragma\n        ) {\n          return true;\n        }\n\n        // \"require('react')\"\n        let requireExpression = null;\n\n        // get \"require('react')\" from: \"{variable} = require('react')\"\n        if (astUtil.isCallExpression(latestDef.node.init)) {\n          requireExpression = latestDef.node.init;\n        }\n        // get \"require('react')\" from: \"variable = require('react').variable\"\n        if (\n          !requireExpression\n          && latestDef.node.init.type === 'MemberExpression'\n          && astUtil.isCallExpression(latestDef.node.init.object)\n        ) {\n          requireExpression = latestDef.node.init.object;\n        }\n\n        // check proper require.\n        if (\n          requireExpression\n          && requireExpression.callee\n          && requireExpression.callee.name === 'require'\n          && requireExpression.arguments[0]\n          && requireExpression.arguments[0].value === pragma.toLocaleLowerCase()\n        ) {\n          return true;\n        }\n\n        return false;\n      }\n\n      // latest definition is an import declaration: import {<variable>} from 'react'\n      if (\n        latestDef.parent\n        && latestDef.parent.type === 'ImportDeclaration'\n        && latestDef.parent.source.value === pragma.toLocaleLowerCase()\n      ) {\n        return true;\n      }\n    }\n  }\n  return false;\n};\n"
  },
  {
    "path": "lib/util/isFirstLetterCapitalized.js",
    "content": "'use strict';\n\n/**\n * Check if the first letter of a string is capitalized.\n * @param {string} word String to check\n * @returns {boolean} True if first letter is capitalized.\n */\nmodule.exports = function isFirstLetterCapitalized(word) {\n  if (!word) {\n    return false;\n  }\n  const firstLetter = word.replace(/^_+/, '').charAt(0);\n  return firstLetter.toUpperCase() === firstLetter;\n};\n"
  },
  {
    "path": "lib/util/jsx.js",
    "content": "/**\n * @fileoverview Utility functions for JSX\n */\n\n'use strict';\n\nconst elementType = require('jsx-ast-utils/elementType');\n\nconst astUtil = require('./ast');\nconst isCreateElement = require('./isCreateElement');\nconst variableUtil = require('./variable');\n\n// See https://github.com/babel/babel/blob/ce420ba51c68591e057696ef43e028f41c6e04cd/packages/babel-types/src/validators/react/isCompatTag.js\n// for why we only test for the first character\nconst COMPAT_TAG_REGEX = /^[a-z]/;\n\n/**\n * Checks if a node represents a DOM element according to React.\n * @param {object} node - JSXOpeningElement to check.\n * @returns {boolean} Whether or not the node corresponds to a DOM element.\n */\nfunction isDOMComponent(node) {\n  const name = elementType(node);\n  return COMPAT_TAG_REGEX.test(name);\n}\n\n/**\n * Test whether a JSXElement is a fragment\n * @param {JSXElement} node\n * @param {string} reactPragma\n * @param {string} fragmentPragma\n * @returns {boolean}\n */\nfunction isFragment(node, reactPragma, fragmentPragma) {\n  const name = node.openingElement.name;\n\n  // <Fragment>\n  if (name.type === 'JSXIdentifier' && name.name === fragmentPragma) {\n    return true;\n  }\n\n  // <React.Fragment>\n  if (\n    name.type === 'JSXMemberExpression'\n    && name.object.type === 'JSXIdentifier'\n    && name.object.name === reactPragma\n    && name.property.type === 'JSXIdentifier'\n    && name.property.name === fragmentPragma\n  ) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Checks if a node represents a JSX element or fragment.\n * @param {object} node - node to check.\n * @returns {boolean} Whether or not the node if a JSX element or fragment.\n */\nfunction isJSX(node) {\n  return node && ['JSXElement', 'JSXFragment'].indexOf(node.type) >= 0;\n}\n\n/**\n * Check if node is like `key={...}` as in `<Foo key={...} />`\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isJSXAttributeKey(node) {\n  return node.type === 'JSXAttribute'\n    && node.name\n    && node.name.type === 'JSXIdentifier'\n    && node.name.name === 'key';\n}\n\n/**\n * Check if value has only whitespaces\n * @param {unknown} value\n * @returns {boolean}\n */\nfunction isWhiteSpaces(value) {\n  return typeof value === 'string' ? /^\\s*$/.test(value) : false;\n}\n\n/**\n * Check if the node is returning JSX or null\n *\n * @param {Context} context The context of `ASTNode`.\n * @param {ASTNode} ASTnode The AST node being checked\n * @param {boolean} [strict] If true, in a ternary condition the node must return JSX in both cases\n * @param {boolean} [ignoreNull] If true, null return values will be ignored\n * @returns {boolean} True if the node is returning JSX or null, false if not\n */\nfunction isReturningJSX(context, ASTnode, strict, ignoreNull) {\n  const isJSXValue = (node) => {\n    if (!node) {\n      return false;\n    }\n    switch (node.type) {\n      case 'ConditionalExpression':\n        if (strict) {\n          return isJSXValue(node.consequent) && isJSXValue(node.alternate);\n        }\n        return isJSXValue(node.consequent) || isJSXValue(node.alternate);\n      case 'LogicalExpression':\n        if (strict) {\n          return isJSXValue(node.left) && isJSXValue(node.right);\n        }\n        return isJSXValue(node.left) || isJSXValue(node.right);\n      case 'SequenceExpression':\n        return isJSXValue(node.expressions[node.expressions.length - 1]);\n      case 'JSXElement':\n      case 'JSXFragment':\n        return true;\n      case 'CallExpression':\n        return isCreateElement(context, node);\n      case 'Literal':\n        if (!ignoreNull && node.value === null) {\n          return true;\n        }\n        return false;\n      case 'Identifier': {\n        const variable = variableUtil.findVariableByName(context, node, node.name);\n        return isJSX(variable);\n      }\n      default:\n        return false;\n    }\n  };\n\n  let found = false;\n  astUtil.traverseReturns(ASTnode, context, (node, breakTraverse) => {\n    if (isJSXValue(node)) {\n      found = true;\n      breakTraverse();\n    }\n  });\n\n  return found;\n}\n\n/**\n * Check if the node is returning only null values\n *\n * @param {ASTNode} ASTnode The AST node being checked\n * @param {Context} context The context of `ASTNode`.\n * @returns {boolean} True if the node is returning only null values\n */\nfunction isReturningOnlyNull(ASTnode, context) {\n  let found = false;\n  let foundSomethingElse = false;\n  astUtil.traverseReturns(ASTnode, context, (node) => {\n    // Traverse return statement\n    astUtil.traverse(node, {\n      enter(childNode) {\n        const setFound = () => {\n          found = true;\n          this.skip();\n        };\n        const setFoundSomethingElse = () => {\n          foundSomethingElse = true;\n          this.skip();\n        };\n        switch (childNode.type) {\n          case 'ReturnStatement':\n            break;\n          case 'ConditionalExpression':\n            if (childNode.consequent.value === null && childNode.alternate.value === null) {\n              setFound();\n            }\n            break;\n          case 'Literal':\n            if (childNode.value === null) {\n              setFound();\n            }\n            break;\n          default:\n            setFoundSomethingElse();\n        }\n      },\n    });\n  });\n\n  return found && !foundSomethingElse;\n}\n\nmodule.exports = {\n  isDOMComponent,\n  isFragment,\n  isJSX,\n  isJSXAttributeKey,\n  isWhiteSpaces,\n  isReturningJSX,\n  isReturningOnlyNull,\n};\n"
  },
  {
    "path": "lib/util/lifecycleMethods.js",
    "content": "/**\n * @fileoverview lifecycle methods\n * @author Tan Nguyen\n */\n\n'use strict';\n\nmodule.exports = {\n  instance: [\n    'getDefaultProps',\n    'getInitialState',\n    'getChildContext',\n    'componentWillMount',\n    'UNSAFE_componentWillMount',\n    'componentDidMount',\n    'componentWillReceiveProps',\n    'UNSAFE_componentWillReceiveProps',\n    'shouldComponentUpdate',\n    'componentWillUpdate',\n    'UNSAFE_componentWillUpdate',\n    'getSnapshotBeforeUpdate',\n    'componentDidUpdate',\n    'componentDidCatch',\n    'componentWillUnmount',\n    'render',\n  ],\n  static: [\n    'getDerivedStateFromProps',\n  ],\n};\n"
  },
  {
    "path": "lib/util/linkComponents.js",
    "content": "/**\n * @fileoverview Utility functions for propWrapperFunctions setting\n */\n\n'use strict';\n\nconst iterFrom = require('es-iterator-helpers/Iterator.from');\nconst map = require('es-iterator-helpers/Iterator.prototype.map');\n\n/** TODO: type {(string | { name: string, linkAttribute: string })[]} */\n/** @type {any} */\nconst DEFAULT_LINK_COMPONENTS = ['a'];\nconst DEFAULT_LINK_ATTRIBUTE = 'href';\n\n/** TODO: type {(string | { name: string, formAttribute: string })[]} */\n/** @type {any} */\nconst DEFAULT_FORM_COMPONENTS = ['form'];\nconst DEFAULT_FORM_ATTRIBUTE = 'action';\n\nfunction getFormComponents(context) {\n  const settings = context.settings || {};\n  const formComponents = /** @type {typeof DEFAULT_FORM_COMPONENTS} */ (\n    DEFAULT_FORM_COMPONENTS.concat(settings.formComponents || [])\n  );\n  return new Map(map(iterFrom(formComponents), (value) => {\n    if (typeof value === 'string') {\n      return [value, [DEFAULT_FORM_ATTRIBUTE]];\n    }\n    return [value.name, [].concat(value.formAttribute)];\n  }));\n}\n\nfunction getLinkComponents(context) {\n  const settings = context.settings || {};\n  const linkComponents = /** @type {typeof DEFAULT_LINK_COMPONENTS} */ (\n    DEFAULT_LINK_COMPONENTS.concat(settings.linkComponents || [])\n  );\n  return new Map(map(iterFrom(linkComponents), (value) => {\n    if (typeof value === 'string') {\n      return [value, [DEFAULT_LINK_ATTRIBUTE]];\n    }\n    return [value.name, [].concat(value.linkAttribute)];\n  }));\n}\n\nmodule.exports = {\n  getFormComponents,\n  getLinkComponents,\n};\n"
  },
  {
    "path": "lib/util/log.js",
    "content": "'use strict';\n\n/**\n * Logs out a message if there is no format option set.\n * @param {string} message - Message to log.\n */\nfunction log(message) {\n  if (!/=-(f|-format)=/.test(process.argv.join('='))) {\n    // eslint-disable-next-line no-console\n    console.log(message);\n  }\n}\n\nmodule.exports = log;\n"
  },
  {
    "path": "lib/util/makeNoMethodSetStateRule.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in lifecycle methods\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst findLast = require('array.prototype.findlast');\n\nconst docsUrl = require('./docsUrl');\nconst report = require('./report');\nconst getAncestors = require('./eslint').getAncestors;\nconst testReactVersion = require('./version').testReactVersion;\n\n// ------------------------------------------------------------------------------\n// Rule Definition\n// ------------------------------------------------------------------------------\n\nfunction mapTitle(methodName) {\n  const map = {\n    componentDidMount: 'did-mount',\n    componentDidUpdate: 'did-update',\n    componentWillUpdate: 'will-update',\n  };\n  const title = map[methodName];\n  if (!title) {\n    throw Error(`No docsUrl for '${methodName}'`);\n  }\n  return `no-${title}-set-state`;\n}\n\nconst messages = {\n  noSetState: 'Do not use setState in {{name}}',\n};\n\nconst methodNoopsAsOf = {\n  componentDidMount: '>= 16.3.0',\n  componentDidUpdate: '>= 16.3.0',\n};\n\nfunction shouldBeNoop(context, methodName) {\n  return methodName in methodNoopsAsOf\n    && testReactVersion(context, methodNoopsAsOf[methodName])\n    && !testReactVersion(context, '999.999.999'); // for when the version is not specified\n}\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * @param {string} methodName\n * @param {(context: import('eslint').Rule.RuleContext) => boolean} [shouldCheckUnsafeCb]\n * @returns {import('eslint').Rule.RuleModule}\n */\nmodule.exports = function makeNoMethodSetStateRule(methodName, shouldCheckUnsafeCb) {\n  return {\n    meta: {\n      docs: {\n        description: `Disallow usage of setState in ${methodName}`,\n        category: 'Best Practices',\n        recommended: false,\n        url: docsUrl(mapTitle(methodName)),\n      },\n\n      messages,\n\n      schema: [{\n        enum: ['disallow-in-func'],\n      }],\n    },\n\n    create(context) {\n      const mode = context.options[0] || 'allow-in-func';\n\n      function nameMatches(name) {\n        if (name === methodName) {\n          return true;\n        }\n\n        if (typeof shouldCheckUnsafeCb === 'function' && shouldCheckUnsafeCb(context)) {\n          return name === `UNSAFE_${methodName}`;\n        }\n\n        return false;\n      }\n\n      if (shouldBeNoop(context, methodName)) {\n        return {};\n      }\n\n      // --------------------------------------------------------------------------\n      // Public\n      // --------------------------------------------------------------------------\n\n      return {\n        CallExpression(node) {\n          const callee = node.callee;\n          if (\n            callee.type !== 'MemberExpression'\n            || callee.object.type !== 'ThisExpression'\n            || !('name' in callee.property)\n            || callee.property.name !== 'setState'\n          ) {\n            return;\n          }\n          const ancestors = getAncestors(context, node);\n          let depth = 0;\n          findLast(ancestors, (ancestor) => {\n          // ancestors.some((ancestor) => {\n            if (/Function(Expression|Declaration)$/.test(ancestor.type)) {\n              depth += 1;\n            }\n            if (\n              (ancestor.type !== 'Property' && ancestor.type !== 'MethodDefinition' && ancestor.type !== 'ClassProperty' && ancestor.type !== 'PropertyDefinition')\n              || !nameMatches(ancestor.key.name)\n              || (mode !== 'disallow-in-func' && depth > 1)\n            ) {\n              return false;\n            }\n            report(context, messages.noSetState, 'noSetState', {\n              node: callee,\n              data: {\n                name: ancestor.key.name,\n              },\n            });\n            return true;\n          });\n        },\n      };\n    },\n  };\n};\n"
  },
  {
    "path": "lib/util/message.js",
    "content": "'use strict';\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\n\nmodule.exports = function getMessageData(messageId, message) {\n  return messageId && semver.satisfies(eslintPkg.version, '>= 4.15') ? { messageId } : { message };\n};\n"
  },
  {
    "path": "lib/util/pragma.js",
    "content": "/**\n * @fileoverview Utility functions for React pragma configuration\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst getSourceCode = require('./eslint').getSourceCode;\n\nconst JSX_ANNOTATION_REGEX = /@jsx\\s+([^\\s]+)/;\n// Does not check for reserved keywords or unicode characters\nconst JS_IDENTIFIER_REGEX = /^[_$a-zA-Z][_$a-zA-Z0-9]*$/;\n\n/**\n * @param {Context} context\n * @returns {string}\n */\nfunction getCreateClassFromContext(context) {\n  let pragma = 'createReactClass';\n  // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  if (context.settings.react && context.settings.react.createClass) {\n    pragma = context.settings.react.createClass;\n  }\n  if (!JS_IDENTIFIER_REGEX.test(pragma)) {\n    throw new Error(`createClass pragma ${pragma} is not a valid function name`);\n  }\n  return pragma;\n}\n\n/**\n * @param {Context} context\n * @returns {string}\n */\nfunction getFragmentFromContext(context) {\n  let pragma = 'Fragment';\n  // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  if (context.settings.react && context.settings.react.fragment) {\n    pragma = context.settings.react.fragment;\n  }\n  if (!JS_IDENTIFIER_REGEX.test(pragma)) {\n    throw new Error(`Fragment pragma ${pragma} is not a valid identifier`);\n  }\n  return pragma;\n}\n\n/**\n * @param {Context} context\n * @returns {string}\n */\nfunction getFromContext(context) {\n  let pragma = 'React';\n\n  const sourceCode = getSourceCode(context);\n  const pragmaNode = sourceCode.getAllComments().find((node) => JSX_ANNOTATION_REGEX.test(node.value));\n\n  if (pragmaNode) {\n    const matches = JSX_ANNOTATION_REGEX.exec(pragmaNode.value);\n    pragma = matches[1].split('.')[0];\n    // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  } else if (context.settings.react && context.settings.react.pragma) {\n    pragma = context.settings.react.pragma;\n  }\n\n  if (!JS_IDENTIFIER_REGEX.test(pragma)) {\n    console.warn(`React pragma ${pragma} is not a valid identifier`);\n    return 'React';\n  }\n  return pragma;\n}\n\nmodule.exports = {\n  getCreateClassFromContext,\n  getFragmentFromContext,\n  getFromContext,\n};\n"
  },
  {
    "path": "lib/util/propTypes.js",
    "content": "/**\n * @fileoverview Common propTypes detection functionality.\n */\n\n'use strict';\n\nconst flatMap = require('array.prototype.flatmap');\n\nconst annotations = require('./annotations');\nconst propsUtil = require('./props');\nconst variableUtil = require('./variable');\nconst testFlowVersion = require('./version').testFlowVersion;\nconst propWrapperUtil = require('./propWrapper');\nconst astUtil = require('./ast');\nconst isFirstLetterCapitalized = require('./isFirstLetterCapitalized');\nconst eslintUtil = require('./eslint');\n\nconst getFirstTokens = eslintUtil.getFirstTokens;\nconst getScope = eslintUtil.getScope;\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n/**\n * Check if node is function type.\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isFunctionType(node) {\n  if (!node) return false;\n  const nodeType = node.type;\n  return nodeType === 'FunctionDeclaration'\n    || nodeType === 'FunctionExpression'\n    || nodeType === 'ArrowFunctionExpression';\n}\n\n/**\n * Checks if we are declaring a props as a generic type in a flow-annotated class.\n *\n * @param {ASTNode} node  the AST node being checked.\n * @returns {boolean} True if the node is a class with generic prop types, false if not.\n */\nfunction isSuperTypeParameterPropsDeclaration(node) {\n  if (node && (node.type === 'ClassDeclaration' || node.type === 'ClassExpression')) {\n    const parameters = propsUtil.getSuperTypeArguments(node);\n    if (parameters && parameters.params.length > 0) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Iterates through a properties node, like a customized forEach.\n * @param {Object} context Array of properties to iterate.\n * @param {Object[]} properties Array of properties to iterate.\n * @param {Function} fn Function to call on each property, receives property key\n    and property value. (key, value) => void\n  * @param {Function} [handleSpreadFn] Function to call on each ObjectTypeSpreadProperty, receives the\n    argument\n */\nfunction iterateProperties(context, properties, fn, handleSpreadFn) {\n  if (properties && properties.length && typeof fn === 'function') {\n    for (let i = 0, j = properties.length; i < j; i++) {\n      const node = properties[i];\n      const key = astUtil.getKeyValue(context, node);\n\n      if (node.type === 'ObjectTypeSpreadProperty' && typeof handleSpreadFn === 'function') {\n        handleSpreadFn(node.argument);\n      }\n\n      const value = node.value;\n      fn(key, value, node);\n    }\n  }\n}\n\n/**\n * Checks if a node is inside a class body.\n *\n * @param {ASTNode} node the AST node being checked.\n * @returns {boolean} True if the node has a ClassBody ancestor, false if not.\n */\nfunction isInsideClassBody(node) {\n  let parent = node.parent;\n  while (parent) {\n    if (parent.type === 'ClassBody') {\n      return true;\n    }\n    parent = parent.parent;\n  }\n  return false;\n}\n\nfunction startWithCapitalizedLetter(node) {\n  return (\n    node.parent.type === 'VariableDeclarator'\n    && !isFirstLetterCapitalized(node.parent.id.name)\n  );\n}\n\nmodule.exports = function propTypesInstructions(context, components, utils) {\n  // Used to track the type annotations in scope.\n  // Necessary because babel's scopes do not track type annotations.\n  let stack = null;\n\n  const classExpressions = [];\n  const defaults = { customValidators: [] };\n  const configuration = Object.assign({}, defaults, context.options[0] || {});\n  const customValidators = configuration.customValidators;\n  const allowedGenericTypes = new Set(['ComponentProps', 'ComponentPropsWithRef', 'ComponentPropsWithoutRef', 'forwardRef', 'ForwardRefRenderFunction', 'VFC', 'VoidFunctionComponent', 'PropsWithChildren', 'SFC', 'StatelessComponent', 'FunctionComponent', 'FC']);\n  const genericTypeParamIndexWherePropsArePresent = {\n    ComponentProps: 0,\n    ComponentPropsWithRef: 0,\n    ComponentPropsWithoutRef: 0,\n    ForwardRefRenderFunction: 1,\n    forwardRef: 1,\n    VoidFunctionComponent: 0,\n    VFC: 0,\n    PropsWithChildren: 0,\n    SFC: 0,\n    StatelessComponent: 0,\n    FunctionComponent: 0,\n    FC: 0,\n  };\n  const genericReactTypesImport = new Set();\n  // import { FC as X } from 'react' -> localToImportedMap = { x: FC }\n  const localToImportedMap = {};\n\n  /**\n   * Returns the full scope.\n   * @returns {Object} The whole scope.\n   */\n  function typeScope() {\n    return stack[stack.length - 1];\n  }\n\n  /**\n   * Gets a node from the scope.\n   * @param {string} key The name of the identifier to access.\n   * @returns {ASTNode} The ASTNode associated with the given identifier.\n   */\n  function getInTypeScope(key) {\n    return stack[stack.length - 1][key];\n  }\n\n  /**\n   * Sets the new value in the scope.\n   * @param {string} key The name of the identifier to access\n   * @param {ASTNode} value The new value for the identifier.\n   * @returns {ASTNode} The ASTNode associated with the given identifier.\n   */\n  function setInTypeScope(key, value) {\n    stack[stack.length - 1][key] = value;\n    return value;\n  }\n\n  /**\n   * Checks if prop should be validated by plugin-react-proptypes\n   * @param {string} validator Name of validator to check.\n   * @returns {boolean} True if validator should be checked by custom validator.\n   */\n  function hasCustomValidator(validator) {\n    return customValidators.indexOf(validator) !== -1;\n  }\n\n  /* eslint-disable no-use-before-define */\n  /** @type {TypeDeclarationBuilders} */\n  const typeDeclarationBuilders = {\n    GenericTypeAnnotation(annotation, parentName, seen) {\n      if (getInTypeScope(annotation.id.name)) {\n        return buildTypeAnnotationDeclarationTypes(getInTypeScope(annotation.id.name), parentName, seen);\n      }\n      return {};\n    },\n\n    ObjectTypeAnnotation(annotation, parentName, seen) {\n      let containsUnresolvedObjectTypeSpread = false;\n      let containsSpread = false;\n      const containsIndexers = !!annotation.indexers && annotation.indexers.length > 0;\n      const shapeTypeDefinition = {\n        type: 'shape',\n        children: {},\n      };\n      iterateProperties(\n        context,\n        annotation.properties,\n        (childKey, childValue, propNode) => {\n          const fullName = [parentName, childKey].join('.');\n          if (childKey || childValue) {\n            const types = buildTypeAnnotationDeclarationTypes(childValue, fullName, seen);\n            types.fullName = fullName;\n            types.name = childKey;\n            types.node = propNode;\n            types.isRequired = !childValue.optional;\n            shapeTypeDefinition.children[childKey] = types;\n          }\n        },\n        (spreadNode) => {\n          const key = astUtil.getKeyValue(context, spreadNode);\n          const types = buildTypeAnnotationDeclarationTypes(spreadNode, key, seen);\n          if (!types.children) {\n            containsUnresolvedObjectTypeSpread = true;\n          } else {\n            Object.assign(shapeTypeDefinition, types.children);\n          }\n          containsSpread = true;\n        }\n      );\n\n      // Mark if this shape has spread or an indexer. We will know to consider all props from this shape as having propTypes,\n      // but still have the ability to detect unused children of this shape.\n      shapeTypeDefinition.containsUnresolvedSpread = containsUnresolvedObjectTypeSpread;\n      shapeTypeDefinition.containsIndexers = containsIndexers;\n      // Deprecated: containsSpread is not used anymore in the codebase, ensure to keep API backward compatibility\n      shapeTypeDefinition.containsSpread = containsSpread;\n\n      return shapeTypeDefinition;\n    },\n\n    UnionTypeAnnotation(annotation, parentName, seen) {\n      /** @type {UnionTypeDefinition} */\n      const unionTypeDefinition = {\n        type: 'union',\n        children: annotation.types.map((type) => buildTypeAnnotationDeclarationTypes(type, parentName, seen)),\n      };\n      if (unionTypeDefinition.children.length === 0) {\n        // no complex type found, simply accept everything\n        return {};\n      }\n      return unionTypeDefinition;\n    },\n\n    ArrayTypeAnnotation(annotation, parentName, seen) {\n      const fullName = [parentName, '*'].join('.');\n      const child = buildTypeAnnotationDeclarationTypes(annotation.elementType, fullName, seen);\n      child.fullName = fullName;\n      child.name = '__ANY_KEY__';\n      child.node = annotation;\n      return {\n        type: 'object',\n        children: {\n          __ANY_KEY__: child,\n        },\n      };\n    },\n  };\n  /* eslint-enable no-use-before-define */\n\n  /**\n   * Resolve the type annotation for a given node.\n   * Flow annotations are sometimes wrapped in outer `TypeAnnotation`\n   * and `NullableTypeAnnotation` nodes which obscure the annotation we're\n   * interested in.\n   * This method also resolves type aliases where possible.\n   *\n   * @param {ASTNode} node The annotation or a node containing the type annotation.\n   * @returns {ASTNode} The resolved type annotation for the node.\n   */\n  function resolveTypeAnnotation(node) {\n    let annotation = (node.left && node.left.typeAnnotation) || node.typeAnnotation || node;\n    while (annotation && (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation')) {\n      annotation = annotation.typeAnnotation;\n    }\n    if (annotation.type === 'GenericTypeAnnotation' && getInTypeScope(annotation.id.name)) {\n      return getInTypeScope(annotation.id.name);\n    }\n    return annotation;\n  }\n\n  /**\n   * Creates the representation of the React props type annotation for the component.\n   * The representation is used to verify nested used properties.\n   * @param {ASTNode} annotation Type annotation for the props class property.\n   * @param {string} parentName\n   * @param {Set<ASTNode>} [seen]\n   * @return {Object} The representation of the declaration, empty object means\n   *    the property is declared without the need for further analysis.\n   */\n  function buildTypeAnnotationDeclarationTypes(annotation, parentName, seen) {\n    if (typeof seen === 'undefined') {\n      // Keeps track of annotations we've already seen to\n      // prevent problems with recursive types.\n      seen = new Set();\n    }\n    if (seen.has(annotation)) {\n      // This must be a recursive type annotation, so just accept anything.\n      return {};\n    }\n    seen.add(annotation);\n\n    if (annotation.type in typeDeclarationBuilders) {\n      return typeDeclarationBuilders[annotation.type](annotation, parentName, seen);\n    }\n    return {};\n  }\n\n  /**\n   * Marks all props found inside ObjectTypeAnnotation as declared.\n   *\n   * Modifies the declaredProperties object\n   * @param {ASTNode} propTypes\n   * @param {Object} declaredPropTypes\n   * @returns {boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)\n   */\n  function declarePropTypesForObjectTypeAnnotation(propTypes, declaredPropTypes) {\n    let ignorePropsValidation = false;\n\n    iterateProperties(context, propTypes.properties, (key, value, propNode) => {\n      if (!value) {\n        ignorePropsValidation = ignorePropsValidation || propNode.type !== 'ObjectTypeSpreadProperty';\n        return;\n      }\n\n      const types = buildTypeAnnotationDeclarationTypes(value, key);\n      types.fullName = key;\n      types.name = key;\n      types.node = propNode;\n      types.isRequired = !propNode.optional;\n      declaredPropTypes[key] = types;\n    }, (spreadNode) => {\n      const key = astUtil.getKeyValue(context, spreadNode);\n      const spreadAnnotation = getInTypeScope(key);\n      if (!spreadAnnotation) {\n        ignorePropsValidation = true;\n      } else {\n        const spreadIgnoreValidation = declarePropTypesForObjectTypeAnnotation(spreadAnnotation, declaredPropTypes);\n        ignorePropsValidation = ignorePropsValidation || spreadIgnoreValidation;\n      }\n    });\n\n    return ignorePropsValidation;\n  }\n\n  /**\n   * Marks all props found inside IntersectionTypeAnnotation as declared.\n   * Since InterSectionTypeAnnotations can be nested, this handles recursively.\n   *\n   * Modifies the declaredPropTypes object\n   * @param {ASTNode} propTypes\n   * @param {Object} declaredPropTypes\n   * @returns {boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)\n   */\n  function declarePropTypesForIntersectionTypeAnnotation(propTypes, declaredPropTypes) {\n    return propTypes.types.some((annotation) => {\n      if (annotation.type === 'ObjectTypeAnnotation') {\n        return declarePropTypesForObjectTypeAnnotation(annotation, declaredPropTypes);\n      }\n\n      if (annotation.type === 'UnionTypeAnnotation') {\n        return true;\n      }\n\n      // Type can't be resolved\n      if (!annotation.id) {\n        return true;\n      }\n\n      const typeNode = getInTypeScope(annotation.id.name);\n\n      if (!typeNode) {\n        return true;\n      }\n      if (typeNode.type === 'IntersectionTypeAnnotation') {\n        return declarePropTypesForIntersectionTypeAnnotation(typeNode, declaredPropTypes);\n      }\n\n      return declarePropTypesForObjectTypeAnnotation(typeNode, declaredPropTypes);\n    });\n  }\n\n  /**\n   * Resolve node of type Identifier when building declaration types.\n   * @param {ASTNode} node\n   * @param {ASTNode} rootNode\n   * @param {Function} callback called with the resolved value only if resolved.\n   */\n  function resolveValueForIdentifierNode(node, rootNode, callback) {\n    if (\n      rootNode\n      && node\n      && node.type === 'Identifier'\n    ) {\n      const scope = getScope(context, rootNode);\n      const identVariable = scope.variableScope.variables.find(\n        (variable) => variable.name === node.name\n      );\n      if (identVariable) {\n        const definition = identVariable.defs[identVariable.defs.length - 1];\n        callback(definition.node.init);\n      }\n    }\n  }\n\n  /**\n   * Creates the representation of the React propTypes for the component.\n   * The representation is used to verify nested used properties.\n   * @param {ASTNode} value Node of the PropTypes for the desired property\n   * @param {string} parentName\n   * @param {ASTNode} rootNode\n   * @return {Object} The representation of the declaration, empty object means\n   *    the property is declared without the need for further analysis.\n   */\n  function buildReactDeclarationTypes(value, parentName, rootNode) {\n    if (\n      value\n      && value.callee\n      && value.callee.object\n      && hasCustomValidator(value.callee.object.name)\n    ) {\n      return {};\n    }\n\n    let identNodeResolved = false;\n    // Resolve identifier node for cases where isRequired is set in\n    // the variable declaration or not at all.\n    // const variableType = PropTypes.shape({ foo: ... }).isRequired\n    // propTypes = {\n    //   example: variableType\n    // }\n    // --------\n    // const variableType = PropTypes.shape({ foo: ... })\n    // propTypes = {\n    //   example: variableType\n    // }\n    resolveValueForIdentifierNode(value, rootNode, (newValue) => {\n      identNodeResolved = true;\n      value = newValue;\n    });\n\n    if (\n      value\n      && value.type === 'MemberExpression'\n      && value.property\n      && value.property.name === 'isRequired'\n    ) {\n      value = value.object;\n    }\n\n    // Resolve identifier node for cases where isRequired is set in\n    // the prop types.\n    // const variableType = PropTypes.shape({ foo: ... })\n    // propTypes = {\n    //   example: variableType.isRequired\n    // }\n    if (!identNodeResolved) {\n      resolveValueForIdentifierNode(value, rootNode, (newValue) => {\n        value = newValue;\n      });\n    }\n\n    // Verify PropTypes that are functions\n    if (\n      astUtil.isCallExpression(value)\n      && value.callee\n      && value.callee.property\n      && value.callee.property.name\n      && value.arguments\n      && value.arguments.length > 0\n    ) {\n      const callName = value.callee.property.name;\n      const argument = value.arguments[0];\n      switch (callName) {\n        case 'shape':\n        case 'exact': {\n          if (argument.type !== 'ObjectExpression') {\n            // Invalid proptype or cannot analyse statically\n            return {};\n          }\n          const shapeTypeDefinition = {\n            type: callName,\n            children: {},\n          };\n          iterateProperties(context, argument.properties, (childKey, childValue, propNode) => {\n            if (childValue) { // skip spread propTypes\n              const fullName = [parentName, childKey].join('.');\n              const types = buildReactDeclarationTypes(childValue, fullName, rootNode);\n              types.fullName = fullName;\n              types.name = childKey;\n              types.node = propNode;\n              shapeTypeDefinition.children[childKey] = types;\n            }\n          });\n          return shapeTypeDefinition;\n        }\n        case 'arrayOf':\n        case 'objectOf': {\n          const fullName = [parentName, '*'].join('.');\n          const child = buildReactDeclarationTypes(argument, fullName, rootNode);\n          child.fullName = fullName;\n          child.name = '__ANY_KEY__';\n          child.node = argument;\n          return {\n            type: 'object',\n            children: {\n              __ANY_KEY__: child,\n            },\n          };\n        }\n        case 'oneOfType': {\n          if (\n            !argument.elements\n            || argument.elements.length === 0\n          ) {\n            // Invalid proptype or cannot analyse statically\n            return {};\n          }\n\n          /** @type {UnionTypeDefinition} */\n          const unionTypeDefinition = {\n            type: 'union',\n            children: argument.elements.map((element) => buildReactDeclarationTypes(element, parentName, rootNode)),\n          };\n          if (unionTypeDefinition.children.length === 0) {\n            // no complex type found, simply accept everything\n            return {};\n          }\n          return unionTypeDefinition;\n        }\n        default:\n          return {};\n      }\n    }\n    // Unknown property or accepts everything (any, object, ...)\n    return {};\n  }\n\n  function isValidReactGenericTypeAnnotation(annotation) {\n    if (annotation.typeName) {\n      if (annotation.typeName.name) { // if FC<Props>\n        const typeName = annotation.typeName.name;\n        if (!genericReactTypesImport.has(typeName)) {\n          return false;\n        }\n      } else if (annotation.typeName.right.name) { // if React.FC<Props>\n        const right = annotation.typeName.right.name;\n        const left = annotation.typeName.left.name;\n\n        if (!genericReactTypesImport.has(left) || !allowedGenericTypes.has(right)) {\n          return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  /**\n   * Returns the left most typeName of a node, e.g: FC<Props>, React.FC<Props>\n   * The representation is used to verify nested used properties.\n   * @param {ASTNode} node\n   * @return {string | undefined}\n   */\n  function getLeftMostTypeName(node) {\n    if (node.name) return node.name;\n    if (node.left) return getLeftMostTypeName(node.left);\n  }\n\n  function getRightMostTypeName(node) {\n    if (node.name) return node.name;\n    if (node.right) return getRightMostTypeName(node.right);\n  }\n\n  /**\n   * Returns true if the node is either a interface or type alias declaration\n   * @param {ASTNode} node\n   * @return {boolean}\n   */\n  function filterInterfaceOrTypeAlias(node) {\n    return (\n      astUtil.isTSInterfaceDeclaration(node) || astUtil.isTSTypeAliasDeclaration(node)\n    );\n  }\n\n  /**\n   * Returns true if the interface or type alias declaration node name matches the type-name str\n   * @param {ASTNode} node\n   * @param {string} typeName\n   * @return {boolean}\n   */\n  function filterInterfaceOrAliasByName(node, typeName) {\n    return (\n      node.id\n      && node.id.name === typeName\n    ) || (\n      node.declaration\n      && node.declaration.id\n      && node.declaration.id.name === typeName\n    );\n  }\n\n  class DeclarePropTypesForTSTypeAnnotation {\n    constructor(propTypes, declaredPropTypes, rootNode) {\n      this.propTypes = propTypes;\n      this.declaredPropTypes = declaredPropTypes;\n      this.foundDeclaredPropertiesList = [];\n      this.referenceNameMap = new Set();\n      this.sourceCode = getSourceCode(context);\n      this.shouldIgnorePropTypes = false;\n      this.rootNode = rootNode;\n      this.visitTSNode(this.propTypes);\n      this.endAndStructDeclaredPropTypes();\n    }\n\n    /**\n     * The node will be distribute to different function.\n     * @param {ASTNode} node\n     */\n    visitTSNode(node) {\n      if (!node) return;\n      if (astUtil.isTSTypeAnnotation(node)) {\n        const typeAnnotation = node.typeAnnotation;\n        this.visitTSNode(typeAnnotation);\n      } else if (astUtil.isTSTypeReference(node)) {\n        this.searchDeclarationByName(node);\n      } else if (astUtil.isTSInterfaceHeritage(node)) {\n        this.searchDeclarationByName(node);\n      } else if (astUtil.isTSTypeLiteral(node)) {\n        // Check node is an object literal\n        if (Array.isArray(node.members)) {\n          this.foundDeclaredPropertiesList = this.foundDeclaredPropertiesList.concat(node.members);\n        }\n      } else if (astUtil.isTSIntersectionType(node)) {\n        this.convertIntersectionTypeToPropTypes(node);\n      } else if (astUtil.isTSParenthesizedType(node)) {\n        const typeAnnotation = node.typeAnnotation;\n        this.visitTSNode(typeAnnotation);\n      } else if (astUtil.isTSTypeParameterInstantiation(node)) {\n        if (Array.isArray(node.params)) {\n          node.params.forEach((x) => this.visitTSNode(x));\n        }\n      } else {\n        this.shouldIgnorePropTypes = true;\n      }\n    }\n\n    /**\n     * Search TSInterfaceDeclaration or TSTypeAliasDeclaration,\n     * by using TSTypeReference and TSInterfaceHeritage name.\n     * @param {ASTNode} node\n     */\n    searchDeclarationByName(node) {\n      let typeName;\n      if (astUtil.isTSTypeReference(node)) {\n        typeName = node.typeName.name;\n        const leftMostName = getLeftMostTypeName(node.typeName);\n        const shouldTraverseTypeParams = genericReactTypesImport.has(leftMostName);\n        const nodeTypeArguments = propsUtil.getTypeArguments(node);\n        if (shouldTraverseTypeParams && nodeTypeArguments && nodeTypeArguments.length !== 0) {\n          // All react Generic types are derived from:\n          // type PropsWithChildren<P> = P & { children?: ReactNode | undefined }\n          // So we should construct an optional children prop\n          this.shouldSpecifyOptionalChildrenProps = true;\n\n          const rightMostName = getRightMostTypeName(node.typeName);\n          if (\n            leftMostName === 'React'\n            && (\n              rightMostName === 'HTMLAttributes'\n              || rightMostName === 'HTMLElement'\n              || rightMostName === 'HTMLProps'\n            )\n          ) {\n            this.shouldSpecifyClassNameProp = true;\n          }\n\n          const importedName = localToImportedMap[rightMostName];\n          const idx = genericTypeParamIndexWherePropsArePresent[\n            leftMostName !== rightMostName ? rightMostName : importedName\n          ];\n          const nextNode = nodeTypeArguments.params[idx];\n          this.visitTSNode(nextNode);\n          return;\n        }\n      } else if (astUtil.isTSInterfaceHeritage(node)) {\n        if (!node.expression && node.id) {\n          typeName = node.id.name;\n        } else {\n          typeName = node.expression.name;\n        }\n      }\n      if (!typeName) {\n        this.shouldIgnorePropTypes = true;\n        return;\n      }\n      if (typeName === 'ReturnType') {\n        this.convertReturnTypeToPropTypes(node, this.rootNode);\n        return;\n      }\n      // Prevent recursive inheritance will cause maximum callstack.\n      if (this.referenceNameMap.has(typeName)) {\n        this.shouldIgnorePropTypes = true;\n        return;\n      }\n      // Add typeName to Set and consider it as traversed.\n      this.referenceNameMap.add(typeName);\n\n      /**\n       * From line 577 to line 581, and line 588 to line 590 are trying to handle typescript-eslint-parser\n       * Need to be deprecated after remove typescript-eslint-parser support.\n       */\n      const candidateTypes = this.sourceCode.ast.body.filter((item) => astUtil.isTSTypeDeclaration(item));\n\n      const declarations = flatMap(\n        candidateTypes,\n        (type) => (\n          type.declarations\n          || (\n            type.declaration\n            && type.declaration.declarations\n          )\n          || type.declaration\n        )\n      );\n\n      // we tried to find either an interface or a type with the TypeReference name\n      const typeDeclaration = declarations.filter((dec) => dec.id.name === typeName);\n\n      const interfaceDeclarations = this.sourceCode.ast.body\n        .filter(filterInterfaceOrTypeAlias)\n        .filter((item) => filterInterfaceOrAliasByName(item, typeName))\n        .map((item) => (item.declaration || item));\n\n      if (typeDeclaration.length !== 0) {\n        typeDeclaration.map((t) => t.init || t.typeAnnotation).forEach(this.visitTSNode, this);\n      } else if (interfaceDeclarations.length !== 0) {\n        interfaceDeclarations.forEach(this.traverseDeclaredInterfaceOrTypeAlias, this);\n      } else {\n        this.shouldIgnorePropTypes = true;\n      }\n    }\n\n    /**\n     * Traverse TSInterfaceDeclaration and TSTypeAliasDeclaration\n     * which retrieve from function searchDeclarationByName;\n     * @param {ASTNode} node\n     */\n    traverseDeclaredInterfaceOrTypeAlias(node) {\n      if (astUtil.isTSInterfaceDeclaration(node)) {\n        // Handle TSInterfaceDeclaration interface Props { name: string, id: number}, should put in properties list directly;\n        this.foundDeclaredPropertiesList = this.foundDeclaredPropertiesList.concat(node.body.body);\n      }\n      // Handle TSTypeAliasDeclaration type Props = {name:string}\n      if (astUtil.isTSTypeAliasDeclaration(node)) {\n        const typeAnnotation = node.typeAnnotation;\n        this.visitTSNode(typeAnnotation);\n      }\n      if (Array.isArray(node.extends)) {\n        node.extends.forEach((x) => this.visitTSNode(x));\n        // This line is trying to handle typescript-eslint-parser\n        // typescript-eslint-parser extension is name as heritage\n      } else if (Array.isArray(node.heritage)) {\n        node.heritage.forEach((x) => this.visitTSNode(x));\n      }\n    }\n\n    convertIntersectionTypeToPropTypes(node) {\n      if (!node) return;\n      if (Array.isArray(node.types)) {\n        node.types.forEach((x) => this.visitTSNode(x));\n      } else {\n        this.shouldIgnorePropTypes = true;\n      }\n    }\n\n    convertReturnTypeToPropTypes(node, rootNode) {\n      // ReturnType<T> should always have one parameter\n      const nodeTypeArguments = propsUtil.getTypeArguments(node);\n      if (nodeTypeArguments) {\n        if (nodeTypeArguments.params.length === 1) {\n          let returnType = nodeTypeArguments.params[0];\n          // This line is trying to handle typescript-eslint-parser\n          // typescript-eslint-parser TSTypeQuery is wrapped by TSTypeReference\n          if (astUtil.isTSTypeReference(returnType)) {\n            returnType = returnType.typeName;\n          }\n          // Handle ReturnType<typeof mapStateToProps>\n          if (astUtil.isTSTypeQuery(returnType)) {\n            const returnTypeFunction = flatMap(this.sourceCode.ast.body\n              .filter((item) => item.type === 'VariableDeclaration'\n                && item.declarations.find((dec) => dec.id.name === returnType.exprName.name)\n              ), (type) => type.declarations).map((dec) => dec.init);\n\n            if (Array.isArray(returnTypeFunction)) {\n              if (returnTypeFunction.length === 0) {\n                // Cannot find identifier in current scope. It might be an exported type.\n                this.shouldIgnorePropTypes = true;\n                return;\n              }\n              returnTypeFunction.forEach((func) => {\n                if (isFunctionType(func)) {\n                  let res = func.body;\n                  if (res.type === 'BlockStatement') {\n                    res = astUtil.findReturnStatement(func);\n                    if (res) {\n                      res = res.argument;\n                    }\n                  }\n                  switch (res.type) {\n                    case 'ObjectExpression':\n                      iterateProperties(context, res.properties, (key, value, propNode) => {\n                        if (propNode && astUtil.isCallExpression(propNode.argument)) {\n                          const propNodeTypeArguments = propsUtil.getTypeArguments(propNode.argument);\n                          if (propNodeTypeArguments) {\n                            this.visitTSNode(propNodeTypeArguments);\n                          } else {\n                            // Ignore this CallExpression return value since it doesn't have any typeParameters to let us know it's types.\n                            this.shouldIgnorePropTypes = true;\n                            return;\n                          }\n                        }\n                        if (!value) {\n                          this.shouldIgnorePropTypes = true;\n                          return;\n                        }\n                        const types = buildReactDeclarationTypes(value, key, rootNode);\n                        types.fullName = key;\n                        types.name = key;\n                        types.node = propNode;\n                        types.isRequired = propsUtil.isRequiredPropType(value);\n                        this.declaredPropTypes[key] = types;\n                      });\n                      break;\n                    case 'CallExpression':\n                      if (propsUtil.getTypeArguments(res)) {\n                        this.visitTSNode(propsUtil.getTypeArguments(res));\n                      } else {\n                        // Ignore this CallExpression return value since it doesn't have any typeParameters to let us know it's types.\n                        this.shouldIgnorePropTypes = true;\n                      }\n                      break;\n                    default:\n                  }\n                }\n              });\n              return;\n            }\n          }\n          // Handle ReturnType<()=>returnType>\n          if (astUtil.isTSFunctionType(returnType)) {\n            if (astUtil.isTSTypeAnnotation(returnType.returnType)) {\n              this.visitTSNode(returnType.returnType);\n              return;\n            }\n            // This line is trying to handle typescript-eslint-parser\n            // typescript-eslint-parser TSFunction name returnType as typeAnnotation\n            if (astUtil.isTSTypeAnnotation(returnType.typeAnnotation)) {\n              this.visitTSNode(returnType.typeAnnotation);\n              return;\n            }\n          }\n        }\n      }\n      this.shouldIgnorePropTypes = true;\n    }\n\n    endAndStructDeclaredPropTypes() {\n      if (this.shouldSpecifyOptionalChildrenProps) {\n        this.declaredPropTypes.children = {\n          fullName: 'children',\n          name: 'children',\n          isRequired: false,\n        };\n      }\n      if (this.shouldSpecifyClassNameProp) {\n        this.declaredPropTypes.className = {\n          fullName: 'className',\n          name: 'className',\n          isRequired: false,\n        };\n      }\n\n      this.foundDeclaredPropertiesList.forEach((tsInterfaceBody) => {\n        if (tsInterfaceBody && (tsInterfaceBody.type === 'TSPropertySignature' || tsInterfaceBody.type === 'TSMethodSignature')) {\n          let accessor = 'name';\n          if (tsInterfaceBody.key.type === 'Literal') {\n            if (typeof tsInterfaceBody.key.value === 'number') {\n              accessor = 'raw';\n            } else {\n              accessor = 'value';\n            }\n          }\n          this.declaredPropTypes[tsInterfaceBody.key[accessor]] = {\n            fullName: tsInterfaceBody.key[accessor],\n            name: tsInterfaceBody.key[accessor],\n            node: tsInterfaceBody,\n            isRequired: !tsInterfaceBody.optional,\n          };\n        }\n      });\n    }\n  }\n\n  /**\n   * Mark a prop type as declared\n   * @param {ASTNode} node The AST node being checked.\n   * @param {ASTNode} propTypes The AST node containing the proptypes\n   * @param {ASTNode} rootNode\n   */\n  function markPropTypesAsDeclared(node, propTypes, rootNode) {\n    let componentNode = node;\n    while (componentNode && !components.get(componentNode)) {\n      componentNode = componentNode.parent;\n    }\n    const component = components.get(componentNode);\n    let declaredPropTypes = (component && component.declaredPropTypes) || {};\n    let ignorePropsValidation = (component && component.ignorePropsValidation) || false;\n    switch (propTypes && propTypes.type) {\n      case 'ObjectTypeAnnotation':\n        ignorePropsValidation = declarePropTypesForObjectTypeAnnotation(propTypes, declaredPropTypes);\n        break;\n      case 'ObjectExpression':\n        iterateProperties(context, propTypes.properties, (key, value, propNode) => {\n          if (!value) {\n            ignorePropsValidation = true;\n            return;\n          }\n          const types = buildReactDeclarationTypes(value, key, rootNode);\n          types.fullName = key;\n          types.name = key;\n          types.node = propNode;\n          types.isRequired = propsUtil.isRequiredPropType(value);\n          declaredPropTypes[key] = types;\n        });\n        break;\n      case 'MemberExpression': {\n        let curDeclaredPropTypes = declaredPropTypes;\n        // Walk the list of properties, until we reach the assignment\n        // ie: ClassX.propTypes.a.b.c = ...\n        while (\n          propTypes\n          && propTypes.parent\n          && propTypes.parent.type !== 'AssignmentExpression'\n          && propTypes.property\n          && curDeclaredPropTypes\n        ) {\n          const propName = propTypes.property.name;\n          if (propName in curDeclaredPropTypes) {\n            curDeclaredPropTypes = curDeclaredPropTypes[propName].children;\n            propTypes = propTypes.parent;\n          } else {\n            // This will crash at runtime because we haven't seen this key before\n            // stop this and do not declare it\n            propTypes = null;\n          }\n        }\n        if (propTypes && propTypes.parent && propTypes.property) {\n          if (!(propTypes === propTypes.parent.left && propTypes.parent.left.object)) {\n            ignorePropsValidation = true;\n            break;\n          }\n          const parentProp = getText(context, propTypes.parent.left.object).replace(/^.*\\.propTypes\\./, '');\n          const types = buildReactDeclarationTypes(\n            propTypes.parent.right,\n            parentProp,\n            rootNode\n          );\n\n          types.name = propTypes.property.name;\n          types.fullName = [parentProp, propTypes.property.name].join('.');\n          types.node = propTypes.parent;\n          types.isRequired = propsUtil.isRequiredPropType(propTypes.parent.right);\n          curDeclaredPropTypes[propTypes.property.name] = types;\n        } else {\n          let isUsedInPropTypes = false;\n          let n = propTypes;\n          while (n) {\n            if (((n.type === 'AssignmentExpression') && propsUtil.isPropTypesDeclaration(n.left))\n              || ((n.type === 'ClassProperty' || n.type === 'PropertyDefinition' || n.type === 'Property') && propsUtil.isPropTypesDeclaration(n))) {\n              // Found a propType used inside of another propType. This is not considered usage, we'll still validate\n              // this component.\n              isUsedInPropTypes = true;\n              break;\n            }\n            n = n.parent;\n          }\n          if (!isUsedInPropTypes) {\n            ignorePropsValidation = true;\n          }\n        }\n        break;\n      }\n      case 'Identifier': {\n        const firstMatchingVariable = variableUtil.getVariableFromContext(context, node, propTypes.name);\n        if (firstMatchingVariable) {\n          const defInScope = firstMatchingVariable.defs[firstMatchingVariable.defs.length - 1];\n          markPropTypesAsDeclared(node, defInScope.node && defInScope.node.init, rootNode);\n          return;\n        }\n        ignorePropsValidation = true;\n        break;\n      }\n      case 'CallExpression': {\n        if (\n          propWrapperUtil.isPropWrapperFunction(\n            context,\n            getText(context, propTypes.callee)\n          )\n          && propTypes.arguments && propTypes.arguments[0]\n        ) {\n          markPropTypesAsDeclared(node, propTypes.arguments[0], rootNode);\n          return;\n        }\n        break;\n      }\n      case 'IntersectionTypeAnnotation':\n        ignorePropsValidation = declarePropTypesForIntersectionTypeAnnotation(propTypes, declaredPropTypes);\n        break;\n      case 'GenericTypeAnnotation':\n        if (propTypes.id.name === '$ReadOnly') {\n          const propTypeArguments = propsUtil.getTypeArguments(propTypes);\n          ignorePropsValidation = declarePropTypesForObjectTypeAnnotation(\n            propTypeArguments.params[0],\n            declaredPropTypes\n          );\n        } else {\n          ignorePropsValidation = true;\n        }\n        break;\n      case 'TSTypeReference':\n      case 'TSTypeAnnotation': {\n        const tsTypeAnnotation = new DeclarePropTypesForTSTypeAnnotation(propTypes, declaredPropTypes, rootNode);\n        ignorePropsValidation = tsTypeAnnotation.shouldIgnorePropTypes;\n        declaredPropTypes = tsTypeAnnotation.declaredPropTypes;\n      }\n        break;\n      case null:\n        break;\n      default:\n        ignorePropsValidation = true;\n        break;\n    }\n\n    components.set(node, {\n      declaredPropTypes,\n      ignorePropsValidation,\n    });\n  }\n\n  /**\n   * @param {ASTNode} node We expect either an ArrowFunctionExpression,\n   *   FunctionDeclaration, or FunctionExpression\n   * @param {ASTNode} rootNode\n   */\n  function markAnnotatedFunctionArgumentsAsDeclared(node, rootNode) {\n    if (!node.params || !node.params.length) {\n      return;\n    }\n\n    let propTypesArguments = null;\n    if (node.parent) {\n      propTypesArguments = propsUtil.getTypeArguments(node.parent);\n    }\n\n    if (\n      node.parent\n      && node.parent.callee\n      && propTypesArguments\n      && propTypesArguments.params\n      && (\n        node.parent.callee.name === 'forwardRef' || (\n          node.parent.callee.object\n          && node.parent.callee.property\n          && node.parent.callee.object.name === 'React'\n          && node.parent.callee.property.name === 'forwardRef'\n        )\n      )\n    ) {\n      const declaredPropTypes = {};\n      const obj = new DeclarePropTypesForTSTypeAnnotation(propTypesArguments.params[1], declaredPropTypes, rootNode);\n      components.set(node, {\n        declaredPropTypes: obj.declaredPropTypes,\n        ignorePropsValidation: obj.shouldIgnorePropTypes,\n      });\n      return;\n    }\n\n    const siblingIdentifier = node.parent && node.parent.id;\n    const siblingHasTypeAnnotation = siblingIdentifier && siblingIdentifier.typeAnnotation;\n    const isNodeAnnotated = annotations.isAnnotatedFunctionPropsDeclaration(node, context);\n\n    if (!isNodeAnnotated && !siblingHasTypeAnnotation) {\n      return;\n    }\n\n    // https://github.com/jsx-eslint/eslint-plugin-react/issues/2784\n    if (isInsideClassBody(node) && !astUtil.isFunction(node)) {\n      return;\n    }\n\n    // Should ignore function that not return JSXElement\n    if (!utils.isReturningJSXOrNull(node) || startWithCapitalizedLetter(node)) {\n      return;\n    }\n\n    if (isNodeAnnotated) {\n      const param = node.params[0];\n      if (param.typeAnnotation && param.typeAnnotation.typeAnnotation && param.typeAnnotation.typeAnnotation.type === 'UnionTypeAnnotation') {\n        param.typeAnnotation.typeAnnotation.types.forEach((annotation) => {\n          if (annotation.type === 'GenericTypeAnnotation') {\n            markPropTypesAsDeclared(node, resolveTypeAnnotation(annotation), rootNode);\n          } else {\n            markPropTypesAsDeclared(node, annotation, rootNode);\n          }\n        });\n      } else {\n        markPropTypesAsDeclared(node, resolveTypeAnnotation(param), rootNode);\n      }\n    } else {\n      // implements what's discussed here: https://github.com/jsx-eslint/eslint-plugin-react/issues/2777#issuecomment-683944481\n      const annotation = siblingIdentifier.typeAnnotation.typeAnnotation;\n\n      if (\n        annotation\n        && annotation.type !== 'TSTypeReference'\n        && propsUtil.getTypeArguments(annotation) == null\n      ) {\n        return;\n      }\n\n      if (!isValidReactGenericTypeAnnotation(annotation)) return;\n\n      markPropTypesAsDeclared(node, resolveTypeAnnotation(siblingIdentifier), rootNode);\n    }\n  }\n\n  /**\n   * Resolve the type annotation for a given class declaration node.\n   *\n   * @param {ASTNode} node The annotation or a node containing the type annotation.\n   * @returns {ASTNode} The resolved type annotation for the node.\n   */\n  function resolveSuperParameterPropsType(node) {\n    let propsParameterPosition;\n    const parameters = propsUtil.getSuperTypeArguments(node);\n\n    try {\n      // Flow <=0.52 had 3 required TypedParameters of which the second one is the Props.\n      // Flow >=0.53 has 2 optional TypedParameters of which the first one is the Props.\n      propsParameterPosition = testFlowVersion(context, '>= 0.53.0') ? 0 : 1;\n    } catch (e) {\n      // In case there is no flow version defined, we can safely assume that when there are 3 Props we are dealing with version <= 0.52\n      propsParameterPosition = parameters.params.length <= 2 ? 0 : 1;\n    }\n\n    let annotation = parameters.params[propsParameterPosition];\n    while (annotation && (annotation.type === 'TypeAnnotation' || annotation.type === 'NullableTypeAnnotation')) {\n      annotation = annotation.typeAnnotation;\n    }\n\n    if (annotation && annotation.type === 'GenericTypeAnnotation' && getInTypeScope(annotation.id.name)) {\n      return getInTypeScope(annotation.id.name);\n    }\n    return annotation;\n  }\n\n  /**\n   * Checks if we are declaring a `props` class property with a flow type annotation.\n   * @param {ASTNode} node The AST node being checked.\n   * @returns {boolean} True if the node is a type annotated props declaration, false if not.\n   */\n  function isAnnotatedClassPropsDeclaration(node) {\n    if (node && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')) {\n      const tokens = getFirstTokens(context, node, 2);\n      if (\n        node.typeAnnotation && (\n          tokens[0].value === 'props'\n          || (tokens[1] && tokens[1].value === 'props')\n        )\n      ) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  return {\n    ClassExpression(node) {\n      // TypeParameterDeclaration need to be added to typeScope in order to handle ClassExpressions.\n      // This visitor is executed before TypeParameterDeclaration are scoped, therefore we postpone\n      // processing class expressions until when the program exists.\n      classExpressions.push(node);\n    },\n\n    ClassDeclaration(node) {\n      if (isSuperTypeParameterPropsDeclaration(node)) {\n        markPropTypesAsDeclared(node, resolveSuperParameterPropsType(node), node);\n      }\n    },\n\n    'ClassProperty, PropertyDefinition'(node) {\n      if (isAnnotatedClassPropsDeclaration(node)) {\n        markPropTypesAsDeclared(node, resolveTypeAnnotation(node), node);\n      } else if (propsUtil.isPropTypesDeclaration(node)) {\n        markPropTypesAsDeclared(node, node.value, node);\n      }\n    },\n\n    ObjectExpression(node) {\n      // Search for the proptypes declaration\n      node.properties.forEach((property) => {\n        if (!propsUtil.isPropTypesDeclaration(property)) {\n          return;\n        }\n        markPropTypesAsDeclared(node, property.value, node);\n      });\n    },\n\n    FunctionExpression(node) {\n      if (node.parent.type !== 'MethodDefinition') {\n        markAnnotatedFunctionArgumentsAsDeclared(node, node);\n      }\n    },\n\n    ImportDeclaration(node) {\n      // parse `import ... from 'react`\n      if (node.source.value === 'react') {\n        node.specifiers.forEach((specifier) => {\n          if (\n            // handles import * as X from 'react'\n            specifier.type === 'ImportNamespaceSpecifier'\n            // handles import React from 'react'\n            || specifier.type === 'ImportDefaultSpecifier'\n          ) {\n            genericReactTypesImport.add(specifier.local.name);\n          }\n\n          // handles import { FC } from 'react' or import { FC as X } from 'react'\n          if (specifier.type === 'ImportSpecifier' && allowedGenericTypes.has(specifier.imported.name)) {\n            genericReactTypesImport.add(specifier.local.name);\n            localToImportedMap[specifier.local.name] = specifier.imported.name;\n          }\n        });\n      }\n    },\n\n    FunctionDeclaration: markAnnotatedFunctionArgumentsAsDeclared,\n\n    ArrowFunctionExpression: markAnnotatedFunctionArgumentsAsDeclared,\n\n    MemberExpression(node) {\n      if (propsUtil.isPropTypesDeclaration(node)) {\n        const component = utils.getRelatedComponent(node);\n        if (!component) {\n          return;\n        }\n        try {\n          markPropTypesAsDeclared(component.node, node.parent.right || node.parent, node);\n        } catch (e) {\n          if (e.constructor !== RangeError) { throw e; }\n        }\n      }\n    },\n\n    MethodDefinition(node) {\n      if (!node.static || node.kind !== 'get' || !propsUtil.isPropTypesDeclaration(node)) {\n        return;\n      }\n\n      let i = node.value.body.body.length - 1;\n      for (; i >= 0; i--) {\n        if (node.value.body.body[i].type === 'ReturnStatement') {\n          break;\n        }\n      }\n\n      if (i >= 0) {\n        markPropTypesAsDeclared(node, node.value.body.body[i].argument, node);\n      }\n    },\n\n    TypeAlias(node) {\n      setInTypeScope(node.id.name, node.right);\n    },\n\n    TypeParameterDeclaration(node) {\n      const identifier = node.params[0];\n\n      if (identifier.typeAnnotation) {\n        setInTypeScope(identifier.name, identifier.typeAnnotation.typeAnnotation);\n      }\n    },\n\n    Program() {\n      stack = [{}];\n    },\n\n    BlockStatement() {\n      stack.push(Object.create(typeScope()));\n    },\n\n    'BlockStatement:exit'() {\n      stack.pop();\n    },\n\n    'Program:exit'() {\n      classExpressions.forEach((node) => {\n        if (isSuperTypeParameterPropsDeclaration(node)) {\n          markPropTypesAsDeclared(node, resolveSuperParameterPropsType(node), node);\n        }\n      });\n    },\n  };\n};\n"
  },
  {
    "path": "lib/util/propTypesSort.js",
    "content": "/**\n * @fileoverview Common propTypes sorting functionality.\n */\n\n'use strict';\n\nconst toSorted = require('array.prototype.tosorted');\n\nconst astUtil = require('./ast');\nconst eslintUtil = require('./eslint');\n\nconst getSourceCode = eslintUtil.getSourceCode;\nconst getText = eslintUtil.getText;\n\n/**\n * Returns the value name of a node.\n *\n * @param {ASTNode} node the node to check.\n * @returns {string} The name of the node.\n */\nfunction getValueName(node) {\n  return node.type === 'Property'\n    && node.value.property\n    && node.value.property.name;\n}\n\n/**\n * Checks if the prop is required or not.\n *\n * @param {ASTNode} node the prop to check.\n * @returns {boolean} true if the prop is required.\n */\nfunction isRequiredProp(node) {\n  return getValueName(node) === 'isRequired';\n}\n\n/**\n * Checks if the proptype is a callback by checking if it starts with 'on'.\n *\n * @param {string} propName the name of the proptype to check.\n * @returns {boolean} true if the proptype is a callback.\n */\nfunction isCallbackPropName(propName) {\n  return /^on[A-Z]/.test(propName);\n}\n\n/**\n * Checks if the prop is PropTypes.shape.\n *\n * @param {ASTNode} node the prop to check.\n * @returns {boolean} true if the prop is PropTypes.shape.\n */\nfunction isShapeProp(node) {\n  return !!(\n    node\n    && node.callee\n    && node.callee.property\n    && node.callee.property.name === 'shape'\n  );\n}\n\n/**\n * Returns the properties of a PropTypes.shape.\n *\n * @param {ASTNode} node the prop to check.\n * @returns {Array} the properties of the PropTypes.shape node.\n */\nfunction getShapeProperties(node) {\n  return node.arguments\n    && node.arguments[0]\n    && node.arguments[0].properties;\n}\n\n/**\n * Compares two elements.\n *\n * @param {ASTNode} a the first element to compare.\n * @param {ASTNode} b the second element to compare.\n * @param {Context} context The context of the two nodes.\n * @param {boolean=} ignoreCase whether or not to ignore case when comparing the two elements.\n * @param {boolean=} requiredFirst whether or not to sort required elements first.\n * @param {boolean=} callbacksLast whether or not to sort callbacks after everything else.\n * @param {boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.\n * @returns {number} the sort order of the two elements.\n */\nfunction sorter(a, b, context, ignoreCase, requiredFirst, callbacksLast, noSortAlphabetically) {\n  const aKey = String(astUtil.getKeyValue(context, a));\n  const bKey = String(astUtil.getKeyValue(context, b));\n\n  if (requiredFirst) {\n    if (isRequiredProp(a) && !isRequiredProp(b)) {\n      return -1;\n    }\n    if (!isRequiredProp(a) && isRequiredProp(b)) {\n      return 1;\n    }\n  }\n\n  if (callbacksLast) {\n    if (isCallbackPropName(aKey) && !isCallbackPropName(bKey)) {\n      return 1;\n    }\n    if (!isCallbackPropName(aKey) && isCallbackPropName(bKey)) {\n      return -1;\n    }\n  }\n\n  if (!noSortAlphabetically) {\n    if (ignoreCase) {\n      return aKey.localeCompare(bKey);\n    }\n\n    if (aKey < bKey) {\n      return -1;\n    }\n    if (aKey > bKey) {\n      return 1;\n    }\n  }\n  return 0;\n}\n\nconst commentnodeMap = new WeakMap(); // all nodes reference WeakMap for start and end range\n\n/**\n * Fixes sort order of prop types.\n *\n * @param {Context} context the second element to compare.\n * @param {Fixer} fixer the first element to compare.\n * @param {Array} declarations The context of the two nodes.\n * @param {boolean=} ignoreCase whether or not to ignore case when comparing the two elements.\n * @param {boolean=} requiredFirst whether or not to sort required elements first.\n * @param {boolean=} callbacksLast whether or not to sort callbacks after everything else.\n * @param {boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.\n * @param {boolean=} sortShapeProp whether or not to sort propTypes defined in PropTypes.shape.\n * @param {boolean=} checkTypes whether or not sorting of prop type definitions are checked.\n * @returns {Object|*|{range, text}} the sort order of the two elements.\n */\nfunction fixPropTypesSort(\n  context,\n  fixer,\n  declarations,\n  ignoreCase,\n  requiredFirst,\n  callbacksLast,\n  noSortAlphabetically,\n  sortShapeProp,\n  checkTypes\n) {\n  function sortInSource(allNodes, source) {\n    const originalSource = source;\n    const sourceCode = getSourceCode(context);\n    for (let i = 0; i < allNodes.length; i++) {\n      const node = allNodes[i];\n      let commentAfter = [];\n      let commentBefore = [];\n      let newStart = 0;\n      let newEnd = 0;\n      try {\n        commentBefore = sourceCode.getCommentsBefore(node);\n        commentAfter = sourceCode.getCommentsAfter(node);\n      } catch (e) { /**/ }\n\n      if (commentAfter.length === 0 || commentBefore.length === 0) {\n        newStart = node.range[0];\n        newEnd = node.range[1];\n      }\n\n      const firstCommentBefore = commentBefore[0];\n      if (commentBefore.length >= 1) {\n        newStart = firstCommentBefore.range[0];\n      }\n      const lastCommentAfter = commentAfter[commentAfter.length - 1];\n      if (commentAfter.length >= 1) {\n        newEnd = lastCommentAfter.range[1];\n      }\n      commentnodeMap.set(node, { start: newStart, end: newEnd, hasComment: true });\n    }\n    const nodeGroups = allNodes.reduce((acc, curr) => {\n      if (curr.type === 'ExperimentalSpreadProperty' || curr.type === 'SpreadElement') {\n        acc.push([]);\n      } else {\n        acc[acc.length - 1].push(curr);\n      }\n      return acc;\n    }, [[]]);\n\n    nodeGroups.forEach((nodes) => {\n      const sortedAttributes = toSorted(\n        nodes,\n        (a, b) => sorter(a, b, context, ignoreCase, requiredFirst, callbacksLast, noSortAlphabetically)\n      );\n\n      const sourceCodeText = getText(context);\n      let separator = '';\n      source = nodes.reduceRight((acc, attr, index) => {\n        const sortedAttr = sortedAttributes[index];\n        const commentNode = commentnodeMap.get(sortedAttr);\n        let sortedAttrText = sourceCodeText.slice(commentNode.start, commentNode.end);\n        const sortedAttrTextLastChar = sortedAttrText[sortedAttrText.length - 1];\n        if (!separator && [';', ','].some((allowedSep) => sortedAttrTextLastChar === allowedSep)) {\n          separator = sortedAttrTextLastChar;\n        }\n        if (sortShapeProp && isShapeProp(sortedAttr.value)) {\n          const shape = getShapeProperties(sortedAttr.value);\n          if (shape) {\n            const attrSource = sortInSource(\n              shape,\n              originalSource\n            );\n            sortedAttrText = attrSource.slice(sortedAttr.range[0], sortedAttr.range[1]);\n          }\n        }\n        const sortedAttrTextVal = checkTypes && !sortedAttrText.endsWith(separator) ? `${sortedAttrText}${separator}` : sortedAttrText;\n        return `${acc.slice(0, commentnodeMap.get(attr).start)}${sortedAttrTextVal}${acc.slice(commentnodeMap.get(attr).end)}`;\n      }, source);\n    });\n    return source;\n  }\n\n  const source = sortInSource(declarations, getText(context));\n\n  const rangeStart = commentnodeMap.get(declarations[0]).start;\n  const rangeEnd = commentnodeMap.get(declarations[declarations.length - 1]).end;\n  return fixer.replaceTextRange([rangeStart, rangeEnd], source.slice(rangeStart, rangeEnd));\n}\n\nmodule.exports = {\n  fixPropTypesSort,\n  isCallbackPropName,\n  isRequiredProp,\n  isShapeProp,\n};\n"
  },
  {
    "path": "lib/util/propWrapper.js",
    "content": "/**\n * @fileoverview Utility functions for propWrapperFunctions setting\n */\n\n'use strict';\n\nconst filter = require('es-iterator-helpers/Iterator.prototype.filter');\nconst some = require('es-iterator-helpers/Iterator.prototype.some');\n\nfunction searchPropWrapperFunctions(name, propWrapperFunctions) {\n  const splitName = name.split('.');\n  return some(propWrapperFunctions.values(), (func) => {\n    if (splitName.length === 2 && func.object === splitName[0] && func.property === splitName[1]) {\n      return true;\n    }\n    return name === func || func.property === name;\n  });\n}\n\nfunction getPropWrapperFunctions(context) {\n  return new Set(context.settings.propWrapperFunctions || []);\n}\n\nfunction isPropWrapperFunction(context, name) {\n  if (typeof name !== 'string') {\n    return false;\n  }\n  const propWrapperFunctions = getPropWrapperFunctions(context);\n  return searchPropWrapperFunctions(name, propWrapperFunctions);\n}\n\nfunction getExactPropWrapperFunctions(context) {\n  const propWrapperFunctions = getPropWrapperFunctions(context);\n  const exactPropWrappers = filter(propWrapperFunctions.values(), (func) => func.exact === true);\n  return new Set(exactPropWrappers);\n}\n\nfunction isExactPropWrapperFunction(context, name) {\n  const exactPropWrappers = getExactPropWrapperFunctions(context);\n  return searchPropWrapperFunctions(name, exactPropWrappers);\n}\n\nfunction formatPropWrapperFunctions(propWrapperFunctions) {\n  return Array.from(propWrapperFunctions, (func) => {\n    if (func.object && func.property) {\n      return `'${func.object}.${func.property}'`;\n    }\n    if (func.property) {\n      return `'${func.property}'`;\n    }\n    return `'${func}'`;\n  }).join(', ');\n}\n\nmodule.exports = {\n  formatPropWrapperFunctions,\n  getExactPropWrapperFunctions,\n  getPropWrapperFunctions,\n  isExactPropWrapperFunction,\n  isPropWrapperFunction,\n};\n"
  },
  {
    "path": "lib/util/props.js",
    "content": "/**\n * @fileoverview Utility functions for props\n */\n\n'use strict';\n\nconst astUtil = require('./ast');\n\n/**\n * Checks if the Identifier node passed in looks like a propTypes declaration.\n * @param {ASTNode} node The node to check. Must be an Identifier node.\n * @returns {boolean} `true` if the node is a propTypes declaration, `false` if not\n */\nfunction isPropTypesDeclaration(node) {\n  if (node && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')) {\n    // Flow support\n    if (node.typeAnnotation && node.key.name === 'props') {\n      return true;\n    }\n  }\n  return astUtil.getPropertyName(node) === 'propTypes';\n}\n\n/**\n * Checks if the node passed in looks like a contextTypes declaration.\n * @param {ASTNode} node The node to check.\n * @returns {boolean} `true` if the node is a contextTypes declaration, `false` if not\n */\nfunction isContextTypesDeclaration(node) {\n  if (node && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')) {\n    // Flow support\n    if (node.typeAnnotation && node.key.name === 'context') {\n      return true;\n    }\n  }\n  return astUtil.getPropertyName(node) === 'contextTypes';\n}\n\n/**\n * Checks if the node passed in looks like a contextType declaration.\n * @param {ASTNode} node The node to check.\n * @returns {boolean} `true` if the node is a contextType declaration, `false` if not\n */\nfunction isContextTypeDeclaration(node) {\n  return astUtil.getPropertyName(node) === 'contextType';\n}\n\n/**\n * Checks if the node passed in looks like a childContextTypes declaration.\n * @param {ASTNode} node The node to check.\n * @returns {boolean} `true` if the node is a childContextTypes declaration, `false` if not\n */\nfunction isChildContextTypesDeclaration(node) {\n  return astUtil.getPropertyName(node) === 'childContextTypes';\n}\n\n/**\n * Checks if the Identifier node passed in looks like a defaultProps declaration.\n * @param {ASTNode} node The node to check. Must be an Identifier node.\n * @returns {boolean} `true` if the node is a defaultProps declaration, `false` if not\n */\nfunction isDefaultPropsDeclaration(node) {\n  const propName = astUtil.getPropertyName(node);\n  return (propName === 'defaultProps' || propName === 'getDefaultProps');\n}\n\n/**\n * Checks if we are declaring a display name\n * @param {ASTNode} node The AST node being checked.\n * @returns {boolean} True if we are declaring a display name, false if not.\n */\nfunction isDisplayNameDeclaration(node) {\n  switch (node.type) {\n    case 'ClassProperty':\n    case 'PropertyDefinition':\n      return node.key && node.key.name === 'displayName';\n    case 'Identifier':\n      return node.name === 'displayName';\n    case 'Literal':\n      return node.value === 'displayName';\n    default:\n      return false;\n  }\n}\n\n/**\n * Checks if the PropTypes MemberExpression node passed in declares a required propType.\n * @param {ASTNode} propTypeExpression node to check. Must be a `PropTypes` MemberExpression.\n * @returns {boolean} `true` if this PropType is required, `false` if not.\n */\nfunction isRequiredPropType(propTypeExpression) {\n  return propTypeExpression.type === 'MemberExpression'\n    && propTypeExpression.property.name === 'isRequired';\n}\n\n/**\n * Returns the type arguments of a node or type parameters if type arguments are not available.\n * @param {ASTNode} node The node to get the type arguments from.\n * @returns {ASTNode} The type arguments or type parameters of the node.\n */\nfunction getTypeArguments(node) {\n  if ('typeArguments' in node) {\n    return node.typeArguments;\n  }\n  return node.typeParameters;\n}\n\n/**\n * Returns the super type arguments of a node or super type parameters if type arguments are not available.\n * @param {ASTNode} node The node to get the super type arguments from.\n * @returns {ASTNode} The super type arguments or parameters of the node.\n */\nfunction getSuperTypeArguments(node) {\n  if ('superTypeArguments' in node) {\n    return node.superTypeArguments;\n  }\n  return node.superTypeParameters;\n}\n\nmodule.exports = {\n  isPropTypesDeclaration,\n  isContextTypesDeclaration,\n  isContextTypeDeclaration,\n  isChildContextTypesDeclaration,\n  isDefaultPropsDeclaration,\n  isDisplayNameDeclaration,\n  isRequiredPropType,\n  getTypeArguments,\n  getSuperTypeArguments,\n};\n"
  },
  {
    "path": "lib/util/report.js",
    "content": "'use strict';\n\nconst getMessageData = require('./message');\n\nmodule.exports = function report(context, message, messageId, data) {\n  context.report(\n    Object.assign(\n      getMessageData(messageId, message),\n      data\n    )\n  );\n};\n"
  },
  {
    "path": "lib/util/usedPropTypes.js",
    "content": "/**\n * @fileoverview Common used propTypes detection functionality.\n */\n\n'use strict';\n\nconst values = require('object.values');\n\nconst astUtil = require('./ast');\nconst componentUtil = require('./componentUtil');\nconst testReactVersion = require('./version').testReactVersion;\nconst eslintUtil = require('./eslint');\n\nconst getScope = eslintUtil.getScope;\nconst getSourceCode = eslintUtil.getSourceCode;\n\n// ------------------------------------------------------------------------------\n// Constants\n// ------------------------------------------------------------------------------\n\nconst LIFE_CYCLE_METHODS = ['componentWillReceiveProps', 'shouldComponentUpdate', 'componentWillUpdate', 'componentDidUpdate'];\nconst ASYNC_SAFE_LIFE_CYCLE_METHODS = ['getDerivedStateFromProps', 'getSnapshotBeforeUpdate', 'UNSAFE_componentWillReceiveProps', 'UNSAFE_componentWillUpdate'];\n\nfunction createPropVariables() {\n  /** @type {Map<string, string[]>} Maps the variable to its definition. `props.a.b` is stored as `['a', 'b']` */\n  let propVariables = new Map();\n  let hasBeenWritten = false;\n  const stack = [{ propVariables, hasBeenWritten }];\n  return {\n    pushScope() {\n      // popVariables is not copied until first write.\n      stack.push({ propVariables, hasBeenWritten: false });\n    },\n    popScope() {\n      stack.pop();\n      propVariables = stack[stack.length - 1].propVariables;\n      hasBeenWritten = stack[stack.length - 1].hasBeenWritten;\n    },\n    /**\n     * Add a variable name to the current scope\n     * @param {string} name\n     * @param {string[]} allNames Example: `props.a.b` should be formatted as `['a', 'b']`\n     * @returns {Map<string, string[]>}\n     */\n    set(name, allNames) {\n      if (!hasBeenWritten) {\n        // copy on write\n        propVariables = new Map(propVariables);\n        Object.assign(stack[stack.length - 1], { propVariables, hasBeenWritten: true });\n        stack[stack.length - 1].hasBeenWritten = true;\n      }\n      return propVariables.set(name, allNames);\n    },\n    /**\n     * Get the definition of a variable.\n     * @param {string} name\n     * @returns {string[]} Example: `props.a.b` is represented by `['a', 'b']`\n     */\n    get(name) {\n      return propVariables.get(name);\n    },\n  };\n}\n\n/**\n * Checks if the string is one of `props`, `nextProps`, or `prevProps`\n * @param {string} name The AST node being checked.\n * @returns {boolean} True if the prop name matches\n */\nfunction isCommonVariableNameForProps(name) {\n  return name === 'props' || name === 'nextProps' || name === 'prevProps';\n}\n\n/**\n * Checks if the component must be validated\n * @param {Object} component The component to process\n * @returns {boolean} True if the component must be validated, false if not.\n */\nfunction mustBeValidated(component) {\n  return !!(component && !component.ignorePropsValidation);\n}\n\n/**\n * Check if we are in a lifecycle method\n * @param {object} context\n * @param {ASTNode} node The AST node being checked.\n * @param {boolean} checkAsyncSafeLifeCycles\n * @return {boolean} true if we are in a class constructor, false if not\n */\nfunction inLifeCycleMethod(context, node, checkAsyncSafeLifeCycles) {\n  let scope = getScope(context, node);\n  while (scope) {\n    if (scope.block && scope.block.parent && scope.block.parent.key) {\n      const name = scope.block.parent.key.name;\n\n      if (LIFE_CYCLE_METHODS.indexOf(name) >= 0) {\n        return true;\n      }\n      if (checkAsyncSafeLifeCycles && ASYNC_SAFE_LIFE_CYCLE_METHODS.indexOf(name) >= 0) {\n        return true;\n      }\n    }\n    scope = scope.upper;\n  }\n  return false;\n}\n\n/**\n * Returns true if the given node is a React Component lifecycle method\n * @param {ASTNode} node The AST node being checked.\n * @param {boolean} checkAsyncSafeLifeCycles\n * @return {boolean} True if the node is a lifecycle method\n */\nfunction isNodeALifeCycleMethod(node, checkAsyncSafeLifeCycles) {\n  if (node.key) {\n    if (node.kind === 'constructor') {\n      return true;\n    }\n\n    const nodeKeyName = node.key.name;\n\n    if (typeof nodeKeyName !== 'string') {\n      return false;\n    }\n\n    if (LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {\n      return true;\n    }\n    if (checkAsyncSafeLifeCycles && ASYNC_SAFE_LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Returns true if the given node is inside a React Component lifecycle\n * method.\n * @param {ASTNode} node The AST node being checked.\n * @param {boolean} checkAsyncSafeLifeCycles\n * @return {boolean} True if the node is inside a lifecycle method\n */\nfunction isInLifeCycleMethod(node, checkAsyncSafeLifeCycles) {\n  if (\n    (node.type === 'MethodDefinition' || node.type === 'Property')\n    && isNodeALifeCycleMethod(node, checkAsyncSafeLifeCycles)\n  ) {\n    return true;\n  }\n\n  if (node.parent) {\n    return isInLifeCycleMethod(node.parent, checkAsyncSafeLifeCycles);\n  }\n\n  return false;\n}\n\n/**\n * Check if a function node is a setState updater\n * @param {ASTNode} node a function node\n * @return {boolean}\n */\nfunction isSetStateUpdater(node) {\n  const unwrappedParentCalleeNode = astUtil.isCallExpression(node.parent)\n    && astUtil.unwrapTSAsExpression(node.parent.callee);\n\n  return unwrappedParentCalleeNode\n    && unwrappedParentCalleeNode.property\n    && unwrappedParentCalleeNode.property.name === 'setState'\n    // Make sure we are in the updater not the callback\n    && node.parent.arguments[0] === node;\n}\n\nfunction isPropArgumentInSetStateUpdater(context, node, name) {\n  if (typeof name !== 'string') {\n    return;\n  }\n  let scope = getScope(context, node);\n  while (scope) {\n    const unwrappedParentCalleeNode = scope.block\n      && astUtil.isCallExpression(scope.block.parent)\n      && astUtil.unwrapTSAsExpression(scope.block.parent.callee);\n    if (\n      unwrappedParentCalleeNode\n      && unwrappedParentCalleeNode.property\n      && unwrappedParentCalleeNode.property.name === 'setState'\n      // Make sure we are in the updater not the callback\n      && scope.block.parent.arguments[0].range[0] === scope.block.range[0]\n      && scope.block.parent.arguments[0].params\n      && scope.block.parent.arguments[0].params.length > 1\n    ) {\n      return scope.block.parent.arguments[0].params[1].name === name;\n    }\n    scope = scope.upper;\n  }\n  return false;\n}\n\n/**\n * @param {Context} context\n * @param {ASTNode} node\n * @returns {boolean}\n */\nfunction isInClassComponent(context, node) {\n  return !!(componentUtil.getParentES6Component(context, node) || componentUtil.getParentES5Component(context, node));\n}\n\n/**\n * Checks if the node is `this.props`\n * @param {ASTNode|undefined} node\n * @returns {boolean}\n */\nfunction isThisDotProps(node) {\n  return !!node\n    && node.type === 'MemberExpression'\n    && astUtil.unwrapTSAsExpression(node.object).type === 'ThisExpression'\n    && node.property.name === 'props';\n}\n\n/**\n * Checks if the prop has spread operator.\n * @param {object} context\n * @param {ASTNode} node The AST node being marked.\n * @returns {boolean} True if the prop has spread operator, false if not.\n */\nfunction hasSpreadOperator(context, node) {\n  const tokens = getSourceCode(context).getTokens(node);\n  return tokens.length && tokens[0].value === '...';\n}\n\n/**\n * Checks if the node is a propTypes usage of the form `this.props.*`, `props.*`, `prevProps.*`, or `nextProps.*`.\n * @param {Context} context\n * @param {ASTNode} node\n * @param {Object} utils\n * @param {boolean} checkAsyncSafeLifeCycles\n * @returns {boolean}\n */\nfunction isPropTypesUsageByMemberExpression(context, node, utils, checkAsyncSafeLifeCycles) {\n  const unwrappedObjectNode = astUtil.unwrapTSAsExpression(node.object);\n\n  if (isInClassComponent(context, node)) {\n    // this.props.*\n    if (isThisDotProps(unwrappedObjectNode)) {\n      return true;\n    }\n    // props.* or prevProps.* or nextProps.*\n    if (\n      isCommonVariableNameForProps(unwrappedObjectNode.name)\n      && (inLifeCycleMethod(context, node, checkAsyncSafeLifeCycles) || astUtil.inConstructor(context, node))\n    ) {\n      return true;\n    }\n    // this.setState((_, props) => props.*))\n    if (isPropArgumentInSetStateUpdater(context, node, unwrappedObjectNode.name)) {\n      return true;\n    }\n    return false;\n  }\n  // props.* in function component\n  return unwrappedObjectNode.name === 'props' && !astUtil.isAssignmentLHS(node);\n}\n\n/**\n * Retrieve the name of a property node\n * @param {Context} context\n * @param {ASTNode} node The AST node with the property.\n * @param {Object} utils\n * @param {boolean} checkAsyncSafeLifeCycles\n * @return {string|undefined} the name of the property or undefined if not found\n */\nfunction getPropertyName(context, node, utils, checkAsyncSafeLifeCycles) {\n  const property = node.property;\n  if (property) {\n    switch (property.type) {\n      case 'Identifier':\n        if (node.computed) {\n          return '__COMPUTED_PROP__';\n        }\n        return property.name;\n      case 'MemberExpression':\n        return;\n      case 'Literal':\n        // Accept computed properties that are literal strings\n        if (typeof property.value === 'string') {\n          return property.value;\n        }\n        // Accept number as well but only accept props[123]\n        if (typeof property.value === 'number') {\n          if (isPropTypesUsageByMemberExpression(context, node, utils, checkAsyncSafeLifeCycles)) {\n            return property.raw;\n          }\n        }\n        // falls through\n      default:\n        if (node.computed) {\n          return '__COMPUTED_PROP__';\n        }\n        break;\n    }\n  }\n}\n\nmodule.exports = function usedPropTypesInstructions(context, components, utils) {\n  const checkAsyncSafeLifeCycles = testReactVersion(context, '>= 16.3.0');\n\n  const propVariables = createPropVariables();\n  const pushScope = propVariables.pushScope;\n  const popScope = propVariables.popScope;\n\n  /**\n   * Mark a prop type as used\n   * @param {ASTNode} node The AST node being marked.\n   * @param {string[]} [parentNames]\n   */\n  function markPropTypesAsUsed(node, parentNames) {\n    parentNames = parentNames || [];\n    let type;\n    let name;\n    let allNames;\n    let properties;\n    if (astUtil.isMemberExpression(node)) {\n      name = getPropertyName(context, node, utils, checkAsyncSafeLifeCycles);\n      if (name) {\n        allNames = parentNames.concat(name);\n        const parent = node.parent;\n        if (\n        // Match props.foo.bar, don't match bar[props.foo]\n          parent.type === 'MemberExpression'\n            && 'object' in parent\n            && parent.object === node\n        ) {\n          markPropTypesAsUsed(parent, allNames);\n        }\n        // Handle the destructuring part of `const {foo} = props.a.b`\n        if (\n          astUtil.isVariableDeclarator(parent)\n            && parent.id.type === 'ObjectPattern'\n        ) {\n          parent.id.parent = parent; // patch for bug in eslint@4 in which ObjectPattern has no parent\n          markPropTypesAsUsed(parent.id, allNames);\n        }\n\n        // const a = props.a\n        if (\n          astUtil.isVariableDeclarator(parent)\n            && parent.id.type === 'Identifier'\n        ) {\n          propVariables.set(parent.id.name, allNames);\n        }\n        // Do not mark computed props as used.\n        type = name !== '__COMPUTED_PROP__' ? 'direct' : null;\n      }\n    } else if (astUtil.isFunctionLike(node)) {\n      if (node.params.length > 0) {\n        type = 'destructuring';\n        const propParam = isSetStateUpdater(node) ? node.params[1] : node.params[0];\n        properties = propParam.type === 'AssignmentPattern'\n          ? propParam.left.properties\n          : propParam.properties;\n      }\n    } else if (astUtil.isObjectPattern(node)) {\n      type = 'destructuring';\n      properties = node.properties;\n    } else if (node.type !== 'TSEmptyBodyFunctionExpression') {\n      throw new Error(`${node.type} ASTNodes are not handled by markPropTypesAsUsed`);\n    }\n\n    const component = components.get(utils.getParentComponent(node));\n    const usedPropTypes = (component && component.usedPropTypes) || [];\n    let ignoreUnusedPropTypesValidation = (component && component.ignoreUnusedPropTypesValidation) || false;\n\n    if (type === 'direct') {\n      // Ignore Object methods\n      if (!(name in Object.prototype)) {\n        const reportedNode = node.property;\n        usedPropTypes.push({\n          name,\n          allNames,\n          node: reportedNode,\n        });\n      }\n    } else if (type === 'destructuring') {\n      for (let k = 0, l = (properties || []).length; k < l; k++) {\n        if (hasSpreadOperator(context, properties[k]) || properties[k].computed) {\n          ignoreUnusedPropTypesValidation = true;\n          break;\n        }\n        const propName = astUtil.getKeyValue(context, properties[k]);\n\n        if (!propName || properties[k].type !== 'Property') {\n          break;\n        }\n\n        usedPropTypes.push({\n          allNames: parentNames.concat([propName]),\n          name: propName,\n          node: properties[k],\n        });\n\n        if (properties[k].value.type === 'ObjectPattern') {\n          markPropTypesAsUsed(properties[k].value, parentNames.concat([propName]));\n        } else if (properties[k].value.type === 'Identifier') {\n          propVariables.set(properties[k].value.name, parentNames.concat(propName));\n        }\n      }\n    }\n\n    let targetNode = component ? component.node : node;\n\n    if (component && !component.declaredPropTypes) {\n      let parentComponent = components.get(node.parent);\n      while (parentComponent) {\n        if (parentComponent.declaredPropTypes) {\n          targetNode = parentComponent.node;\n          break;\n        }\n        parentComponent = components.get(parentComponent.parent);\n      }\n    }\n\n    components.set(targetNode, {\n      usedPropTypes,\n      ignoreUnusedPropTypesValidation,\n    });\n  }\n\n  /**\n   * @param {ASTNode} node We expect either an ArrowFunctionExpression,\n   *   FunctionDeclaration, or FunctionExpression\n   */\n  function markDestructuredFunctionArgumentsAsUsed(node) {\n    const param = node.params && isSetStateUpdater(node) ? node.params[1] : node.params[0];\n\n    const destructuring = param && (\n      param.type === 'ObjectPattern'\n      || ((param.type === 'AssignmentPattern') && (param.left.type === 'ObjectPattern'))\n    );\n\n    if (destructuring && (components.get(node) || components.get(node.parent))) {\n      markPropTypesAsUsed(node);\n    }\n  }\n\n  function handleSetStateUpdater(node) {\n    if (!node.params || node.params.length < 2 || !isSetStateUpdater(node)) {\n      return;\n    }\n    markPropTypesAsUsed(node);\n  }\n\n  /**\n   * Handle both stateless functions and setState updater functions.\n   * @param {ASTNode} node We expect either an ArrowFunctionExpression,\n   *   FunctionDeclaration, or FunctionExpression\n   */\n  function handleFunctionLikeExpressions(node) {\n    pushScope();\n    handleSetStateUpdater(node);\n    markDestructuredFunctionArgumentsAsUsed(node);\n  }\n\n  function handleCustomValidators(component) {\n    const propTypes = component.declaredPropTypes;\n    if (!propTypes) {\n      return;\n    }\n\n    Object.keys(propTypes).forEach((key) => {\n      const node = propTypes[key].node;\n\n      if (node && node.value && astUtil.isFunctionLikeExpression(node.value)) {\n        markPropTypesAsUsed(node.value);\n      }\n    });\n  }\n\n  return {\n    VariableDeclarator(node) {\n      const unwrappedInitNode = astUtil.unwrapTSAsExpression(node.init);\n\n      // let props = this.props\n      if (isThisDotProps(unwrappedInitNode) && isInClassComponent(context, node) && node.id.type === 'Identifier') {\n        propVariables.set(node.id.name, []);\n      }\n\n      // Only handles destructuring\n      if (node.id.type !== 'ObjectPattern' || !unwrappedInitNode) {\n        return;\n      }\n\n      // let {props: {firstname}} = this\n      const propsProperty = node.id.properties.find((property) => (\n        property.key\n        && (property.key.name === 'props' || property.key.value === 'props')\n      ));\n\n      if (unwrappedInitNode.type === 'ThisExpression' && propsProperty && propsProperty.value.type === 'ObjectPattern') {\n        markPropTypesAsUsed(propsProperty.value);\n        return;\n      }\n\n      // let {props} = this\n      if (unwrappedInitNode.type === 'ThisExpression' && propsProperty && propsProperty.value.name === 'props') {\n        propVariables.set('props', []);\n        return;\n      }\n\n      // let {firstname} = props\n      if (\n        isCommonVariableNameForProps(unwrappedInitNode.name)\n        && (utils.getParentStatelessComponent(node) || isInLifeCycleMethod(node, checkAsyncSafeLifeCycles))\n      ) {\n        markPropTypesAsUsed(node.id);\n        return;\n      }\n\n      // let {firstname} = this.props\n      if (isThisDotProps(unwrappedInitNode) && isInClassComponent(context, node)) {\n        markPropTypesAsUsed(node.id);\n        return;\n      }\n\n      // let {firstname} = thing, where thing is defined by const thing = this.props.**.*\n      if (propVariables.get(unwrappedInitNode.name)) {\n        markPropTypesAsUsed(node.id, propVariables.get(unwrappedInitNode.name));\n      }\n    },\n\n    FunctionDeclaration: handleFunctionLikeExpressions,\n\n    ArrowFunctionExpression: handleFunctionLikeExpressions,\n\n    FunctionExpression: handleFunctionLikeExpressions,\n\n    'FunctionDeclaration:exit': popScope,\n\n    'ArrowFunctionExpression:exit': popScope,\n\n    'FunctionExpression:exit': popScope,\n\n    JSXSpreadAttribute(node) {\n      const component = components.get(utils.getParentComponent(node));\n      components.set(component ? component.node : node, {\n        ignoreUnusedPropTypesValidation: node.argument.type !== 'ObjectExpression',\n      });\n    },\n\n    'MemberExpression, OptionalMemberExpression'(node) {\n      if (isPropTypesUsageByMemberExpression(context, node, utils, checkAsyncSafeLifeCycles)) {\n        markPropTypesAsUsed(node);\n        return;\n      }\n\n      const propVariable = propVariables.get(astUtil.unwrapTSAsExpression(node.object).name);\n      if (propVariable) {\n        markPropTypesAsUsed(node, propVariable);\n      }\n    },\n\n    ObjectPattern(node) {\n      // If the object pattern is a destructured props object in a lifecycle\n      // method -- mark it for used props.\n      if (isNodeALifeCycleMethod(node.parent.parent, checkAsyncSafeLifeCycles) && node.properties.length > 0) {\n        markPropTypesAsUsed(node.parent);\n      }\n    },\n\n    'Program:exit'() {\n      values(components.list())\n        .filter((component) => mustBeValidated(component))\n        .forEach((component) => {\n          handleCustomValidators(component);\n        });\n    },\n  };\n};\n"
  },
  {
    "path": "lib/util/variable.js",
    "content": "/**\n * @fileoverview Utility functions for React components detection\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst getScope = require('./eslint').getScope;\n\n/**\n * Search a particular variable in a list\n * @param {Array} variables The variables list.\n * @param {string} name The name of the variable to search.\n * @returns {boolean} True if the variable was found, false if not.\n */\nfunction findVariable(variables, name) {\n  return variables.some((variable) => variable.name === name);\n}\n\n/**\n * Find and return a particular variable in a list\n * @param {Array} variables The variables list.\n * @param {string} name The name of the variable to search.\n * @returns {Object} Variable if the variable was found, null if not.\n */\nfunction getVariable(variables, name) {\n  return variables.find((variable) => variable.name === name);\n}\n\n/**\n * Searches for a variable in the given scope.\n *\n * @param {Object} context The current rule context.\n * @param {ASTNode} node The node to start looking from.\n * @param {string} name The name of the variable to search.\n * @returns {Object | undefined} Variable if the variable was found, undefined if not.\n */\nfunction getVariableFromContext(context, node, name) {\n  let scope = getScope(context, node);\n\n  while (scope) {\n    let variable = getVariable(scope.variables, name);\n\n    if (!variable && scope.childScopes.length) {\n      variable = getVariable(scope.childScopes[0].variables, name);\n\n      if (!variable && scope.childScopes[0].childScopes.length) {\n        variable = getVariable(scope.childScopes[0].childScopes[0].variables, name);\n      }\n    }\n\n    if (variable) {\n      return variable;\n    }\n    scope = scope.upper;\n  }\n  return undefined;\n}\n\n/**\n * Find a variable by name in the current scope.\n * @param {Object} context The current rule context.\n * @param {ASTNode} node The node to check. Must be an Identifier node.\n * @param  {string} name Name of the variable to look for.\n * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise.\n */\nfunction findVariableByName(context, node, name) {\n  const variable = getVariableFromContext(context, node, name);\n\n  if (!variable || !variable.defs[0] || !variable.defs[0].node) {\n    return null;\n  }\n\n  if (variable.defs[0].node.type === 'TypeAlias') {\n    return variable.defs[0].node.right;\n  }\n\n  if (variable.defs[0].type === 'ImportBinding') {\n    return variable.defs[0].node;\n  }\n\n  return variable.defs[0].node.init;\n}\n\n/**\n * Returns the latest definition of the variable.\n * @param {Object} variable\n * @returns {Object | undefined} The latest variable definition or undefined.\n */\nfunction getLatestVariableDefinition(variable) {\n  return variable.defs[variable.defs.length - 1];\n}\n\nmodule.exports = {\n  findVariable,\n  findVariableByName,\n  getVariable,\n  getVariableFromContext,\n  getLatestVariableDefinition,\n};\n"
  },
  {
    "path": "lib/util/version.js",
    "content": "/**\n * @fileoverview Utility functions for React and Flow version configuration\n * @author Yannick Croissant\n */\n\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst resolve = require('resolve');\nconst semver = require('semver');\nconst error = require('./error');\n\nconst ULTIMATE_LATEST_SEMVER = '999.999.999';\n\nlet warnedForMissingVersion = false;\n\nfunction resetWarningFlag() {\n  warnedForMissingVersion = false;\n}\n\nlet cachedDetectedReactVersion;\n\nfunction resetDetectedVersion() {\n  cachedDetectedReactVersion = undefined;\n}\n\nfunction resolveBasedir(contextOrFilename) {\n  if (contextOrFilename) {\n    const filename = typeof contextOrFilename === 'string' ? contextOrFilename : contextOrFilename.getFilename();\n    const dirname = path.dirname(filename);\n    try {\n      if (fs.statSync(filename).isFile()) {\n        // dirname must be dir here\n        return dirname;\n      }\n    } catch (err) {\n      // https://github.com/eslint/eslint/issues/11989\n      if (err.code === 'ENOTDIR') {\n        // virtual filename could be recursive\n        return resolveBasedir(dirname);\n      }\n    }\n  }\n  return process.cwd();\n}\n\nfunction convertConfVerToSemver(confVer) {\n  const fullSemverString = /^[0-9]+\\.[0-9]+$/.test(confVer) ? `${confVer}.0` : confVer;\n  return semver.coerce(fullSemverString.split('.').map((part) => Number(part)).join('.'));\n}\n\nlet defaultVersion = ULTIMATE_LATEST_SEMVER;\n\nfunction resetDefaultVersion() {\n  defaultVersion = ULTIMATE_LATEST_SEMVER;\n}\n\nfunction readDefaultReactVersionFromContext(context) {\n  // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  if (context.settings && context.settings.react && context.settings.react.defaultVersion) {\n    let settingsDefaultVersion = context.settings.react.defaultVersion;\n    if (typeof settingsDefaultVersion !== 'string') {\n      error(`Warning: default React version specified in eslint-pluigin-react-settings must be a string; got \"${typeof settingsDefaultVersion}\"`);\n    }\n    settingsDefaultVersion = String(settingsDefaultVersion);\n    const result = convertConfVerToSemver(settingsDefaultVersion);\n    if (result) {\n      defaultVersion = result.version;\n    } else {\n      error(`Warning: React version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “${settingsDefaultVersion}”. Falling back to latest version as default.`);\n    }\n  } else {\n    defaultVersion = ULTIMATE_LATEST_SEMVER;\n  }\n}\n\n// TODO, semver-major: remove context fallback\nfunction detectReactVersion(context) {\n  if (cachedDetectedReactVersion) {\n    return cachedDetectedReactVersion;\n  }\n\n  const basedir = resolveBasedir(context);\n\n  try {\n    const reactPath = resolve.sync('react', { basedir });\n    const react = require(reactPath); // eslint-disable-line global-require, import/no-dynamic-require\n    cachedDetectedReactVersion = react.version;\n    return cachedDetectedReactVersion;\n  } catch (e) {\n    if (e.code === 'MODULE_NOT_FOUND') {\n      if (!warnedForMissingVersion) {\n        let sentence2 = 'Assuming latest React version for linting.';\n        if (defaultVersion !== ULTIMATE_LATEST_SEMVER) {\n          sentence2 = `Assuming default React version for linting: \"${defaultVersion}\".`;\n        }\n        error(`Warning: React version was set to \"detect\" in eslint-plugin-react settings, but the \"react\" package is not installed. ${sentence2}`);\n        warnedForMissingVersion = true;\n      }\n      cachedDetectedReactVersion = defaultVersion;\n      return cachedDetectedReactVersion;\n    }\n    throw e;\n  }\n}\n\nfunction getReactVersionFromContext(context) {\n  readDefaultReactVersionFromContext(context);\n  let confVer = defaultVersion;\n  // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  if (context.settings && context.settings.react && context.settings.react.version) {\n    let settingsVersion = context.settings.react.version;\n    if (settingsVersion === 'detect') {\n      settingsVersion = detectReactVersion(context);\n    }\n    if (typeof settingsVersion !== 'string') {\n      error(`Warning: React version specified in eslint-plugin-react-settings must be a string; got “${typeof settingsVersion}”`);\n    }\n    confVer = String(settingsVersion);\n  } else if (!warnedForMissingVersion) {\n    error('Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration.');\n    warnedForMissingVersion = true;\n  }\n\n  const result = convertConfVerToSemver(confVer);\n  if (!result) {\n    error(`Warning: React version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “${confVer}”`);\n  }\n  return result ? result.version : defaultVersion;\n}\n\n// TODO, semver-major: remove context fallback\nfunction detectFlowVersion(context) {\n  const basedir = resolveBasedir(context);\n\n  try {\n    const flowPackageJsonPath = resolve.sync('flow-bin/package.json', { basedir });\n    const flowPackageJson = require(flowPackageJsonPath); // eslint-disable-line global-require, import/no-dynamic-require\n    return flowPackageJson.version;\n  } catch (e) {\n    if (e.code === 'MODULE_NOT_FOUND') {\n      error('Warning: Flow version was set to \"detect\" in eslint-plugin-react settings, '\n        + 'but the \"flow-bin\" package is not installed. Assuming latest Flow version for linting.');\n      return ULTIMATE_LATEST_SEMVER;\n    }\n    throw e;\n  }\n}\n\nfunction getFlowVersionFromContext(context) {\n  let confVer = defaultVersion;\n  // .eslintrc shared settings (https://eslint.org/docs/user-guide/configuring#adding-shared-settings)\n  if (context.settings.react && context.settings.react.flowVersion) {\n    let flowVersion = context.settings.react.flowVersion;\n    if (flowVersion === 'detect') {\n      flowVersion = detectFlowVersion(context);\n    }\n    if (typeof flowVersion !== 'string') {\n      error('Warning: Flow version specified in eslint-plugin-react-settings must be a string; '\n        + `got “${typeof flowVersion}”`);\n    }\n    confVer = String(flowVersion);\n  } else {\n    throw 'Could not retrieve flowVersion from settings'; // eslint-disable-line no-throw-literal\n  }\n\n  const result = convertConfVerToSemver(confVer);\n  if (!result) {\n    error(`Warning: Flow version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “${confVer}”`);\n  }\n  return result ? result.version : defaultVersion;\n}\n\nfunction test(semverRange, confVer) {\n  return semver.satisfies(confVer, semverRange);\n}\n\nfunction testReactVersion(context, semverRange) {\n  return test(semverRange, getReactVersionFromContext(context));\n}\n\nfunction testFlowVersion(context, semverRange) {\n  return test(semverRange, getFlowVersionFromContext(context));\n}\n\nmodule.exports = {\n  testReactVersion,\n  testFlowVersion,\n  resetWarningFlag,\n  resetDetectedVersion,\n  resetDefaultVersion,\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"eslint-plugin-react\",\n  \"version\": \"7.37.5\",\n  \"author\": \"Yannick Croissant <yannick.croissant+npm@gmail.com>\",\n  \"description\": \"React specific linting rules for ESLint\",\n  \"main\": \"index.js\",\n  \"types\": \"index.d.ts\",\n  \"scripts\": {\n    \"clean-built-types\": \"rm -f $(find . -maxdepth 1 -type f -name '*.d.ts*') $(find lib -type f -name '*.d.ts*' ! -name 'types.d.ts')\",\n    \"prebuild-types\": \"npm run clean-built-types\",\n    \"build-types\": \"tsc -p build.tsconfig.json\",\n    \"prepack\": \"npm run build-types && npmignore --auto --commentLines=autogenerated\",\n    \"prelint\": \"npm run lint:docs\",\n    \"lint:docs\": \"markdownlint \\\"**/*.md\\\"\",\n    \"postlint:docs\": \"npm run update:eslint-docs -- --check\",\n    \"lint\": \"eslint .\",\n    \"postlint\": \"npm run type-check\",\n    \"pretest\": \"npm run lint\",\n    \"test\": \"npm run unit-test\",\n    \"posttest\": \"npx npm@'>= 10.2' audit --production\",\n    \"type-check\": \"tsc\",\n    \"unit-test\": \"istanbul cover node_modules/mocha/bin/_mocha tests/lib/**/*.js tests/util/**/*.js tests/index.js tests/flat-config.js\",\n    \"update:eslint-docs\": \"eslint-doc-generator\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/jsx-eslint/eslint-plugin-react\"\n  },\n  \"directories\": {\n    \"test\": [\n      \"test\",\n      \"tests\",\n      \"test-published-types\"\n    ]\n  },\n  \"homepage\": \"https://github.com/jsx-eslint/eslint-plugin-react\",\n  \"bugs\": \"https://github.com/jsx-eslint/eslint-plugin-react/issues\",\n  \"dependencies\": {\n    \"array-includes\": \"^3.1.9\",\n    \"array.prototype.findlast\": \"^1.2.5\",\n    \"array.prototype.flatmap\": \"^1.3.3\",\n    \"array.prototype.tosorted\": \"^1.1.4\",\n    \"doctrine\": \"^2.1.0\",\n    \"es-iterator-helpers\": \"^1.2.2\",\n    \"estraverse\": \"^5.3.0\",\n    \"hasown\": \"^2.0.2\",\n    \"jsx-ast-utils\": \"^2.4.1 || ^3.0.0\",\n    \"minimatch\": \"^3.1.2\",\n    \"object.entries\": \"^1.1.9\",\n    \"object.fromentries\": \"^2.0.8\",\n    \"object.values\": \"^1.2.1\",\n    \"prop-types\": \"^15.8.1\",\n    \"resolve\": \"^2.0.0-next.5\",\n    \"semver\": \"^6.3.1\",\n    \"string.prototype.matchall\": \"^4.0.12\",\n    \"string.prototype.repeat\": \"^1.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.29.0\",\n    \"@babel/eslint-parser\": \"^7.28.6\",\n    \"@babel/plugin-syntax-decorators\": \"^7.28.6\",\n    \"@babel/plugin-syntax-do-expressions\": \"^7.28.6\",\n    \"@babel/plugin-syntax-function-bind\": \"^7.28.6\",\n    \"@babel/preset-react\": \"^7.28.5\",\n    \"@types/eslint\": \"=7.2.10\",\n    \"@types/estree\": \"0.0.52\",\n    \"@types/node\": \"^4.9.5\",\n    \"@typescript-eslint/parser\": \"^2.34.0 || ^3.10.1 || ^4 || ^5 || ^6.20 || ^7.14.1 || 8.4 - 8.17\",\n    \"babel-eslint\": \"^8 || ^9 || ^10.1.0\",\n    \"eslint\": \"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7\",\n    \"eslint-config-airbnb-base\": \"^15.0.0\",\n    \"eslint-doc-generator\": \"^3.0.2\",\n    \"eslint-plugin-eslint-plugin\": \"^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5\",\n    \"eslint-plugin-import\": \"^2.32.0\",\n    \"eslint-remote-tester\": \"^3.0.1\",\n    \"eslint-remote-tester-repositories\": \"^1.0.1\",\n    \"eslint-scope\": \"^3.7.3\",\n    \"espree\": \"^3.5.4\",\n    \"gfm-footnotes\": \"^2.0.0\",\n    \"glob\": \"=10.3.7\",\n    \"istanbul\": \"^0.4.5\",\n    \"jackspeak\": \"=2.1.1\",\n    \"ls-engines\": \"^0.8.1\",\n    \"markdownlint-cli\": \"^0.8.0 || ^0.32.2\",\n    \"mocha\": \"^5.2.0\",\n    \"npmignore\": \"^0.3.5\",\n    \"sinon\": \"^7.5.0\",\n    \"typescript\": \"^3.9.9\",\n    \"typescript-eslint-parser\": \"^20.1.1\"\n  },\n  \"peerDependencies\": {\n    \"eslint\": \"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7\"\n  },\n  \"engines\": {\n    \"node\": \">=4\"\n  },\n  \"keywords\": [\n    \"eslint\",\n    \"eslint-plugin\",\n    \"eslintplugin\",\n    \"react\"\n  ],\n  \"license\": \"MIT\",\n  \"publishConfig\": {\n    \"ignore\": [\n      \".github/\",\n      \"!lib\",\n      \"docs/\",\n      \"test/\",\n      \"test-published-types/\",\n      \"tests/\",\n      \"*.md\",\n      \"*.config.js\",\n      \".eslint-doc-generatorrc.js\",\n      \".eslintrc\",\n      \".editorconfig\",\n      \"tsconfig.json\",\n      \"build.tsconfig.json\",\n      \".markdownlint*\",\n      \"types\",\n      \"!*.d.ts\",\n      \"!*.d.ts.map\"\n    ]\n  }\n}\n"
  },
  {
    "path": "test/eslint-remote-tester.config.js",
    "content": "'use strict';\n\nconst eslintRemoteTesterRepositories = require('eslint-remote-tester-repositories');\n\nmodule.exports = {\n  repositories: eslintRemoteTesterRepositories.getRepositories({ randomize: true }),\n\n  pathIgnorePattern: eslintRemoteTesterRepositories.getPathIgnorePattern(),\n\n  extensions: ['js', 'jsx', 'ts', 'tsx'],\n\n  concurrentTasks: 3,\n\n  logLevel: 'info',\n\n  /** Optional boolean flag used to enable caching of cloned repositories. For CIs it's ideal to disable caching. Defauls to true. */\n  cache: false,\n\n  eslintrc: {\n    root: true,\n    env: {\n      es6: true,\n    },\n    overrides: [\n      {\n        files: ['*.ts', '*.tsx', '*.mts', '*.cts'],\n        parser: '@typescript-eslint/parser',\n      },\n    ],\n    parserOptions: {\n      ecmaVersion: 2020,\n      sourceType: 'module',\n      ecmaFeatures: {\n        jsx: true,\n      },\n    },\n    settings: {\n      react: {\n        version: '16.13.1',\n      },\n    },\n    extends: ['plugin:react/all'],\n  },\n};\n"
  },
  {
    "path": "test/mocha.opts",
    "content": "--reporter=min\n"
  },
  {
    "path": "test-published-types/.npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": "test-published-types/index.js",
    "content": "'use strict';\n\nconst react = require('eslint-plugin-react');\n\n/** @type {import('eslint').Linter.Config[]} */\nconst config = [\n  {\n    plugins: {\n      react,\n    },\n  },\n];\n\nmodule.exports = config;\n"
  },
  {
    "path": "test-published-types/package.json",
    "content": "{\n  \"name\": \"eslint-plugin-react-test-published-types\",\n  \"private\": true,\n  \"version\": \"0.0.0\",\n  \"dependencies\": {\n    \"eslint\": \"~9.38.0\"\n  }\n}\n"
  },
  {
    "path": "test-published-types/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n\n  \"files\": [\n    \"index.js\"\n  ],\n\n  \"compilerOptions\": {\n    \"lib\": [\"esnext\"],\n    \"types\": [\"node\"],\n    \"skipLibCheck\": true\n  }\n}\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-all/eslint.config-deep.js",
    "content": "'use strict';\n\nconst reactAll = require('../../../../configs/all');\n\nmodule.exports = [{\n  files: ['**/*.jsx'],\n  ...reactAll,\n  languageOptions: {\n    ...reactAll.languageOptions\n  }\n}];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-all/eslint.config-root.js",
    "content": "'use strict';\n\nconst reactPlugin = require('../../../..');\n\nmodule.exports = [{\n  files: ['**/*.jsx'],\n  ...reactPlugin.configs.flat.all\n}];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-all/test.jsx",
    "content": "<div foo=\"hello\">\n    test\n</div>\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-jsx-runtime/eslint.config-deep.js",
    "content": "'use strict';\n\nconst reactRecommended = require('../../../../configs/recommended');\nconst reactJSXRuntime = require('../../../../configs/jsx-runtime');\n\nmodule.exports = [\n  {\n    files: ['**/*.jsx'],\n    ...reactRecommended,\n    languageOptions: {\n      ...reactRecommended.languageOptions\n    }\n  },\n  reactJSXRuntime\n];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-jsx-runtime/eslint.config-root.js",
    "content": "'use strict';\n\nconst reactPlugin = require('../../../..');\n\nmodule.exports = [\n  {\n    files: ['**/*.jsx'],\n    ...reactPlugin.configs.flat.recommended\n  },\n  reactPlugin.configs.flat['jsx-runtime']\n];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-jsx-runtime/test.jsx",
    "content": "<div foo=\"hello\">\n    test\n</div>\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-recommended/eslint.config-deep.js",
    "content": "'use strict';\n\nconst reactRecommended = require('../../../../configs/recommended');\n\nmodule.exports = [{\n  files: ['**/*.jsx'],\n  ...reactRecommended,\n  languageOptions: {\n    ...reactRecommended.languageOptions\n  }\n}];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-recommended/eslint.config-root.js",
    "content": "'use strict';\n\nconst reactPlugin = require('../../../..');\n\nmodule.exports = [{\n  files: ['**/*.jsx'],\n  ...reactPlugin.configs.flat.recommended\n}];\n"
  },
  {
    "path": "tests/fixtures/flat-config/config-recommended/test.jsx",
    "content": "<div foo=\"hello\">\n    test\n</div>\n"
  },
  {
    "path": "tests/fixtures/flat-config/plugin/eslint.config.js",
    "content": "'use strict';\n\nconst react = require('../../../..');\n\nmodule.exports = [{\n  files: ['**/*.jsx'],\n  languageOptions: {\n    parserOptions: {\n      ecmaFeatures: {\n        jsx: true,\n      },\n    },\n  },\n  plugins: {\n    react,\n  },\n  rules: {\n    'react/jsx-no-literals': 1,\n  },\n}];\n"
  },
  {
    "path": "tests/fixtures/flat-config/plugin/test.jsx",
    "content": "<div foo=\"hello\">\n    test\n</div>\n"
  },
  {
    "path": "tests/fixtures/flat-config/plugin-and-config/eslint.config-deep.js",
    "content": "'use strict';\n\nconst react = require('../../../..');\nconst reactRecommended = require('../../../../configs/recommended');\n\nmodule.exports = [\n  {\n    files: ['**/*.jsx'],\n    plugins: { react }\n  },\n  {\n    files: ['**/*.jsx'],\n    ...reactRecommended,\n    languageOptions: {\n      ...reactRecommended.languageOptions\n    }\n  }\n];\n"
  },
  {
    "path": "tests/fixtures/flat-config/plugin-and-config/eslint.config-root.js",
    "content": "'use strict';\n\nconst react = require('../../../..');\nconst reactRecommended = require('../../../../configs/recommended');\n\nmodule.exports = [\n  {\n    files: ['**/*.jsx'],\n    plugins: { react }\n  },\n  {\n    files: ['**/*.jsx'],\n    ...react.configs.flat.recommended\n  }\n];\n"
  },
  {
    "path": "tests/fixtures/flat-config/plugin-and-config/test.jsx",
    "content": "<div foo=\"hello\">\n    test\n</div>\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/detect-version-child/node_modules/flow-bin/package.json",
    "content": "{\n  \"name\": \"flow-bin\",\n  \"version\": \"3.92.0\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/detect-version-child/node_modules/react/index.js",
    "content": "'use strict';\n\nmodule.exports = {\n  version: '3.4.5',\n};\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/detect-version-child/node_modules/react/package.json",
    "content": "{\n  \"name\": \"react\",\n  \"version\": \"3.4.5\",\n  \"main\": \"index.js\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/detect-version-child/test.js",
    "content": ""
  },
  {
    "path": "tests/fixtures/version/detect-version/node_modules/flow-bin/package.json",
    "content": "{\n  \"name\": \"flow-bin\",\n  \"version\": \"0.92.0\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/node_modules/react/index.js",
    "content": "'use strict';\n\nmodule.exports = {\n  version: '1.2.3',\n};\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/node_modules/react/package.json",
    "content": "{\n  \"name\": \"react\",\n  \"version\": \"1.2.3\",\n  \"main\": \"index.js\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version/test.js",
    "content": ""
  },
  {
    "path": "tests/fixtures/version/detect-version-missing/node_modules/react/index.js",
    "content": "'use strict';\n\nconst error = new Error();\nerror.code = 'MODULE_NOT_FOUND';\nthrow error;\n"
  },
  {
    "path": "tests/fixtures/version/detect-version-missing/node_modules/react/package.json",
    "content": "{\n    \"name\": \"react\",\n    \"main\": \"index.js\"\n  }\n"
  },
  {
    "path": "tests/fixtures/version/detect-version-missing/test.js",
    "content": ""
  },
  {
    "path": "tests/fixtures/version/detect-version-sibling/node_modules/flow-bin/package.json",
    "content": "{\n  \"name\": \"flow-bin\",\n  \"version\": \"2.92.0\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version-sibling/node_modules/react/index.js",
    "content": "'use strict';\n\nmodule.exports = {\n  version: '2.3.4',\n};\n"
  },
  {
    "path": "tests/fixtures/version/detect-version-sibling/node_modules/react/package.json",
    "content": "{\n  \"name\": \"react\",\n  \"version\": \"2.3.4\",\n  \"main\": \"index.js\"\n}\n"
  },
  {
    "path": "tests/fixtures/version/detect-version-sibling/test.js",
    "content": ""
  },
  {
    "path": "tests/flat-config.js",
    "content": "/* eslint-env mocha */\n\n'use strict';\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\n\nif (!semver.satisfies(eslintPkg.version, '>= 8.23.0')) {\n  return;\n}\n\nconst ESLint = semver.major(eslintPkg.version) < 9\n  ? require('eslint/use-at-your-own-risk').FlatESLint // eslint-disable-line import/no-unresolved -- false positive\n  : require('eslint').ESLint;\n\nconst path = require('path');\nconst assert = require('assert');\n\ndescribe('eslint-plugin-react in flat config', () => {\n  const fixturesdDir = path.resolve(__dirname, 'fixtures', 'flat-config');\n\n  it('should work when the plugin is used directly', () => {\n    const eslint = new ESLint({\n      cwd: path.resolve(fixturesdDir, 'plugin'),\n    });\n\n    return eslint.lintFiles(['test.jsx']).then((results) => {\n      const result = results[0];\n\n      assert.strictEqual(result.messages.length, 1);\n      assert.strictEqual(result.messages[0].severity, 1);\n      assert.strictEqual(result.messages[0].ruleId, 'react/jsx-no-literals');\n      assert.strictEqual(result.messages[0].messageId, 'literalNotInJSXExpression');\n    });\n  });\n\n  ['root', 'deep'].forEach((configAccess) => {\n    const overrideConfigFile = `eslint.config-${configAccess}.js`;\n\n    it(`should work when the plugin is used with \"all\" config (${configAccess})`, () => {\n      const eslint = new ESLint({\n        cwd: path.resolve(fixturesdDir, 'config-all'),\n        overrideConfigFile,\n      });\n\n      return eslint.lintFiles(['test.jsx']).then((results) => {\n        const result = results[0];\n\n        assert.strictEqual(result.messages.length, 3);\n        assert.strictEqual(result.messages[0].severity, 2);\n        assert.strictEqual(result.messages[0].ruleId, 'react/react-in-jsx-scope');\n        assert.strictEqual(result.messages[0].messageId, 'notInScope');\n        assert.strictEqual(result.messages[1].severity, 2);\n        assert.strictEqual(result.messages[1].ruleId, 'react/no-unknown-property');\n        assert.strictEqual(result.messages[1].messageId, 'unknownProp');\n        assert.strictEqual(result.messages[2].severity, 2);\n        assert.strictEqual(result.messages[2].ruleId, 'react/jsx-no-literals');\n        assert.strictEqual(result.messages[2].messageId, 'literalNotInJSXExpression');\n      });\n    });\n\n    it(`should work when the plugin is used with \"recommended\" config (${configAccess})`, () => {\n      const eslint = new ESLint({\n        cwd: path.resolve(fixturesdDir, 'config-recommended'),\n        overrideConfigFile,\n      });\n\n      return eslint.lintFiles(['test.jsx']).then((results) => {\n        const result = results[0];\n\n        assert.strictEqual(result.messages.length, 2);\n        assert.strictEqual(result.messages[0].severity, 2);\n        assert.strictEqual(result.messages[0].ruleId, 'react/react-in-jsx-scope');\n        assert.strictEqual(result.messages[0].messageId, 'notInScope');\n        assert.strictEqual(result.messages[1].severity, 2);\n        assert.strictEqual(result.messages[1].ruleId, 'react/no-unknown-property');\n        assert.strictEqual(result.messages[1].messageId, 'unknownProp');\n      });\n    });\n\n    it(`should work when the plugin is used with \"recommended\" and \"jsx-runtime\" configs (${configAccess})`, () => {\n      const eslint = new ESLint({\n        cwd: path.resolve(fixturesdDir, 'config-jsx-runtime'),\n        overrideConfigFile,\n      });\n\n      return eslint.lintFiles(['test.jsx']).then((results) => {\n        const result = results[0];\n\n        assert.strictEqual(result.messages.length, 1);\n        assert.strictEqual(result.messages[0].severity, 2);\n        assert.strictEqual(result.messages[0].ruleId, 'react/no-unknown-property');\n        assert.strictEqual(result.messages[0].messageId, 'unknownProp');\n      });\n    });\n\n    // https://github.com/jsx-eslint/eslint-plugin-react/issues/3693\n    it(`should work when the plugin is used directly and with \"recommended\" config (${configAccess})`, () => {\n      const eslint = new ESLint({\n        cwd: path.resolve(fixturesdDir, 'plugin-and-config'),\n        overrideConfigFile,\n      });\n\n      return eslint.lintFiles(['test.jsx']).then((results) => {\n        const result = results[0];\n\n        assert.strictEqual(result.messages.length, 2);\n        assert.strictEqual(result.messages[0].severity, 2);\n        assert.strictEqual(result.messages[0].ruleId, 'react/react-in-jsx-scope');\n        assert.strictEqual(result.messages[0].messageId, 'notInScope');\n        assert.strictEqual(result.messages[1].severity, 2);\n        assert.strictEqual(result.messages[1].ruleId, 'react/no-unknown-property');\n        assert.strictEqual(result.messages[1].messageId, 'unknownProp');\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/helpers/getESLintCoreRule.js",
    "content": "'use strict';\n\nconst version = require('eslint/package.json').version;\nconst semver = require('semver');\n\nconst isESLintV8 = semver.major(version) >= 8;\n\n// eslint-disable-next-line global-require, import/no-dynamic-require, import/no-unresolved\nconst getESLintCoreRule = (ruleId) => (isESLintV8 ? require('eslint/use-at-your-own-risk').builtinRules.get(ruleId) : require(`eslint/lib/rules/${ruleId}`));\n\nmodule.exports = getESLintCoreRule;\n"
  },
  {
    "path": "tests/helpers/getRuleDefiner.js",
    "content": "'use strict';\n\nconst eslint = require('eslint');\n\n// `ruleTester` is a RuleTester instance\nconst getRuleDefiner = (ruleTester) => (typeof Symbol !== 'undefined' && Symbol.for && ruleTester[Symbol.for('react.RuleTester.RuleDefiner')])\n    || ruleTester.linter\n    || eslint.linter\n    || eslint.Linter;\n\nmodule.exports = getRuleDefiner;\n"
  },
  {
    "path": "tests/helpers/parsers.js",
    "content": "'use strict';\n\nconst semver = require('semver');\nconst entries = require('object.entries');\nconst version = require('eslint/package.json').version;\nconst flatMap = require('array.prototype.flatmap');\nconst tsParserVersion = require('@typescript-eslint/parser/package.json').version;\n\nconst disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser\n  ? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') })\n  : (x) => x;\n\nfunction minEcmaVersion(features, parserOptions) {\n  const minEcmaVersionForFeatures = {\n    'class fields': 2022,\n    'optional chaining': 2020,\n    'nullish coalescing': 2020,\n  };\n  const result = Math.max.apply(\n    Math,\n    [].concat(\n      (parserOptions && parserOptions.ecmaVersion) || [],\n      flatMap(entries(minEcmaVersionForFeatures), (entry) => {\n        const f = entry[0];\n        const y = entry[1];\n        return features.has(f) ? y : [];\n      })\n    ).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) // normalize editions to years\n  );\n  return Number.isFinite(result) ? result : undefined;\n}\n\nconst parsers = {\n  BABEL_ESLINT: require.resolve('babel-eslint'),\n  '@BABEL_ESLINT': require.resolve('@babel/eslint-parser'),\n  TYPESCRIPT_ESLINT: require.resolve('typescript-eslint-parser'),\n  '@TYPESCRIPT_ESLINT': require.resolve('@typescript-eslint/parser'),\n  disableNewTS,\n  skipDueToMultiErrorSorting: semver.satisfies(process.versions.node, '^8 || ^9'),\n  babelParserOptions: function parserOptions(test, features) {\n    return Object.assign({}, test.parserOptions, {\n      requireConfigFile: false,\n      babelOptions: {\n        presets: [\n          '@babel/preset-react',\n        ],\n        plugins: [\n          '@babel/plugin-syntax-do-expressions',\n          '@babel/plugin-syntax-function-bind',\n          ['@babel/plugin-syntax-decorators', { legacy: true }],\n        ],\n        parserOpts: {\n          allowSuperOutsideMethod: false,\n          allowReturnOutsideFunction: false,\n        },\n      },\n      ecmaFeatures: Object.assign(\n        {},\n        test.parserOptions && test.parserOptions.ecmaFeatures,\n        {\n          jsx: true,\n          modules: true,\n          legacyDecorators: features.has('decorators'),\n        }\n      ),\n    });\n  },\n  all: function all(tests) {\n    const t = flatMap(tests, (test) => {\n      if (typeof test === 'string') {\n        test = { code: test };\n      }\n      if ('parser' in test) {\n        delete test.features;\n        return test;\n      }\n      const features = new Set([].concat(test.features || []));\n      delete test.features;\n\n      const es = minEcmaVersion(features, test.parserOptions);\n\n      function addComment(testObject, parser) {\n        const extras = [].concat(\n          `features: [${Array.from(features).join(',')}]`,\n          `parser: ${parser}`,\n          testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [],\n          testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [],\n          testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : []\n        );\n\n        const extraComment = `\\n// ${extras.join(', ')}`;\n\n        // Augment expected fix code output with extraComment\n        const nextCode = { code: testObject.code + extraComment };\n        const nextOutput = testObject.output && { output: testObject.output + extraComment };\n\n        // Augment expected suggestion outputs with extraComment\n        // `errors` may be a number (expected number of errors) or an array of\n        // error objects.\n        const nextErrors = testObject.errors\n          && typeof testObject.errors !== 'number'\n          && {\n            errors: testObject.errors.map(\n              (errorObject) => {\n                const nextSuggestions = errorObject.suggestions && typeof errorObject.suggestions !== 'number' && {\n                  suggestions: errorObject.suggestions.map((suggestion) => Object.assign({}, suggestion, {\n                    output: suggestion.output + extraComment,\n                  })),\n                };\n\n                return Object.assign({}, errorObject, nextSuggestions);\n              }\n            ),\n          };\n\n        return Object.assign(\n          {},\n          testObject,\n          nextCode,\n          nextOutput,\n          nextErrors\n        );\n      }\n\n      const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8'))\n        || (es >= 2020 && semver.satisfies(version, '< 6'))\n        || features.has('no-default')\n        || features.has('bind operator')\n        || features.has('do expressions')\n        || features.has('decorators')\n        || features.has('flow')\n        || features.has('ts')\n        || features.has('types')\n        || (features.has('fragment') && semver.satisfies(version, '< 5'));\n\n      const skipBabel = features.has('no-babel');\n      const skipOldBabel = skipBabel\n        || features.has('no-babel-old')\n        || features.has('optional chaining')\n        || semver.satisfies(version, '>= 8');\n      const skipNewBabel = skipBabel\n        || features.has('no-babel-new')\n        || !semver.satisfies(version, '^7.5.0') // require('@babel/eslint-parser/package.json').peerDependencies.eslint\n        || features.has('flow')\n        || features.has('types')\n        || features.has('ts');\n      const skipTS = semver.satisfies(version, '<= 5') // TODO: make these pass on eslint 5\n        || features.has('no-ts')\n        || features.has('flow')\n        || features.has('jsx namespace')\n        || features.has('bind operator')\n        || features.has('do expressions');\n      const tsOld = !skipTS && !features.has('no-ts-old');\n      const tsNew = !skipTS && !features.has('no-ts-new');\n\n      return [].concat(\n        skipBase ? [] : addComment(\n          Object.assign({}, test, typeof es === 'number' && {\n            parserOptions: Object.assign({}, test.parserOptions, { ecmaVersion: es }),\n          }),\n          'default'\n        ),\n        skipOldBabel ? [] : addComment(Object.assign({}, test, {\n          parser: parsers.BABEL_ESLINT,\n          parserOptions: parsers.babelParserOptions(test, features),\n        }), 'babel-eslint'),\n        skipNewBabel ? [] : addComment(Object.assign({}, test, {\n          parser: parsers['@BABEL_ESLINT'],\n          parserOptions: parsers.babelParserOptions(test, features),\n        }), '@babel/eslint-parser'),\n        tsOld ? addComment(Object.assign({}, test, { parser: parsers.TYPESCRIPT_ESLINT }), 'typescript-eslint') : [],\n        tsNew ? addComment(Object.assign({}, test, { parser: parsers['@TYPESCRIPT_ESLINT'] }), '@typescript-eslint/parser') : []\n      );\n    });\n\n    return t;\n  },\n};\n\nmodule.exports = parsers;\n"
  },
  {
    "path": "tests/helpers/ruleTester.js",
    "content": "'use strict';\n\nconst ESLintRuleTester = require('eslint').RuleTester;\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\n\n// `item` can be a config passed to the constructor, or a test case object/string\nfunction convertToFlat(item, plugins) {\n  if (typeof item === 'string') {\n    return item;\n  }\n\n  if (typeof item !== 'object' || item === null) {\n    throw new TypeError('Invalid value for \"item\" option. Expected an object or a string.');\n  }\n\n  const newItem = Object.assign({}, item, { languageOptions: {} });\n\n  if (newItem.parserOptions) {\n    newItem.languageOptions.parserOptions = newItem.parserOptions;\n\n    if (newItem.parserOptions.ecmaVersion) {\n      newItem.languageOptions.ecmaVersion = newItem.parserOptions.ecmaVersion;\n    }\n\n    if (newItem.parserOptions.sourceType) {\n      newItem.languageOptions.sourceType = newItem.parserOptions.sourceType;\n    }\n\n    delete newItem.parserOptions;\n  }\n\n  if (newItem.parser) {\n    newItem.languageOptions.parser = require(newItem.parser); // eslint-disable-line global-require, import/no-dynamic-require\n    delete newItem.parser;\n  }\n\n  if (newItem.globals) {\n    newItem.languageOptions.globals = newItem.globals;\n    delete newItem.globals;\n  }\n\n  if (plugins) {\n    newItem.plugins = plugins;\n  }\n\n  return newItem;\n}\n\nlet RuleTester = ESLintRuleTester;\n\nif (semver.major(eslintPkg.version) >= 9) {\n  const PLUGINS = Symbol('eslint-plugin-react plugins');\n  const RULE_DEFINER = Symbol.for('react.RuleTester.RuleDefiner');\n\n  RuleTester = class extends ESLintRuleTester {\n    constructor(config) {\n      if ((typeof config !== 'object' && typeof config !== 'undefined') || config === null) {\n        throw new TypeError('Invalid value for \"config\" option. Expected an object or undefined.');\n      }\n\n      const newConfig = convertToFlat(config || {});\n\n      if (!newConfig.languageOptions.ecmaVersion) {\n        newConfig.languageOptions.ecmaVersion = 5; // old default\n      }\n\n      if (!newConfig.languageOptions.sourceType) {\n        newConfig.languageOptions.sourceType = 'script'; // old default\n      }\n\n      super(newConfig);\n\n      this[RULE_DEFINER] = {\n        defineRule: (ruleId, rule) => {\n          if (!this[PLUGINS]) {\n            this[PLUGINS] = {};\n          }\n\n          const ruleIdSplit = ruleId.split('/');\n\n          if (ruleIdSplit.length !== 2) {\n            throw new Error('ruleId should be in the format: plugin-name/rule-name');\n          }\n\n          const pluginName = ruleIdSplit[0];\n          const ruleName = ruleIdSplit[1];\n\n          if (!this[PLUGINS][pluginName]) {\n            this[PLUGINS][pluginName] = { rules: {} };\n          }\n\n          this[PLUGINS][pluginName].rules[ruleName] = rule;\n        },\n      };\n    }\n\n    run(ruleName, rule, tests) {\n      const newTests = {\n        valid: tests.valid.map((test) => convertToFlat(test, this[PLUGINS])),\n        invalid: tests.invalid.map((test) => convertToFlat(test, this[PLUGINS])),\n      };\n\n      super.run(ruleName, rule, newTests);\n    }\n  };\n}\n\nmodule.exports = RuleTester;\n"
  },
  {
    "path": "tests/index.js",
    "content": "/* eslint-env mocha */\n\n'use strict';\n\nconst assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nconst plugin = require('..');\nconst index = require('../lib/rules');\n\nconst ruleFiles = fs.readdirSync(path.resolve(__dirname, '../lib/rules/'))\n  .filter((f) => f.endsWith('.js'))\n  .map((f) => path.basename(f, '.js'))\n  .filter((f) => f !== 'index');\n\ndescribe('all rule files should be exported by the plugin', () => {\n  ruleFiles.forEach((ruleName) => {\n    it(`should export ${ruleName}`, () => {\n      assert.equal(\n        plugin.rules[ruleName],\n        require(path.join('../lib/rules', ruleName)) // eslint-disable-line global-require, import/no-dynamic-require\n      );\n    });\n\n    it(`should export ${ruleName} from lib/rules/index`, () => {\n      assert.equal(\n        plugin.rules[ruleName],\n        index[ruleName]\n      );\n    });\n  });\n});\n\ndescribe('deprecated rules', () => {\n  it('marks all deprecated rules as deprecated', () => {\n    ruleFiles.forEach((ruleName) => {\n      const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];\n      const isDeprecated = plugin.rules[ruleName].meta.deprecated;\n      if (inDeprecatedRules) {\n        assert(isDeprecated, `${ruleName} metadata should mark it as deprecated`);\n      } else {\n        assert(!isDeprecated, `${ruleName} metadata should not mark it as deprecated`);\n      }\n    });\n  });\n});\n\ndescribe('configurations', () => {\n  it('should export a ‘recommended’ configuration', () => {\n    const configName = 'recommended';\n    assert(plugin.configs[configName]);\n\n    Object.keys(plugin.configs[configName].rules).forEach((ruleName) => {\n      assert.ok(ruleName.startsWith('react/'));\n      const subRuleName = ruleName.slice('react/'.length);\n      assert(plugin.rules[subRuleName]);\n    });\n\n    ruleFiles.forEach((ruleName) => {\n      const inRecommendedConfig = !!plugin.configs[configName].rules[`react/${ruleName}`];\n      const isRecommended = plugin.rules[ruleName].meta.docs[configName];\n      if (inRecommendedConfig) {\n        assert(isRecommended, `${ruleName} metadata should mark it as recommended`);\n      } else {\n        assert(!isRecommended, `${ruleName} metadata should not mark it as recommended`);\n      }\n    });\n  });\n\n  it('should export an ‘all’ configuration', () => {\n    const configName = 'all';\n    assert(plugin.configs[configName]);\n\n    Object.keys(plugin.configs[configName].rules).forEach((ruleName) => {\n      assert.ok(ruleName.startsWith('react/'));\n      assert.equal(plugin.configs[configName].rules[ruleName], 2);\n    });\n\n    ruleFiles.forEach((ruleName) => {\n      const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];\n      const inConfig = typeof plugin.configs[configName].rules[`react/${ruleName}`] !== 'undefined';\n      assert(inDeprecatedRules ^ inConfig); // eslint-disable-line no-bitwise\n    });\n  });\n\n  it('should export a ‘jsx-runtime’ configuration', () => {\n    const configName = 'jsx-runtime';\n    assert(plugin.configs[configName]);\n\n    Object.keys(plugin.configs[configName].rules).forEach((ruleName) => {\n      assert.ok(ruleName.startsWith('react/'));\n      assert.equal(plugin.configs[configName].rules[ruleName], 0);\n\n      const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];\n      const inConfig = typeof plugin.configs[configName].rules[ruleName] !== 'undefined';\n      assert(inDeprecatedRules ^ inConfig); // eslint-disable-line no-bitwise\n    });\n  });\n});\n"
  },
  {
    "path": "tests/lib/rules/async-server-action.js",
    "content": "/**\n * @fileoverview Require functions with the `use server` directive to be async\n * @author Jorge Zreik\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/async-server-action');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nruleTester.run('async-server-action', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        async function addToCart(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        async function requestUsername(formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        async function addToCart(data) {\n          \"use server\";\n        }\n      `,\n    },\n    {\n      code: `\n        async function requestUsername(formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        function addToCart(data) {\n          console.log(\"test\");\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        function requestUsername(formData) {\n          const username = formData.get('username');\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        function addToCart(data) {\n          console.log(\"use server\");\n        }\n      `,\n    },\n    {\n      code: `\n        function requestUsername(formData) {\n          console.log(\"use server\");\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async (data) => {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = async (formData) => {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async (data) => {\n          \"use server\";\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = async (formData) => {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = (data) => {\n          console.log(\"test\");\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = (formData) => {\n          const username = formData.get('username');\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = (data) => {\n          console.log(\"use server\");\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = (formData) => {\n          console.log(\"use server\");\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async function (data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = async function (formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async function (data) {\n          \"use server\";\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = async function (formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = function (data) {\n          console.log(\"test\");\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = function (formData) {\n          const username = formData.get('username');\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = function (data) {\n          console.log(\"use server\");\n        }\n      `,\n    },\n    {\n      code: `\n        const requestUsername = function (formData) {\n          console.log(\"use server\");\n          const username = formData.get('username');\n        }\n      `,\n    },\n    {\n      code: `\n        async function addToCart(data) {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        function addToCart(data) {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async (data) => {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = (data) => {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async function (data) {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = function (data) {\n          \\`use server\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async function* (data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = async function* (data) {\n          \"use server\";\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = function* (data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const addToCart = function* (data) {\n          \"use server\";\n        }\n      `,\n    },\n    {\n      code: `\n        function* addToCart(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        async function* addToCart(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        export async function addToCart(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        export default async function addToCart(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        export default async function (data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        const obj = {\n          async action() {\n            'use server';\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        const obj = {\n          async action() {\n            'use server';\n            const x = 1;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Foo {\n          async action() {\n            'use server';\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo {\n          static async action() {\n            'use server';\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        function outer() {\n          async function inner() {\n            'use server';\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        const action = async function named(data) {\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        function addToCart(data) {\n          'use strict';\n          console.log('use server');\n        }\n      `,\n    },\n    {\n      code: `\n        function empty() {}\n      `,\n    },\n    {\n      code: `\n        const fn = () => 'use server';\n      `,\n    },\n    {\n      code: `\n        <form action={async () => { 'use server'; }} />\n      `,\n    },\n    {\n      code: `\n        <button onClick={async () => { 'use server'; doSomething(); }} />\n      `,\n    },\n    {\n      code: `\n        async function action() {\n          'use strict';\n          'use server';\n        }\n      `,\n    },\n    {\n      code: `\n        function action() {\n          'use strict';\n          'use server';\n        }\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        function addToCart(data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `addToCart` an `async` function',\n              output: `\n        async function addToCart(data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        function requestUsername(formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `requestUsername` an `async` function',\n              output: `\n        async function requestUsername(formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        function addToCart(data) {\n          \"use server\";\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `addToCart` an `async` function',\n              output: `\n        async function addToCart(data) {\n          \"use server\";\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        function requestUsername(formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `requestUsername` an `async` function',\n              output: `\n        async function requestUsername(formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const addToCart = (data) => {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const addToCart = async (data) => {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const requestUsername = (formData) => {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const requestUsername = async (formData) => {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const addToCart = (data) => {\n          \"use server\";\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const addToCart = async (data) => {\n          \"use server\";\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const requestUsername = (formData) => {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const requestUsername = async (formData) => {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const addToCart = function (data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const addToCart = async function (data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const requestUsername = function (formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const requestUsername = async function (formData) {\n          'use server';\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const addToCart = function (data) {\n          \"use server\";\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const addToCart = async function (data) {\n          \"use server\";\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const requestUsername = function (formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        const requestUsername = async function (formData) {\n          \"use server\";\n          const username = formData.get('username');\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        export function addToCart(data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `addToCart` an `async` function',\n              output: `\n        export async function addToCart(data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        export default function addToCart(data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `addToCart` an `async` function',\n              output: `\n        export default async function addToCart(data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        export default function (data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        export default async function (data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const obj = {\n          action() {\n            'use server';\n          }\n        };\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `action` an `async` function',\n              output: `\n        const obj = {\n          async action() {\n            'use server';\n          }\n        };\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo {\n          action() {\n            'use server';\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `action` an `async` function',\n              output: `\n        class Foo {\n          async action() {\n            'use server';\n          }\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo {\n          static action() {\n            'use server';\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `action` an `async` function',\n              output: `\n        class Foo {\n          static async action() {\n            'use server';\n          }\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        function outer() {\n          function inner() {\n            'use server';\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `inner` an `async` function',\n              output: `\n        function outer() {\n          async function inner() {\n            'use server';\n          }\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const action = function named(data) {\n          'use server';\n        }\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make `named` an `async` function',\n              output: `\n        const action = async function named(data) {\n          'use server';\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        <form action={() => { 'use server'; }} />\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        <form action={async () => { 'use server'; }} />\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        <form\n          action={function () {\n            'use server';\n            doSomething();\n          }}\n        />\n      `,\n      errors: [\n        {\n          message: 'Server Actions must be async',\n          suggestions: [\n            {\n              desc: 'Make this function `async`',\n              output: `\n        <form\n          action={async function () {\n            'use server';\n            doSomething();\n          }}\n        />\n      `,\n            },\n          ],\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/boolean-prop-naming.js",
    "content": "/**\n * @fileoverview Enforces consistent naming for boolean props\n * @author Ev Haus\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/boolean-prop-naming');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('boolean-prop-naming', rule, {\n  valid: parsers.all([\n    {\n      // Should support both `is` and `has` prefixes by default\n      code: `\n        var Hello = createReactClass({\n          propTypes: {isSomething: PropTypes.bool, hasValue: PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      // createReactClass components with PropTypes\n      code: `\n        var Hello = createReactClass({\n          propTypes: {isSomething: PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // createReactClass components with React.PropTypes\n      code: `\n        var Hello = createReactClass({\n          propTypes: {isSomething: React.PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // React.createClass components with PropTypes\n      code: `\n        var Hello = React.createClass({\n          propTypes: {isSomething: PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n    },\n    {\n      // React.createClass components with non-boolean PropTypes\n      code: `\n        var Hello = React.createClass({\n          propTypes: {something: PropTypes.any},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n    },\n    {\n      // ES6 components as React.Component with boolean PropTypes\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {isSomething: PropTypes.bool}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // ES6 components as React.Component with non-boolean PropTypes\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = wrap({ a: PropTypes.bool })\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.any}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // ES6 components as Component with boolean PropTypes\n      code: `\n        class Hello extends Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {isSomething: PropTypes.bool}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // ES6 components with static class properties and PropTypes\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {isSomething: PropTypes.bool};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n    },\n    {\n      // ES6 components with static class properties and Object.spread syntax in PropTypes\n      code: `\n        const spreadProps = { aSpreadProp: PropTypes.string };\n        class Hello extends React.Component {\n          static propTypes = {isSomething: PropTypes.bool, ...spreadProps};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n    },\n    {\n      // ES6 components as Component with boolean PropTypes and Object.spread syntax in PropTypes\n      code: `\n        const spreadProps = { aSpreadProp: PropTypes.string };\n        class Hello extends Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {isSomething: PropTypes.bool, ...spreadProps}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // ES6 components with static class properties and React.PropTypes\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {isSomething: React.PropTypes.bool};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n    },\n    {\n      // ES6 components with static class properties an non-booleans\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {something: PropTypes.any};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n    },\n    {\n      // ES6 components and Flowtype booleans\n      code: `\n        class Hello extends React.Component {\n          props: {isSomething: boolean};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields', 'flow'],\n    },\n    {\n      // ES6 components and Flowtype non-booleans\n      code: `\n        class Hello extends React.Component {\n          props: {something: any};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n    },\n    {\n      // Stateless components\n      code: `\n        var Hello = ({isSomething}) => { return <div /> }\n        Hello.propTypes = {isSomething: PropTypes.bool};\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // Functional components and Flowtype booleans\n      code: `\n        type Props = {\n          isSomething: boolean;\n        };\n        function Hello(props: Props): React.Element { return <div /> }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n    },\n    {\n      // Custom `propTypeNames` option\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            isSomething: PropTypes.mutuallyExclusiveTrueProps,\n            something: PropTypes.bool\n          };\n          render () { return <div />; }\n        }\n      `,\n      options: [\n        {\n          propTypeNames: ['mutuallyExclusiveTrueProps'],\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      // Custom PropTypes that are specified as variables\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            isSomething: mutuallyExclusiveTrueProps,\n            isSomethingElse: bool\n          };\n          render () { return <div />; }\n        }\n      `,\n      options: [\n        {\n          propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      // Ensure rule doesn't crash on destructured objects [Issue #1369]\n      code: `\n        var x = {a: 1}\n        var y = {...x}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // Ensure rule doesn't crash on on components reference old-style Flow props\n      code: `\n        class Hello extends PureComponent {\n          props: PropsType;\n          render () { return <div /> }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n    },\n    {\n      // No propWrapperFunctions setting\n      code: `\n      function Card(props) {\n        return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n      }\n      Card.propTypes = merge({}, Card.propTypes, {\n          showScore: PropTypes.bool\n      });`,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // Ensure the rule does not throw when a prop isRequired when ES5.\n      code: `\n        var Hello = createReactClass({\n          propTypes: {isSomething: PropTypes.bool.isRequired, hasValue: PropTypes.bool.isRequired},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      // Ensure the rule does not throw when a prop isRequired when ES6 with static properties.\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            isSomething: PropTypes.bool.isRequired,\n            hasValue: PropTypes.bool.isRequired\n          };\n\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Ensure the rule does not throw when a prop isRequired when ES6 without static properties.\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          isSomething: PropTypes.bool.isRequired,\n          hasValue: PropTypes.bool.isRequired\n        }\n      `,\n    },\n    {\n      // Ensure the rule does not throw when a shape prop isRequired.\n      code: `\n        var Hello = createReactClass({\n          propTypes: {something: PropTypes.shape({}).isRequired},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n    },\n    {\n      // inline Flow type\n      code: `\n        function SomeComponent({\n            isSomething,\n        }: {\n            isSomething: boolean,\n        }) {\n            return (\n                <span>{isSomething}</span>\n            );\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          isSomething: PropTypes.bool.isRequired,\n          nested: PropTypes.shape({\n            isWorking: PropTypes.bool\n          })\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          isSomething: PropTypes.bool.isRequired,\n          nested: PropTypes.shape({\n            nested: PropTypes.shape({\n              isWorking: PropTypes.bool\n            })\n          })\n        };\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          validateNested: true,\n        },\n      ],\n    },\n    {\n      code: `\n        type TestFNType = {\n          isEnabled: boolean\n        }\n        const HelloNew = (props: TestFNType) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        } & OtherProps\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        } & {\n          hasLOL: boolean\n        } & OtherProps\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        }\n\n        const HelloNew: React.FC<Props> = (props) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        } & {\n          hasLOL: boolean\n        }\n\n        const HelloNew: React.FC<Props> = (props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        } | {\n          hasLOL: boolean\n        }\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          isEnabled: boolean\n        } & ({\n          hasLOL: boolean\n        } | {\n          isLOL: boolean\n        })\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        export const DataRow = (props: { label: string; value: string; } & React.HTMLAttributes<HTMLDivElement>) => {\n            const { label, value, ...otherProps } = props;\n            return (\n                <div {...otherProps}>\n                    <span>{label}</span>\n                    <span>{value}</span>\n                </div>\n            );\n        };\n      `,\n      options: [{ rule: '(^(is|has|should|without)[A-Z]([A-Za-z0-9]?)+|disabled|required|checked|defaultChecked)' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        // Strip @jsx comments, see https://github.com/microsoft/fluentui/issues/29126\n        const resultCode = result.code\n          .replace('/** @jsxRuntime automatic */', '')\n          .replace('/** @jsxImportSource @fluentui/react-jsx-runtime */', '');\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      // createReactClass components with PropTypes\n      code: `\n        var Hello = createReactClass({\n          propTypes: {something: PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // createReactClass components with React.PropTypes\n      code: `\n        var Hello = createReactClass({\n          propTypes: {something: React.PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // React.createClass components with PropTypes\n      code: `\n        var Hello = React.createClass({\n          propTypes: {something: PropTypes.bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as React.Component with boolean PropTypes\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.bool}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as Component with non-boolean PropTypes\n      code: `\n        class Hello extends Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.bool}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as React.Component with non-boolean PropTypes\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {something: PropTypes.bool};\n          render () { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as React.Component with non-boolean PropTypes and Object.spread syntax\n      code: `\n        const spreadProps = { aSpreadProp: PropTypes.string };\n        class Hello extends Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.bool, ...spreadProps}\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as React.Component with static class property, non-boolean PropTypes, and Object.spread syntax\n      code: `\n        const spreadProps = { aSpreadProp: PropTypes.string };\n        class Hello extends React.Component {\n          static propTypes = {something: PropTypes.bool, ...spreadProps};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components as React.Component with non-boolean PropTypes\n      code: `\n        class Hello extends React.Component {\n          props: {something: boolean};\n          render () { return <div />; }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = ({something}) => { return <div /> }\n        Hello.propTypes = {something: PropTypes.bool};\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          something: boolean;\n        };\n        function Hello(props: Props): React.Element { return <div /> }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // ES6 components and Flowtype non-booleans\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {something: PropTypes.mutuallyExclusiveTrueProps};\n          render () { return <div />; }\n        }\n      `,\n      options: [\n        {\n          propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n        },\n      ],\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            something: PropTypes.mutuallyExclusiveTrueProps,\n            somethingElse: PropTypes.bool\n          };\n          render () { return <div />; }\n        }\n      `,\n      options: [\n        {\n          propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n        },\n      ],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'somethingElse', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            something: mutuallyExclusiveTrueProps,\n            somethingElse: bool\n          };\n          render () { return <div />; }\n        }\n      `,\n      options: [\n        {\n          propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n        },\n      ],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'somethingElse', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      function Card(props) {\n        return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n      }\n      Card.propTypes = merge({}, Card.propTypes, {\n          showScore: PropTypes.bool\n      });`,\n      settings: {\n        propWrapperFunctions: ['merge'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      function Card(props) {\n        return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n      }\n      Card.propTypes = Object.assign({}, Card.propTypes, {\n          showScore: PropTypes.bool\n      });`,\n      settings: {\n        propWrapperFunctions: ['Object.assign'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      function Card(props) {\n        return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n      }\n      Card.propTypes = _.assign({}, Card.propTypes, {\n          showScore: PropTypes.bool\n      });`,\n      settings: {\n        propWrapperFunctions: ['_.assign'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      function Card(props) {\n        return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n      }\n      Card.propTypes = forbidExtraProps({\n          showScore: PropTypes.bool\n      });`,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      class Card extends React.Component {\n        render() {\n          return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n        }\n      }\n      Card.propTypes = forbidExtraProps({\n          showScore: PropTypes.bool\n      });`,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      class Card extends React.Component {\n        static propTypes = forbidExtraProps({\n          showScore: PropTypes.bool\n        });\n        render() {\n          return <div>{props.showScore ? 'yeh' : 'no'}</div>;\n        }\n      }`,\n      features: ['class fields'],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      options: [\n        { rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'showScore', pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // If a custom message is provided, use it.\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.bool}\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          message: 'Boolean prop names must begin with either \\'is\\' or \\'has\\'',\n        },\n      ],\n      errors: [\n        {\n          message: 'Boolean prop names must begin with either \\'is\\' or \\'has\\'',\n        },\n      ],\n    },\n    {\n      // Custom messages use eslint string templating.\n      code: `\n        class Hello extends React.Component {\n          render () { return <div />; }\n        }\n        Hello.propTypes = {something: PropTypes.bool}\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          message: 'It is better if your prop ({{ propName }}) matches this pattern: ({{ pattern }})',\n        },\n      ],\n      errors: [\n        {\n          message: 'It is better if your prop (something) matches this pattern: (^is[A-Z]([A-Za-z0-9]?)+)',\n        },\n      ],\n    },\n    {\n      // Works when a prop isRequired in ES5.\n      code: `\n        var Hello = createReactClass({\n          propTypes: {something: PropTypes.bool.isRequired},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // Works when a prop isRequired in ES6 with static properties.\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            something: PropTypes.bool.isRequired\n          };\n\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // Works when a prop isRequired in ES6 without static properties.\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          something: PropTypes.bool.isRequired\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      // inline Flow type\n      code: `\n        function SomeComponent({\n            something,\n        }: {\n            something: boolean,\n        }) {\n            return (\n                <span>{something}</span>\n            );\n        }\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          isSomething: PropTypes.bool.isRequired,\n          nested: PropTypes.shape({\n            failingItIs: PropTypes.bool\n          })\n        };\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          validateNested: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'failingItIs', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return (\n              <div />\n            );\n          }\n        }\n\n        Hello.propTypes = {\n          isSomething: PropTypes.bool.isRequired,\n          nested: PropTypes.shape({\n            nested: PropTypes.shape({\n              failingItIs: PropTypes.bool\n            })\n          })\n        };\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          validateNested: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'failingItIs', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n      import { bool } from 'prop-types';\n        var Hello = createReactClass({\n          propTypes: {something: bool},\n          render: function() { return <div />; }\n        });\n      `,\n      options: [\n        {\n          rule: '^is[A-Z]([A-Za-z0-9]?)+',\n          validateNested: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: { propName: 'something', pattern: '^is[A-Z]([A-Za-z0-9]?)+' },\n        },\n      ],\n    },\n    {\n      code: `\n        type TestConstType = {\n          enabled: boolean\n        }\n        const HelloNew = (props: TestConstType) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^is[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type TestFNType = {\n          enabled: boolean\n        }\n        const HelloNew = (props: TestFNType) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^is[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        } & OtherProps\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^is[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        } & {\n          hasLOL: boolean\n        } & OtherProps\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        }\n\n        const HelloNew: React.FC<Props> = (props) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^is[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        } & {\n          hasLOL: boolean\n        }\n\n        const HelloNew: React.FC<Props> = (props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        } | {\n          hasLOL: boolean\n        }\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        } & ({\n          hasLOL: boolean\n        } | {\n          lol: boolean\n        })\n\n        const HelloNew = (props: Props) => { return <div /> };\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['types', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'lol',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        interface TestFNType {\n          enabled: boolean\n        }\n        const HelloNew = (props: TestFNType) => { return <div /> };\n      `,\n      options: [{ rule: '^is[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^is[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: 'const Hello = (props: {enabled:boolean}) => <div />;',\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        };\n        type BaseProps = {\n          semi: boolean\n        };\n\n        const Hello = (props: Props & BaseProps) => <div />;\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-babel', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'semi',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          enabled: boolean\n        };\n\n        const Hello = (props: Props & {\n          semi: boolean\n        }) => <div />;\n      `,\n      options: [{ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+' }],\n      features: ['ts', 'no-babel', 'no-ts-old'],\n      errors: [\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'enabled',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n        {\n          messageId: 'patternMismatch',\n          data: {\n            propName: 'semi',\n            pattern: '^(is|has)[A-Z]([A-Za-z0-9]?)+',\n          },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/button-has-type.js",
    "content": "/**\n * @fileoverview Forbid \"button\" element without an explicit \"type\" attribute\n * @author Filipp Riabchun\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/button-has-type');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('button-has-type', rule, {\n  valid: parsers.all([\n    { code: '<span/>' },\n    { code: '<span type=\"foo\"/>' },\n    { code: '<button type=\"button\"/>' },\n    { code: '<button type=\"submit\"/>' },\n    { code: '<button type=\"reset\"/>' },\n    { code: '<button type={\"button\"}/>' },\n    { code: '<button type={\\'button\\'}/>' },\n    { code: '<button type={`button`}/>' },\n    { code: '<button type={condition ? \"button\" : \"submit\"}/>' },\n    { code: '<button type={condition ? \\'button\\' : \\'submit\\'}/>' },\n    { code: '<button type={condition ? `button` : `submit`}/>' },\n    {\n      code: '<button type=\"button\"/>',\n      options: [{ reset: false }],\n    },\n    { code: 'React.createElement(\"span\")' },\n    { code: 'React.createElement(\"span\", {type: \"foo\"})' },\n    { code: 'React.createElement(\"button\", {type: \"button\"})' },\n    { code: 'React.createElement(\"button\", {type: \\'button\\'})' },\n    { code: 'React.createElement(\"button\", {type: `button`})' },\n    { code: 'React.createElement(\"button\", {type: \"submit\"})' },\n    { code: 'React.createElement(\"button\", {type: \\'submit\\'})' },\n    { code: 'React.createElement(\"button\", {type: `submit`})' },\n    { code: 'React.createElement(\"button\", {type: \"reset\"})' },\n    { code: 'React.createElement(\"button\", {type: \\'reset\\'})' },\n    { code: 'React.createElement(\"button\", {type: `reset`})' },\n    { code: 'React.createElement(\"button\", {type: condition ? \"button\" : \"submit\"})' },\n    { code: 'React.createElement(\"button\", {type: condition ? \\'button\\' : \\'submit\\'})' },\n    { code: 'React.createElement(\"button\", {type: condition ? `button` : `submit`})' },\n    {\n      code: 'React.createElement(\"button\", {type: \"button\"})',\n      options: [{ reset: false }],\n    },\n    {\n      code: 'document.createElement(\"button\")',\n    },\n    {\n      code: 'Foo.createElement(\"span\")',\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: `\n        function MyComponent(): ReactElement {\n          const buttonProps: (Required<Attributes> & ButtonHTMLAttributes<HTMLButtonElement>)[] = [\n            {\n              children: 'test',\n              key: 'test',\n              onClick: (): void => {\n                return;\n              },\n            },\n          ];\n\n          return <>\n            {\n              buttonProps.map(\n                ({ key, ...props }: Required<Attributes> & ButtonHTMLAttributes<HTMLButtonElement>): ReactElement =>\n                  <button key={key} type=\"button\" {...props} />\n              )\n            }\n          </>;\n        }\n      `,\n      features: ['fragment', 'types'],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<button/>',\n      errors: [\n        { messageId: 'missingType' },\n      ],\n    },\n    {\n      code: '<button type=\"foo\"/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type={foo}/>',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: '<button type={\"foo\"}/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type={\\'foo\\'}/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type={`foo`}/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type={`button${foo}`}/>',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: '<button type=\"reset\"/>',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: '<button type={condition ? \"button\" : foo}/>',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: '<button type={condition ? \"button\" : \"foo\"}/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type={condition ? \"button\" : \"reset\"}/>',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: '<button type={condition ? foo : \"button\"}/>',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: '<button type={condition ? \"foo\" : \"button\"}/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<button type/>',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: true },\n        },\n      ],\n    },\n    {\n      code: '<button type={condition ? \"reset\" : \"button\"}/>',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\")',\n      errors: [\n        { messageId: 'missingType' },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: foo})',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: \"foo\"})',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: \"reset\"})',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? \"button\" : foo})',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? \"button\" : \"foo\"})',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? \"button\" : \"reset\"})',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? foo : \"button\"})',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? \"foo\" : \"button\"})',\n      errors: [\n        {\n          messageId: 'invalidValue',\n          data: { value: 'foo' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {type: condition ? \"reset\" : \"button\"})',\n      options: [{ reset: false }],\n      errors: [\n        {\n          messageId: 'forbiddenValue',\n          data: { value: 'reset' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {...extraProps})',\n      errors: [\n        { messageId: 'missingType' },\n      ],\n    },\n    {\n      code: 'Foo.createElement(\"button\")',\n      errors: [\n        { messageId: 'missingType' },\n      ],\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: 'function Button({ type, ...extraProps }) { const button = type; return <button type={button} {...extraProps} />; }',\n      errors: [\n        { messageId: 'complexType' },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/checked-requires-onchange-or-readonly.js",
    "content": "/**\n * @fileoverview Enforce the use of the 'onChange' or 'readonly' attribute when 'checked' is used'\n * @author Jaesoekjjang\n */\n\n'use strict';\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/checked-requires-onchange-or-readonly');\n\nconst parsers = require('../../helpers/parsers');\n\nconst ruleTester = new RuleTester({\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n});\n\nruleTester.run('checked-requires-onchange-or-readonly', rule, {\n  valid: parsers.all([\n    '<input type=\"checkbox\" />',\n    '<input type=\"checkbox\" onChange={noop} />',\n    '<input type=\"checkbox\" readOnly />',\n    '<input type=\"checkbox\" checked onChange={noop} />',\n    '<input type=\"checkbox\" checked={true} onChange={noop} />',\n    '<input type=\"checkbox\" checked={false} onChange={noop} />',\n    '<input type=\"checkbox\" checked readOnly />',\n    '<input type=\"checkbox\" checked={true} readOnly />',\n    '<input type=\"checkbox\" checked={false} readOnly />',\n    '<input type=\"checkbox\" defaultChecked />',\n    \"React.createElement('input')\",\n    \"React.createElement('input', { checked: true, onChange: noop })\",\n    \"React.createElement('input', { checked: false, onChange: noop })\",\n    \"React.createElement('input', { checked: true, readOnly: true })\",\n    \"React.createElement('input', { checked: true, onChange: noop, readOnly: true })\",\n    \"React.createElement('input', { checked: foo, onChange: noop, readOnly: true })\",\n    {\n      code: '<input type=\"checkbox\" checked />',\n      options: [{ ignoreMissingProperties: true }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked={true} />',\n      options: [{ ignoreMissingProperties: true }],\n    },\n    {\n      code: '<input type=\"checkbox\" onChange={noop} checked defaultChecked />',\n      options: [{ ignoreExclusiveCheckedAttribute: true }],\n    },\n    {\n      code: '<input type=\"checkbox\" onChange={noop} checked={true} defaultChecked />',\n      options: [{ ignoreExclusiveCheckedAttribute: true }],\n    },\n    {\n      code: '<input type=\"checkbox\" onChange={noop} checked defaultChecked />',\n      options: [{ ignoreMissingProperties: true, ignoreExclusiveCheckedAttribute: true }],\n    },\n    '<span/>',\n    \"React.createElement('span')\",\n    '(()=>{})()',\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<input type=\"radio\" checked />',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"radio\" checked={true} />',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked />',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked={true} />',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked={condition ? true : false} />',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked defaultChecked />',\n      errors: [\n        { messageId: 'exclusiveCheckedAttribute' },\n        { messageId: 'missingProperty' },\n      ],\n    },\n    {\n      code: 'React.createElement(\"input\", { checked: false })',\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: 'React.createElement(\"input\", { checked: true, defaultChecked: true })',\n      errors: [\n        { messageId: 'exclusiveCheckedAttribute' },\n        { messageId: 'missingProperty' },\n      ],\n    },\n    {\n      code: '<input type=\"checkbox\" checked defaultChecked />',\n      options: [{ ignoreMissingProperties: true }],\n      errors: [{ messageId: 'exclusiveCheckedAttribute' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked defaultChecked />',\n      options: [{ ignoreExclusiveCheckedAttribute: true }],\n      errors: [{ messageId: 'missingProperty' }],\n    },\n    {\n      code: '<input type=\"checkbox\" checked defaultChecked />',\n      options: [{ ignoreMissingProperties: false, ignoreExclusiveCheckedAttribute: false }],\n      errors: [\n        { messageId: 'exclusiveCheckedAttribute' },\n        { messageId: 'missingProperty' },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/default-props-match-prop-types.js",
    "content": "/**\n * @fileoverview Enforce all defaultProps are declared and non-required propTypes\n * @author Vitor Balocco\n * @author Roy Sutton\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/default-props-match-prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nruleTester.run('default-props-match-prop-types', rule, {\n  valid: parsers.all([\n    // stateless components\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string.isRequired,\n          bar: React.PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes.foo = React.PropTypes.string;\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      options: [\n        { allowRequiredDefaults: true },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes.foo = React.PropTypes.string;\n        MyStatelessComponent.defaultProps = {};\n        MyStatelessComponent.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo }) {\n          return <div>{foo}</div>;\n        }\n        MyStatelessComponent.propTypes = {};\n        MyStatelessComponent.propTypes.foo = React.PropTypes.string;\n        MyStatelessComponent.defaultProps = {};\n        MyStatelessComponent.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        const types = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n\n    // createReactClass components\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: React.PropTypes.string.isRequired,\n            bar: React.PropTypes.string.isRequired\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: React.PropTypes.string,\n            bar: React.PropTypes.string.isRequired\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\"\n            };\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: React.PropTypes.string,\n            bar: React.PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\",\n              bar: \"bar\"\n            };\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          }\n        });\n      `,\n    },\n\n    // ES6 class component\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = React.PropTypes.string;\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = React.PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {};\n        Greeting.propTypes.foo = React.PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n    },\n\n    // edge cases\n\n    // not a react component\n    {\n      code: `\n        function NotAComponent({ foo, bar }) {}\n        NotAComponent.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.defaulProps = {\n          bar: \"bar\"\n        };\n      `,\n    },\n    // external references\n    {\n      code: `\n        const defaults = require(\"./defaults\");\n        const types = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = require(\"./propTypes\");\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = require(\"./defaults\").foo;\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = require(\"./defaults\").foo;\n        MyStatelessComponent.defaultProps.bar = \"bar\";\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        import defaults from \"./defaults\";\n\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = defaults;\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    {\n      code: `\n        import { foo } from \"./defaults\";\n\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = foo;\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    // using spread operator\n    {\n      code: `\n        const component = rowsOfType(GuestlistEntry, (rowData, ownProps) => ({\n            ...rowData,\n            onPress: () => ownProps.onPress(rowData.id),\n        }));\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          ...stuff,\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = {\n         foo: \"foo\"\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = {\n         ...defaults,\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          ...someProps,\n          bar: React.PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          ...defaults,\n          bar: \"bar\"\n        };\n      `,\n    },\n\n    // with Flow annotations\n    {\n      code: `\n        type Props = {\n          foo: string\n        };\n\n        class Hello extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n\n        class Hello extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n\n        Hello.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string,\n            bar?: string\n          };\n\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n\n        Hello.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string\n          };\n\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: { foo: string }) {\n          return <div>Hello {foo}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = (props: { foo?: string }) => {\n          return <div>Hello {props.foo}</div>;\n        };\n\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = (props: { foo: string }) => {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        };\n\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo: string }) {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n\n        type Props2 = {\n          foo: string,\n          baz?: string\n        }\n\n        function Hello(props: Props | Props2) {\n          return <div>Hello {props.foo}</div>;\n        }\n\n        Hello.defaultProps = {\n          bar: \"bar\",\n          baz: \"baz\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { foo?: string };\n        type PropsB = { bar?: string, fooBar: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props;\n          static defaultProps = {\n            foo: \"foo\",\n          }\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = any;\n\n        const Hello = function({ foo }: Props) {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type ImportedProps from \"fake\";\n        type Props = ImportedProps;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type DefaultProps1 = {|\n          bar1?: string\n        |};\n        type DefaultProps2 = {|\n          ...DefaultProps1,\n          bar2?: string\n        |};\n        type Props = {\n          foo: string,\n          ...DefaultProps2\n        };\n\n        function Hello(props: Props) {\n          return <div>Hello {props.foo}</div>;\n        }\n\n        Hello.defaultProps = {\n          bar1: \"bar1\",\n          bar2: \"bar2\",\n        };\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type DefaultProps1 = {|\n          bar1?: string\n        |};\n        type DefaultProps2 = {|\n          ...DefaultProps1,\n          bar2?: string\n        |};\n        type Props = {\n          foo: string,\n          ...DefaultProps2\n        };\n\n        class Hello extends React.Component<Props> {\n          render() {\n            return <div>Hello {props.foo}</div>;\n          }\n        }\n\n        Hello.defaultProps = {\n          bar1: \"bar1\",\n          bar2: \"bar2\",\n        };\n      `,\n      features: ['flow'],\n    },\n    // don't error when variable is not in scope\n    {\n      code: `\n        import type { ImportedType } from \"fake\";\n        type Props = ImportedType;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // make sure error is not thrown with multiple assignments\n    {\n      code: `\n        import type ImportedProps from \"fake\";\n        type NestedProps = ImportedProps;\n        type Props = NestedProps;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // don't error when variable is not in scope with intersection\n    {\n      code: `\n        import type ImportedProps from \"fake\";\n        type Props = ImportedProps & {\n          foo: string\n        };\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type { FieldProps } from 'redux-form';\n\n        type Props = FieldProps & {\n          name: string,\n          type: string,\n          label?: string,\n          placeholder?: string,\n          disabled?: boolean,\n        };\n\n        TextField.defaultProps = {\n          label: '',\n          placeholder: '',\n          disabled: false,\n        };\n      `,\n      features: ['types'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    // stateless components\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          baz: \"baz\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = forbidExtraProps({\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        })\n        MyStatelessComponent.defaultProps = {\n          baz: \"baz\"\n        };\n      `,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        const propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes = forbidExtraProps(propTypes);\n        MyStatelessComponent.defaultProps = {\n          baz: \"baz\"\n        };\n      `,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          baz: \"baz\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 10,\n          column: 11,\n        },\n      ],\n      options: [{ allowRequiredDefaults: true }],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          bar: \"bar\"\n        };\n        MyStatelessComponent.defaultProps.baz = \"baz\";\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 10,\n          column: 11,\n        },\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 12,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        const types = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 12,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: React.PropTypes.string.isRequired,\n          bar: React.PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = {\n          foo: React.PropTypes.string.isRequired,\n          bar: React.PropTypes.string\n        };\n\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n\n    // createReactClass components\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: React.PropTypes.string,\n            bar: React.PropTypes.string.isRequired\n          },\n          getDefaultProps: function() {\n            return {\n              baz: \"baz\"\n            };\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 12,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: React.PropTypes.string.isRequired,\n            bar: React.PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\"\n            };\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 12,\n          column: 15,\n        },\n      ],\n    },\n\n    // ES6 class component\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          baz: \"baz\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 14,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: React.PropTypes.string.isRequired,\n          bar: React.PropTypes.string\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 14,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = React.PropTypes.string.isRequired;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 14,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: React.PropTypes.string\n        };\n        Greeting.propTypes.foo = React.PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.baz = \"baz\";\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 14,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {};\n        Greeting.propTypes.foo = React.PropTypes.string.isRequired;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 12,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        const props = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        Greeting.propTypes = props;\n        const defaults = {\n          bar: \"bar\"\n        };\n        Greeting.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 15,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        const props = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string\n        };\n        const defaults = {\n          baz: \"baz\"\n        };\n        Greeting.propTypes = props;\n        Greeting.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 14,\n          column: 11,\n        },\n      ],\n    },\n\n    // ES6 classes with static getter methods\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: React.PropTypes.string.isRequired\n            };\n          }\n          static get defaultProps() {\n            return {\n              name: \"name\"\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'name' },\n          line: 10,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              foo: React.PropTypes.string,\n              bar: React.PropTypes.string\n            };\n          }\n          static get defaultProps() {\n            return {\n              baz: \"world\"\n            };\n          }\n          render() {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 11,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: React.PropTypes.string\n        };\n        const defaults = {\n          baz: \"baz\"\n        };\n\n        class Hello extends React.Component {\n          static get propTypes() {\n            return props;\n          }\n          static get defaultProps() {\n            return defaults;\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 6,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          bar: \"world\"\n        };\n\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              foo: React.PropTypes.string,\n              bar: React.PropTypes.string.isRequired\n            };\n          }\n          static get defaultProps() {\n            return defaults;\n          }\n          render() {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n\n    // ES6 classes with property initializers\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = {\n            foo: React.PropTypes.string,\n            bar: React.PropTypes.string.isRequired\n          };\n          static defaultProps = {\n            bar: \"bar\"\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 13,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = {\n            foo: React.PropTypes.string,\n            bar: React.PropTypes.string\n          };\n          static defaultProps = {\n            baz: \"baz\"\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 13,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string.isRequired\n        };\n        const defaults = {\n          bar: \"bar\"\n        };\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = props;\n          static defaultProps = defaults;\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'bar' },\n          line: 7,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: React.PropTypes.string,\n          bar: React.PropTypes.string\n        };\n        const defaults = {\n          baz: \"baz\"\n        };\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = props;\n          static defaultProps = defaults;\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'baz' },\n          line: 7,\n          column: 11,\n        },\n      ],\n    },\n\n    // edge cases\n    {\n      code: `\n        let Greetings = {};\n        Greetings.Hello = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Greetings.Hello.propTypes = {\n          foo: React.PropTypes.string.isRequired\n        };\n        Greetings.Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 12,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        var Greetings = ({ foo = \"foo\" }) => {\n          return <div>Hello {this.props.foo}</div>;\n        }\n        Greetings.propTypes = {\n          foo: React.PropTypes.string.isRequired\n        };\n        Greetings.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 9,\n          column: 11,\n        },\n      ],\n    },\n\n    // with Flow annotations\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string,\n            bar?: string\n          };\n\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n\n        Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 14,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: { foo: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string\n        };\n\n        function Hello(props: Props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props: { foo: string, bar?: string }) => {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.defaultProps = { foo: \"foo\", bar: \"bar\" };\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 5,\n          column: 32,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n\n        type Props2 = {\n          foo: string,\n          baz?: string\n        }\n\n        function Hello(props: Props | Props2) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = { foo: \"foo\", frob: \"frob\" };\n      `,\n      features: ['flow'], // TODO: FIXME: change to \"types\" and fix failures\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 15,\n          column: 32,\n        },\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'frob' },\n          line: 15,\n          column: 44,\n        },\n      ],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props;\n          static defaultProps = {\n            fooBar: \"fooBar\",\n            foo: \"foo\",\n          }\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'fooBar' },\n        },\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class SomeComponent extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        SomeComponent.propTypes = {\n          \"firstProperty\": PropTypes.string.isRequired,\n        };\n\n        SomeComponent.defaultProps = {\n          \"firstProperty\": () => undefined\n        };\n      `,\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'firstProperty' },\n        },\n      ],\n    },\n    {\n      code: `\n        type DefaultProps = {\n          baz?: string,\n          bar?: string\n        };\n\n        type Props = {\n          foo: string,\n          ...DefaultProps\n        }\n\n        function Hello(props: Props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = { foo: \"foo\", frob: \"frob\", baz: \"bar\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 15,\n          column: 32,\n        },\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'frob' },\n          line: 15,\n          column: 44,\n        },\n      ],\n    },\n    {\n      code: `\n        type DefaultProps = {\n          baz?: string,\n          bar?: string\n        };\n\n        type Props = {\n          foo: string,\n          ...DefaultProps\n        }\n\n        class Hello extends React.Component<Props> {\n          render() {\n            return <div>Hello {props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = { foo: \"foo\", frob: \"frob\", baz: \"bar\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: { name: 'foo' },\n          line: 17,\n          column: 32,\n        },\n        {\n          messageId: 'defaultHasNoType',\n          data: { name: 'frob' },\n          line: 17,\n          column: 44,\n        },\n      ],\n    },\n    {\n      code: `\n        export type SharedProps = {|\n            disabled: boolean,\n        |};\n\n        type Props = {|\n            ...SharedProps,\n            focused?: boolean,\n        |};\n\n        class Foo extends React.Component<Props> {\n            static defaultProps = {\n              disabled: false\n            };\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'requiredHasDefault',\n          data: {\n            name: 'disabled',\n          },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/destructuring-assignment.js",
    "content": "/**\n * @fileoverview Rule to forbid or enforce destructuring assignment consistency.\n */\n\n'use strict';\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/destructuring-assignment');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('destructuring-assignment', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        export const revisionStates2 = {\n            [A.b]: props => {\n              return props.editor !== null\n                ? 'xyz'\n                : 'abc'\n            },\n        };\n      `,\n    },\n    {\n      code: `\n        export function hof(namespace) {\n          const initialState = {\n            bounds: null,\n            search: false,\n          };\n          return (props) => {\n            const {x, y} = props\n            if (y) {\n              return <span>{y}</span>;\n            }\n            return <span>{x}</span>\n          };\n        }\n      `,\n    },\n    {\n      code: `\n        export function hof(namespace) {\n          const initialState = {\n            bounds: null,\n            search: false,\n          };\n\n          return (state = initialState, action) => {\n            if (action.type === 'ABC') {\n              return {...state, bounds: stuff ? action.x : null};\n            }\n\n            if (action.namespace !== namespace) {\n              return state;\n            }\n\n            return null\n          };\n        }\n      `,\n    },\n    {\n      code: `\n        const MyComponent = ({ id, className }) => (\n          <div id={id} className={className} />\n        );\n      `,\n    },\n    {\n      code: `\n        const MyComponent = ({ id, className }) => (\n          <div id={id} className={className} />\n        );\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const { id, className } = props;\n          return <div id={id} className={className} />\n        };\n      `,\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const { id, className } = props;\n          return <div id={id} className={className} />\n        };\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const MyComponent = (props) => (\n          <div id={id} props={props} />\n        );\n      `,\n    },\n    {\n      code: `\n        const MyComponent = (props) => (\n          <div id={id} props={props} />\n        );\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const MyComponent = (props, { color }) => (\n          <div id={id} props={props} color={color} />\n        );\n      `,\n    },\n    {\n      code: `\n        const MyComponent = (props, { color }) => (\n          <div id={id} props={props} color={color} />\n        );\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        };\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          doStuff() {}\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            const { foo } = this.props;\n            return <div>{foo}</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            const { foo } = this.props;\n            return <div>{foo}</div>;\n          }\n        };\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const { h, i } = hi;\n          return <div id={props.id} className={props.className} />\n        };\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          constructor() {\n            this.state = {};\n            this.state.foo = 'bar';\n          }\n        };\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const div = styled.div\\`\n          & .button {\n            border-radius: \\${props => props.borderRadius}px;\n          }\n        \\`\n      `,\n    },\n    {\n      code: `\n        export default (context: $Context) => ({\n          foo: context.bar\n        });\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Foo {\n          bar(context) {\n            return context.baz;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo {\n          bar(props) {\n            return props.baz;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          bar = this.props.bar\n        }\n      `,\n      options: ['always', { ignoreClassFields: true }],\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Input extends React.Component {\n          id = \\`\\${this.props.name}\\`;\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: ['always', { ignoreClassFields: true }],\n      features: ['class fields'],\n    },\n    // https://github.com/jsx-eslint/eslint-plugin-react/issues/2911\n    {\n      code: `\n        function Foo({ context }) {\n          const d = context.describe();\n          return <div>{d}</div>;\n        }\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        const obj = {\n          foo(arg) {\n            const a = arg.func();\n            return null;\n          },\n        };\n      `,\n    },\n    {\n      code: `\n        const columns = [\n          {\n            render: (val) => {\n              if (val.url) {\n                return (\n                  <a href={val.url}>\n                    {val.test}\n                  </a>\n                );\n              }\n              return null;\n            },\n          },\n        ];\n      `,\n    },\n    {\n      code: `\n        const columns = [\n          {\n            render: val => <span>{val}</span>,\n          },\n          {\n            someRenderFunc: function(val) {\n              if (val.url) {\n                return (\n                  <a href={val.url}>\n                    {val.test}\n                  </a>\n                );\n              }\n              return null;\n            },\n          },\n        ];\n      `,\n    },\n    {\n      code: `\n        export default (fileName) => {\n          const match = fileName.match(/some expression/);\n          if (match) {\n            return fn;\n          }\n          return null;\n        };\n      `,\n    },\n    {\n      code: `\n        class C extends React.Component {\n          componentDidMount() {\n            const { forwardRef } = this.props;\n\n            this.ref.current.focus();\n\n            if (typeof forwardRef === 'function') {\n              forwardRef(this.ref);\n            }\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo(props) {\n          const {a} = props;\n          return <Goo {...props}>{a}</Goo>;\n        }\n      `,\n      options: ['always', { destructureInSignature: 'always' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          const {a} = props;\n          return <Goo f={() => props}>{a}</Goo>;\n        }\n      `,\n      options: ['always', { destructureInSignature: 'always' }],\n    },\n    {\n      code: `\n        import { useContext } from 'react';\n\n        const MyComponent = (props) => {\n          const {foo} = useContext(aContext);\n          return <div>{foo}</div>\n        };\n      `,\n      options: ['always'],\n      settings: { react: { version: '16.9.0' } },\n    },\n    {\n      code: `\n        import { useContext } from 'react';\n\n        const MyComponent = (props) => {\n          const foo = useContext(aContext);\n          return <div>{foo.test}</div>\n        };\n      `,\n      options: ['never'],\n      settings: { react: { version: '16.9.0' } },\n    },\n    {\n      code: `\n        import { useContext } from 'react';\n\n        const MyComponent = (props) => {\n          const foo = useContext(aContext);\n          return <div>{foo.test}</div>\n        };\n      `,\n      options: ['always'],\n      settings: { react: { version: '16.9.0' } },\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const foo = useContext(aContext);\n          return <div>{foo.test}</div>\n        };\n      `,\n      options: ['always'],\n      settings: { react: { version: '16.8.999' } },\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const {foo} = useContext(aContext);\n          return <div>{foo}</div>\n        };\n      `,\n      options: ['never'],\n      settings: { react: { version: '16.8.999' } },\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const {foo} = useContext(aContext);\n          return <div>{foo}</div>\n        };\n      `,\n      options: ['always'],\n      settings: { react: { version: '16.8.999' } },\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const foo = useContext(aContext);\n          return <div>{foo.test}</div>\n        };\n      `,\n      options: ['never'],\n      settings: { react: { version: '16.8.999' } },\n    },\n    {\n      code: `\n        import { useContext } from 'react';\n\n        const MyComponent = (props) => {\n          const foo = useContext(aContext);\n          return <div>{foo?.test}</div>\n        };\n      `,\n      features: ['optional chaining'],\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        const MyComponent = (props) => {\n          return (<div id={props.id} />)\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = ({ id, className }) => (\n          <div id={id} className={className} />\n        );\n      `,\n      options: ['never'],\n      errors: [\n        { messageId: 'noDestructPropsInSFCArg' },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = (props, { color }) => (\n          <div id={props.id} className={props.className} />\n        );\n      `,\n      options: ['never'],\n      errors: [\n        { messageId: 'noDestructContextInSFCArg' },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            return <div>{this.state.foo}</div>;\n          }\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'state' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            return <div>{this.context.foo}</div>;\n          }\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'context' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() { return this.foo(); }\n          foo() {\n            return this.props.children;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <Text>{this.props.foo}</Text>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        module.exports = {\n          Foo(props) {\n            return <p>{props.a}</p>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        export default function Foo(props) {\n          return <p>{props.a}</p>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        function hof() {\n          return (props) => <p>{props.a}</p>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            const foo = this.props.foo;\n            return <div>{foo}</div>;\n          }\n        };\n        `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            const { foo } = this.props;\n            return <div>{foo}</div>;\n          }\n        };\n      `,\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          const { id, className } = props;\n          return <div id={id} className={className} />\n        };\n      `,\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            const { foo } = this.state;\n            return <div>{foo}</div>;\n          }\n        };\n      `,\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noDestructAssignment',\n          data: { type: 'state' },\n        },\n      ],\n    },\n    {\n      code: `\n        const columns = [\n          {\n            CustomComponentName: function(props) {\n              if (props.url) {\n                return (\n                  <a href={props.url}>\n                    {props.test}\n                  </a>\n                );\n              }\n              return null;\n            },\n          },\n        ];\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 5,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 7,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 8,\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo(props, context) {\n          const d = context.describe();\n          return <div>{d}</div>;\n        }\n      `,\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'context' },\n        },\n      ],\n    },\n    {\n      code: `\n        export default (props) => {\n          const match = props.str.match(/some expression/);\n          if (match) {\n            return <span>jsx</span>;\n          }\n          return null;\n        };\n      `,\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const TestComp = (props) => {\n          props.onClick3102();\n\n          return (\n            <div\n              onClick={(evt) => {\n                if (props.onClick3102) {\n                  props.onClick3102(evt);\n                }\n              }}\n            >\n              <div />\n            </div>\n          );\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 5,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 10,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        export const revisionStates2 = {\n            [A.b]: props => {\n              return props.editor !== null\n                ? <span>{props.editor}</span>\n                : null\n            },\n        };\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 4,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        export function hof(namespace) {\n          const initialState = {\n            bounds: null,\n            search: false,\n          };\n          return (props) => {\n            if (props.y) {\n              return <span>{props.y}</span>;\n            }\n            return <span>{props.x}</span>\n          };\n        }\n      `,\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 8,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 9,\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n          line: 11,\n        },\n      ],\n    },\n    // Ignore for ESLint < 4 because ESLint < 4 does not support array fixer.\n    semver.satisfies(eslintPkg.version, '>= 4') ? [\n      {\n        code: `\n          function Foo(props) {\n            const {a} = props;\n            return <p>{a}</p>;\n          }\n        `,\n        options: ['always', { destructureInSignature: 'always' }],\n        errors: [\n          {\n            messageId: 'destructureInSignature',\n            line: 3,\n          },\n        ],\n        output: `\n          function Foo({a}) {\n${'            '}\n            return <p>{a}</p>;\n          }\n        `,\n      },\n      {\n        code: `\n          function Foo(props: FooProps) {\n            const {a} = props;\n            return <p>{a}</p>;\n          }\n        `,\n        options: ['always', { destructureInSignature: 'always' }],\n        errors: [\n          {\n            messageId: 'destructureInSignature',\n            line: 3,\n          },\n        ],\n        output: `\n          function Foo({a}: FooProps) {\n${'            '}\n            return <p>{a}</p>;\n          }\n        `,\n        features: ['ts', 'no-babel'],\n      },\n    ] : [],\n    {\n      code: `\n        type Props = { text: string };\n        export const MyComponent: React.FC<Props> = (props) => {\n          type MyType = typeof props.text;\n          return <div>{props.text as MyType}</div>;\n        };\n      `,\n      options: ['always', { destructureInSignature: 'always' }],\n      features: ['types', 'no-babel'],\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          type: 'TSQualifiedName',\n          data: { type: 'props' },\n        },\n        {\n          messageId: 'useDestructAssignment',\n          type: 'MemberExpression',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = { text: string };\n        export const MyOtherComponent: React.FC<Props> = (props) => {\n          const { text } = props;\n          type MyType = typeof props.text;\n          return <div>{text as MyType}</div>;\n        };\n      `,\n      options: ['always', { destructureInSignature: 'always' }],\n      features: ['types', 'no-babel'],\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          type: 'TSQualifiedName',\n          data: { type: 'props' },\n        },\n      ],\n    },\n    {\n      code: `\n        function C(props: Props) {\n          void props.a\n          typeof props.b\n          return <div />\n        }\n      `,\n      options: ['always'],\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n        {\n          messageId: 'useDestructAssignment',\n          data: { type: 'props' },\n        },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/display-name.js",
    "content": "/**\n * @fileoverview Prevent missing displayName in a React component definition\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/display-name');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('display-name', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const TestComponent = function () {\n          {\n            const memo = (cb) => cb()\n            const forwardRef = (cb) => cb()\n            const React = { memo, forwardRef }\n\n            const BlockMemo = memo(() => <div>shadowed</div>)\n            const BlockForwardRef = forwardRef(() => <div>shadowed</div>)\n            const BlockReactMemo = React.memo(() => <div>shadowed</div>)\n          }\n          return null\n        }\n      `,\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const Test1 = function (memo) {\n          return memo(() => <div>param shadowed</div>)\n        }\n\n        const Test2 = function ({ forwardRef }) {\n          return forwardRef(() => <div>destructured param</div>)\n        }\n      `,\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const TestComponent = function () {\n          function innerFunction() {\n            const memo = (cb) => cb()\n            const React = { forwardRef }\n\n            const Comp = memo(() => <div>nested</div>)\n            const ForwardComp = React.forwardRef(() => <div>nested</div>)\n            return [Comp, ForwardComp]\n          }\n          return innerFunction()\n        }\n      `,\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const MixedShadowed = function () {\n          const memo = (cb) => cb()\n          const { forwardRef } = { forwardRef: () => null }\n          const [React] = [{ memo, forwardRef }]\n\n          const Comp = memo(() => <div>shadowed</div>)\n          const ReactMemo = React.memo(() => null)\n          const ReactForward = React.forwardRef((props, ref) => \\`\\${props} \\${ref}\\`)\n          const OtherComp = forwardRef((props, ref) => \\`\\${props} \\${ref}\\`)\n\n          return [Comp, ReactMemo, ReactForward, OtherComp]\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          displayName: 'Hello',\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.displayName = 'Hello'\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        class Hello {\n          render() {\n            return 'Hello World';\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends Greetings {\n          static text = 'Hello World';\n          render() {\n            return Hello.text;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello {\n          method;\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get displayName() {\n            return 'Hello';\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static displayName = 'Widget';\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      features: ['class fields'],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        export default class Hello {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello;\n        Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        module.exports = createReactClass({\n          \"displayName\": \"Hello\",\n          \"render\": function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        export default class {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        export const Hello = React.memo(function Hello() {\n          return <p />;\n        })\n      `,\n    },\n    {\n      code: `\n        var Hello = function() {\n          return <div>Hello {this.props.name}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        function Hello() {\n          return <div>Hello {this.props.name}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = () => {\n          return <div>Hello {this.props.name}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        module.exports = function Hello() {\n          return <div>Hello {this.props.name}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        function Hello() {\n          return <div>Hello {this.props.name}</div>;\n        }\n        Hello.displayName = 'Hello';\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var Hello = () => {\n          return <div>Hello {this.props.name}</div>;\n        }\n        Hello.displayName = 'Hello';\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var Hello = function() {\n          return <div>Hello {this.props.name}</div>;\n        }\n        Hello.displayName = 'Hello';\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var Mixins = {\n          Greetings: {\n            Hello: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n        }\n        Mixins.Greetings.Hello.displayName = 'Hello';\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>{this._renderHello()}</div>;\n          },\n          _renderHello: function() {\n            return <span>Hello {this.props.name}</span>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {\n            return <div>{this._renderHello()}</div>;\n          },\n          _renderHello: function() {\n            return <span>Hello {this.props.name}</span>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        const Mixin = {\n          Button() {\n            return (\n              <button />\n            );\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        var obj = {\n          pouf: function() {\n            return any\n          }\n        };\n      `,\n      options: [{ ignoreTranspilerName: true }],\n    },\n    {\n      code: `\n        var obj = {\n          pouf: function() {\n            return any\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        export default {\n          renderHello() {\n            let {name} = this.props;\n            return <div>{name}</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        import React, { createClass } from 'react';\n        export default createClass({\n          displayName: 'Foo',\n          render() {\n            return <h1>foo</h1>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n    },\n    {\n      code: `\n        import React, {Component} from \"react\";\n        function someDecorator(ComposedComponent) {\n          return class MyDecorator extends Component {\n            render() {return <ComposedComponent {...this.props} />;}\n          };\n        }\n        module.exports = someDecorator;\n      `,\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        const SomeComponent = (props) => {\n          const {foo, bar} = props;\n          return someComponentFactory({\n            onClick: () => foo(bar(\"x\"))\n          });\n        };\n      `,\n    },\n    {\n      code: `\n        const element = (\n          <Media query={query} render={() => {\n            renderWasCalled = true\n            return <div/>\n          }}/>\n        )\n      `,\n    },\n    {\n      code: `\n        const element = (\n          <Media query={query} render={function() {\n            renderWasCalled = true\n            return <div/>\n          }}/>\n        )\n      `,\n    },\n    {\n      code: `\n        module.exports = {\n          createElement: tagName => document.createElement(tagName)\n        };\n      `,\n    },\n    {\n      code: `\n        const { createElement } = document;\n        createElement(\"a\");\n      `,\n    },\n    {\n      code: `\n        import React from 'react'\n        import { string } from 'prop-types'\n\n        function Component({ world }) {\n          return <div>Hello {world}</div>\n        }\n\n        Component.propTypes = {\n          world: string,\n        }\n\n        export default React.memo(Component)\n      `,\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ComponentWithMemo = React.memo(function Component({ world }) {\n          return <div>Hello {world}</div>\n        })\n      `,\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const Hello = React.memo(function Hello() {\n          return;\n        });\n      `,\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ForwardRefComponentLike = React.forwardRef(function ComponentLike({ world }, ref) {\n          return <div ref={ref}>Hello {world}</div>\n        })\n      `,\n    },\n    {\n      code: `\n        function F() {\n          let items = [];\n          let testData = [\n            {a: \"test1\", displayName: \"test2\"}, {a: \"test1\", displayName: \"test2\"}];\n          for (let item of testData) {\n              items.push({a: item.a, b: item.displayName});\n          }\n          return <div>{items}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        import {Component} from \"react\";\n        type LinkProps = {...{}};\n        class Link extends Component<LinkProps> {}\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        const x = {\n          title: \"URL\",\n          dataIndex: \"url\",\n          key: \"url\",\n          render: url => (\n            <a href={url} target=\"_blank\" rel=\"noopener noreferrer\">\n              <p>lol</p>\n            </a>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        const renderer = a => function Component(listItem) {\n          return <div>{a} {listItem}</div>;\n        };\n      `,\n    },\n    {\n      // issue 3032\n      code: `\n        const Comp = React.forwardRef((props, ref) => <main />);\n        Comp.displayName = 'MyCompName';\n      `,\n    },\n    {\n      // issue 3032\n      code: `\n        const Comp = React.forwardRef((props, ref) => <main data-as=\"yes\" />) as SomeComponent;\n        Comp.displayName = 'MyCompNameAs';\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        function Test() {\n          const data = [\n            {\n              name: 'Bob',\n            },\n          ];\n\n          const columns = [\n            {\n              Header: 'Name',\n              accessor: 'name',\n              Cell: ({ value }) => <div>{value}</div>,\n            },\n          ];\n\n          return <ReactTable columns={columns} data={data} />;\n        }\n      `,\n    },\n    {\n      // issue #3300\n      code: `\n        const f = (a) => () => {\n          if (a) {\n            return null;\n          }\n          return 1;\n        };\n      `,\n    },\n    {\n      code: `\n        class Test {\n          render() {\n            const data = [\n              {\n                name: 'Bob',\n              },\n            ];\n\n            const columns = [\n              {\n                Header: 'Name',\n                accessor: 'name',\n                Cell: ({ value }) => <div>{value}</div>,\n              },\n            ];\n\n            return <ReactTable columns={columns} data={data} />;\n          }\n        }\n      `,\n    },\n    {\n      // issue #3289\n      code: `\n        export const demo = (a) => (b) => {\n          if (a == null) return null;\n          return b;\n        }\n      `,\n    },\n    {\n      // issue #3329\n      code: `\n        let demo = null;\n        demo = (a) => {\n          if (a == null) return null;\n          return f(a);\n        };`,\n    },\n    {\n      // issue #3334\n      code: `\n        obj._property = (a) => {\n          if (a == null) return null;\n          return f(a);\n        };\n      `,\n    },\n    {\n      // issue #3334\n      code: `\n        _variable = (a) => {\n          if (a == null) return null;\n          return f(a);\n        };\n      `,\n    },\n    {\n      // issue #3346\n      code: `\n        demo = () => () => null;\n      `,\n    },\n    {\n      // issue #3346\n      code: `\n        demo = {\n          property: () => () => null\n        }\n      `,\n    },\n    {\n      // issue #3346\n      code: `\n        demo = function() {return function() {return null;};};\n      `,\n    },\n    {\n      // issue #3346\n      code: `\n        demo = {\n          property: function() {return function() {return null;};}\n        }\n      `,\n    },\n    {\n      // issue #3303\n      code: `\n        function MyComponent(props) {\n          return <b>{props.name}</b>;\n        }\n\n        const MemoizedMyComponent = React.memo(\n          MyComponent,\n          (prevProps, nextProps) => prevProps.name === nextProps.name\n        )\n      `,\n    },\n    {\n      // Nested React.forwardRef should be accepted in React versions in the following range:\n      // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(function({ world }, ref) {\n            return <div ref={ref}>Hello {world}</div>\n        })\n        )\n      `,\n      settings: {\n        react: {\n          version: '16.14.0',\n        },\n      },\n    },\n    {\n      // Nested React.forwardRef should be accepted in React versions in the following range:\n      // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(({ world }, ref) => {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      settings: {\n        react: {\n          version: '15.7.0',\n        },\n      },\n    },\n    {\n      // Nested React.forwardRef should be accepted in React versions in the following range:\n      // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(function ComponentLike({ world }, ref) {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      settings: {\n        react: {\n          version: '16.12.1',\n        },\n      },\n    },\n    {\n      // Nested React.forwardRef should be accepted in React versions in the following range:\n      // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        export const ComponentWithForwardRef = React.memo(\n          React.forwardRef(function Component({ world }) {\n            return <div>Hello {world}</div>\n          })\n        )\n      `,\n      settings: {\n        react: {\n          version: '0.14.11',\n        },\n      },\n    },\n    {\n      // Nested React.forwardRef should be accepted in React versions in the following range:\n      // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(function({ world }, ref) {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      settings: {\n        react: {\n          version: '15.7.1',\n        },\n      },\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const Hello = React.createContext();\n        Hello.displayName = \"HelloContext\"\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n        Hello.displayName = \"HelloContext\"\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n\n        const obj = {};\n        obj.displayName = \"False positive\";\n\n        Hello.displayName = \"HelloContext\"\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import * as React from 'react';\n\n        const Hello = React.createContext();\n\n        const obj = {};\n        obj.displayName = \"False positive\";\n\n        Hello.displayName = \"HelloContext\";\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        const obj = {};\n        obj.displayName = \"False positive\";\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    // React.createContext should be accepted in React versions in the following range:\n    // >= 16.13.0\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n      `,\n      settings: {\n        react: {\n          version: '16.2.0',\n        },\n      },\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n        Hello.displayName = \"HelloContext\";\n      `,\n      settings: {\n        react: {\n          version: '>16.3.0',\n        },\n      },\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        let Hello;\n        Hello = createContext();\n        Hello.displayName = \"HelloContext\";\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n      `,\n      settings: {\n        react: {\n          version: '>16.3.0',\n        },\n      },\n      options: [{ checkContextObjects: false }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        var Hello;\n        Hello = createContext();\n        Hello.displayName = \"HelloContext\";\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        var Hello;\n        Hello = React.createContext();\n        Hello.displayName = \"HelloContext\";\n      `,\n      options: [{ checkContextObjects: true }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const TestComponent = function () {\n          {\n            const BlockReactMemo = React.memo(() => {\n              return <div>not shadowed</div>\n            })\n\n            const BlockMemo = memo(() => {\n              return <div>not shadowed</div>\n            })\n\n            const BlockForwardRef = forwardRef((props, ref) => {\n              return \\`\\${props} \\${ref}\\`\n            })\n          }\n\n          return null\n        }\n      `,\n      errors: [\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n      ],\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const Test1 = function () {\n          const Comp = memo(() => <div>not param shadowed</div>)\n          return Comp\n        }\n\n        const Test2 = function () {\n          function innerFunction() {\n            const Comp = memo(() => <div>nested not shadowed</div>)\n            const ForwardComp = React.forwardRef(() => <div>nested</div>)\n            return [Comp, ForwardComp]\n          }\n          return innerFunction()\n        }\n      `,\n      errors: [\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n      ],\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react'\n\n        const MixedNotShadowed = function () {\n          const Comp = memo(() => {\n            return <div>not shadowed</div>\n          })\n          const ReactMemo = React.memo(() => null)\n          const ReactForward = React.forwardRef((props, ref) => {\n            return \\`\\${props} \\${ref}\\`\n          })\n          const OtherComp = forwardRef((props, ref) => \\`\\${props} \\${ref}\\`)\n\n          return [Comp, ReactMemo, ReactForward, OtherComp]\n        }\n      `,\n      errors: [\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n        { messageId: 'noDisplayName' },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return React.createElement(\"div\", {}, \"text content\");\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [\n        {\n          messageId: 'noDisplayName',\n        }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            return React.createElement(\"div\", {}, \"text content\");\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          return createReactClass({\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n        }\n        module.exports = HelloComponent();\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        module.exports = () => {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        module.exports = function() {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        module.exports = createReactClass({\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          _renderHello: function() {\n            return <span>Hello {this.props.name}</span>;\n          },\n          render: function() {\n            return <div>{this._renderHello()}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        var Hello = Foo.createClass({\n          _renderHello: function() {\n            return <span>Hello {this.props.name}</span>;\n          },\n          render: function() {\n            return <div>{this._renderHello()}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      settings: {\n        react: {\n          pragma: 'Foo',\n          createClass: 'createClass',\n        },\n      },\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        /** @jsx Foo */\n        var Hello = Foo.createClass({\n          _renderHello: function() {\n            return <span>Hello {this.props.name}</span>;\n          },\n          render: function() {\n            return <div>{this._renderHello()}</div>;\n          }\n        });\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        const Mixin = {\n          Button() {\n            return (\n              <button />\n            );\n          }\n        };\n      `,\n      options: [{ ignoreTranspilerName: true }],\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        function Hof() {\n          return function () {\n            return <div />\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React, { createElement } from \"react\";\n        export default (props) => {\n          return createElement(\"div\", {}, \"hello\");\n        };\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ComponentWithMemo = React.memo(({ world }) => {\n          return <div>Hello {world}</div>\n        })\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ComponentWithMemo = React.memo(function() {\n          return <div>Hello {world}</div>\n        })\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ForwardRefComponentLike = React.forwardRef(({ world }, ref) => {\n          return <div ref={ref}>Hello {world}</div>\n        })\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        const ForwardRefComponentLike = React.forwardRef(function({ world }, ref) {\n          return <div ref={ref}>Hello {world}</div>\n        })\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n    // Only trigger an error for the outer React.memo,\n    // if the React version is not in the following range:\n    // ^0.14.10 || ^15.7.0 || >= 16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(({ world }, ref) => {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      errors: [\n        {\n          messageId: 'noDisplayName',\n        }],\n      settings: {\n        react: {\n          version: '15.6.0',\n        },\n      },\n    },\n    {\n    // Only trigger an error for the outer React.memo,\n    // if the React version is not in the following range:\n    // ^0.14.10 || ^15.7.0 || >= ^16.12.0\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(function({ world }, ref) {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n      settings: {\n        react: {\n          version: '0.14.2',\n        },\n      },\n    },\n    {\n    // React does not handle the result of forwardRef being passed into memo\n    // ComponentWithMemoAndForwardRef gets shown as Memo(Anonymous)\n    // See https://github.com/facebook/react/issues/16722\n      code: `\n        import React from 'react'\n\n        const MemoizedForwardRefComponentLike = React.memo(\n          React.forwardRef(function ComponentLike({ world }, ref) {\n            return <div ref={ref}>Hello {world}</div>\n          })\n        )\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n      settings: {\n        react: {\n          version: '15.0.1',\n        },\n      },\n    },\n    {\n      code: `\n        import React from \"react\";\n        const { createElement } = React;\n        export default (props) => {\n          return createElement(\"div\", {}, \"hello\");\n        };\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        const createElement = React.createElement;\n        export default (props) => {\n          return createElement(\"div\", {}, \"hello\");\n        };\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        module.exports = function () {\n          function a () {}\n          const b = function b () {}\n          const c = function () {}\n          const d = () => {}\n          const obj = {\n            a: function a () {},\n            b: function b () {},\n            c () {},\n            d: () => {},\n          }\n          return React.createElement(\"div\", {}, \"text content\");\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        module.exports = () => {\n          function a () {}\n          const b = function b () {}\n          const c = function () {}\n          const d = () => {}\n          const obj = {\n            a: function a () {},\n            b: function b () {},\n            c () {},\n            d: () => {},\n          }\n\n          return React.createElement(\"div\", {}, \"text content\");\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        export default class extends React.Component {\n          render() {\n            function a () {}\n            const b = function b () {}\n            const c = function () {}\n            const d = () => {}\n            const obj = {\n              a: function a () {},\n              b: function b () {},\n              c () {},\n              d: () => {},\n            }\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDisplayName' }],\n    },\n    {\n      code: `\n        export default class extends React.PureComponent {\n          render() {\n            return <Card />;\n          }\n        }\n\n        const Card = (() => {\n          return React.memo(({ }) => (\n            <div />\n          ));\n        })();\n      `,\n      errors: [\n        {\n          messageId: 'noDisplayName',\n          line: 2,\n          column: 24,\n        },\n        {\n          messageId: 'noDisplayName',\n          line: 9,\n          column: 18,\n        },\n      ],\n    },\n    {\n      code: `\n        const renderer = a => listItem => (\n          <div>{a} {listItem}</div>\n        );\n      `,\n      errors: [\n        { message: 'Component definition is missing display name' },\n      ],\n    },\n    {\n      code: `\n        const processData = (options?: { value: string }) => options?.value || 'no data';\n\n        export const Component = observer(() => {\n          const data = processData({ value: 'data' });\n          return <div>{data}</div>;\n        });\n\n        export const Component2 = observer(() => {\n          const data = processData();\n          return <div>{data}</div>;\n        });\n      `,\n      features: ['optional chaining', 'types'],\n      settings: { componentWrapperFunctions: ['observer'] },\n      errors: [\n        {\n          message: 'Component definition is missing display name',\n          line: 4,\n        },\n        {\n          message: 'Component definition is missing display name',\n          line: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const Hello = React.createContext();\n      `,\n      errors: [\n        {\n          messageId: 'noContextDisplayName',\n          line: 4,\n        },\n      ],\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import * as React from 'react';\n\n        const Hello = React.createContext();\n      `,\n      errors: [\n        {\n          messageId: 'noContextDisplayName',\n          line: 4,\n        },\n      ],\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        const Hello = createContext();\n      `,\n      errors: [\n        {\n          messageId: 'noContextDisplayName',\n          line: 4,\n        },\n      ],\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        var Hello;\n        Hello = createContext();\n      `,\n      errors: [\n        {\n          messageId: 'noContextDisplayName',\n          line: 5,\n        },\n      ],\n      options: [{ checkContextObjects: true }],\n    },\n    {\n      code: `\n        import { createContext } from 'react';\n\n        var Hello;\n        Hello = React.createContext();\n      `,\n      errors: [\n        {\n          messageId: 'noContextDisplayName',\n          line: 5,\n        },\n      ],\n      options: [{ checkContextObjects: true }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forbid-component-props.js",
    "content": "/**\n * @fileoverview Tests for forbid-component-props\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/forbid-component-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('forbid-component-props', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div className=\"foo\" />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div style={{color: \"red\"}} />;\n          }\n        });\n      `,\n      options: [{ forbid: ['style'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo bar=\"baz\" />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['style'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['style', 'foo'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <this.Foo bar=\"baz\" />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class First extends createReactClass {\n          render() {\n            return <this.foo className=\"bar\" />;\n          }\n        }\n      `,\n      options: [{ forbid: ['style'] }],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <this.Foo {...props} />\n        );\n      `,\n    },\n    {\n      code: `\n        const item = (<ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<AntdLayout.Content className=\"antdFoo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['AntdLayout.Content'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<this.ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['this.ReactModal'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<Foo className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        <fbt:param name=\"Total number of files\" number={true} />\n      `,\n      features: ['jsx namespace'],\n    },\n    {\n      code: `\n        const item = (\n          <Foo className=\"bar\">\n            <ReactModal style={{color: \"red\"}} />\n          </Foo>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['OtherModal', 'ReactModal'],\n            },\n            {\n              propName: 'style',\n              disallowedFor: ['Foo'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (\n          <Foo className=\"bar\">\n            <ReactModal style={{color: \"red\"}} />\n          </Foo>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['OtherModal', 'ReactModal'],\n            },\n            {\n              propName: 'style',\n              allowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<this.ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = () => (\n          <div aria-label=\"welcome\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propNamePattern: '**-**',\n              allowedFor: ['div'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = (\n          <Root>\n            <SomeIcon className=\"size-lg\" />\n            <AnotherIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" />\n            <UICard className=\"size-lg\" />\n            <UIButton className=\"size-lg\" />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedForPatterns: ['*Icon', '*Svg', 'UI*'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = (\n          <Root>\n            <SomeIcon className=\"size-lg\" />\n            <AnotherIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" />\n            <UICard className=\"size-lg\" />\n            <UIButton className=\"size-lg\" />\n            <ButtonLegacy className=\"size-lg\" />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['ButtonLegacy'],\n              allowedForPatterns: ['*Icon', '*Svg', 'UI*'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = (\n          <Root>\n            <SomeIcon className=\"size-lg\" />\n            <AnotherIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" />\n            <UICard className=\"size-lg\" />\n            <UIButton className=\"size-lg\" />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['Modal'],\n              disallowedForPatterns: ['*Legacy', 'Shared*'],\n            },\n          ],\n        },\n      ],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 5,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo style={{color: \"red\"}} />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'style' },\n          line: 5,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['className', 'style'] }],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 5,\n          column: 25,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo style={{color: \"red\"}} />;\n          }\n        });\n      `,\n      options: [{ forbid: ['className', 'style'] }],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'style' },\n          line: 5,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo style={{color: \"red\"}} />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'style',\n              disallowedFor: ['Foo'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'style' },\n          line: 5,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<Foo className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 2,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<this.ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              allowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 2,\n          column: 40,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<this.ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['this.ReactModal'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 2,\n          column: 40,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<ReactModal className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['ReactModal'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 2,\n          column: 35,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<AntdLayout.Content className=\"antdFoo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['AntdLayout.Content'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 2,\n          column: 43,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = (<Foo className=\"foo\" />);\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              message: 'Please use ourCoolClassName instead of ClassName',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use ourCoolClassName instead of ClassName',\n          line: 2,\n          column: 28,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = () => (\n          <Foo className=\"foo\">\n            <Bar option=\"high\" />\n          </Foo>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              message: 'Please use ourCoolClassName instead of ClassName',\n            },\n            {\n              propName: 'option',\n              message: 'Avoid using option',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use ourCoolClassName instead of ClassName',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using option',\n          line: 4,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const item = () => (\n          <Foo className=\"foo\">\n            <Bar option=\"high\" />\n          </Foo>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            { propName: 'className' },\n            {\n              propName: 'option',\n              message: 'Avoid using option',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using option',\n          line: 4,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = () => (\n          <Foo kebab-case-prop={123} />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propNamePattern: '**-**',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'kebab-case-prop' },\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = () => (\n          <Foo kebab-case-prop={123} />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propNamePattern: '**-**',\n              message: 'Avoid using kebab-case',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Avoid using kebab-case',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = () => (\n          <div>\n            <div aria-label=\"Hello Akul\" />\n            <Foo kebab-case-prop={123} />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propNamePattern: '**-**',\n              allowedFor: ['div'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'kebab-case-prop' },\n          line: 5,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = () => (\n          <div>\n            <div aria-label=\"Hello Akul\" />\n            <h1 data-id=\"my-heading\" />\n            <Foo kebab-case-prop={123} />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propNamePattern: '**-**',\n              disallowedFor: ['Foo'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'kebab-case-prop' },\n          line: 6,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = () => (\n          <Root>\n            <SomeIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              message: 'className available only for icons',\n              allowedForPatterns: ['*Icon'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'className available only for icons',\n          line: 5,\n          column: 22,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = () => (\n          <Root>\n            <UICard style={{backgroundColor: black}}/>\n            <SomeIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" style={{fill: currentColor}} />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              message: 'className available only for icons',\n              allowedForPatterns: ['*Icon'],\n            },\n            {\n              propName: 'style',\n              message: 'style available only for SVGs',\n              allowedForPatterns: ['*Svg'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'style available only for SVGs',\n          line: 4,\n          column: 21,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'className available only for icons',\n          line: 6,\n          column: 22,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const rootElement = (\n          <Root>\n            <SomeIcon className=\"size-lg\" />\n            <AnotherIcon className=\"size-lg\" />\n            <SomeSvg className=\"size-lg\" />\n            <UICard className=\"size-lg\" />\n            <ButtonLegacy className=\"size-lg\" />\n          </Root>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['SomeSvg'],\n              disallowedForPatterns: ['UI*', '*Icon'],\n              message: 'Avoid using className for SomeSvg and components that match the `UI*` and `*Icon` patterns',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Avoid using className for SomeSvg and components that match the `UI*` and `*Icon` patterns',\n          line: 4,\n          column: 23,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using className for SomeSvg and components that match the `UI*` and `*Icon` patterns',\n          line: 5,\n          column: 26,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using className for SomeSvg and components that match the `UI*` and `*Icon` patterns',\n          line: 6,\n          column: 22,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using className for SomeSvg and components that match the `UI*` and `*Icon` patterns',\n          line: 7,\n          column: 21,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forbid-dom-props.js",
    "content": "/**\n * @fileoverview Tests for forbid-dom-props\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/forbid-dom-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('forbid-dom-props', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <Foo id=\"foo\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['id'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <Foo id=\"bar\" style={{color: \"red\"}} />;\n          }\n        });\n      `,\n      options: [{ forbid: ['style', 'id'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <this.Foo bar=\"baz\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['id'] }],\n    },\n    {\n      code: `\n        class First extends createReactClass {\n          render() {\n            return <this.foo id=\"bar\" />;\n          }\n        }\n      `,\n      options: [{ forbid: ['id'] }],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <this.Foo {...props} />\n        );\n      `,\n      options: [{ forbid: ['id'] }],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <fbt:param name=\"name\">{props.name}</fbt:param>\n        );\n      `,\n      options: [{ forbid: ['id'] }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div name=\"foo\" />\n        );\n      `,\n      options: [{ forbid: ['id'] }],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div otherProp=\"bar\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'otherProp',\n              disallowedFor: ['span'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div someProp=\"someValue\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'someProp',\n              disallowedValues: [],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <Foo someProp=\"someValue\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'someProp',\n              disallowedValues: ['someValue'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div someProp=\"value\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'someProp',\n              disallowedValues: ['someValue'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div someProp=\"someValue\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'someProp',\n              disallowedValues: ['someValue'],\n              disallowedFor: ['span'],\n            },\n          ],\n        },\n      ],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <div id=\"bar\" />;\n          }\n        });\n      `,\n      options: [{ forbid: ['id'] }],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'id' },\n          line: 5,\n          column: 25,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends createReactClass {\n          render() {\n            return <div id=\"bar\" />;\n          }\n        }\n      `,\n      options: [{ forbid: ['id'] }],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'id' },\n          line: 4,\n          column: 25,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div id=\"foo\" />\n        );\n      `,\n      options: [{ forbid: ['id'] }],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'id' },\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div className=\"foo\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [{ propName: 'className', message: 'Please use class instead of ClassName' }],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use class instead of ClassName',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <span otherProp=\"bar\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'otherProp',\n              disallowedFor: ['span'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'otherProp' },\n          line: 3,\n          column: 17,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div someProp=\"someValue\" />\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'someProp',\n              disallowedValues: ['someValue'],\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbiddenWithValue',\n          data: { prop: 'someProp', propValue: 'someValue' },\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div className=\"foo\">\n            <div otherProp=\"bar\" />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            { propName: 'className', message: 'Please use class instead of ClassName' },\n            { propName: 'otherProp', message: 'Avoid using otherProp' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use class instead of ClassName',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using otherProp',\n          line: 4,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div className=\"foo\">\n            <div otherProp=\"bar\" />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            { propName: 'className' },\n            { propName: 'otherProp', message: 'Avoid using otherProp' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propIsForbidden',\n          data: { prop: 'className' },\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using otherProp',\n          line: 4,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <form accept='file'>\n            <input type=\"file\" id=\"videoFile\" accept=\"video/*\" />\n            <input type=\"hidden\" name=\"fullname\" />\n          </form>\n        );\n      `,\n      options: [\n        {\n          forbid: [{\n            propName: 'accept',\n            disallowedFor: ['form'],\n            message: 'Avoid using the accept attribute on <form>',\n          }],\n        },\n      ],\n      errors: [\n        {\n          message: 'Avoid using the accept attribute on <form>',\n          line: 3,\n          column: 17,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div className=\"foo\">\n            <input className=\"boo\" />\n            <span className=\"foobar\">Foobar</span>\n            <div otherProp=\"bar\" />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['div', 'span'],\n              message: 'Please use class instead of ClassName',\n            },\n            { propName: 'otherProp', message: 'Avoid using otherProp' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use class instead of ClassName',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Please use class instead of ClassName',\n          line: 5,\n          column: 19,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using otherProp',\n          line: 6,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => (\n          <div className=\"foo\">\n            <input className=\"boo\" />\n            <span className=\"foobar\">Foobar</span>\n            <div otherProp=\"bar\" />\n            <p thirdProp=\"foo\" />\n            <div thirdProp=\"baz\" />\n            <p thirdProp=\"bar\" />\n            <p thirdProp=\"baz\" />\n          </div>\n        );\n      `,\n      options: [\n        {\n          forbid: [\n            {\n              propName: 'className',\n              disallowedFor: ['div', 'span'],\n              message: 'Please use class instead of ClassName',\n            },\n            { propName: 'otherProp', message: 'Avoid using otherProp' },\n            {\n              propName: 'thirdProp',\n              disallowedFor: ['p'],\n              disallowedValues: ['bar', 'baz'],\n              message: 'Do not use thirdProp with values bar and baz on p',\n            },\n          ],\n        },\n      ],\n      errors: [\n        {\n          message: 'Please use class instead of ClassName',\n          line: 3,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Please use class instead of ClassName',\n          line: 5,\n          column: 19,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Avoid using otherProp',\n          line: 6,\n          column: 18,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Do not use thirdProp with values bar and baz on p',\n          line: 9,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n        {\n          message: 'Do not use thirdProp with values bar and baz on p',\n          line: 10,\n          column: 16,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forbid-elements.js",
    "content": "/**\n * @fileoverview Tests for forbid-elements\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/forbid-elements');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nrequire('babel-eslint');\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('forbid-elements', rule, {\n  valid: parsers.all([\n    {\n      code: '<button />',\n      options: [],\n    },\n    {\n      code: '<button />',\n      options: [{ forbid: [] }],\n    },\n    {\n      code: '<Button />',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: '<Button />',\n      options: [{ forbid: [{ element: 'button' }] }],\n    },\n    {\n      code: 'React.createElement(button)',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'createElement(\"button\")',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'NotReact.createElement(\"button\")',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'React.createElement(\"_thing\")',\n      options: [{ forbid: ['_thing'] }],\n    },\n    {\n      code: 'React.createElement(\"Modal\")',\n      options: [{ forbid: ['Modal'] }],\n    },\n    {\n      code: 'React.createElement(\"dotted.component\")',\n      options: [{ forbid: ['dotted.component'] }],\n    },\n    {\n      code: 'React.createElement(function() {})',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'React.createElement({})',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'React.createElement(1)',\n      options: [{ forbid: ['button'] }],\n    },\n    {\n      code: 'React.createElement()',\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<button />',\n      options: [{ forbid: ['button'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n      ],\n    },\n    {\n      code: '[<Modal />, <button />]',\n      options: [{ forbid: ['button', 'Modal'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'Modal' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n      ],\n    },\n    {\n      code: '<dotted.component />',\n      options: [{ forbid: ['dotted.component'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'dotted.component' },\n        },\n      ],\n    },\n    {\n      code: '<dotted.Component />',\n      options: [\n        {\n          forbid: [\n            { element: 'dotted.Component', message: 'that ain\\'t cool' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement_message',\n          data: { element: 'dotted.Component', message: 'that ain\\'t cool' },\n        },\n      ],\n    },\n    {\n      code: '<button />',\n      options: [\n        {\n          forbid: [\n            { element: 'button', message: 'use <Button> instead' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement_message',\n          data: { element: 'button', message: 'use <Button> instead' },\n        },\n      ],\n    },\n    {\n      code: '<button><input /></button>',\n      options: [\n        {\n          forbid: [\n            { element: 'button' },\n            { element: 'input' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'input' },\n        },\n      ],\n    },\n    {\n      code: '<button><input /></button>',\n      options: [{ forbid: [{ element: 'button' }, 'input'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'input' },\n        },\n      ],\n    },\n    {\n      code: '<button><input /></button>',\n      options: [{ forbid: ['input', { element: 'button' }] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'input' },\n        },\n      ],\n    },\n    {\n      code: '<button />',\n      options: [\n        {\n          forbid: [\n            { element: 'button', message: 'use <Button> instead' },\n            { element: 'button', message: 'use <Button2> instead' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement_message',\n          data: { element: 'button', message: 'use <Button2> instead' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {}, child)',\n      options: [{ forbid: ['button'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n      ],\n    },\n    {\n      code: '[React.createElement(Modal), React.createElement(\"button\")]',\n      options: [{ forbid: ['button', 'Modal'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'Modal' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(dotted.Component)',\n      options: [\n        {\n          forbid: [\n            { element: 'dotted.Component', message: 'that ain\\'t cool' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement_message',\n          data: { element: 'dotted.Component', message: 'that ain\\'t cool' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(dotted.component)',\n      options: [{ forbid: ['dotted.component'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'dotted.component' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(_comp)',\n      options: [{ forbid: ['_comp'] }],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: '_comp' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\")',\n      options: [\n        {\n          forbid: [\n            { element: 'button', message: 'use <Button> instead' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement_message',\n          data: { element: 'button', message: 'use <Button> instead' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"button\", {}, React.createElement(\"input\"))',\n      options: [\n        {\n          forbid: [\n            { element: 'button' }, { element: 'input' },\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'button' },\n        },\n        {\n          messageId: 'forbiddenElement',\n          data: { element: 'input' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forbid-foreign-prop-types.js",
    "content": "/**\n * @fileoverview Tests for forbid-foreign-prop-types\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/forbid-foreign-prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('forbid-foreign-prop-types', rule, {\n  valid: parsers.all([\n    {\n      code: 'import { propTypes } from \"SomeComponent\";',\n    },\n    {\n      code: 'import { propTypes as someComponentPropTypes } from \"SomeComponent\";',\n    },\n    {\n      code: 'const foo = propTypes',\n    },\n    {\n      code: 'foo(propTypes)',\n    },\n    {\n      code: 'foo + propTypes',\n    },\n    {\n      code: 'const foo = [propTypes]',\n    },\n    {\n      code: 'const foo = { propTypes }',\n    },\n    {\n      code: 'Foo.propTypes = propTypes',\n    },\n    {\n      code: 'Foo[\"propTypes\"] = propTypes',\n    },\n    {\n      code: 'const propTypes = \"bar\"; Foo[propTypes];',\n    },\n    {\n      code: `\n        const Message = (props) => (<div>{props.message}</div>);\n        Message.propTypes = {\n          message: PropTypes.string\n        };\n        const Hello = (props) => (<Message>Hello {props.name}</Message>);\n        Hello.propTypes = {\n          name: Message.propTypes.message\n        };\n      `,\n      options: [{ allowInPropTypes: true }],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            baz: Qux.propTypes.baz\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [{ allowInPropTypes: true }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Foo = createReactClass({\n          propTypes: Bar.propTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          propTypes: Bar[\"propTypes\"],\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: `\n        var { propTypes } = SomeComponent\n        var Foo = createReactClass({\n          propTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var { propTypes: things, ...foo } = SomeComponent\n        var Foo = createReactClass({\n          propTypes,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static fooBar = {\n            baz: Qux.propTypes.baz\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts'], // TODO: FIXME: remove \"no-ts\" and fix\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        var { propTypes: typesOfProps } = SomeComponent\n        var Foo = createReactClass({\n          propTypes: typesOfProps,\n          render: function() {\n            return <Foo className=\"bar\" />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const Message = (props) => (<div>{props.message}</div>);\n        Message.propTypes = {\n          message: PropTypes.string\n        };\n        const Hello = (props) => (<Message>Hello {props.name}</Message>);\n        Hello.propTypes = {\n          name: Message.propTypes.message\n        };\n      `,\n      options: [{ allowInPropTypes: false }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            baz: Qux.propTypes.baz\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts'], // TODO: FIXME: remove \"no-ts\" and fix\n      options: [{ allowInPropTypes: false }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          type: 'Identifier',\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forbid-prop-types.js",
    "content": "/**\n * @fileoverview Tests for forbid-prop-types\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst semver = require('semver');\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/forbid-prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('forbid-prop-types', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            s: PropTypes.string,\n            n: PropTypes.number,\n            i: PropTypes.instanceOf,\n            b: PropTypes.bool\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.array\n          },\n          render: function() {\n            return <div />;\n          }\n        })\n      `,\n      options: [{ forbid: ['any', 'object'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            o: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ forbid: ['any', 'array'] }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            o: PropTypes.object,\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        { forbid: ['any', 'array'] },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string\n        };\n        First.propTypes.justforcheck = PropTypes.string;\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          elem: PropTypes.instanceOf(HTMLElement)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n      // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          propTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static propTypes = {\n            intl: React.propTypes.number,\n            ...propTypes\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static get propTypes() {\n            return {\n              intl: React.propTypes.number,\n              ...propTypes\n            };\n          };\n        }\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: externalPropTypes,\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            s: PropTypes.string,\n            n: PropTypes.number,\n            i: PropTypes.instanceOf,\n            b: PropTypes.bool\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            a: PropTypes.array\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'object'],\n          checkContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            o: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'array'],\n          checkContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            o: PropTypes.object,\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'array'],\n          checkContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.childContextTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string\n        };\n        First.childContextTypes.justforcheck = PropTypes.string;\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.childContextTypes = {\n          elem: PropTypes.instanceOf(HTMLElement)\n        };\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.childContextTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n      // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          childContextTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n      options: [{ checkContextTypes: true }],\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          childContextTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static childContextTypes = {\n            intl: React.childContextTypes.number,\n            ...childContextTypes\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static get childContextTypes() {\n            return {\n              intl: React.childContextTypes.number,\n              ...childContextTypes\n            };\n          };\n        }\n      `,\n      options: [{ checkContextTypes: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: externalPropTypes,\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            s: PropTypes.string,\n            n: PropTypes.number,\n            i: PropTypes.instanceOf,\n            b: PropTypes.bool\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            a: PropTypes.array\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'object'],\n          checkChildContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            o: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'array'],\n          checkChildContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            o: PropTypes.object,\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['any', 'array'],\n          checkChildContextTypes: true,\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.childContextTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string\n        };\n        First.childContextTypes.justforcheck = PropTypes.string;\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.childContextTypes = {\n          elem: PropTypes.instanceOf(HTMLElement)\n        };\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.childContextTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n      // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          childContextTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n      options: [{ checkChildContextTypes: true }],\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          childContextTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static childContextTypes = {\n            intl: React.childContextTypes.number,\n            ...childContextTypes\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      // Proptypes declared with a spread property\n      code: `\n        class Test extends React.component {\n          static get childContextTypes() {\n            return {\n              intl: React.childContextTypes.number,\n              ...childContextTypes\n            };\n          };\n        }\n      `,\n      options: [{ checkChildContextTypes: true }],\n    },\n    {\n      code: `\n        class TestComponent extends React.Component {\n          static defaultProps = function () {\n            const date = new Date();\n            return {\n              date\n            };\n          }();\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class HeroTeaserList extends React.Component {\n          render() { return null; }\n        }\n        HeroTeaserList.propTypes = Object.assign({\n          heroIndex: PropTypes.number,\n          preview: PropTypes.bool,\n        }, componentApi, teaserListProps);\n      `,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        const Foo = {\n          foo: PropTypes.string,\n        };\n        const Bar = {\n          bar: PropTypes.shape(Foo),\n        };\n      `,\n    },\n    {\n      code: `\n        import yup from \"yup\"\n        const formValidation = Yup.object().shape({\n          name: Yup.string(),\n          customer_ids: Yup.array()\n        });\n      `,\n    },\n    {\n      code: `\n        import yup from \"Yup\"\n        const validation = yup.object().shape({\n          address: yup.object({\n            city: yup.string(),\n            zip: yup.string(),\n          })\n        })\n      `,\n      options: [\n        {\n          forbid: ['string', 'object'],\n        },\n      ],\n    },\n    {\n      code: `\n        import yup from \"yup\"\n        Yup.array(\n          Yup.object().shape({\n            value: Yup.number()\n          })\n        )\n      `,\n      options: [{ forbid: ['number'] }],\n    },\n    {\n      code: `\n        import CustomPropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: CustomPropTypes.shape({\n            b: CustomPropTypes.String,\n            c: CustomPropTypes.number.isRequired,\n          })\n        }\n      `,\n    },\n    {\n      code: `\n        import CustomReact from \"react\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: CustomReact.PropTypes.string,\n        }\n      `,\n    },\n    {\n      code: `\n        import PropTypes from \"yup\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: PropTypes.array(),\n        }\n      `,\n    },\n    {\n      code: `\n        import { PropTypes, shape, any } from \"yup\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: PropTypes.any,\n        }\n      `,\n      options: [{ forbid: ['any'] }],\n    },\n    {\n      code: `\n        import { PropTypes } from \"not-react\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: PropTypes.array(),\n        }\n      `,\n    }\n  )),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            n: PropTypes.number\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'number' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n      options: [\n        { forbid: ['number'] },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.array\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'array' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.array.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'array' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.object.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.array,\n            o: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.array\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            o: PropTypes.object\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            a: PropTypes.array,\n            o: PropTypes.object\n        };\n        class Second extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Second.propTypes = {\n            a: PropTypes.array,\n            o: PropTypes.object\n        };\n      `,\n      errors: 4,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = forbidExtraProps({\n            a: PropTypes.array\n        });\n      `,\n      errors: 1,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        import { forbidExtraProps } from \"airbnb-prop-types\";\n        export const propTypes = {dpm: PropTypes.any};\n        export default function Component() {}\n        Component.propTypes = propTypes;\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n        },\n      ],\n    },\n    {\n      code: `\n        import { forbidExtraProps } from \"airbnb-prop-types\";\n        export const propTypes = {a: PropTypes.any};\n        export default function Component() {}\n        Component.propTypes = forbidExtraProps(propTypes);\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.array,\n            o: PropTypes.object\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static get propTypes() {\n            return {\n              a: PropTypes.array,\n              o: PropTypes.object\n            };\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = forbidExtraProps({\n            a: PropTypes.array,\n            o: PropTypes.object\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: 2,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static get propTypes() {\n            return forbidExtraProps({\n              a: PropTypes.array,\n              o: PropTypes.object\n            });\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      errors: 2,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ forbid: ['instanceOf'] }],\n      errors: 1,\n    },\n    {\n      code: `\n        var object = PropTypes.object;\n        var Hello = createReactClass({\n          propTypes: {\n            retailer: object,\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ forbid: ['object'] }],\n      errors: 1,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          contextTypes: {\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          static contextTypes = {\n            a: PropTypes.any\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ checkContextTypes: true }],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          static get contextTypes() {\n            return {\n              a: PropTypes.any\n            };\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ checkContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 5,\n          column: 15,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          render() {\n            return <div />;\n          }\n        }\n        Foo.contextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 8,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo(props) {\n          return <div />;\n        }\n        Foo.contextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 6,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = (props) => {\n          return <div />;\n        };\n        Foo.contextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 6,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static contextTypes = forbidExtraProps({\n            a: PropTypes.array,\n            o: PropTypes.object\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: 2,\n      options: [{ checkContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static get contextTypes() {\n            return forbidExtraProps({\n              a: PropTypes.array,\n              o: PropTypes.object\n            });\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      errors: 2,\n      options: [{ checkContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.contextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        function Component(props) {\n          return <div />;\n        }\n        Component.contextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        const Component = (props) => {\n          return <div />;\n        };\n        Component.contextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          contextTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static contextTypes = {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static get contextTypes() {\n            return {\n              retailer: PropTypes.instanceOf(Map).isRequired,\n              requestRetailer: PropTypes.func.isRequired\n            };\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.contextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        };\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        function Component(props) {\n          return <div />;\n        }\n        Component.contextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        };\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        const Component = (props) => {\n          return <div />;\n        };\n        Component.contextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        }\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          childContextTypes: {\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ checkChildContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          static childContextTypes = {\n            a: PropTypes.any\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ checkChildContextTypes: true }],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          static get childContextTypes() {\n            return {\n              a: PropTypes.any\n            };\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ checkChildContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 5,\n          column: 15,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          render() {\n            return <div />;\n          }\n        }\n        Foo.childContextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkChildContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 8,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo(props) {\n          return <div />;\n        }\n        Foo.childContextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkChildContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 6,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = (props) => {\n          return <div />;\n        };\n        Foo.childContextTypes = {\n          a: PropTypes.any\n        };\n      `,\n      options: [{ checkChildContextTypes: true }],\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'any' },\n          line: 6,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static childContextTypes = forbidExtraProps({\n            a: PropTypes.array,\n            o: PropTypes.object\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: 2,\n      options: [{ checkChildContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static get childContextTypes() {\n            return forbidExtraProps({\n              a: PropTypes.array,\n              o: PropTypes.object\n            });\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      errors: 2,\n      options: [{ checkChildContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.childContextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkChildContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        function Component(props) {\n          return <div />;\n        }\n        Component.childContextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkChildContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        const Component = (props) => {\n          return <div />;\n        };\n        Component.childContextTypes = forbidExtraProps({\n          a: PropTypes.array,\n          o: PropTypes.object\n        });\n      `,\n      errors: 2,\n      options: [{ checkChildContextTypes: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          childContextTypes: {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkChildContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static childContextTypes = {\n            retailer: PropTypes.instanceOf(Map).isRequired,\n            requestRetailer: PropTypes.func.isRequired\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkChildContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.childContextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        };\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkChildContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        function Component(props) {\n          return <div />;\n        }\n        Component.childContextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        };\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkChildContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        const Component = (props) => {\n          return <div />;\n        };\n        Component.childContextTypes = {\n          retailer: PropTypes.instanceOf(Map).isRequired,\n          requestRetailer: PropTypes.func.isRequired\n        };\n      `,\n      options: [\n        {\n          forbid: ['instanceOf'],\n          checkChildContextTypes: true,\n        },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        import { object, string } from \"prop-types\";\n        function C({ a, b }) { return [a, b]; }\n        C.propTypes = {\n          a: object,\n          b: string\n        };\n      `,\n      options: [\n        { forbid: ['object'] },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        import { objectOf, any } from \"prop-types\";\n        function C({ a }) { return a; }\n        C.propTypes = {\n          a: objectOf(any)\n        };\n      `,\n      options: [\n        { forbid: ['any'] },\n      ],\n      errors: 1,\n    },\n    {\n      code: `\n        import { objectOf, any } from \"prop-types\";\n        function C({ a }) { return a; }\n        C.propTypes = {\n          a: objectOf(any)\n        };\n      `,\n      options: [{ forbid: ['objectOf'] }],\n      errors: 1,\n    },\n    {\n      code: `\n        import { shape, any } from \"prop-types\";\n        function C({ a }) { return a; }\n        C.propTypes = {\n          a: shape({\n            b: any\n          })\n        };\n      `,\n      options: [{ forbid: ['any'] }],\n      errors: 1,\n    },\n    {\n      code: `\n        import { any } from \"prop-types\";\n        function C({ a }) { return a; }\n        C.propTypes = {\n          a: PropTypes.shape({\n            b: any\n          })\n        };\n      `,\n      options: [{ forbid: ['any'] }],\n      errors: 1,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            s: PropTypes.shape({\n              o: PropTypes.object\n            })\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: 1,\n    },\n    {\n      code: `\n        import React from './React';\n\n        import { arrayOf, object } from 'prop-types';\n\n        const App = ({ foo }) => (\n          <div>\n            Hello world {foo}\n          </div>\n        );\n\n        App.propTypes = {\n          foo: arrayOf(object)\n        }\n\n        export default App;\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from './React';\n\n        import PropTypes, { arrayOf } from 'prop-types';\n\n        const App = ({ foo }) => (\n          <div>\n            Hello world {foo}\n          </div>\n        );\n\n        App.propTypes = {\n          foo: arrayOf(PropTypes.object)\n        }\n\n        export default App;\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n        },\n      ],\n    },\n    {\n      code: `\n        import CustomPropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: CustomPropTypes.shape({\n            b: CustomPropTypes.String,\n            c: CustomPropTypes.object.isRequired,\n          })\n        }\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n        },\n      ],\n    },\n    {\n      code: `\n        import { PropTypes as CustomPropTypes } from \"react\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: CustomPropTypes.shape({\n            b: CustomPropTypes.String,\n            c: CustomPropTypes.object.isRequired,\n          })\n        }\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n        },\n      ],\n    },\n    {\n      code: `\n        import CustomReact from \"react\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: CustomReact.PropTypes.object,\n        }\n      `,\n      errors: [\n        {\n          messageId: 'forbiddenPropType',\n          data: { target: 'object' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/forward-ref-uses-ref.js",
    "content": "/**\n * @fileoverview Require all forwardRef components include a ref parameter\n * @author Tiger Oakes\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/forward-ref-uses-ref');\nconst parsers = require('../../helpers/parsers');\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n  },\n});\n\nruleTester.run('forward-ref-uses-ref', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef((props, ref) => {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef((props, ref) => null);\n      `,\n    },\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef(function (props, ref) {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef(function Component(props, ref) {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef((props, ref) => {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef((props, ref) => null);\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef(function (props, ref) {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef(function Component(props, ref) {\n          return null;\n        });\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        function Component(props) {\n          return null;\n        };\n      `,\n    },\n    {\n      code: `\n        import * as React from 'react'\n        (props) => null;\n      `,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef((props) => {\n          return null;\n        });\n      `,\n      errors: [\n        {\n          message: 'forwardRef is used with this component but no ref parameter is set',\n          suggestions: [\n            {\n              messageId: 'addRefParameter',\n              output: `\n        import { forwardRef } from 'react'\n        forwardRef((props, ref) => {\n          return null;\n        });\n      `,\n            },\n            {\n              messageId: 'removeForwardRef',\n              output: `\n        import { forwardRef } from 'react'\n        (props) => {\n          return null;\n        };\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { forwardRef } from 'react'\n        forwardRef(props => {\n          return null;\n        });\n      `,\n      errors: [\n        {\n          message: 'forwardRef is used with this component but no ref parameter is set',\n          suggestions: [\n            {\n              messageId: 'addRefParameter',\n              output: `\n        import { forwardRef } from 'react'\n        forwardRef((props, ref) => {\n          return null;\n        });\n      `,\n            },\n            {\n              messageId: 'removeForwardRef',\n              output: `\n        import { forwardRef } from 'react'\n        props => {\n          return null;\n        };\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef((props) => null);\n      `,\n      errors: [\n        {\n          message: 'forwardRef is used with this component but no ref parameter is set',\n          suggestions: [\n            {\n              messageId: 'addRefParameter',\n              output: `\n        import * as React from 'react'\n        React.forwardRef((props, ref) => null);\n      `,\n            },\n            {\n              messageId: 'removeForwardRef',\n              output: `\n        import * as React from 'react'\n        (props) => null;\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { forwardRef } from 'react'\n        const Component = forwardRef(function (props) {\n          return null;\n        });\n      `,\n      errors: [\n        {\n          message: 'forwardRef is used with this component but no ref parameter is set',\n          suggestions: [\n            {\n              messageId: 'addRefParameter',\n              output: `\n        import { forwardRef } from 'react'\n        const Component = forwardRef(function (props, ref) {\n          return null;\n        });\n      `,\n            },\n            {\n              messageId: 'removeForwardRef',\n              output: `\n        import { forwardRef } from 'react'\n        const Component = function (props) {\n          return null;\n        };\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import * as React from 'react'\n        React.forwardRef(function Component(props) {\n          return null;\n        });\n      `,\n      errors: [\n        {\n          message: 'forwardRef is used with this component but no ref parameter is set',\n          suggestions: [\n            {\n              messageId: 'addRefParameter',\n              output: `\n        import * as React from 'react'\n        React.forwardRef(function Component(props, ref) {\n          return null;\n        });\n      `,\n            },\n            {\n              messageId: 'removeForwardRef',\n              output: `\n        import * as React from 'react'\n        function Component(props) {\n          return null;\n        };\n      `,\n            },\n          ],\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/function-component-definition.js",
    "content": "/**\n * @fileoverview Standardize the way function component get defined\n * @author Stefan Wullems\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/function-component-definition');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst parsers = require('../../helpers/parsers');\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('function-component-definition', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Hello extends React.Component {\n          render() { return <div>Hello {this.props.name}</div> }\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() { return <div>Hello {this.props.name}</div> }\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() { return <div>Hello {this.props.name}</div> }\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: 'var Hello = (props) => { return <div/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: 'const Hello = (props) => { return <div/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: 'function Hello(props) { return <div/> }',\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: 'var Hello = function(props) { return <div/> }',\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: 'const Hello = function(props) { return <div/> }',\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: 'function Hello() { return function() { return <div/> } }',\n      options: [{ unnamedComponents: 'function-expression' }],\n    },\n    {\n      code: 'function Hello() { return () => { return <div/> }}',\n      options: [{ unnamedComponents: 'arrow-function' }],\n    },\n    {\n      code: 'var Foo = React.memo(function Foo() { return <p/> })',\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: 'const Foo = React.memo(function Foo() { return <p/> })',\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      // shouldn't trigger this rule since functions stating with a lowercase\n      // letter are not considered components\n      code: `\n        const selectAvatarByUserId = (state, id) => {\n          const user = selectUserById(state, id)\n          return null\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      // shouldn't trigger this rule since functions stating with a lowercase\n      // letter are not considered components\n      code: `\n        function ensureValidSourceType(sourceType: string) {\n          switch (sourceType) {\n            case 'ALBUM':\n            case 'PLAYLIST':\n              return sourceType;\n            default:\n              return null;\n          }\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: 'function Hello(props: Test) { return <p/> }',\n      options: [{ namedComponents: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello = function(props: Test) { return <p/> }',\n      options: [{ namedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello = (props: Test) => { return <p/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello: React.FC<Test> = function(props) { return <p/> }',\n      options: [{ namedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello: React.FC<Test> = (props) => { return <p/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: 'function Hello<Test>(props: Props<Test>) { return <p/> }',\n      options: [{ namedComponents: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: 'function Hello<Test extends {}>(props: Props<Test>) { return <p/> }',\n      options: [{ namedComponents: 'function-declaration' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: 'var Hello = function<Test>(props: Props<Test>) { return <p/> }',\n      options: [{ namedComponents: 'function-expression' }],\n      features: ['ts'],\n    },\n    {\n      code: 'var Hello = function<Test extends {}>(props: Props<Test>) { return <p/> }',\n      options: [{ namedComponents: 'function-expression' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: 'var Hello = <Test extends {}>(props: Props<Test>) => { return <p/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: 'function wrapper() { return function<Test>(props: Props<Test>) { return <p/> } } ',\n      options: [{ unnamedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: 'function wrapper() { return function<Test extends {}>(props: Props<Test>) { return <p/> } } ',\n      options: [{ unnamedComponents: 'function-expression' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: 'function wrapper() { return<Test extends {}>(props: Props<Test>) => { return <p/> } } ',\n      options: [{ unnamedComponents: 'arrow-function' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: 'var Hello = function(props): ReactNode { return <p/> }',\n      options: [{ namedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello = (props): ReactNode => { return <p/> }',\n      options: [{ namedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: 'function wrapper() { return function(props): ReactNode { return <p/> } }',\n      options: [{ unnamedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: 'function wrapper() { return (props): ReactNode => { return <p/> } }',\n      options: [{ unnamedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: 'function Hello(props): ReactNode { return <p/> }',\n      options: [{ namedComponents: 'function-declaration' }],\n      features: ['types'],\n    },\n    // https://github.com/jsx-eslint/eslint-plugin-react/issues/2765\n    {\n      code: `\n        const obj = {\n          serialize: (el) => {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: (el) => {\n            return <p/>\n          }\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: (el) => {\n            return <p/>\n          }\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: function (el) {\n            return <p/>\n          }\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: function (el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: function (el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize(el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize(el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize(el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize(el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize(el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: (el) => {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: (el) => {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: function (el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        const obj = {\n          serialize: function (el) {\n            return <p/>\n          }\n        };\n      `,\n      options: [{ unnamedComponents: 'function-expression' }],\n    },\n\n    {\n      code: 'function Hello(props) { return <div/> }',\n      options: [{ namedComponents: ['function-declaration', 'function-expression'] }],\n    },\n    {\n      code: 'var Hello = function(props) { return <div/> }',\n      options: [{ namedComponents: ['function-declaration', 'function-expression'] }],\n    },\n    {\n      code: 'var Foo = React.memo(function Foo() { return <p/> })',\n      options: [{ namedComponents: ['function-declaration', 'function-expression'] }],\n    },\n    {\n      code: 'function Hello(props: Test) { return <p/> }',\n      options: [{ namedComponents: ['function-declaration', 'function-expression'] }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello = function(props: Test) { return <p/> }',\n      options: [{ namedComponents: ['function-expression', 'function-expression'] }],\n      features: ['types'],\n    },\n    {\n      code: 'var Hello = (props: Test) => { return <p/> }',\n      options: [{ namedComponents: ['arrow-function', 'function-expression'] }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return function(props) {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      options: [{ unnamedComponents: ['arrow-function', 'function-expression'] }],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return (props) => {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      options: [{ unnamedComponents: ['arrow-function', 'function-expression'] }],\n    },\n    {\n      // should not report non-jsx components\n      code: `\n        export default (key, subTree = {}) => {\n          return (state) => {\n            const dataInStore = getFromDataModel(key)(state);\n            const fullPaths = dataInStore.map((item, index) => {\n              return [key, index];\n            });\n\n            return {\n              key,\n              paths: fullPaths.map((p) => [p[1]]),\n              fullPaths,\n              subTree: Object.keys(subTree).length ? subTree : null,\n            }\n          };\n        }\n      `,\n    },\n    {\n      // should not report non-jsx components\n      code: `\n        function mapStateToProps() {\n          const internItems = makeInternArray();\n          const internClassList = makeInternArray();\n\n          return (state, props) => {\n            const { store, bucket, singleCharacter } = props;\n\n            return {\n              store: null,\n              destinyVersion: store.destinyVersion,\n              storeId: store.id,\n            }\n          }\n        }\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        var Hello = function(props) {\n          return <div/>;\n        };\n      `,\n      output: `\n        var Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n    },\n    {\n      code: `\n        var Hello = function(props) {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div/>;\n        };\n      `,\n      output: `\n        var Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        let Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        let Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        let Hello;\n        Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        let Hello;\n        Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        let Hello = (props) => {\n          return <div/>;\n        }\n        Hello = function(props) {\n          return <span/>;\n        }\n      `,\n      output: `\n        let Hello = function(props) {\n          return <div/>;\n        }\n        Hello = function(props) {\n          return <span/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return function(props) {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return (props) => {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      errors: [{ messageId: 'arrow-function' }],\n      options: [{ unnamedComponents: 'arrow-function' }],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return (props) => {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return function(props) {\n            return <div><Component {...props}/></div>;\n          };\n        }\n      `,\n      errors: [{ messageId: 'function-expression' }],\n      options: [{ unnamedComponents: 'function-expression' }],\n    },\n    {\n      code: `\n        var Hello = (props: Test) => {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello = function(props: Test) {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = (props: Test) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello = function(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello = (props: Test) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = function(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      output: `\n        var Hello = function(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        import * as React from 'react';\n        function Hello(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      output: `\n        import * as React from 'react';\n        const Hello = function(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        export function Hello(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      output: `\n        export const Hello = function(props: Test) {\n          return React.createElement('div');\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return React.createElement('div');\n        }\n        export default Hello;\n      `,\n      output: `\n        const Hello = function(props) {\n          return React.createElement('div');\n        }\n        export default Hello;\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        var Hello = (props: Test) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello = function(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello: React.FC<Test> = (props) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello: React.FC<Test> = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello: React.FC<Test> = function(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello: React.FC<Test> = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello: React.FC<Test> = function(props) {\n          return <div/>;\n        }\n      `,\n      output: null,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello: React.FC<Test> = (props) => {\n          return <div/>;\n        };\n      `,\n      output: null,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = <Test extends {}>(props: Test) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        function Hello<Test>(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: null,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = function<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        var Hello = function<Test extends {}>(props: Test) {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        var Hello = <Test extends {}>(props: Test) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello = function<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-expression' }],\n      errors: [{ messageId: 'function-expression' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        var Hello = function<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        var Hello = <Test extends {}>(props: Test) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        var Hello = function<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      output: `\n        function Hello<Test extends {}>(props: Test) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return function<Test extends {}>(props) {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return <Test extends {}>(props) => {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      errors: [{ messageId: 'arrow-function' }],\n      options: [{ unnamedComponents: 'arrow-function' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return function<Test>(props) {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      output: null,\n      errors: [{ messageId: 'arrow-function' }],\n      options: [{ unnamedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return <Test extends {}>(props) => {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return function<Test extends {}>(props) {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      errors: [{ messageId: 'function-expression' }],\n      options: [{ unnamedComponents: 'function-expression' }],\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return function(props): ReactNode {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return (props): ReactNode => {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      errors: [{ messageId: 'arrow-function' }],\n      options: [{ unnamedComponents: 'arrow-function' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        function wrap(Component) {\n          return (props): ReactNode => {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      output: `\n        function wrap(Component) {\n          return function(props): ReactNode {\n            return <div><Component {...props}/></div>\n          }\n        }\n      `,\n      errors: [{ messageId: 'function-expression' }],\n      options: [{ unnamedComponents: 'function-expression' }],\n      features: ['types'],\n    },\n    {\n      code: `\n        export function Hello(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        export const Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        export var Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        export var Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        export var Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      output: `\n        export function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'function-declaration' }],\n      errors: [{ messageId: 'function-declaration' }],\n    },\n    {\n      code: `\n        export default function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        module.exports = function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ unnamedComponents: 'arrow-function' }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      output: `\n        const Hello = (props) => {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: ['arrow-function', 'function-expression'] }],\n      errors: [{ messageId: 'arrow-function' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div/>;\n        };\n      `,\n      output: `\n        function Hello(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: ['function-declaration', 'function-expression'] }],\n      errors: [{ messageId: 'function-declaration' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div/>;\n        };\n      `,\n      output: `\n        var Hello = function(props) {\n          return <div/>;\n        }\n      `,\n      options: [{ namedComponents: ['function-expression', 'function-declaration'] }],\n      errors: [{ messageId: 'function-expression' }],\n    },\n    {\n      code: `\n        const genX = (symbol) => \\`the symbol is \\${symbol}\\`;\n\n        const IndexPage = () => {\n          return (\n            <div>\n              Hello World.{genX('$')}\n            </div>\n          )\n        }\n\n        export default IndexPage;\n      `,\n      output: `\n        const genX = (symbol) => \\`the symbol is \\${symbol}\\`;\n\n        function IndexPage() {\n          return (\n            <div>\n              Hello World.{genX('$')}\n            </div>\n          )\n        }\n\n        export default IndexPage;\n      `,\n      options: [{ namedComponents: ['function-declaration'] }],\n      errors: [{ messageId: 'function-declaration' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/hook-use-state.js",
    "content": "/**\n * @fileoverview Ensure symmetric naming of setState hook value and setter variables\n * @author Duncan Beevers\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/hook-use-state');\nconst parsers = require('../../helpers/parsers');\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n  },\n});\n\nconst tests = {\n  valid: parsers.all([\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState()\n          return [color, setColor]\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useRGB() {\n          const [rgb, setRGB] = useState()\n          return [rgb, setRGB]\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useRGBValue() {\n          const [rgbValue, setRGBValue] = useState()\n          return [rgbValue, setRGBValue]\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useCustomColorValue() {\n          const [customColorValue, setCustomColorValue] = useState()\n          return [customColorValue, setCustomColorValue]\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState('#ffffff')\n          return [color, setColor]\n        }\n      `,\n    },\n    {\n      code: `\n        import React from 'react'\n        function useColor() {\n          const [color, setColor] = React.useState()\n          return [color, setColor]\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color1, setColor1] = useState()\n          return [color1, setColor1]\n        }\n      `,\n    },\n    {\n      code: 'useState()',\n    },\n    {\n      code: 'const result = useState()',\n    },\n    {\n      code: 'const [color, setFlavor] = useState()',\n    },\n    {\n      code: `\n        import React from 'react'\n        import useState from 'someOtherUseState'\n        const [color, setFlavor] = useState()\n      `,\n    },\n    {\n      code: `\n        import { useRef } from 'react'\n        const result = useState()\n      `,\n    },\n    {\n      code: `\n        import { useState as useStateAlternativeName } from 'react'\n        function useColor() {\n          const [color, setColor] = useStateAlternativeName()\n          return [color, setColor]\n        }\n      `,\n    },\n    {\n      code: 'const result = React.useState()',\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          return useState()\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          function useState() { // shadows React's useState\n            return null\n          }\n\n          const result = useState()\n        }\n      `,\n    },\n    {\n      code: `\n        import React from 'react'\n        function useColor() {\n          const React = {\n            useState: () => {\n              return null\n            }\n          }\n\n          const result = React.useState()\n        }\n      `,\n    },\n    {\n      code: `\n        import { useState } from 'react';\n        function useColor() {\n          const [color, setColor] = useState<string>()\n          return [color, setColor]\n        }\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n        function useColor() {\n          const [color, setColor] = useState<string>('#ffffff')\n          return [color, setColor]\n        }\n      `,\n      features: ['ts'],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n\n        const [{foo, bar, baz}, setFooBarBaz] = useState({foo: \"bbb\", bar: \"aaa\", baz: \"qqq\"})\n      `,\n      options: [{ allowDestructuredState: true }],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n\n        const [[index, value], setValueWithIndex] = useState([0, \"hello\"])\n      `,\n      options: [{ allowDestructuredState: true }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        import { useState } from 'react';\n        const result = useState()\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n        function useColor() {\n          const result = useState()\n          return result\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState as useStateAlternativeName } from 'react'\n        function useColor() {\n          const result = useStateAlternativeName()\n          return result\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import React from 'react'\n        function useColor() {\n          const result = React.useState()\n          return result\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import ReactAlternative from 'react'\n        function useColor() {\n          const result = ReactAlternative.useState()\n          return result\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const result = useState()\n          return result\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [, , extra1] = useState()\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [, setColor] = useState()\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const { color } = useState()\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [] = useState()\n        }\n      `,\n      errors: [{\n        message: 'useState call is not destructured into value + setter pair',\n      }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [, , , ,] = useState()\n        }\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color] = useState()\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState()\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor(initialColor) {\n          const [color] = useState(initialColor)\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestMemo',\n              output: `\n        import { useState, useMemo } from 'react'\n        function useColor(initialColor) {\n          const color = useMemo(() => initialColor, [])\n        }\n      `,\n            },\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        function useColor(initialColor) {\n          const [color, setColor] = useState(initialColor)\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState, useMemo as useMemoAlternative } from 'react'\n        function useColor(initialColor) {\n          const [color] = useState(initialColor)\n        }\n      `,\n      errors: [{\n        message: 'useState call is not destructured into value + setter pair',\n        suggestions: [\n          {\n            messageId: 'suggestMemo',\n            output: `\n        import { useState, useMemo as useMemoAlternative } from 'react'\n        function useColor(initialColor) {\n          const color = useMemoAlternative(() => initialColor, [])\n        }\n      `,\n          },\n          {\n            messageId: 'suggestPair',\n            output: `\n        import { useState, useMemo as useMemoAlternative } from 'react'\n        function useColor(initialColor) {\n          const [color, setColor] = useState(initialColor)\n        }\n      `,\n          },\n        ],\n      }],\n    },\n    {\n      code: `\n        import React from 'react'\n        function useColor(initialColor) {\n          const [color] = React.useState(initialColor)\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestMemo',\n              output: `\n        import React from 'react'\n        function useColor(initialColor) {\n          const color = React.useMemo(() => initialColor, [])\n        }\n      `,\n            },\n            {\n              messageId: 'suggestPair',\n              output: `\n        import React from 'react'\n        function useColor(initialColor) {\n          const [color, setColor] = React.useState(initialColor)\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, , extra1] = useState()\n          return [color]\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState()\n          return [color]\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor, extra1, extra2, extra3] = useState()\n          return [color, setColor]\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState()\n          return [color, setColor]\n        }\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        const [, makeColor] = useState()\n      `,\n      errors: [{ message: 'useState call is not destructured into value + setter pair' }],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        const [color, setFlavor, extraneous] = useState()\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        const [color, setColor] = useState()\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        const [color, setFlavor] = useState()\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        const [color, setColor] = useState()\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n\n        const [{foo, bar, baz}, setFooBarBaz] = useState({foo: \"bbb\", bar: \"aaa\", baz: \"qqq\"})\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair (you can allow destructuring by enabling \"allowDestructuredState\" option)',\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n\n        const [[index, value], setValueWithIndex] = useState([0, \"hello\"])\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair (you can allow destructuring by enabling \"allowDestructuredState\" option)',\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react';\n\n        const [{foo, bar, baz}, {setFooBarBaz}] = useState({foo: \"bbb\", bar: \"aaa\", baz: \"qqq\"})\n      `,\n      options: [{ allowDestructuredState: true }],\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n        },\n      ],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        const [color, setFlavor] = useState<string>()\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        const [color, setColor] = useState<string>()\n      `,\n            },\n          ],\n        },\n      ],\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setFlavor] = useState<string>('#ffffff')\n          return [color, setFlavor]\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import { useState } from 'react'\n        function useColor() {\n          const [color, setColor] = useState<string>('#ffffff')\n          return [color, setFlavor]\n        }\n      `,\n            },\n          ],\n        },\n      ],\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from 'react'\n        function useColor() {\n          const [color, setFlavor] = React.useState<string>('#ffffff')\n          return [color, setFlavor]\n        }\n      `,\n      errors: [\n        {\n          message: 'useState call is not destructured into value + setter pair',\n          suggestions: [\n            {\n              messageId: 'suggestPair',\n              output: `\n        import React from 'react'\n        function useColor() {\n          const [color, setColor] = React.useState<string>('#ffffff')\n          return [color, setFlavor]\n        }\n      `,\n            },\n          ],\n        },\n      ],\n      features: ['ts', 'no-babel-old'],\n    },\n  ]),\n};\n\nruleTester.run('hook-set-state-names', rule, tests);\n"
  },
  {
    "path": "tests/lib/rules/iframe-missing-sandbox.js",
    "content": "/**\n * @fileoverview TBD\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/iframe-missing-sandbox');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('iframe-missing-sandbox', rule, {\n  valid: parsers.all([\n    { code: '<div sandbox=\"__unknown__\" />;' },\n\n    { code: '<iframe sandbox=\"\" />;' },\n    { code: '<iframe sandbox={\"\"} />' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"\" });' },\n\n    { code: '<iframe src=\"foo.htm\" sandbox></iframe>' },\n    { code: 'React.createElement(\"iframe\", { src: \"foo.htm\", sandbox: true })' },\n\n    { code: '<iframe src=\"foo.htm\" sandbox sandbox></iframe>' },\n\n    { code: '<iframe sandbox=\"allow-forms\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-modals\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-orientation-lock\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-pointer-lock\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-popups\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-popups-to-escape-sandbox\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-presentation\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-same-origin\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-scripts\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-top-navigation\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-top-navigation-by-user-activation\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-forms allow-modals\"></iframe>' },\n    { code: '<iframe sandbox=\"allow-popups allow-popups-to-escape-sandbox allow-pointer-lock allow-same-origin allow-top-navigation\"></iframe>' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-forms\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-modals\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-orientation-lock\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-pointer-lock\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-popups\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-popups-to-escape-sandbox\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-presentation\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-same-origin\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-scripts\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-top-navigation\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-top-navigation-by-user-activation\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-forms allow-modals\" })' },\n    { code: 'React.createElement(\"iframe\", { sandbox: \"allow-popups allow-popups-to-escape-sandbox allow-pointer-lock allow-same-origin allow-top-navigation\" })' },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<iframe></iframe>;',\n      errors: [{ messageId: 'attributeMissing' }],\n    },\n    {\n      code: '<iframe/>;',\n      errors: [{ messageId: 'attributeMissing' }],\n    },\n    {\n      code: 'React.createElement(\"iframe\");',\n      errors: [{ messageId: 'attributeMissing' }],\n    },\n    {\n      code: 'React.createElement(\"iframe\", {});',\n      errors: [{ messageId: 'attributeMissing' }],\n    },\n    {\n      code: 'React.createElement(\"iframe\", null);',\n      errors: [{ messageId: 'attributeMissing' }],\n    },\n\n    {\n      code: '<iframe sandbox=\"__unknown__\"></iframe>',\n      errors: [{ messageId: 'invalidValue', data: { value: '__unknown__' } }],\n    },\n    {\n      code: 'React.createElement(\"iframe\", { sandbox: \"__unknown__\" })',\n      errors: [{ messageId: 'invalidValue', data: { value: '__unknown__' } }],\n    },\n\n    {\n      code: '<iframe sandbox=\"allow-popups __unknown__\"/>',\n      errors: [{ messageId: 'invalidValue', data: { value: '__unknown__' } }],\n    },\n    {\n      code: '<iframe sandbox=\"__unknown__ allow-popups\"/>',\n      errors: [{ messageId: 'invalidValue', data: { value: '__unknown__' } }],\n    },\n    {\n      code: '<iframe sandbox=\" allow-forms __unknown__ allow-popups __unknown__  \"/>',\n      errors: [\n        { messageId: 'invalidValue', data: { value: '__unknown__' } },\n        { messageId: 'invalidValue', data: { value: '__unknown__' } },\n      ],\n    },\n    {\n      code: '<iframe sandbox=\"allow-scripts allow-same-origin\"></iframe>;',\n      errors: [{ messageId: 'invalidCombination' }],\n    },\n    {\n      code: '<iframe sandbox=\"allow-same-origin allow-scripts\"/>;',\n      errors: [{ messageId: 'invalidCombination' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-boolean-value.js",
    "content": "/**\n * @fileoverview Enforce boolean attributes notation in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-boolean-value');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-boolean-value', rule, {\n  valid: parsers.all([\n    {\n      code: '<App foo />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo bar={true} />;',\n      options: ['always', { never: ['foo'] }],\n    },\n    {\n      code: '<App foo />;',\n    },\n    {\n      code: '<App foo={true} />;',\n      options: ['always'],\n    },\n    {\n      code: '<App foo={true} bar />;',\n      options: ['never', { always: ['foo'] }],\n    },\n    {\n      code: '<App />;',\n      options: ['never', { assumeUndefinedIsFalse: true }],\n    },\n    {\n      code: '<App foo={false} />;',\n      options: ['never', { assumeUndefinedIsFalse: false }],\n    },\n    {\n      code: '<App foo={false} />;',\n      options: ['never', { assumeUndefinedIsFalse: true, always: ['foo'] }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<App foo={true} />;',\n      output: '<App foo />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={true} bar={true} baz={true} />;',\n      output: '<App foo bar baz={true} />;',\n      options: ['always', { never: ['foo', 'bar'] }],\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'bar' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={true} />;',\n      output: '<App foo />;',\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<App foo = {true} />;',\n      output: '<App foo />;',\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<App foo />;',\n      output: '<App foo={true} />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'setBoolean',\n          data: { propName: 'foo' },\n        },\n      ],\n    },\n    {\n      code: '<App foo bar baz />;',\n      output: '<App foo={true} bar={true} baz />;',\n      options: ['never', { always: ['foo', 'bar'] }],\n      errors: [\n        {\n          messageId: 'setBoolean',\n          data: { propName: 'foo' },\n        },\n        {\n          messageId: 'setBoolean',\n          data: { propName: 'bar' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={false} bak={false} />;',\n      output: '<App   />;',\n      options: ['never', { assumeUndefinedIsFalse: true }],\n      errors: [\n        {\n          messageId: 'omitPropAndBoolean',\n          data: { propName: 'foo' },\n        },\n        {\n          messageId: 'omitPropAndBoolean',\n          data: { propName: 'bak' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={true} bak={false} />;',\n      output: '<App foo  />;',\n      options: ['never', { assumeUndefinedIsFalse: true }],\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n        {\n          messageId: 'omitPropAndBoolean',\n          data: { propName: 'bak' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={true} bar={false} baz={false} bak={false} />;',\n      output: '<App foo={true} bar={false}   />;',\n      options: [\n        'always',\n        { assumeUndefinedIsFalse: true, never: ['baz', 'bak'] },\n      ],\n      errors: [\n        {\n          messageId: 'omitPropAndBoolean',\n          data: { propName: 'baz' },\n        },\n        {\n          messageId: 'omitPropAndBoolean',\n          data: { propName: 'bak' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={true} bar={true} baz />;',\n      output: '<App foo bar baz={true} />;',\n      options: ['always', { never: ['foo', 'bar'] }],\n      errors: [\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'foo' },\n        },\n        {\n          messageId: 'omitBoolean',\n          data: { propName: 'bar' },\n        },\n        {\n          messageId: 'setBoolean',\n          data: { propName: 'baz' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-child-element-spacing.js",
    "content": "'use strict';\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-child-element-spacing');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  sourceType: 'module',\n  ecmaVersion: 2015,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-child-element-spacing', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <App>\n          foo\n        </App>\n      `,\n    },\n    {\n      code: `\n        <>\n          foo\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <App>\n          <a>bar</a>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <a>\n            <b>nested</b>\n          </a>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo\n          bar\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo<a>bar</a>baz\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo\n          {' '}\n          <a>bar</a>\n          {' '}\n          baz\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo\n          {' '}<a>bar</a>{' '}\n          baz\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo{' '}\n          <a>bar</a>\n          {' '}baz\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo{/*\n          */}<a>bar</a>{/*\n          */}baz\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          Please take a look at <a href=\"https://js.org\">this link</a>.\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          Please take a look at\n          {' '}\n          <a href=\"https://js.org\">this link</a>.\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <p>A</p>\n          <p>B</p>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <p>A</p><p>B</p>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <a>foo</a>\n          <a>bar</a>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <a>\n            <b>nested1</b>\n            <b>nested2</b>\n          </a>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          A\n          B\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          A\n          <br/>\n          B\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          A<br/>\n          B\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          A<br/>B\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>A<br/>B</App>\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App>\n          foo\n          <a>bar</a>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'a' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <>\n          foo\n          <a>bar</a>\n        </>\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'a' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <a>bar</a>\n          baz\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingAfterPrev',\n          data: { element: 'a' },\n          line: 3,\n          column: 21,\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          {' '}<a>bar</a>\n          baz\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingAfterPrev',\n          data: { element: 'a' },\n          line: 3,\n          column: 26,\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          Please take a look at\n          <a href=\"https://js.org\">this link</a>.\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'a' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          Some <code>loops</code> and some\n          <code>if</code> statements.\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'code' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          Here is\n          <a href=\"https://js.org\">a link</a> and here is\n          <a href=\"https://js.org\">another</a>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'a' },\n          line: 4,\n          column: 11,\n        },\n        {\n          messageId: 'spacingBeforeNext',\n          data: { element: 'a' },\n          line: 5,\n          column: 11,\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-closing-bracket-location.js",
    "content": "/**\n * @fileoverview Validate closing bracket location in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-closing-bracket-location');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst MESSAGE_AFTER_PROPS = 'placed after the last prop';\nconst MESSAGE_AFTER_TAG = 'placed after the opening tag';\n\nconst MESSAGE_PROPS_ALIGNED = 'aligned with the last prop';\nconst MESSAGE_TAG_ALIGNED = 'aligned with the opening tag';\nconst MESSAGE_LINE_ALIGNED = 'aligned with the line containing the opening tag';\n\nfunction details(expectedColumn, expectedNextLine) {\n  return ` (expected column ${expectedColumn}${expectedNextLine ? ' on the next line)' : ')'}`;\n}\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-closing-bracket-location', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <App />\n      `,\n    },\n    {\n      code: `\n        <App foo />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n    },\n    {\n      code: `\n        <App foo />\n      `,\n      options: [{ location: 'after-props' }],\n    },\n    {\n      code: `\n        <App foo />\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        <App foo />\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo />\n      `,\n      options: ['after-props'],\n    },\n    {\n      code: `\n        <App\n          foo\n          />\n      `,\n      options: ['props-aligned'],\n    },\n    {\n      code: `\n        <App\n          foo />\n      `,\n      options: [{ location: 'after-props' }],\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo\n          />\n      `,\n      options: [{ location: 'props-aligned' }],\n    },\n    {\n      code: `\n        <App foo></App>\n      `,\n    },\n    {\n      code: `\n        <App\n          foo\n        ></App>\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo\n        ></App>\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo\n          ></App>\n      `,\n      options: [{ location: 'props-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo={function() {\n            console.log('bar');\n          }} />\n      `,\n      options: [{ location: 'after-props' }],\n    },\n    {\n      code: `\n        <App\n          foo={function() {\n            console.log('bar');\n          }}\n          />\n      `,\n      options: [{ location: 'props-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo={function() {\n            console.log('bar');\n          }}\n        />\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        <App\n          foo={function() {\n            console.log('bar');\n          }}\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <App foo={function() {\n          console.log('bar');\n        }}/>\n      `,\n      options: [{ location: 'after-props' }],\n    },\n    {\n      code: `\n         <App foo={function() {\n                console.log('bar');\n              }}\n              />\n      `,\n      options: [{ location: 'props-aligned' }],\n    },\n    {\n      code: `\n        <App foo={function() {\n          console.log('bar');\n        }}\n        />\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        <App foo={function() {\n          console.log('bar');\n        }}\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <Provider store>\n          <App\n            foo />\n        </Provider>\n      `,\n      options: [{ selfClosing: 'after-props' }],\n    },\n    {\n      code: `\n        <Provider\n          store\n        >\n          <App\n            foo />\n        </Provider>\n      `,\n      options: [{ selfClosing: 'after-props' }],\n    },\n    {\n      code: `\n        <Provider\n          store>\n          <App\n            foo\n          />\n        </Provider>\n      `,\n      options: [{ nonEmpty: 'after-props' }],\n    },\n    {\n      code: `\n        <Provider store>\n          <App\n            foo\n            />\n        </Provider>\n      `,\n      options: [{ selfClosing: 'props-aligned' }],\n    },\n    {\n      code: `\n        <Provider\n          store\n          >\n          <App\n            foo\n          />\n        </Provider>\n      `,\n      options: [{ nonEmpty: 'props-aligned' }],\n    },\n    {\n      code: `\n        var x = function() {\n          return <App\n            foo\n                 >\n              bar\n                 </App>\n        }\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        var x = function() {\n          return <App\n            foo\n                 />\n        }\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        var x = <App\n          foo\n                />\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n    {\n      code: `\n        var x = function() {\n          return <App\n            foo={function() {\n              console.log('bar');\n            }}\n          />\n        }\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        var x = <App\n          foo={function() {\n            console.log('bar');\n          }}\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <Provider\n          store\n        >\n          <App\n            foo={function() {\n              console.log('bar');\n            }}\n          />\n        </Provider>\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <Provider\n          store\n        >\n          {baz && <App\n            foo={function() {\n              console.log('bar');\n            }}\n          />}\n        </Provider>\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        <App>\n          <Foo\n            bar\n          >\n          </Foo>\n          <Foo\n            bar />\n        </App>\n      `,\n      options: [\n        {\n          nonEmpty: false,\n          selfClosing: 'after-props',\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <Foo\n            bar>\n          </Foo>\n          <Foo\n            bar\n          />\n        </App>\n      `,\n      options: [\n        {\n          nonEmpty: 'after-props',\n          selfClosing: false,\n        },\n      ],\n    },\n    {\n      code: `\n        <div className={[\n          \"some\",\n          \"stuff\",\n          2 ]}\n        >\n          Some text\n        </div>\n      `,\n      options: [{ location: 'tag-aligned' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App\n        />\n      `,\n      output: `\n        <App />\n      `,\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_TAG,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo\n        />\n      `,\n      output: `\n        <App foo/>\n      `,\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo\n        ></App>\n      `,\n      output: `\n        <App foo></App>\n      `,\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo />\n      `,\n      output: `\n        <App\n          foo\n          />\n      `,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(11, true),\n          },\n          line: 3,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo />\n      `,\n      output: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, true),\n          },\n          line: 3,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo />\n      `,\n      output: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(9, true),\n          },\n          line: 3,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      output: `\n        <App\n          foo/>\n      `,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      output: `\n        <App\n          foo\n          />\n      `,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(11, false),\n          },\n          line: 4,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          />\n      `,\n      output: `\n        <App\n          foo/>\n      `,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          />\n      `,\n      output: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, false),\n          },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          />\n      `,\n      output: `\n        <App\n          foo\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(9, false),\n          },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n        ></App>\n      `,\n      output: `\n        <App\n          foo></App>\n      `,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n        ></App>\n      `,\n      output: `\n        <App\n          foo\n          ></App>\n      `,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(11, false),\n          },\n          line: 4,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          ></App>\n      `,\n      output: `\n        <App\n          foo></App>\n      `,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          ></App>\n      `,\n      output: `\n        <App\n          foo\n        ></App>\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, false),\n          },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo\n          ></App>\n      `,\n      output: `\n        <App\n          foo\n        ></App>\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(9, false),\n          },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        <Provider\n          store>${/* <-- */''}\n          <App\n            foo\n            />\n        </Provider>\n      `,\n      output: `\n        <Provider\n          store\n        >\n          <App\n            foo\n            />\n        </Provider>\n      `,\n      options: [{ selfClosing: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, true),\n          },\n          line: 3,\n          column: 16,\n        },\n      ],\n    },\n    {\n      code: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n                                            >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      output: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n              >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      options: ['props-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(15, false),\n          },\n          line: 7,\n          column: 45,\n        },\n      ],\n    },\n    {\n      code: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n                                            >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      output: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n            >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      options: ['tag-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(13, false),\n          },\n          line: 7,\n          column: 45,\n        },\n      ],\n    },\n    {\n      code: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n                                            >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      output: `\n        const Button = function(props) {\n          return (\n            <Button\n              size={size}\n              onClick={onClick}\n            >\n              Button Text\n            </Button>\n          );\n        };\n      `,\n      options: ['line-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(13, false),\n          },\n          line: 7,\n          column: 45,\n        },\n      ],\n    },\n    {\n      code: `\n        <Provider\n          store\n          >\n          <App\n            foo\n            />${''/* <-- */}\n        </Provider>\n      `,\n      output: `\n        <Provider\n          store\n          >\n          <App\n            foo\n          />\n        </Provider>\n      `,\n      options: [{ nonEmpty: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(11, false),\n          },\n          line: 7,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        <Provider\n          store>${''/* <-- */}\n          <App\n            foo />\n        </Provider>\n      `,\n      output: `\n        <Provider\n          store\n        >\n          <App\n            foo />\n        </Provider>\n      `,\n      options: [{ selfClosing: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, true),\n          },\n          line: 3,\n          column: 16,\n        },\n      ],\n    },\n    {\n      code: `\n        <Provider\n          store>\n          <App\n            foo\n            />${''/* <--*/}\n        </Provider>\n      `,\n      output: `\n        <Provider\n          store>\n          <App\n            foo\n          />\n        </Provider>\n      `,\n      options: [{ nonEmpty: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(11, false),\n          },\n          line: 6,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        var x = function() {\n          return <App\n            foo\n                />\n        }\n      `,\n      output: `\n        var x = function() {\n          return <App\n            foo\n          />\n        }\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(11, false),\n          },\n          line: 5,\n          column: 17,\n        },\n      ],\n    },\n    {\n      code: `\n        var x = <App\n          foo\n                />\n      `,\n      output: `\n        var x = <App\n          foo\n        />\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(9, false),\n          },\n          line: 4,\n          column: 17,\n        },\n      ],\n    },\n    {\n      code: `\n        var x = (\n          <div\n            className=\"MyComponent\"\n            {...props} />\n        )\n      `,\n      output: `\n        var x = (\n          <div\n            className=\"MyComponent\"\n            {...props}\n          />\n        )\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(11, true),\n          },\n          line: 5,\n          column: 24,\n        },\n      ],\n    },\n    {\n      code: `\n        var x = (\n          <Something\n            content={<Foo />} />\n        )\n      `,\n      output: `\n        var x = (\n          <Something\n            content={<Foo />}\n          />\n        )\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(11, true),\n          },\n          line: 4,\n          column: 31,\n        },\n      ],\n    },\n    {\n      code: `\n        var x = (\n          <Something\n            />\n        )\n      `,\n      output: `\n        var x = (\n          <Something />\n        )\n      `,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_TAG,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div className={[\n          \"some\",\n          \"stuff\",\n          2 ]}>\n          Some text\n        </div>\n      `,\n      output: `\n        <div className={[\n          \"some\",\n          \"stuff\",\n          2 ]}\n        >\n          Some text\n        </div>\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(9, true),\n          },\n          line: 5,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo />\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(6, true),\n          },\n          line: 3,\n          column: 10,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo />\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, true),\n          },\n          line: 3,\n          column: 10,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo />\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(5, true),\n          },\n          line: 3,\n          column: 10,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo/>\n\\t\\t\\t`,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(6, false),\n          },\n          line: 4,\n          column: 5,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo/>\n\\t\\t\\t`,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, false),\n          },\n          line: 4,\n          column: 6,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(5, false),\n          },\n          line: 4,\n          column: 6,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo></App>\n\\t\\t\\t`,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      options: [{ location: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(6, false),\n          },\n          line: 4,\n          column: 5,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo></App>\n\\t\\t\\t`,\n      options: [{ location: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_PROPS,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, false),\n          },\n          line: 4,\n          column: 6,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t></App>\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(5, false),\n          },\n          line: 4,\n          column: 6,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore\n\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      options: [{ selfClosing: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, true),\n          },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      options: ['props-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_PROPS_ALIGNED,\n            details: details(8, false),\n          },\n          line: 7,\n          column: 23,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      options: ['tag-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(7, false),\n          },\n          line: 7,\n          column: 23,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tconst Button = function(props) {\n\\t\\t\\t\\t\\treturn (\n\\t\\t\\t\\t\\t\\t<Button\n\\t\\t\\t\\t\\t\\t\\tsize={size}\n\\t\\t\\t\\t\\t\\t\\tonClick={onClick}\n\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\tButton Text\n\\t\\t\\t\\t\\t\\t</Button>\n\\t\\t\\t\\t\\t);\n\\t\\t\\t\\t};\n\\t\\t\\t`,\n      options: ['line-aligned'],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(7, false),\n          },\n          line: 7,\n          column: 23,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      options: [{ nonEmpty: 'props-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(6, false),\n          },\n          line: 7,\n          column: 7,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo />\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore\n\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo />\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      options: [{ selfClosing: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, true),\n          },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<Provider\n\\t\\t\\t\\t\\tstore>\n\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t</Provider>\n\\t\\t\\t`,\n      options: [{ nonEmpty: 'after-props' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(6, false),\n          },\n          line: 6,\n          column: 7,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tvar x = function() {\n\\t\\t\\t\\t\\treturn <App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t}\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tvar x = function() {\n\\t\\t\\t\\t\\treturn <App\n\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t}\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(6, false),\n          },\n          line: 5,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tvar x = <App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tvar x = <App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(5, false),\n          },\n          line: 4,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<div\n\\t\\t\\t\\t\\t\\tclassName=\"MyComponent\"\n\\t\\t\\t\\t\\t\\t{...props} />\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<div\n\\t\\t\\t\\t\\t\\tclassName=\"MyComponent\"\n\\t\\t\\t\\t\\t\\t{...props}\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(6, true),\n          },\n          line: 5,\n          column: 18,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<Something\n\\t\\t\\t\\t\\t\\tcontent={<Foo />} />\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<Something\n\\t\\t\\t\\t\\t\\tcontent={<Foo />}\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_LINE_ALIGNED,\n            details: details(6, true),\n          },\n          line: 4,\n          column: 25,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<Something\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\tvar x = (\n\\t\\t\\t\\t\\t<Something />\n\\t\\t\\t\\t)\n\\t\\t\\t`,\n      options: [{ location: 'line-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_AFTER_TAG,\n            details: '',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<div className={[\n\\t\\t\\t\\t\\t\"some\",\n\\t\\t\\t\\t\\t\"stuff\",\n\\t\\t\\t\\t\\t2 ]}>\n\\t\\t\\t\\t\\tSome text\n\\t\\t\\t\\t</div>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<div className={[\n\\t\\t\\t\\t\\t\"some\",\n\\t\\t\\t\\t\\t\"stuff\",\n\\t\\t\\t\\t\\t2 ]}\n\\t\\t\\t\\t>\n\\t\\t\\t\\t\\tSome text\n\\t\\t\\t\\t</div>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(5, true),\n          },\n          line: 5,\n          column: 10,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t\\t\\t\\t<div\n\\t\\t\\t\\t\\t\\t\\t\\tclassName={styles}\n\\t\\t\\t\\t\\t >\n\\t\\t\\t\\t\\t\\t\\t\\t{props}\n\\t\\t\\t\\t\\t\\t\\t</div>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t\\t\\t\\t<div\n\\t\\t\\t\\t\\t\\t\\t\\tclassName={styles}\n\\t\\t\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\t\\t\\t{props}\n\\t\\t\\t\\t\\t\\t\\t</div>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(8, false),\n          },\n          line: 4,\n          column: 7,\n        },\n      ],\n    },\n    {\n      code: `\n          <div\n            className={styles}\n            >\n            {props}\n          </div>\n      `,\n      output: `\n          <div\n            className={styles}\n          >\n            {props}\n          </div>\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(11, false),\n          },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n          <App\n            foo\n            />\n      `,\n      output: `\n          <App\n            foo\n          />\n      `,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(11, false),\n          },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: [{ location: 'tag-aligned' }],\n      errors: [\n        {\n          messageId: 'bracketLocation',\n          data: {\n            location: MESSAGE_TAG_ALIGNED,\n            details: details(7, false),\n          },\n          line: 4,\n          column: 6,\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-closing-tag-location.js",
    "content": "/**\n * @fileoverview Validate closing tag location in JSX\n * @author Ross Solomon\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-closing-tag-location');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  sourceType: 'module',\n  ecmaVersion: 2015,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-closing-tag-location', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        const foo = () => {\n          return <App>\n       bar</App>\n        }\n      `,\n      options: [{ location: 'line-aligned' }],\n    },\n    {\n      code: `\n        const foo = () => {\n          return <App>\n              bar</App>\n        }\n      `,\n    },\n    {\n      code: `\n        const foo = () => {\n          return <App>\n              bar\n          </App>\n        }\n      `,\n      options: ['line-aligned'],\n    },\n    {\n      code: `\n        const foo = <App>\n              bar\n        </App>\n      `,\n      options: ['line-aligned'],\n    },\n    {\n      code: `\n        const x = <App>\n              foo\n                  </App>\n      `,\n    },\n    {\n      code: `\n        const foo =\n          <App>\n              bar\n          </App>\n      `,\n      options: ['line-aligned'],\n    },\n    {\n      code: `\n        const foo =\n          <App>\n              bar\n          </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo\n        </App>\n      `,\n      options: ['line-aligned'],\n    },\n    {\n      code: `\n        <App>foo</App>\n      `,\n    },\n    {\n      code: `\n        <>\n          foo\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>foo</>\n      `,\n      features: ['fragment'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App>\n          foo\n          </App>\n      `,\n      output: `\n        <App>\n          foo\n        </App>\n      `,\n      errors: [{ messageId: 'matchIndent' }],\n    },\n    {\n      code: `\n        <App>\n          foo</App>\n      `,\n      output: `\n        <App>\n          foo\n        </App>\n      `,\n      errors: [{ messageId: 'onOwnLine' }],\n    },\n    {\n      code: `\n        <>\n          foo\n          </>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        <>\n          foo\n        </>\n      `,\n      errors: [{ messageId: 'matchIndent' }],\n    },\n    {\n      code: `\n        <>\n          foo</>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        <>\n          foo\n        </>\n      `,\n      errors: [{ messageId: 'onOwnLine' }],\n    },\n    {\n      code: `\n        const x = () => {\n          return <App>\n              foo</App>\n        }\n      `,\n      output: `\n        const x = () => {\n          return <App>\n              foo\n          </App>\n        }\n      `,\n      errors: [{ messageId: 'onOwnLine' }],\n      options: ['line-aligned'],\n    },\n    {\n      code: `\n        const x = <App>\n              foo\n                  </App>\n      `,\n      output: `\n        const x = <App>\n              foo\n        </App>\n      `,\n      errors: [{ messageId: 'alignWithOpening' }],\n      options: ['line-aligned'],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-curly-brace-presence.js",
    "content": "/**\n * @fileoverview Enforce curly braces or disallow unnecessary curly braces in JSX\n * @author Jacky Ho\n */\n\n'use strict';\n\n/* eslint-disable quotes */ // For better readability on tests involving quotes\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-curly-brace-presence');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  sourceType: 'module',\n  ecmaVersion: 2015,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-curly-brace-presence', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: '<App {...props}>foo</App>',\n    },\n    {\n      code: '<>foo</>',\n      features: ['fragment'],\n    },\n    {\n      code: '<App {...props}>foo</App>',\n      options: [{ props: 'never' }],\n    },\n    /*\n     * There is no way to inject the space into JSX without an expression container\n     * so this format should always be allowed regardless of the `children` option.\n     */\n    {\n      code: '<App>{\\' \\'}</App>',\n    },\n    {\n      code: '<App>{\\' \\'}\\n</App>',\n    },\n    {\n      code: '<App>{\\'     \\'}</App>',\n    },\n    {\n      code: '<App>{\\'     \\'}\\n</App>',\n    },\n    {\n      code: '<App>{\\' \\'}</App>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<App>{\\'    \\'}</App>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<App>{\\' \\'}</App>',\n      options: [{ children: 'always' }],\n    },\n    {\n      code: '<App>{\\'        \\'}</App>',\n      options: [{ children: 'always' }],\n    },\n    {\n      code: '<App {...props}>foo</App>',\n      options: [{ props: 'always' }],\n    },\n    {\n      code: '<App>{`Hello ${word} World`}</App>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <React.Fragment>\n          foo{' '}\n          <span>bar</span>\n        </React.Fragment>\n      `,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <>\n          foo{' '}\n          <span>bar</span>\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<App>{`Hello \\\\n World`}</App>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<App>{`Hello ${word} World`}{`foo`}</App>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<App prop={`foo ${word} bar`}>foo</App>',\n      options: [{ props: 'never' }],\n    },\n    {\n      code: '<App prop={`foo ${word} bar`} />',\n      options: [{ props: 'never' }],\n    },\n    {\n      code: '<App>{<myApp></myApp>}</App>',\n      options: [{ children: 'always' }],\n    },\n    {\n      code: '<App>{[]}</App>',\n    },\n    {\n      code: '<App>foo</App>',\n    },\n    {\n      code: '<App>{\"foo\"}{<Component>bar</Component>}</App>',\n    },\n    {\n      code: `<App prop='bar'>foo</App>`,\n    },\n    {\n      code: '<App prop={true}>foo</App>',\n    },\n    {\n      code: '<App prop>foo</App>',\n    },\n    {\n      code: `<App prop='bar'>{'foo \\\\n bar'}</App>`,\n    },\n    {\n      code: `<App prop={ ' ' }/>`,\n    },\n    {\n      code: `<MyComponent prop='bar'>foo</MyComponent>`,\n      options: [{ props: 'never' }],\n    },\n    {\n      code: `<MyComponent prop=\"bar\">foo</MyComponent>`,\n      options: [{ props: 'never' }],\n    },\n    {\n      code: '<MyComponent>foo</MyComponent>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: '<MyComponent>{<App/>}{\"123\"}</MyComponent>',\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `<App>{\"foo 'bar' \\\\\"foo\\\\\" bar\"}</App>`,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>foo</MyComponent>`,\n      options: [{ props: 'always' }],\n    },\n    {\n      code: `<MyComponent>{'foo'}</MyComponent>`,\n      options: [{ children: 'always' }],\n    },\n    {\n      code: `<MyComponent prop={\"bar\"}>foo</MyComponent>`,\n      options: [{ props: 'always' }],\n    },\n    {\n      code: `<MyComponent>{\"foo\"}</MyComponent>`,\n      options: [{ children: 'always' }],\n    },\n    {\n      code: `<MyComponent>{'foo'}</MyComponent>`,\n      options: [{ children: 'ignore' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>foo</MyComponent>`,\n      options: [{ props: 'ignore' }],\n    },\n    {\n      code: '<MyComponent>foo</MyComponent>',\n      options: [{ children: 'ignore' }],\n    },\n    {\n      code: `<MyComponent prop='bar'>foo</MyComponent>`,\n      options: [{ props: 'ignore' }],\n    },\n    {\n      code: `<MyComponent prop=\"bar\">foo</MyComponent>`,\n      options: [{ props: 'ignore' }],\n    },\n    {\n      code: `<MyComponent prop='bar'>{'foo'}</MyComponent>`,\n      options: [{ children: 'always', props: 'never' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>foo</MyComponent>`,\n      options: [{ children: 'never', props: 'always' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>{'foo'}</MyComponent>`,\n      options: ['always'],\n    },\n    {\n      code: `<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>`,\n      options: ['always'],\n    },\n    {\n      code: `<MyComponent prop={\"bar\"} attr={'foo'} />`,\n      options: ['always'],\n    },\n    {\n      code: `<MyComponent prop=\"bar\" attr='foo' />`,\n      options: ['never'],\n    },\n    {\n      code: `<MyComponent prop='bar'>foo</MyComponent>`,\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent prop={`bar ${word} foo`}>{`foo ${word}`}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"div { margin-top: 0; }\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"<Foo />\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent prop={\"Hello \\\\u1026 world\"}>bar</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"Hello \\\\u1026 world\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent prop={\"Hello &middot; world\"}>bar</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"Hello &middot; world\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"Hello \\\\n world\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\"space after \"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{\" space before\"}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{`space after `}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: '<MyComponent>{` space before`}</MyComponent>',\n      options: ['never'],\n    },\n    {\n      code: ['<a a={\"start\\\\', '\\\\', 'end\"}/>'].join('/n'),\n      options: ['never'],\n    },\n    {\n      code: `\n        <App prop={\\`\n          a\n          b\n        \\`} />\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        <App prop={\\`\n          a\n          b\n        \\`} />\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <App>\n          {\\`\n            a\n            b\n          \\`}\n        </App>\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        <App>{\\`\n          a\n          b\n        \\`}</App>\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <MyComponent>\n          %\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <MyComponent>\n          { 'space after ' }\n          <b>foo</b>\n          { ' space before' }\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <MyComponent>\n          { \\`space after \\` }\n          <b>foo</b>\n          { \\` space before\\` }\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <MyComponent>\n          foo\n          <div>bar</div>\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n    },\n    {\n      code: `\n        <MyComponent p={<Foo>Bar</Foo>}>\n        </MyComponent>\n      `,\n    },\n    {\n      code: `\n        <MyComponent>\n          <div>\n            <p>\n              <span>\n                {\"foo\"}\n              </span>\n            </p>\n          </div>\n        </MyComponent>\n      `,\n      options: [{ children: 'always' }],\n    },\n    {\n      code: `\n        <App>\n          <Component />&nbsp;\n          &nbsp;\n        </App>\n      `,\n      options: [{ children: 'always' }],\n    },\n    {\n      code: `\n        const Component2 = () => {\n          return <span>/*</span>;\n        };\n      `,\n      features: ['no-ts-old'], // the old TS parser hangs forever on this one\n    },\n    {\n      code: `\n        const Component2 = () => {\n          return <span>/*</span>;\n        };\n      `,\n      options: [{ props: 'never', children: 'never' }],\n      features: ['no-ts-old'], // the old TS parser hangs forever on this one\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const Component = () => {\n          return <span>{\"/*\"}</span>;\n        };\n      `,\n      options: [{ props: 'never', children: 'never' }],\n      features: ['no-ts-old'], // the old TS parser hangs forever on this one\n    },\n    {\n      code: `<App>{/* comment */}</App>`,\n    },\n    (semver.satisfies(eslintPkg.version, '> 3') ? [\n      {\n        code: `<App>{/* comment */ <Foo />}</App>`,\n      },\n      {\n        code: `<App>{/* comment */ 'foo'}</App>`,\n      },\n      {\n        code: `<App prop={/* comment */ 'foo'} />`,\n      },\n      {\n        code: `\n          <App>\n            {\n              // comment\n              <Foo />\n            }\n          </App>\n        `,\n      },\n    ] : []),\n    {\n      code: `<App horror=<div /> />`,\n      features: ['no-ts'],\n    },\n    {\n      code: `<App horror={<div />} />`,\n    },\n    {\n      code: `<App horror=<div /> />`,\n      options: [{ propElementValues: 'ignore' }],\n      features: ['no-ts'],\n    },\n    {\n      code: `<App horror={<div />} />`,\n      options: [{ propElementValues: 'ignore' }],\n    },\n    {\n      code: `\n        <script>{\\`window.foo = \"bar\"\\`}</script>\n      `,\n    },\n    {\n      code: `\n        <CollapsibleTitle\n          extra={<span className=\"activity-type\">{activity.type}</span>}\n        />\n      `,\n      features: ['no-ts'],\n      options: ['never'],\n    },\n    // legit as this single template literal might be used for stringifying\n    {\n      code: '<App label={`${label}`} />',\n      options: ['never'],\n    },\n    {\n      code: '<App>{`${label}`}</App>',\n      options: ['never'],\n    }\n  )),\n\n  invalid: parsers.all([].concat(\n    {\n      code: '<App prop={`foo`} />',\n      options: [{ props: 'never' }],\n      output: '<App prop=\"foo\" />',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<App>{<myApp></myApp>}</App>',\n      options: [{ children: 'never' }],\n      output: '<App><myApp></myApp></App>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<App>{<myApp></myApp>}</App>',\n      output: '<App><myApp></myApp></App>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<App prop={`foo`}>foo</App>',\n      options: [{ props: 'never' }],\n      output: '<App prop=\"foo\">foo</App>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<App>{`foo`}</App>',\n      options: [{ children: 'never' }],\n      output: '<App>foo</App>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<>{`foo`}</>',\n      options: [{ children: 'never' }],\n      features: ['fragment'],\n      output: '<>foo</>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<MyComponent>{'foo'}</MyComponent>`,\n      output: '<MyComponent>foo</MyComponent>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>foo</MyComponent>`,\n      output: `<MyComponent prop=\"bar\">foo</MyComponent>`,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<MyComponent>{'foo'}</MyComponent>`,\n      options: [{ children: 'never' }],\n      output: '<MyComponent>foo</MyComponent>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>foo</MyComponent>`,\n      options: [{ props: 'never' }],\n      output: '<MyComponent prop=\"bar\">foo</MyComponent>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `\n        <MyComponent>\n          {'%'}\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n      output: `\n        <MyComponent>\n          %\n        </MyComponent>\n      `,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `\n        <MyComponent>\n          {'foo'}\n          <div>\n            {'bar'}\n          </div>\n          {'baz'}\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n      output: `\n        <MyComponent>\n          foo\n          <div>\n            bar\n          </div>\n          baz\n        </MyComponent>\n      `,\n      errors: [\n        { messageId: 'unnecessaryCurly' },\n        { messageId: 'unnecessaryCurly' },\n        { messageId: 'unnecessaryCurly' },\n      ],\n    },\n    {\n      code: `\n        <MyComponent>\n          {'foo'}\n          <div>\n            {'bar'}\n          </div>\n          {'baz'}\n          {'some-complicated-exp'}\n        </MyComponent>\n      `,\n      output: `\n        <MyComponent>\n          foo\n          <div>\n            bar\n          </div>\n          {'baz'}\n          {'some-complicated-exp'}\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n      features: ['no-default', 'no-ts-new', 'no-babel-new'], // TODO: FIXME: remove no-default and no-ts-new and fix\n      errors: [\n        { messageId: 'unnecessaryCurly', line: 3 },\n        { messageId: 'unnecessaryCurly', line: 5 },\n      ],\n    },\n    semver.satisfies(eslintPkg.version, '^7.5.0') ? { // require('@babel/eslint-parser/package.json').peerDependencies.eslint\n      // TODO: figure out how to make all other parsers work this well\n      code: `\n        <MyComponent>\n          {'foo'}\n          <div>\n            {'bar'}\n          </div>\n          {'baz'}\n          {'some-complicated-exp'}\n        </MyComponent>\n      `,\n      options: [{ children: 'never' }],\n      parser: parsers['@BABEL_ESLINT'],\n      parserOptions: parsers.babelParserOptions({}, new Set()),\n      output: `\n        <MyComponent>\n          foo\n          <div>\n            bar\n          </div>\n          baz\n          some-complicated-exp\n        </MyComponent>\n      `,\n      errors: [\n        { messageId: 'unnecessaryCurly', line: 3 },\n        { messageId: 'unnecessaryCurly', line: 5 },\n        { messageId: 'unnecessaryCurly', line: 7 },\n        { messageId: 'unnecessaryCurly', line: 8 },\n      ],\n    } : [],\n    {\n      code: `<MyComponent prop='bar'>foo</MyComponent>`,\n      options: [{ props: 'always' }],\n      output: '<MyComponent prop={\"bar\"}>foo</MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent prop=\"foo 'bar'\">foo</MyComponent>`,\n      options: [{ props: 'always' }],\n      output: `<MyComponent prop={\"foo 'bar'\"}>foo</MyComponent>`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent prop='foo \"bar\"'>foo</MyComponent>`,\n      options: [{ props: 'always' }],\n      output: `<MyComponent prop={\"foo \\\\\"bar\\\\\"\"}>foo</MyComponent>`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo bar </MyComponent>',\n      options: [{ children: 'always' }],\n      output: `<MyComponent>{\"foo bar \"}</MyComponent>`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent prop=\"foo 'bar' \\\\n \">foo</MyComponent>`,\n      options: [{ props: 'always' }],\n      output: `<MyComponent prop={\"foo 'bar' \\\\\\\\n \"}>foo</MyComponent>`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo bar \\\\r </MyComponent>',\n      options: [{ children: 'always' }],\n      output: '<MyComponent>{\"foo bar \\\\\\\\r \"}</MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent>foo bar 'foo'</MyComponent>`,\n      options: [{ children: 'always' }],\n      output: `<MyComponent>{\"foo bar 'foo'\"}</MyComponent>`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo bar \"foo\"</MyComponent>',\n      options: [{ children: 'always' }],\n      output: '<MyComponent>{\"foo bar \\\\\"foo\\\\\"\"}</MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo bar <App/></MyComponent>',\n      options: [{ children: 'always' }],\n      output: '<MyComponent>{\"foo bar \"}<App/></MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo \\\\n bar</MyComponent>',\n      options: [{ children: 'always' }],\n      output: '<MyComponent>{\"foo \\\\\\\\n bar\"}</MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<MyComponent>foo \\\\u1234 bar</MyComponent>',\n      options: [{ children: 'always' }],\n      output: '<MyComponent>{\"foo \\\\\\\\u1234 bar\"}</MyComponent>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent prop='foo \\\\u1234 bar' />`,\n      options: [{ props: 'always' }],\n      output: '<MyComponent prop={\"foo \\\\\\\\u1234 bar\"} />',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<MyComponent prop={'bar'}>{'foo'}</MyComponent>`,\n      options: ['never'],\n      output: '<MyComponent prop=\"bar\">foo</MyComponent>',\n      errors: [\n        { messageId: 'unnecessaryCurly' },\n        { messageId: 'unnecessaryCurly' },\n      ],\n    },\n    {\n      code: `<MyComponent prop='bar'>foo</MyComponent>`,\n      options: ['always'],\n      output: '<MyComponent prop={\"bar\"}>{\"foo\"}</MyComponent>',\n      errors: [\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n      ],\n    },\n    {\n      code: `<App prop={'foo'} attr={\" foo \"} />`,\n      options: [{ props: 'never' }],\n      output: '<App prop=\"foo\" attr=\" foo \" />',\n      errors: [\n        { messageId: 'unnecessaryCurly' },\n        { messageId: 'unnecessaryCurly' },\n      ],\n    },\n    {\n      code: `<App prop='foo' attr=\"bar\" />`,\n      options: [{ props: 'always' }],\n      output: '<App prop={\"foo\"} attr={\"bar\"} />',\n      errors: [\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n      ],\n    },\n    {\n      code: `<App prop='foo' attr={\"bar\"} />`,\n      options: [{ props: 'always' }],\n      output: `<App prop={\"foo\"} attr={\"bar\"} />`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<App prop={'foo'} attr='bar' />`,\n      options: [{ props: 'always' }],\n      output: `<App prop={'foo'} attr={\"bar\"} />`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<App prop='foo &middot; bar' />`,\n      options: [{ props: 'always' }],\n      output: `<App prop={\"foo &middot; bar\"} />`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: '<App>foo &middot; bar</App>',\n      options: [{ children: 'always' }],\n      output: '<App>{\"foo &middot; bar\"}</App>',\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<App>{'foo \"bar\"'}</App>`,\n      options: [{ children: 'never' }],\n      output: `<App>foo \"bar\"</App>`,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<App>{\"foo 'bar'\"}</App>`,\n      options: [{ children: 'never' }],\n      output: `<App>foo 'bar'</App>`,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `\n        <App prop=\"${'    '}\n           a${'     '}\n             b      c\n                d\n        \">\n          a\n              b     c${'   '}\n                 d${'      '}\n        </App>\n      `,\n      options: ['always'],\n      output: `\n        <App prop=\"${'    '}\n           a${'     '}\n             b      c\n                d\n        \">\n          {\"a\"}\n              {\"b     c   \"}\n                 {\"d      \"}\n        </App>\n      `,\n      errors: [\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n      ],\n    },\n    {\n      code: `\n        <App prop='${'    '}\n           a${'     '}\n             b      c\n                d\n        '>\n          a\n              b     c${'   '}\n                 d${'      '}\n        </App>\n      `,\n      options: ['always'],\n      output: `\n        <App prop='${'    '}\n           a${'     '}\n             b      c\n                d\n        '>\n          {\"a\"}\n              {\"b     c   \"}\n                 {\"d      \"}\n        </App>\n      `,\n      errors: [\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n      ],\n    },\n    {\n      code: `\n        <App>\n          foo bar\n          <div>foo bar foo</div>\n          <span>\n            foo bar <i>foo bar</i>\n            <strong>\n              foo bar\n            </strong>\n          </span>\n        </App>\n      `,\n      options: [{ children: 'always' }],\n      output: `\n        <App>\n          {\"foo bar\"}\n          <div>{\"foo bar foo\"}</div>\n          <span>\n            {\"foo bar \"}<i>{\"foo bar\"}</i>\n            <strong>\n              {\"foo bar\"}\n            </strong>\n          </span>\n        </App>\n      `,\n      errors: [\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n        { messageId: 'missingCurly' },\n      ],\n    },\n    {\n      code: `\n        <App>\n          &lt;Component&gt;\n          &nbsp;<Component />&nbsp;\n          &nbsp;\n        </App>\n      `,\n      options: [{ children: 'always' }],\n      output: `\n        <App>\n          &lt;{\"Component\"}&gt;\n          &nbsp;<Component />&nbsp;\n          &nbsp;\n        </App>\n      `,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `\n        <Box mb={'1rem'} />\n      `,\n      options: [{ props: 'never' }],\n      output: `\n        <Box mb=\"1rem\" />\n      `,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `\n        <Box mb={'1rem {}'} />\n      `,\n      options: ['never'],\n      output: `\n        <Box mb=\"1rem {}\" />\n      `,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<MyComponent prop={\"{ style: true }\"}>bar</MyComponent>',\n      options: ['never'],\n      output: '<MyComponent prop=\"{ style: true }\">bar</MyComponent>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: '<MyComponent prop={\"< style: true >\"}>foo</MyComponent>',\n      options: ['never'],\n      output: '<MyComponent prop=\"< style: true >\">foo</MyComponent>',\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<App horror=<div /> />`,\n      options: [{ props: 'always', children: 'always', propElementValues: 'always' }],\n      features: ['no-ts'],\n      output: `<App horror={<div />} />`,\n      errors: [{ messageId: 'missingCurly' }],\n    },\n    {\n      code: `<App horror={<div />} />`,\n      options: [{ props: 'never', children: 'never', propElementValues: 'never' }],\n      features: ['no-ts'],\n      output: `<App horror=<div /> />`,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `<Foo bar={\"'\"} />`,\n      options: [{ props: 'never', children: 'never', propElementValues: 'never' }],\n      output: `<Foo bar=\"'\" />`,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    },\n    {\n      code: `\n        <Foo help={'The maximum time range for searches. (i.e. \"P30D\" for 30 days, \"PT24H\" for 24 hours)'} />\n      `,\n      options: ['never'],\n      output: `\n        <Foo help='The maximum time range for searches. (i.e. \"P30D\" for 30 days, \"PT24H\" for 24 hours)' />\n      `,\n      errors: [{ messageId: 'unnecessaryCurly' }],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-curly-newline.js",
    "content": "/**\n * @fileoverview enforce consistent line breaks inside jsx curly\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-curly-newline');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst LEFT_MISSING_ERROR = { messageId: 'expectedAfter', type: 'Punctuator' };\nconst LEFT_UNEXPECTED_ERROR = { messageId: 'unexpectedAfter', type: 'Punctuator' };\nconst RIGHT_MISSING_ERROR = { messageId: 'expectedBefore', type: 'Punctuator' };\nconst RIGHT_UNEXPECTED_ERROR = { messageId: 'unexpectedBefore', type: 'Punctuator' };\n// const EXPECTED_BETWEEN = {messageId: 'expectedBetween', type: 'Identifier'};\n\nconst CONSISTENT = ['consistent'];\nconst NEVER = ['never'];\nconst MULTILINE_REQUIRE = [{ singleline: 'consistent', multiline: 'require' }];\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nruleTester.run('jsx-curly-newline', rule, {\n  valid: parsers.all([\n    // consistent option (default)\n    {\n      code: '<div>{foo}</div>',\n      options: ['consistent'],\n    },\n\n    {\n      code: `\n        <div>\n          {\n            foo\n          }\n        </div>\n      `,\n      options: CONSISTENT,\n    },\n\n    {\n      code: `\n        <div>\n          { foo &&\n            foo.bar }\n        </div>\n      `,\n      options: CONSISTENT,\n    },\n\n    {\n      code: `\n        <div>\n          {\n            foo &&\n            foo.bar\n          }\n        </div>\n      `,\n      options: CONSISTENT,\n    },\n\n    {\n      code: `\n        <div foo={\n          bar\n        } />\n      `,\n      options: CONSISTENT,\n    },\n\n    // {singleline: 'consistent', multiline: 'require'} option\n    {\n      code: '<div>{foo}</div>',\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: '<div foo={bar} />',\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: `\n        <div>\n          {\n            foo &&\n            foo.bar\n          }\n        </div>\n      `,\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: `\n        <div>\n          {\n            foo\n          }\n        </div>\n      `,\n      options: MULTILINE_REQUIRE,\n    },\n\n    // never option\n\n    {\n      code: '<div>{foo}</div>',\n      options: NEVER,\n    },\n\n    {\n      code: '<div foo={bar} />',\n      options: NEVER,\n    },\n\n    {\n      code: `\n        <div>\n          { foo &&\n            foo.bar }\n        </div>\n      `,\n      options: NEVER,\n    },\n  ]),\n\n  invalid: parsers.all([\n    // consistent option (default)\n    {\n      code: `\n        <div>\n          { foo \\n}\n        </div>\n      `,\n      output: `\n        <div>\n          { foo}\n        </div>\n      `,\n      options: CONSISTENT,\n      errors: [RIGHT_UNEXPECTED_ERROR],\n    },\n\n    {\n      code: `\n        <div>\n          { foo &&\n            foo.bar \\n}\n        </div>\n      `,\n      output: `\n        <div>\n          { foo &&\n            foo.bar}\n        </div>\n      `,\n      options: CONSISTENT,\n      errors: [RIGHT_UNEXPECTED_ERROR],\n    },\n    {\n      code: `\n        <div>\n          { foo &&\n            bar\n          }\n        </div>\n      `,\n      output: `\n        <div>\n          { foo &&\n            bar}\n        </div>\n      `,\n      options: CONSISTENT,\n      errors: [RIGHT_UNEXPECTED_ERROR],\n    },\n\n    // {singleline: 'consistent', multiline: 'require'} option\n    {\n      code: '<div>{foo\\n}</div>',\n      output: '<div>{foo}</div>',\n      errors: [RIGHT_UNEXPECTED_ERROR],\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: '<div>{\\nfoo}</div>',\n      output: '<div>{\\nfoo\\n}</div>',\n      errors: [RIGHT_MISSING_ERROR],\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: `\n        <div>\n          { foo &&\n            bar }\n        </div>\n      `,\n      output: `\n        <div>\n          {\\n foo &&\n            bar \\n}\n        </div>\n      `,\n      errors: [LEFT_MISSING_ERROR, RIGHT_MISSING_ERROR],\n      options: MULTILINE_REQUIRE,\n    },\n    {\n      code: `\n        <div style={foo &&\n          foo.bar\n        } />\n      `,\n      output: `\n        <div style={\\nfoo &&\n          foo.bar\n        } />\n      `,\n      errors: [LEFT_MISSING_ERROR],\n      options: MULTILINE_REQUIRE,\n    },\n\n    // never options\n    {\n      code: `\n        <div>\n          {\\nfoo\\n}\n        </div>\n      `,\n      output: `\n        <div>\n          {foo}\n        </div>\n      `,\n      options: NEVER,\n      errors: [LEFT_UNEXPECTED_ERROR, RIGHT_UNEXPECTED_ERROR],\n    },\n\n    {\n      code: `\n        <div>\n          {\n            foo &&\n            foo.bar\n          }\n        </div>\n      `,\n      output: `\n        <div>\n          {foo &&\n            foo.bar}\n        </div>\n      `,\n      options: NEVER,\n      errors: [LEFT_UNEXPECTED_ERROR, RIGHT_UNEXPECTED_ERROR],\n    },\n\n    {\n      code: `\n        <div>\n          { foo &&\n            foo.bar\n          }\n        </div>\n      `,\n      output: `\n        <div>\n          { foo &&\n            foo.bar}\n        </div>\n      `,\n      options: NEVER,\n      errors: [RIGHT_UNEXPECTED_ERROR],\n    },\n\n    {\n      code: `\n        <div>\n          { /* not fixed due to comment */\n            foo }\n        </div>\n      `,\n      output: null,\n      options: NEVER,\n      errors: [LEFT_UNEXPECTED_ERROR],\n    },\n\n    {\n      code: `\n        <div>\n          { foo\n            /* not fixed due to comment */}\n        </div>\n      `,\n      output: null,\n      options: NEVER,\n      errors: [RIGHT_UNEXPECTED_ERROR],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-curly-spacing.js",
    "content": "/**\n * @fileoverview Enforce or disallow spaces inside of curly braces in JSX attributes.\n * @author Yannick Croissant\n * @author Erik Wendel\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-curly-spacing');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-curly-spacing', rule, {\n  valid: parsers.all([\n    {\n      code: '<App foo={bar} />;',\n    },\n    {\n      code: '<App foo={bar}>{bar}</App>;',\n    },\n    {\n      code: '<App foo={bar}>{ bar }</App>;',\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        }>\n        {bar}\n        </App>;\n      `,\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }}>{{ bar: true, baz: true }}</App>;',\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }}>{ { bar: true, baz: true } }</App>;',\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        }>\n        {{ bar: true, baz: true }}\n        </App>;\n      `,\n    },\n    {\n      code: '<App>{ foo /* comment 1 */ }</App>',\n    },\n    {\n      code: '<App>{ /* comment 1 */ foo }</App>',\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ attributes: true }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: true }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: true }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ attributes: true }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ attributes: false }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: false }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: false }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ attributes: false }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ attributes: false }],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      options: [{ attributes: false }],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      options: [{ children: true }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: true }],\n    },\n    {\n      code: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: true }],\n    },\n    {\n      code: `\n        <App>{\n        { bar: true, baz: true }\n        }</App>;\n      `,\n      options: [{ children: true }],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      options: [{ children: false }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: false }],\n    },\n    {\n      code: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: false }],\n    },\n    {\n      code: `\n        <App>{\n        { bar: true, baz: true }\n        }</App>;\n      `,\n      options: [{ children: false }],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      options: [{ children: false }],\n    },\n    {\n      code: '<App>{ { bar: true, baz: true } }</App>;',\n      options: [{ children: false }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ when: 'never' }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ when: 'never', allowMultiline: false }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ when: 'never', allowMultiline: true }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ when: 'never', allowMultiline: true }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ when: 'never', spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ when: 'never', spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ when: 'always' }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ when: 'always', allowMultiline: false }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ when: 'always', allowMultiline: true }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ when: 'always', allowMultiline: true }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ when: 'always', spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ when: 'always', spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n    },\n    {\n      code: '<App foo={{ bar:baz }} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={ {bar:baz} } />;',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always', allowMultiline: true } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'never', allowMultiline: true } }],\n    },\n    {\n      code: '<App foo={bar/* comment 2 */} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', spacing: {} } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always', spacing: {} } }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: [{ attributes: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n    },\n    {\n      code: '<App>{{ bar:baz }}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: `\n        <App>{\n        { bar: true, baz: true }\n        }</App>;\n      `,\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{ {bar:baz} }</App>;',\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App>{\n        { bar: true, baz: true }\n        }</App>;\n      `,\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'always', allowMultiline: true } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'never', allowMultiline: true } }],\n    },\n    {\n      code: `\n        <App>{/* comment 3 */}</App>;\n      `,\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{bar/* comment 4 */}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', spacing: {} } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'always', spacing: {} } }],\n    },\n    {\n      code: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n    },\n    {\n      code: `\n        <App>{\n        { bar: true, baz: true }\n        }</App>;\n      `,\n      options: [{ children: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n    },\n    {\n      code: '<App {...bar} />;',\n    },\n    {\n      code: '<App {...bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always', allowMultiline: true } }],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'never', allowMultiline: true } }],\n    },\n    {\n      code: '<App {...bar/* comment 5 */} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n    },\n    {\n      code: '<App foo={{ bar:baz }} {...baz} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={ {bar:baz} } { ...baz } />;',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...bar\n        } />;\n      `,\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: '<App foo={bar/* comment 6 */} {...baz/* comment 7 */} />;',\n      options: [{ attributes: { when: 'never' } }],\n    },\n    {\n      code: '<App foo={3} bar={ {a: 2} } />',\n      options: [{ attributes: { when: 'never', spacing: { objectLiterals: 'always' } } }],\n    },\n    {\n      code: '<App>{bar/* comment 8 */}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{bar} {baz}</App>;',\n    },\n    {\n      code: '<App>{bar} {baz}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n    },\n    {\n      code: '<App>{{ bar:baz }} {baz}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{ {bar:baz} } { baz }</App>;',\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        } {\n        bar\n        }</App>;\n      `,\n      options: [{ children: { when: 'always' } }],\n    },\n    {\n      code: '<App>{bar/* comment 9 */} {baz/* comment 10 */}</App>;',\n      options: [{ children: { when: 'never' } }],\n    },\n    {\n      code: '<App>{3} { {a: 2} }</App>',\n      options: [{ children: { when: 'never', spacing: { objectLiterals: 'always' } } }],\n    },\n    {\n      code: '<App foo={ bar }>{bar}</App>',\n      options: [{ attributes: { when: 'always' } }],\n    },\n    {\n      code: `\n        <App foo={ 42 } { ...bar } baz={{ 4: 2 }}>\n        {foo} {{ bar: baz }}\n        </App>\n      `,\n      options: [\n        {\n          when: 'never',\n          attributes: { when: 'always', spacing: { objectLiterals: 'never' } },\n          children: true,\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={42} {...bar} baz={ { 4: 2 } }>\n        {foo} { { bar: baz } }\n        </App>\n      `,\n      options: [\n        {\n          when: 'never',\n          spacing: { objectLiterals: 'always' },\n          attributes: true,\n          children: { when: 'never' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={42} {...bar} baz={ { 4: 2 } }>\n        {foo} { { bar: baz } }\n        </App>\n      `,\n      options: [\n        {\n          spacing: { objectLiterals: 'always' },\n          attributes: { when: 'never', spacing: { objectLiterals: 'always' } },\n          children: { when: 'never' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      options: ['never'],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: ['never', { spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: ['always'],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: ['always', { allowMultiline: false }],\n    },\n    {\n      code: '<App foo={{ bar:baz }} />;',\n      options: ['never'],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: ['never'],\n    },\n    {\n      code: '<App foo={ {bar:baz} } />;',\n      options: ['always'],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        <App>{/* comment 11 */}</App>;\n      `,\n      options: ['never'],\n    },\n    {\n      code: '<App foo={bar/* comment 12 */} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      options: ['always', { spacing: {} }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: ['always', { spacing: {} }],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      options: ['always', { spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      options: ['always', { allowMultiline: true }],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      options: ['always', { spacing: { objectLiterals: 'never' } }],\n    },\n    {\n      code: '<App {...bar} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App { ...bar } />;',\n      options: ['always'],\n    },\n    {\n      code: '<App { ...bar } />;',\n      options: ['always', { allowMultiline: false }],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      options: ['never'],\n    },\n    {\n      code: '<App {...bar/* comment 13 */} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      options: ['always'],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      options: ['always', { allowMultiline: false }],\n    },\n    {\n      code: '<App foo={{ bar:baz }} {...baz} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={ {bar:baz} } { ...baz } />;',\n      options: ['always'],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...bar\n        }/>;\n      `,\n      options: ['always'],\n    },\n    {\n      code: '<App foo={bar/* comment 14 */} {...baz/* comment 15 */} />;',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={3} bar={ {a: 2} } />',\n      options: ['never', { spacing: { objectLiterals: 'always' } }],\n    },\n    {\n      code: '<App foo={ bar }>{bar}</App>',\n      options: ['always'],\n    },\n    {\n      code: `\n        <App>{\\`\n        text\n        \\`}</App>\n      `,\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n    },\n    {\n      code: '<>{bar} {baz}</>;',\n      features: ['fragment'],\n    },\n    {\n      code: '<div onLayout={() => { /* dummy callback to fix android bug with component measuring */ }} />',\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<App foo={ bar }>{bar}</App>;',\n      output: '<App foo={bar}>{bar}</App>;',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar }>{ bar }</App>;',\n      output: '<App foo={bar}>{ bar }</App>;',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } }>{{ bar: true, baz: true }}</App>;',\n      output: '<App foo={{ bar: true, baz: true }}>{{ bar: true, baz: true }}</App>;',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } }>{ { bar: true, baz: true } }</App>;',\n      output: '<App foo={{ bar: true, baz: true }}>{ { bar: true, baz: true } }</App>;',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      output: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<>{ bar }</>;',\n      output: '<>{bar}</>;',\n      features: ['fragment'],\n      options: [{ children: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ { bar: true, baz: true } }</App>;',\n      output: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ when: 'never' }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={bar} />;\n      `,\n      options: [{ when: 'never', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      output: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ when: 'never', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={{ bar: true, baz: true }} />;\n      `,\n      options: [{ when: 'never', allowMultiline: false, spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      output: '<App foo={ { bar: true, baz: true } } />;',\n      options: [{ when: 'never', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={ { bar: true, baz: true } } />;\n      `,\n      options: [{ when: 'never', allowMultiline: false, spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ when: 'always' }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={ bar } />;\n      `,\n      options: [{ when: 'always', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      output: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ when: 'always', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={{ bar: true, baz: true }} />;\n      `,\n      options: [{ when: 'always', allowMultiline: false, spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      output: '<App foo={ { bar: true, baz: true } } />;',\n      options: [{ when: 'always', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={ { bar: true, baz: true } } />;\n      `,\n      options: [{ when: 'always', allowMultiline: false, spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: true, when: 'never' }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={bar} />;\n      `,\n      options: [{ attributes: true, when: 'never', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      output: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: true, when: 'never', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      output: '<App foo={ { bar: true, baz: true } } />;',\n      options: [{ attributes: true, when: 'never', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: true, when: 'always' }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={ bar } />;\n      `,\n      options: [{ attributes: true, when: 'always', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          data: { token: '}' },\n          messageId: 'noNewlineBefore',\n        },\n      ],\n    },\n    {\n      code: '<App foo={ { bar: true, baz: true } } />;',\n      output: '<App foo={{ bar: true, baz: true }} />;',\n      options: [{ attributes: true, when: 'always', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={{ bar: true, baz: true }} />;',\n      output: '<App foo={ { bar: true, baz: true } } />;',\n      options: [{ attributes: true, when: 'always', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        }],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={bar} />;\n      `,\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={ bar } />;\n      `,\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={ bar } />;',\n      options: [{ attributes: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ {bar: true, baz: true} } />;',\n      output: '<App foo={{bar: true, baz: true}} />;',\n      options: [{ attributes: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: true, when: 'never' }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      output: `\n        <App>{bar}</App>;\n      `,\n      options: [{ children: true, when: 'never', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ { bar: true, baz: true } }</App>;',\n      output: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: true, when: 'never', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{{ bar: true, baz: true }}</App>;',\n      output: '<App>{ { bar: true, baz: true } }</App>;',\n      options: [{ children: true, when: 'never', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: true, when: 'always' }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      output: `\n        <App>{ bar }</App>;\n      `,\n      options: [{ children: true, when: 'always', allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ { bar: true, baz: true } }</App>;',\n      output: '<App>{{ bar: true, baz: true }}</App>;',\n      options: [{ children: true, when: 'always', spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{{ bar: true, baz: true }}</App>;',\n      output: '<App>{ { bar: true, baz: true } }</App>;',\n      options: [{ children: true, when: 'always', spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar }</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar }</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar}</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar }</App>;',\n      output: '<App>{bar}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      output: `\n        <App>{bar}</App>;\n      `,\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        }</App>;\n      `,\n      output: `\n        <App>{ bar }</App>;\n      `,\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar}</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar }</App>;',\n      output: '<App>{ bar }</App>;',\n      options: [{ children: { when: 'always', spacing: {} } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ {bar: true, baz: true} }</App>;',\n      output: '<App>{{bar: true, baz: true}}</App>;',\n      options: [{ children: { when: 'always', spacing: { objectLiterals: 'never' } } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar } />;',\n      output: '<App {...bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar } />;',\n      output: '<App {...bar} />;',\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar} />;',\n      output: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar} />;',\n      output: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar} />;',\n      output: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar } />;',\n      output: '<App { ...bar } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar} />;',\n      output: '<App {...bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar } />;',\n      output: '<App {...bar} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      output: `\n        <App {...bar} />;\n      `,\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      output: `\n        <App { ...bar } />;\n      `,\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} { ...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } {...baz } />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} { ...baz} />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } {...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: [{ attributes: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...baz\n        } />;\n      `,\n      output: `\n        <App foo={bar} {...baz} />;\n      `,\n      options: [{ attributes: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...baz\n        } />;\n      `,\n      output: `\n        <App foo={ bar } { ...baz } />;\n      `,\n      options: [{ attributes: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ 3 } bar={{a: 2}} />',\n      output: '<App foo={3} bar={ {a: 2} } />',\n      options: [{ attributes: { when: 'never', spacing: { objectLiterals: 'always' } } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ foo /* comment 16 */ } />',\n      output: '<App foo={foo /* comment 16 */} />',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={foo /* comment 17 */} />',\n      output: '<App foo={ foo /* comment 17 */ } />',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ /* comment 18 */ foo } />',\n      output: '<App foo={/* comment 18 */ foo} />',\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={/* comment 19 */ foo} />',\n      output: '<App foo={ /* comment 19 */ foo } />',\n      options: [{ attributes: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar } { baz }</App>;',\n      output: '<App>{bar} {baz}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar } { baz }</App>;',\n      output: '<App>{bar} {baz}</App>;',\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar} {baz}</App>;',\n      output: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar} {baz}</App>;',\n      output: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar} { baz}</App>;',\n      output: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar } {baz }</App>;',\n      output: '<App>{ bar } { baz }</App>;',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ bar} { baz}</App>;',\n      output: '<App>{bar} {baz}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{bar } {baz }</App>;',\n      output: '<App>{bar} {baz}</App>;',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        } {\n        baz\n        }</App>;\n      `,\n      output: `\n        <App>{bar} {baz}</App>;\n      `,\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\n        bar\n        } {\n        baz\n        }</App>;\n      `,\n      output: `\n        <App>{ bar } { baz }</App>;\n      `,\n      options: [{ children: { when: 'always', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ 3 } bar={{a: 2}}</App>',\n      output: '<App>{3} bar={ {a: 2} }</App>',\n      options: [{ children: { when: 'never', spacing: { objectLiterals: 'always' } } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{foo /* comment 20 */}</App>',\n      output: '<App>{ foo /* comment 20 */ }</App>',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{/* comment 21 */ foo}</App>',\n      output: '<App>{ /* comment 21 */ foo }</App>',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } />;',\n      output: '<App foo={bar} />;',\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={{ bar: true, baz: true }} />;\n      `,\n      options: ['never', { allowMultiline: false, spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={ { bar: true, baz: true } } />;\n      `,\n      options: ['never', { allowMultiline: false, spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={{ bar: true, baz: true }} />;\n      `,\n      options: ['always', { allowMultiline: false, spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        { bar: true, baz: true }\n        } />;\n      `,\n      output: `\n        <App foo={ { bar: true, baz: true } } />;\n      `,\n      options: ['always', { allowMultiline: false, spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={ bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={ bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={bar} />;\n      `,\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } />;\n      `,\n      output: `\n        <App foo={ bar } />;\n      `,\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} />;',\n      output: '<App foo={ bar } />;',\n      options: ['always', { spacing: {} }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} />;',\n      output: '<App foo={ bar } />;',\n      options: ['always', { spacing: {} }],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } />;',\n      output: '<App foo={ bar } />;',\n      options: ['always', { spacing: {} }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ {bar: true, baz: true} } />;',\n      output: '<App foo={{bar: true, baz: true}} />;',\n      options: ['always', { spacing: { objectLiterals: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar } />;',\n      output: '<App {...bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar } />;',\n      output: '<App {...bar} />;',\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar} />;',\n      output: '<App { ...bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar} />;',\n      output: '<App { ...bar } />;',\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar} />;',\n      output: '<App { ...bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar } />;',\n      output: '<App { ...bar } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App { ...bar} />;',\n      output: '<App {...bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App {...bar } />;',\n      output: '<App {...bar} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      output: `\n        <App {...bar} />;\n      `,\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App {\n        ...bar\n        } />;\n      `,\n      output: `\n        <App { ...bar } />;\n      `,\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar } { ...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar} {...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} { ...baz} />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } {...baz } />;',\n      output: '<App foo={ bar } { ...baz } />;',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ bar} { ...baz} />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={bar } {...baz } />;',\n      output: '<App foo={bar} {...baz} />;',\n      options: ['never'],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...baz\n        } />;\n      `,\n      output: `\n        <App foo={bar} {...baz} />;\n      `,\n      options: ['never', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={\n        bar\n        } {\n        ...baz\n        } />;\n      `,\n      output: `\n        <App foo={ bar } { ...baz } />;\n      `,\n      options: ['always', { allowMultiline: false }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={ 3 } bar={{a: 2}} />',\n      output: '<App foo={3} bar={ {a: 2} } />',\n      options: ['never', { spacing: { objectLiterals: 'always' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={foo /* comment 22 */} />',\n      output: '<App foo={ foo /* comment 22 */ } />',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App foo={/* comment 23 */ foo} />',\n      output: '<App foo={ /* comment 23 */ foo } />',\n      options: ['always'],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{/*comment24*/ }</App>',\n      output: '<App>{/*comment24*/}</App>',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: '<App>{ /*comment25*/}</App>',\n      output: '<App>{/*comment25*/}</App>',\n      options: [{ children: { when: 'never' } }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: '<App>{/*comment26*/}</App>',\n      output: '<App>{ /*comment26*/ }</App>',\n      options: [{ children: { when: 'always' } }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n        { /* comment 27 */ }\n        </App>;\n      `,\n      output: `\n        <App>\n        {/* comment 27 */}\n        </App>;\n      `,\n      options: [{ when: 'never', children: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n        {/* comment 28 */}\n        </App>;\n      `,\n      output: `\n        <App>\n        { /* comment 28 */ }\n        </App>;\n      `,\n      options: [{ when: 'always', children: true }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n        {/*comment29*/\n        }\n        </App>\n      `,\n      output: `\n        <App>\n        {/*comment29*/}\n        </App>\n      `,\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n        {\n        /*comment30*/}\n        </App>\n      `,\n      output: `\n        <App>\n        {/*comment30*/}\n        </App>\n      `,\n      options: [{ children: { when: 'never', allowMultiline: false } }],\n      errors: [\n        {\n          messageId: 'noNewlineAfter',\n          data: { token: '{' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{ /* comment 31 */\n        bar\n        } {\n        baz\n        /* comment 32 */ }</App>;\n      `,\n      output: `\n        <App>{/* comment 31 */\n        bar\n        } {\n        baz\n        /* comment 32 */}</App>;\n      `,\n      options: [{ when: 'never', children: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{/* comment 33 */\n        bar\n        } {\n        baz\n        /* comment 33 */}</App>;\n      `,\n      output: `\n        <App>{ /* comment 33 */\n        bar\n        } {\n        baz\n        /* comment 33 */ }</App>;\n      `,\n      options: [{ when: 'always', children: true }],\n      errors: [\n        {\n          messageId: 'spaceNeededAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'spaceNeededBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <div className={ this.state.renderInfo ? \"infoPanel col-xs-12\" : \"unToggled col-xs-12\" } />\n      `,\n      output: `\n        <div className={this.state.renderInfo ? \"infoPanel col-xs-12\" : \"unToggled col-xs-12\"} />\n      `,\n      options: ['never', { allowMultiline: true }],\n      errors: [\n        {\n          messageId: 'noSpaceAfter',\n          data: { token: '{' },\n        },\n        {\n          messageId: 'noSpaceBefore',\n          data: { token: '}' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-equals-spacing.js",
    "content": "/**\n * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.\n * @author ryym\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-equals-spacing');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-equals-spacing', rule, {\n  valid: parsers.all([\n    {\n      code: '<App />',\n    },\n    {\n      code: '<App foo />',\n    },\n    {\n      code: '<App foo=\"bar\" />',\n    },\n    {\n      code: '<App foo={e => bar(e)} />',\n    },\n    {\n      code: '<App {...props} />',\n    },\n    {\n      code: '<App />',\n      options: ['never'],\n    },\n    {\n      code: '<App foo />',\n      options: ['never'],\n    },\n    {\n      code: '<App foo=\"bar\" />',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={e => bar(e)} />',\n      options: ['never'],\n    },\n    {\n      code: '<App {...props} />',\n      options: ['never'],\n    },\n    {\n      code: '<App />',\n      options: ['always'],\n    },\n    {\n      code: '<App foo />',\n      options: ['always'],\n    },\n    {\n      code: '<App foo = \"bar\" />',\n      options: ['always'],\n    },\n    {\n      code: '<App foo = {e => bar(e)} />',\n      options: ['always'],\n    },\n    {\n      code: '<App {...props} />',\n      options: ['always'],\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<App foo = {bar} />',\n      output: '<App foo={bar} />',\n      errors: [\n        { messageId: 'noSpaceBefore', type: 'JSXAttribute' },\n        { messageId: 'noSpaceAfter', type: 'JSXAttribute' },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<App foo = {bar} />',\n      output: '<App foo={bar} />',\n      options: ['never'],\n      errors: [\n        { messageId: 'noSpaceBefore', type: 'JSXAttribute' },\n        { messageId: 'noSpaceAfter', type: 'JSXAttribute' },\n      ],\n    },\n    {\n      code: '<App foo ={bar} />',\n      output: '<App foo={bar} />',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceBefore', type: 'JSXAttribute' }],\n    },\n    {\n      code: '<App foo= {bar} />',\n      output: '<App foo={bar} />',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceAfter', type: 'JSXAttribute' }],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<App foo= {bar} bar = {baz} />',\n      output: '<App foo={bar} bar={baz} />',\n      options: ['never'],\n      errors: [\n        { messageId: 'noSpaceAfter', type: 'JSXAttribute' },\n        { messageId: 'noSpaceBefore', type: 'JSXAttribute' },\n        { messageId: 'noSpaceAfter', type: 'JSXAttribute' },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<App foo={bar} />',\n      output: '<App foo = {bar} />',\n      options: ['always'],\n      errors: [\n        { messageId: 'needSpaceBefore', type: 'JSXAttribute' },\n        { messageId: 'needSpaceAfter', type: 'JSXAttribute' },\n      ],\n    },\n    {\n      code: '<App foo ={bar} />',\n      output: '<App foo = {bar} />',\n      options: ['always'],\n      errors: [{ messageId: 'needSpaceAfter', type: 'JSXAttribute' }],\n    },\n    {\n      code: '<App foo= {bar} />',\n      output: '<App foo = {bar} />',\n      options: ['always'],\n      errors: [{ messageId: 'needSpaceBefore', type: 'JSXAttribute' }],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<App foo={bar} bar ={baz} />',\n      output: '<App foo = {bar} bar = {baz} />',\n      options: ['always'],\n      errors: [\n        { messageId: 'needSpaceBefore', type: 'JSXAttribute' },\n        { messageId: 'needSpaceAfter', type: 'JSXAttribute' },\n        { messageId: 'needSpaceAfter', type: 'JSXAttribute' },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-filename-extension.js",
    "content": "/**\n * @fileoverview Restrict file extensions that may contain JSX\n * @author Joe Lencioni\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-filename-extension');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Code Snippets\n// ------------------------------------------------------------------------------\n\nconst withJSXElement = 'module.exports = function MyComponent() { return <div>\\n<div />\\n</div>; }';\nconst withJSXFragment = 'module.exports = function MyComponent() { return <>\\n</>; }';\nconst withoutJSX = 'module.exports = {}';\nconst onlyComments = [\n  '// some initial comment',\n  '',\n  '/* multiline',\n  ' * comment',\n  ' */',\n].join('\\n');\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-filename-extension', rule, {\n  valid: parsers.all([\n    {\n      filename: '<text>',\n      code: withJSXElement,\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withJSXElement,\n    },\n    {\n      filename: 'MyComponent.js',\n      code: withoutJSX,\n      options: [{ allow: 'as-needed' }],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withJSXElement,\n      options: [{ allow: 'as-needed' }],\n    },\n    {\n      filename: 'MyComponent.js',\n      options: [{ extensions: ['.js', '.jsx'] }],\n      code: withJSXElement,\n    },\n    {\n      filename: 'notAComponent.js',\n      code: withoutJSX,\n    },\n    {\n      filename: '<text>',\n      code: withJSXFragment,\n      features: ['fragment'],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withJSXFragment,\n      features: ['fragment'],\n    },\n    {\n      filename: 'MyComponent.js',\n      options: [{ extensions: ['.js', '.jsx'] }],\n      code: withJSXFragment,\n      features: ['fragment'],\n    },\n    {\n      filename: 'MyComponent.js',\n      code: onlyComments,\n      options: [{ allow: 'as-needed' }],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: onlyComments,\n      options: [{ allow: 'as-needed', ignoreFilesWithoutCode: true }],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: '',\n      options: [{ allow: 'as-needed', ignoreFilesWithoutCode: true }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      filename: 'MyComponent.js',\n      code: withJSXElement,\n      errors: [\n        {\n          messageId: 'noJSXWithExtension',\n          data: { ext: '.js' },\n        },\n      ],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withoutJSX,\n      options: [{ allow: 'as-needed' }],\n      errors: [\n        {\n          messageId: 'extensionOnlyForJSX',\n          data: { ext: '.jsx' },\n        },\n      ],\n    },\n    {\n      filename: 'notAComponent.js',\n      code: withJSXElement,\n      options: [{ allow: 'as-needed' }],\n      errors: [\n        {\n          messageId: 'noJSXWithExtension',\n          data: { ext: '.js' },\n        },\n      ],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withJSXElement,\n      options: [{ extensions: ['.js'] }],\n      errors: [\n        {\n          messageId: 'noJSXWithExtension',\n          data: { ext: '.jsx' },\n        },\n      ],\n    },\n    {\n      filename: 'MyComponent.js',\n      code: withJSXFragment,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'noJSXWithExtension',\n          data: { ext: '.js' },\n        },\n      ],\n    },\n    {\n      filename: 'MyComponent.jsx',\n      code: withJSXFragment,\n      features: ['fragment'],\n      options: [{ extensions: ['.js'] }],\n      errors: [\n        {\n          messageId: 'noJSXWithExtension',\n          data: { ext: '.jsx' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-first-prop-new-line.js",
    "content": "/**\n * @fileoverview Ensure proper position of the first property in JSX\n * @author Joachim Seminck\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-first-prop-new-line');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n  jsx: true,\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-first-prop-new-line', rule, {\n  valid: parsers.all([\n    {\n      code: '<Foo />',\n      options: ['never'],\n    },\n    {\n      code: '<Foo prop=\"bar\" />',\n      options: ['never'],\n    },\n    {\n      code: '<Foo {...this.props} />',\n      options: ['never'],\n    },\n    {\n      code: '<Foo a a a />',\n      options: ['never'],\n    },\n    {\n      code: `\n        <Foo a\n          b\n        />\n      `,\n      options: ['never'],\n    },\n    {\n      code: '<Foo />',\n      options: ['multiline'],\n    },\n    {\n      code: '<Foo prop=\"one\" />',\n      options: ['multiline'],\n    },\n    {\n      code: '<Foo {...this.props} />',\n      options: ['multiline'],\n    },\n    {\n      code: '<Foo a a a />',\n      options: ['multiline'],\n    },\n    {\n      code: `\n        <Foo\n          propOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      options: ['multiline'],\n    },\n    {\n      code: `\n        <Foo\n          {...this.props}\n          propTwo=\"two\"\n        />\n      `,\n      options: ['multiline'],\n    },\n    {\n      code: `\n        <Foo bar />\n      `,\n      options: ['multiline-multiprop'],\n    },\n    {\n      code: `\n        <Foo bar baz />\n      `,\n      options: ['multiline-multiprop'],\n    },\n    {\n      code: `\n        <Foo prop={{\n        }} />\n      `,\n      options: ['multiline-multiprop'],\n    },\n    {\n      code: `\n        <Foo\n          foo={{\n          }}\n          bar\n        />\n      `,\n      options: ['multiline-multiprop'],\n    },\n    {\n      code: '<Foo />',\n      options: ['always'],\n    },\n    {\n      code: `\n        <Foo\n          propOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <Foo\n          {...this.props}\n          propTwo=\"two\"\n        />\n      `,\n      options: ['always'],\n    },\n    {\n      code: `\n        <Foo />\n      `,\n      options: ['multiprop'],\n    },\n    {\n      code: `\n        <Foo bar />\n      `,\n      options: ['multiprop'],\n    },\n    {\n      code: `\n        <Foo {...this.props} />\n      `,\n      options: ['multiprop'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <Foo propOne=\"one\" propTwo=\"two\" />\n      `,\n      output: `\n        <Foo\npropOne=\"one\" propTwo=\"two\" />\n      `,\n      options: ['always'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n    {\n      code: `\n        <Foo propOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      output: `\n        <Foo\npropOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      options: ['always'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n    {\n      code: `\n        <Foo\n          propOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      output: `\n        <Foo propOne=\"one\"\n          propTwo=\"two\"\n        />\n      `,\n      options: ['never'],\n      errors: [{ messageId: 'propOnSameLine' }],\n    },\n    {\n      code: `\n        <Foo prop={{\n        }} />\n      `,\n      output: `\n        <Foo\nprop={{\n        }} />\n      `,\n      options: ['multiline'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n    {\n      code: `\n        <Foo bar={{\n        }} baz />\n      `,\n      output: `\n        <Foo\nbar={{\n        }} baz />\n      `,\n      options: ['multiline-multiprop'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n    {\n      code: `\n      <Foo propOne=\"one\" propTwo=\"two\" />\n      `,\n      output: `\n      <Foo\npropOne=\"one\" propTwo=\"two\" />\n      `,\n      options: ['multiprop'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n    {\n      code: `\n      <Foo\nbar />\n      `,\n      output: `\n      <Foo bar />\n      `,\n      options: ['multiprop'],\n      errors: [{ messageId: 'propOnSameLine' }],\n    },\n    {\n      code: `\n      <Foo\n{...this.props} />\n      `,\n      output: `\n      <Foo {...this.props} />\n      `,\n      options: ['multiprop'],\n      errors: [{ messageId: 'propOnSameLine' }],\n    },\n    {\n      code: `\n        <DataTable<Items> fullscreen keyField=\"id\" items={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      features: ['ts', 'no-babel-old'],\n      output: `\n        <DataTable<Items>\nfullscreen keyField=\"id\" items={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      options: ['multiline'],\n      errors: [{ messageId: 'propOnNewLine' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-fragments.js",
    "content": "/**\n * @fileoverview Tests for jsx-fragments\n * @author Alex Zherdev\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-fragments');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    version: '16.2',\n    pragma: 'Act',\n    fragment: 'Frag',\n  },\n};\n\nconst settingsOld = {\n  react: {\n    version: '16.1',\n    pragma: 'Act',\n    fragment: 'Frag',\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-fragments', rule, {\n  valid: parsers.all([\n    {\n      code: '<><Foo /></>',\n      features: ['fragment', 'no-ts-old'],\n      settings,\n    },\n    {\n      code: '<Act.Frag><Foo /></Act.Frag>',\n      options: ['element'],\n      settings,\n    },\n    {\n      code: '<Act.Frag />',\n      options: ['element'],\n      settings,\n    },\n    {\n      code: `\n        import Act, { Frag as F } from 'react';\n        <F><Foo /></F>;\n      `,\n      options: ['element'],\n      settings,\n    },\n    {\n      code: `\n        const F = Act.Frag;\n        <F><Foo /></F>;\n      `,\n      options: ['element'],\n      settings,\n    },\n    {\n      code: `\n        const { Frag } = Act;\n        <Frag><Foo /></Frag>;\n      `,\n      options: ['element'],\n      settings,\n    },\n    {\n      code: `\n        const { Frag } = require('react');\n        <Frag><Foo /></Frag>;\n      `,\n      options: ['element'],\n      settings,\n    },\n    {\n      code: '<Act.Frag key=\"key\"><Foo /></Act.Frag>',\n      options: ['syntax'],\n      settings,\n    },\n    {\n      code: '<Act.Frag key=\"key\" />',\n      options: ['syntax'],\n      settings,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<><Foo /></>',\n      features: ['fragment', 'no-ts-old'],\n      settings: settingsOld,\n      errors: [\n        { messageId: 'fragmentsNotSupported' },\n      ],\n    },\n    {\n      code: '<Act.Frag><Foo /></Act.Frag>',\n      settings: settingsOld,\n      errors: [\n        { messageId: 'fragmentsNotSupported' },\n      ],\n    },\n    {\n      code: '<Act.Frag />',\n      settings: settingsOld,\n      errors: [\n        { messageId: 'fragmentsNotSupported' },\n      ],\n    },\n    {\n      code: '<><Foo /></>',\n      output: '<Act.Frag><Foo /></Act.Frag>',\n      features: ['fragment', 'no-ts-old'],\n      options: ['element'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferPragma',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: '<><Foo /></>',\n      output: null, // should get '<Act.Frag><Foo /></Act.Frag>', but the old TS parser lacks opening/closing Fragment info\n      features: ['fragment', 'no-babel', 'ts', 'no-ts-new'],\n      options: ['element'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferPragma',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: '<Act.Frag><Foo /></Act.Frag>',\n      output: '<><Foo /></>',\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: '<Act.Frag />',\n      output: '<></>',\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Act, { Frag as F } from 'react';\n        <F />;\n      `,\n      output: `\n        import Act, { Frag as F } from 'react';\n        <></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Act, { Frag as F } from 'react';\n        <F><Foo /></F>;\n      `,\n      output: `\n        import Act, { Frag as F } from 'react';\n        <><Foo /></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Act, { Frag } from 'react';\n        <Frag><Foo /></Frag>;\n      `,\n      output: `\n        import Act, { Frag } from 'react';\n        <><Foo /></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        const F = Act.Frag;\n        <F><Foo /></F>;\n      `,\n      output: `\n        const F = Act.Frag;\n        <><Foo /></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        const { Frag } = Act;\n        <Frag><Foo /></Frag>;\n      `,\n      output: `\n        const { Frag } = Act;\n        <><Foo /></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n    {\n      code: `\n        const { Frag } = require('react');\n        <Frag><Foo /></Frag>;\n      `,\n      output: `\n        const { Frag } = require('react');\n        <><Foo /></>;\n      `,\n      options: ['syntax'],\n      settings,\n      errors: [\n        {\n          messageId: 'preferFragment',\n          data: { react: 'Act', fragment: 'Frag' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-handler-names.js",
    "content": "/**\n * @fileoverview Tests for jsx-handler-names\n * @author Jake Marsh\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-handler-names');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-handler-names', rule, {\n  valid: parsers.all([\n    {\n      code: '<TestComponent onChange={this.handleChange} />',\n    },\n    {\n      // TODO: make this an invalid test\n      code: '<TestComponent onChange={this.handle123Change} />',\n    },\n    {\n      code: '<TestComponent onChange={this.props.onChange} />',\n    },\n    {\n      code: `\n        <TestComponent\n          onChange={\n            this\n              .handleChange\n          } />\n      `,\n    },\n    {\n      code: `\n        <TestComponent\n          onChange={\n            this\n              .props\n              .handleChange\n          } />\n      `,\n    },\n    {\n      code: '<TestComponent onChange={handleChange} />',\n      options: [{ checkLocalVariables: true }],\n    },\n    {\n      code: '<TestComponent onChange={takeCareOfChange} />',\n      options: [{ checkLocalVariables: false }],\n    },\n    {\n      code: '<TestComponent onChange={event => window.alert(event.target.value)} />',\n      options: [{ checkInlineFunction: false }],\n    },\n    {\n      code: '<TestComponent onChange={() => handleChange()} />',\n      options: [\n        {\n          checkInlineFunction: true,\n          checkLocalVariables: true,\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={() => this.handleChange()} />',\n      options: [{ checkInlineFunction: true }],\n    },\n    {\n      code: '<TestComponent onChange={() => 42} />',\n    },\n    {\n      code: '<TestComponent onChange={this.props.onFoo} />',\n    },\n    {\n      code: '<TestComponent isSelected={this.props.isSelected} />',\n    },\n    {\n      code: '<TestComponent shouldDisplay={this.state.shouldDisplay} />',\n    },\n    {\n      code: '<TestComponent shouldDisplay={arr[0].prop} />',\n    },\n    {\n      code: '<TestComponent onChange={props.onChange} />',\n    },\n    {\n      code: '<TestComponent ref={this.handleRef} />',\n    },\n    {\n      code: '<TestComponent ref={this.somethingRef} />',\n    },\n    {\n      code: '<TestComponent test={this.props.content} />',\n      options: [\n        {\n          eventHandlerPrefix: 'on',\n          eventHandlerPropPrefix: 'on',\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={props::handleChange} />',\n      features: ['bind operator'],\n    },\n    {\n      code: '<TestComponent onChange={::props.onChange} />',\n      features: ['bind operator'],\n    },\n    {\n      code: '<TestComponent onChange={props.foo::handleChange} />',\n      features: ['bind operator'],\n    },\n    {\n      code: '<TestComponent onChange={() => props::handleChange()} />',\n      features: ['bind operator'],\n      options: [{ checkInlineFunction: true }],\n    },\n    {\n      code: '<TestComponent onChange={() => ::props.onChange()} />',\n      features: ['bind operator'],\n      options: [{ checkInlineFunction: true }],\n    },\n    {\n      code: '<TestComponent onChange={() => props.foo::handleChange()} />',\n      features: ['bind operator'],\n      options: [{ checkInlineFunction: true }],\n    },\n    {\n      code: '<TestComponent only={this.only} />',\n    },\n    {\n      code: '<TestComponent onChange={this.someChange} />',\n      options: [\n        {\n          eventHandlerPrefix: false,\n          eventHandlerPropPrefix: 'on',\n        },\n      ],\n    },\n    {\n      code: '<TestComponent somePrefixChange={this.someChange} />',\n      options: [\n        {\n          eventHandlerPrefix: false,\n          eventHandlerPropPrefix: 'somePrefix',\n        },\n      ],\n    },\n    {\n      code: '<TestComponent someProp={this.handleChange} />',\n      options: [{ eventHandlerPropPrefix: false }],\n    },\n    {\n      code: '<TestComponent someProp={this.somePrefixChange} />',\n      options: [\n        {\n          eventHandlerPrefix: 'somePrefix',\n          eventHandlerPropPrefix: false,\n        },\n      ],\n    },\n    {\n      code: '<TestComponent someProp={props.onChange} />',\n      options: [{ eventHandlerPropPrefix: false }],\n    },\n    {\n      code: '<ComponentFromOtherLibraryBar customPropNameBar={handleSomething} />;',\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['ComponentFromOtherLibraryBar'] }],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <div>\n              <MyLibInput customPropNameBar={handleSomething} />;\n              <MyLibCheckbox customPropNameBar={handleSomething} />;\n              <MyLibButtom customPropNameBar={handleSomething} />;\n            </div>\n          )\n        }\n      `,\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLib*'] }],\n    },\n    {\n      code: '<A.TestComponent customPropNameBar={handleSomething} />',\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['A.TestComponent'] }],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <div>\n              <A.MyLibInput customPropNameBar={handleSomething} />;\n              <A.MyLibCheckbox customPropNameBar={handleSomething} />;\n              <A.MyLibButtom customPropNameBar={handleSomething} />;\n            </div>\n          )\n        }\n      `,\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['A.MyLib*'] }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<TestComponent onChange={this.doSomethingOnChange} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.handlerChange} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.handle} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.handle2} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.handl3Change} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.handle4change} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={takeCareOfChange} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n      options: [{ checkLocalVariables: true }],\n    },\n    {\n      code: '<TestComponent onChange={() => this.takeCareOfChange()} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n      options: [{ checkInlineFunction: true }],\n    },\n    {\n      code: '<TestComponent only={this.handleChange} />',\n      errors: [\n        { message: 'Prop key for handleChange must begin with \\'on\\'' },\n      ],\n    },\n    {\n      code: '<TestComponent2 only={this.handleChange} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'on' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent handleChange={this.handleChange} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'on' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent whenChange={handleChange} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'on' },\n        },\n      ],\n      options: [{ checkLocalVariables: true }],\n    },\n    {\n      code: '<TestComponent whenChange={() => handleChange()} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'on' },\n        },\n      ],\n      options: [\n        {\n          checkInlineFunction: true,\n          checkLocalVariables: true,\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={handleChange} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'when' },\n        },\n      ],\n      options: [\n        {\n          checkLocalVariables: true,\n          eventHandlerPrefix: 'handle',\n          eventHandlerPropPrefix: 'when',\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={() => handleChange()} />',\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleChange', handlerPropPrefix: 'when' },\n        },\n      ],\n      options: [\n        {\n          checkInlineFunction: true,\n          checkLocalVariables: true,\n          eventHandlerPrefix: 'handle',\n          eventHandlerPropPrefix: 'when',\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={this.onChange} />',\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={props::onChange} />',\n      features: ['bind operator'],\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: '<TestComponent onChange={props.foo::onChange} />',\n      features: ['bind operator'],\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <div>\n              <MyLibInput customPropNameBar={handleInput} />;\n              <MyLibCheckbox customPropNameBar={handleCheckbox} />;\n              <MyLibButtom customPropNameBar={handleButton} />;\n            </div>\n          )\n        }\n      `,\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLibrary*'] }],\n      errors: [\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleInput', handlerPropPrefix: 'on' },\n        },\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleCheckbox', handlerPropPrefix: 'on' },\n        },\n        {\n          messageId: 'badPropKey',\n          data: { propValue: 'handleButton', handlerPropPrefix: 'on' },\n        },\n      ],\n    },\n    {\n      code: '<A.TestComponent onChange={onChange} />',\n      options: [{ checkLocalVariables: true, ignoreComponentNames: ['B.TestComponent', 'TestComponent', 'Test*'] }],\n      errors: [\n        {\n          messageId: 'badHandlerName',\n          data: { propKey: 'onChange', handlerPrefix: 'handle' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-indent-props.js",
    "content": "/**\n * @fileoverview Validate props indentation in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-indent-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-indent-props', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <App foo\n        />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        const Test = () => ([\n          (x\n            ? <div key=\"1\" />\n            : <div key=\"2\" />),\n          <div\n            key=\"3\"\n            align=\"left\"\n          />,\n          <div\n            key=\"4\"\n            align=\"left\"\n          />,\n        ]);\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        <App\n        foo\n        />\n      `,\n      options: [0],\n    },\n    {\n      code: `\n          <App\n        foo\n          />\n      `,\n      options: [-2],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: ['tab'],\n    },\n    {\n      code: `\n        <App/>\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <App aaa\n             b\n             cc\n        />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <App   aaa\n               b\n               cc\n        />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        const test = <App aaa\n                          b\n                          cc\n                     />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <App aaa x\n             b y\n             cc\n        />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        const test = <App aaa x\n                          b y\n                          cc\n                     />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <App aaa\n             b\n        >\n            <Child c\n                   d/>\n        </App>\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <Fragment>\n          <App aaa\n               b\n               cc\n          />\n          <OtherApp a\n                    bbb\n                    c\n          />\n        </Fragment>\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        <App\n          a\n          b\n        />\n      `,\n      options: ['first'],\n    },\n    {\n      code: `\n        {this.props.ignoreTernaryOperatorFalse\n          ? <span\n              className=\"value\"\n              some={{aaa}}\n            />\n          : null}\n      `,\n      output: `\n        {this.props.ignoreTernaryOperatorFalse\n          ? <span\n            className=\"value\"\n            some={{aaa}}\n          />\n          : null}\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: false,\n        },\n      ],\n    },\n    {\n      code: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n            id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: false,\n        },\n      ],\n    },\n    {\n      code: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n            id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: true,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      options: [\n        {\n          indentMode: 'tab',\n          ignoreTernaryOperator: false,\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      options: [\n        {\n          indentMode: 'tab',\n          ignoreTernaryOperator: true,\n        },\n      ],\n    },\n    {\n      code: `\n        {this.props.ignoreTernaryOperatorTrue\n          ? <span\n            className=\"value\"\n            some={{aaa}}\n            />\n          : null}\n      `,\n      output: `\n        {this.props.ignoreTernaryOperatorTrue\n          ? <span\n            className=\"value\"\n            some={{aaa}}\n          />\n          : null}\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: true,\n        },\n      ],\n    },\n    {\n      code: `\n        <a\n          role={'button'}\n          className={\\`navbar-burger \\${open ? 'is-active' : ''}\\`}\n          href={'#'}\n          aria-label={'menu'}\n          aria-expanded={false}\n          onClick={openMenu}>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n        </a>\n      `,\n      options: [{ indentMode: 2 }],\n    },\n    {\n      code: `\n        <a role={'button'}\n           className={\\`navbar-burger \\${open ? 'is-active' : ''}\\`}\n           href={'#'}\n           aria-label={'menu'}\n           aria-expanded={false}\n           onClick={openMenu}>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n        </a>\n      `,\n      options: ['first'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App\n          foo\n        />\n      `,\n      output: `\n        <App\n            foo\n        />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n            foo\n        />\n      `,\n      output: `\n        <App\n          foo\n        />\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const test = true\n          ? <span\n            attr=\"value\"\n            />\n          : <span\n            attr=\"otherValue\"\n            />\n      `,\n      output: `\n        const test = true\n          ? <span\n              attr=\"value\"\n            />\n          : <span\n              attr=\"otherValue\"\n            />\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const test = true\n          ? <span attr=\"value\" />\n          : (\n            <span\n                attr=\"otherValue\"\n            />\n          )\n      `,\n      output: `\n        const test = true\n          ? <span attr=\"value\" />\n          : (\n            <span\n              attr=\"otherValue\"\n            />\n          )\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 16,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        {test.isLoading\n          ? <Value/>\n          : <OtherValue\n            some={aaa}/>\n        }\n      `,\n      output: `\n        {test.isLoading\n          ? <Value/>\n          : <OtherValue\n              some={aaa}/>\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        {test.isLoading\n          ? <Value/>\n          : <OtherValue\n            some={aaa}\n            other={bbb}/>\n        }\n      `,\n      output: `\n        {test.isLoading\n          ? <Value/>\n          : <OtherValue\n              some={aaa}\n              other={bbb}/>\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        {this.props.test\n          ? <span\n            className=\"value\"\n            some={{aaa}}\n            />\n          : null}\n      `,\n      output: `\n        {this.props.test\n          ? <span\n              className=\"value\"\n              some={{aaa}}\n            />\n          : null}\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App1\n            foo\n        />\n      `,\n      output: `\n        <App1\n\\tfoo\n        />\n      `,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 1,\n            type: 'tab',\n            characters: 'character',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App\n\\t\\t\\t\\t\\tfoo\n\\t\\t\\t\\t/>\n\\t\\t\\t`,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 5,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 7,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App a\n          b\n        />\n      `,\n      output: `\n        <App a\n             b\n        />\n      `,\n      options: ['first'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 13,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App  a\n           b\n        />\n      `,\n      output: `\n        <App  a\n              b\n        />\n      `,\n      options: ['first'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n              a\n           b\n        />\n      `,\n      output: `\n        <App\n              a\n              b\n        />\n      `,\n      options: ['first'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 14,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          a\n         b\n           c\n        />\n      `,\n      output: `\n        <App\n          a\n          b\n          c\n        />\n      `,\n      options: ['first'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 9,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n              id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      output: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n            id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: false,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 14,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n              id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      output: `\n        const F = () => {\n          const foo = true\n            ? <div id=\"id\">test</div>\n            : false;\n\n          return <div\n            id=\"id\"\n          >\n            test\n          </div>\n        }\n      `,\n      options: [\n        {\n          indentMode: 2,\n          ignoreTernaryOperator: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 14,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      output: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      options: [\n        {\n          indentMode: 'tab',\n          ignoreTernaryOperator: false,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 6,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 7,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      output: `\n\\t\\t\\t\\tconst F = () => {\n\\t\\t\\t\\t\\tconst foo = true\n\\t\\t\\t\\t\\t\\t? <div id=\"id\">test</div>\n\\t\\t\\t\\t\\t\\t: false;\n\n\\t\\t\\t\\t\\treturn <div\n\\t\\t\\t\\t\\t\\tid=\"id\"\n\\t\\t\\t\\t\\t>\n\\t\\t\\t\\t\\t\\ttest\n\\t\\t\\t\\t\\t</div>\n\\t\\t\\t\\t}\n`,\n      options: [\n        {\n          indentMode: 'tab',\n          ignoreTernaryOperator: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 6,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 7,\n          },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-indent.js",
    "content": "/**\n * @fileoverview Validate JSX indentation\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintVersion = require('eslint/package.json').version;\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-indent');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-indent', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <App></App>\n      `,\n    },\n    {\n      code: `\n        <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <App>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <>\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <App>\n          <Foo />\n        </App>\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        <App>\n          <></>\n        </App>\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        <>\n          <Foo />\n        </>\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        <App>\n        <Foo />\n        </App>\n      `,\n      options: [0],\n    },\n    {\n      code: `\n          <App>\n        <Foo />\n          </App>\n      `,\n      options: [-2],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App>\n\\t\\t\\t\\t\\t<Foo />\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      options: ['tab'],\n    },\n    {\n      code: `\n        function App() {\n          return <App>\n            <Foo />\n          </App>;\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        function App() {\n          return <App>\n            <></>\n          </App>;\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        function App() {\n          return (<App>\n            <Foo />\n          </App>);\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        function App() {\n          return (<App>\n            <></>\n          </App>);\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <App>\n              <Foo />\n            </App>\n          );\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <App>\n              <></>\n            </App>\n          );\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        it(\n          (\n            <div>\n              <span />\n            </div>\n          )\n        )\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        it(\n          (\n            <div>\n              <></>\n            </div>\n          )\n        )\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        it(\n          (<div>\n            <span />\n            <span />\n            <span />\n          </div>)\n        )\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        (\n          <div>\n            <span />\n          </div>\n        )\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        {\n          head.title &&\n          <h1>\n            {head.title}\n          </h1>\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        {\n          head.title &&\n          <>\n            {head.title}\n          </>\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        {\n          head.title &&\n            <h1>\n              {head.title}\n            </h1>\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        {\n          head.title && (\n          <h1>\n            {head.title}\n          </h1>)\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        {\n          head.title && (\n            <h1>\n              {head.title}\n            </h1>\n          )\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        [\n          <div />,\n          <div />\n        ]\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        [\n          <></>,\n          <></>\n        ]\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        <div>\n            {\n                [\n                    <Foo />,\n                    <Bar />\n                ]\n            }\n        </div>\n      `,\n    },\n    {\n      code: `\n        <div>\n            {foo &&\n                [\n                    <Foo />,\n                    <Bar />\n                ]\n            }\n        </div>\n      `,\n    },\n    {\n      code: `\n        <div>\n            {foo &&\n                [\n                    <></>,\n                    <></>\n                ]\n            }\n        </div>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <div>\n            bar <div>\n                bar\n                bar {foo}\n                bar </div>\n        </div>\n      `,\n    },\n    {\n      code: `\n        <>\n            bar <>\n                bar\n                bar {foo}\n                bar </>\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression)\n      code: `\n        foo ?\n            <Foo /> :\n            <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></> :\n            <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the start of the second expression)\n      code: `\n        foo ?\n            <Foo />\n            : <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></>\n            : <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line)\n      code: `\n        foo ?\n            <Foo />\n        :\n            <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></>\n        :\n            <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (multiline JSX, colon on its own line)\n      code: `\n        {!foo ?\n            <Foo\n                onClick={this.onClick}\n            />\n        :\n            <Bar\n                onClick={this.onClick}\n            />\n        }\n      `,\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the end of the first expression)\n      code: `\n        foo ? <Foo /> :\n        <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? <></> :\n        <></>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the start of the second expression)\n      code: `\n        foo ? <Foo />\n        : <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? <></>\n        : <></>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon on its own line)\n      code: `\n        foo ? <Foo />\n        :\n        <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? <></>\n        :\n        <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, parenthesized first expression)\n      code: `\n        foo ? (\n            <Foo />\n        ) :\n            <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        ) :\n            <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the start of the second expression, parenthesized first expression)\n      code: `\n        foo ? (\n            <Foo />\n        )\n            : <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        )\n            : <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, parenthesized first expression)\n      code: `\n        foo ? (\n            <Foo />\n        )\n        :\n            <Bar />\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        )\n        :\n            <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo /> : (\n                <Bar />\n            )\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></> : (\n                <></>\n            )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo />\n        : (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></>\n        : (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon indented on its own line, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo />\n            : (\n                <Bar />\n            )\n      `,\n    },\n    {\n      code: `\n        foo ?\n            <></>\n            : (\n                <></>\n            )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, both expression parenthesized)\n      code: `\n        foo ? (\n            <Foo />\n        ) : (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        ) : (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, both expression parenthesized)\n      code: `\n        foo ? (\n            <Foo />\n        )\n        : (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        )\n        : (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, both expression parenthesized)\n      code: `\n        foo ? (\n            <Foo />\n        )\n        :\n        (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ? (\n            <></>\n        )\n        :\n        (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the end of the first expression, parenthesized second expression)\n      code: `\n        foo ? <Foo /> : (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ? <></> : (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the start of the second expression, parenthesized second expression)\n      code: `\n        foo ? <Foo />\n        : (<Bar />)\n      `,\n    },\n    {\n      code: `\n        foo ? <></>\n        : (<></>)\n      `,\n      features: ['fragment'],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon on its own line, parenthesized second expression)\n      code: `\n        foo ? <Foo />\n        : (\n            <Bar />\n        )\n      `,\n    },\n    {\n      code: `\n        foo ? <></>\n        : (\n            <></>\n        )\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <span>\n          {condition ?\n            <Thing\n              foo={\\`bar\\`}\n            /> :\n            <Thing/>\n          }\n        </span>\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        <span>\n          {condition ?\n            <Thing\n              foo={\"bar\"}\n            /> :\n            <Thing/>\n          }\n        </span>\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        function foo() {\n          <span>\n            {condition ?\n              <Thing\n                foo={superFoo}\n              /> :\n              <Thing/>\n            }\n          </span>\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        function foo() {\n          <span>\n            {condition ?\n              <Thing\n                foo={superFoo}\n              /> :\n              <></>\n            }\n          </span>\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                const num = rollDice();\n                <Thing num={num} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                const num = rollDice();\n                <Thing num={num} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                const purposeOfLife = getPurposeOfLife();\n                if (purposeOfLife == 42) {\n                    <Thing />;\n                } else {\n                    <AnotherThing />;\n                }\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                const purposeOfLife = getPurposeOfLife();\n                if (purposeOfLife == 42) {\n                    <Thing />;\n                } else {\n                    <AnotherThing />;\n                }\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                <Thing num={rollDice()} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                <Thing num={rollDice()} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                <Thing num={rollDice()} />;\n                <Thing num={rollDice()} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                <Thing num={rollDice()} />;\n                <Thing num={rollDice()} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                const purposeOfLife = 42;\n                <Thing num={purposeOfLife} />;\n                <Thing num={purposeOfLife} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                const purposeOfLife = 42;\n                <Thing num={purposeOfLife} />;\n                <Thing num={purposeOfLife} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n    },\n    {\n      code: `\n        class Test extends React.Component {\n          render() {\n            return (\n              <div>\n                <div />\n                <div />\n              </div>\n            );\n          }\n        }\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        class Test extends React.Component {\n          render() {\n            return (\n              <>\n                <></>\n                <></>\n              </>\n            );\n          }\n        }\n      `,\n      features: ['fragment'],\n      options: [2],\n    },\n    {\n      code: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n        )}\n          />\n        );\n      `,\n      output: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n            )}\n          />\n        );\n      `,\n      options: [2],\n    },\n    {\n      code: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n)}\n\\t/>\n);\n    `,\n      output: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n\\t\\t)}\n\\t/>\n);\n    `,\n      options: ['tab'],\n    },\n    {\n      code: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n        )}\n          />\n        );\n      `,\n      output: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n            )}\n          />\n        );\n      `,\n      options: [2, { checkAttributes: false }],\n    },\n    {\n      code: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n)}\n\\t/>\n);\n    `,\n      output: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n\\t\\t)}\n\\t/>\n);\n    `,\n      options: ['tab', { checkAttributes: false }],\n    },\n    {\n      code: `\n        function Foo() {\n          return (\n            <input\n              type=\"radio\"\n              defaultChecked\n            />\n          );\n        }\n      `,\n      options: [2, { checkAttributes: true }],\n    },\n    {\n      code: `\n        function Foo() {\n          return (\n            <div>\n              {condition && (\n                <p>Bar</p>\n              )}\n            </div>\n          );\n        }\n      `,\n      options: [2, { indentLogicalExpressions: true }],\n    },\n    {\n      code: `\n        <App>\n            text\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n            text\n            text\n            text\n        </App>\n      `,\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App>\n\\t\\t\\t\\t\\ttext\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      options: ['tab'],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App>\n\\t\\t\\t\\t\\t{undefined}\n\\t\\t\\t\\t\\t{null}\n\\t\\t\\t\\t\\t{true}\n\\t\\t\\t\\t\\t{false}\n\\t\\t\\t\\t\\t{42}\n\\t\\t\\t\\t\\t{NaN}\n\\t\\t\\t\\t\\t{\"foo\"}\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      options: ['tab'],\n    },\n    {\n    // don't check literals not within JSX. See #2563\n      code: `\n        function foo() {\n          const a = \\`aa\\`;\n          const b = \\`b\\nb\\`;\n        }\n      `,\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <App />\n          );\n        }\n      `,\n      options: [2],\n      parserOptions,\n    },\n    {\n      code: `\n        function App() {\n          return <App>\n            <Foo />\n          </App>;\n        }\n      `,\n      options: [2],\n      parserOptions,\n    },\n    {\n      code: `\n        const myFunction = () => (\n          [\n            <Tag\n              {...properties}\n            />,\n            <Tag\n              {...properties}\n            />,\n            <Tag\n              {...properties}\n            />,\n          ]\n        )\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        const Item = ({ id, name, onSelect }) => <div onClick={onSelect}>\n          {id}: {name}\n        </div>;\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        type Props = {\n          email: string,\n          password: string,\n          error: string,\n        }\n\n        const SomeFormComponent = ({\n          email,\n          password,\n          error,\n        }: Props) => (\n          // JSX\n        );\n      `,\n      features: ['flow'].concat(semver.satisfies(eslintVersion, '< 8') ? 'no-babel-old' : []),\n    },\n    {\n      code: `\n        <a role={'button'}\n          className={\\`navbar-burger \\${open ? 'is-active' : ''}\\`}\n          href={'#'}\n          aria-label={'menu'}\n          aria-expanded={false}\n          onClick={openMenu}>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n          <span aria-hidden={'true'}/>\n        </a>\n      `,\n      options: [2],\n    },\n    {\n      code: `\n        export default class App extends React.Component {\n          state = {\n            name: '',\n          }\n\n          componentDidMount() {\n            this.fetchName()\n              .then(name => {\n                this.setState({name})\n              });\n          }\n\n          fetchName = () => {\n            const url = 'https://api.github.com/users/job13er'\n            return fetch(url)\n              .then(resp => resp.json())\n              .then(json => json.name)\n          }\n\n          render() {\n            const {name} = this.state\n            return (\n              <h1>Hello, {name}</h1>\n            )\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [2],\n    },\n    {\n      code: `\n        function test (foo) {\n          return foo != null\n            ? Math.max(0, Math.min(1, 10))\n            : 0\n        }\n      `,\n      options: [99],\n    },\n    {\n      code: `\n        function test (foo) {\n          return foo != null\n            ? <div>foo</div>\n            : <div>bar</div>\n        }\n      `,\n      options: [2],\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        <div>\n        bar <div>\n           bar\n           bar {foo}\n           bar </div>\n        </div>\n      `,\n      output: `\n        <div>\n            bar <div>\n            bar\n            bar {foo}\n            bar </div>\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <Foo />\n        </App>\n      `,\n      output: `\n        <App>\n            <Foo />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <></>\n        </App>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        <App>\n            <></>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <>\n          <Foo />\n        </>\n      `,\n      features: ['fragment'],\n      output: `\n        <>\n            <Foo />\n        </>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n            <Foo />\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo />\n        </App>\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n            <Foo />\n        </App>\n      `,\n      output: `\n        <App>\n\\t<Foo />\n        </App>\n      `,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 1,\n            type: 'tab',\n            characters: 'character',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return <App>\n            <Foo />\n                 </App>;\n        }\n      `,\n      output: `\n        function App() {\n          return <App>\n            <Foo />\n          </App>;\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          line: 3,\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 17,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          line: 5,\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 17,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return (<App>\n            <Foo />\n            </App>);\n        }\n      `,\n      output: `\n        function App() {\n          return (<App>\n            <Foo />\n          </App>);\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          line: 3,\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          line: 5,\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return (\n        <App>\n          <Foo />\n        </App>\n          );\n        }\n      `,\n      // The detection logic only thinks <App> is indented wrong, not the other\n      // two lines following. I *think* because it incorrectly uses <App>'s indention\n      // as the baseline for the next two, instead of the realizing the entire three\n      // lines are wrong together. See #608\n      output: `\n        function App() {\n          return (\n            <App>\n          <Foo />\n        </App>\n          );\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n           {test}\n        </App>\n      `,\n      output: `\n        <App>\n            {test}\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 11,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n            {options.map((option, index) => (\n                <option key={index} value={option.key}>\n                   {option.name}\n                </option>\n            ))}\n        </App>\n      `,\n      output: `\n        <App>\n            {options.map((option, index) => (\n                <option key={index} value={option.key}>\n                    {option.name}\n                </option>\n            ))}\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 20,\n            type: 'space',\n            characters: 'characters',\n            gotten: 19,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n        {test}\n        </App>\n      `,\n      output: `\n        <App>\n\\t{test}\n        </App>\n      `,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 1,\n            type: 'tab',\n            characters: 'character',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App>\n\\t\\t\\t\\t\\t{options.map((option, index) => (\n\\t\\t\\t\\t\\t\\t<option key={index} value={option.key}>\n\\t\\t\\t\\t\\t\\t{option.name}\n\\t\\t\\t\\t\\t\\t</option>\n\\t\\t\\t\\t\\t))}\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App>\n\\t\\t\\t\\t\\t{options.map((option, index) => (\n\\t\\t\\t\\t\\t\\t<option key={index} value={option.key}>\n\\t\\t\\t\\t\\t\\t\\t{option.name}\n\\t\\t\\t\\t\\t\\t</option>\n\\t\\t\\t\\t\\t))}\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 7,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 6,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n\\t\\t\\t\\t<App>\\n\n\\t\\t\\t\\t<Foo />\\n\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      output: `\n\\t\\t\\t\\t<App>\\n\n\\t\\t\\t\\t\\t<Foo />\\n\n\\t\\t\\t\\t</App>\n\\t\\t\\t`,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 5,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 4,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        [\n          <div />,\n            <div />\n        ]\n      `,\n      output: `\n        [\n          <div />,\n          <div />\n        ]\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        [\n          <div />,\n            <></>\n        ]\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        [\n          <div />,\n          <></>\n        ]\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n\n         <Foo />\n\n        </App>\n      `,\n      output: `\n        <App>\n\n\\t<Foo />\n\n        </App>\n      `,\n      options: ['tab'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 1,\n            type: 'tab',\n            characters: 'character',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n\n        \\t<Foo />\n\n        </App>\n      `,\n      output: `\n        <App>\n\n          <Foo />\n\n        </App>\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div>\n            {\n                [\n                    <Foo />,\n                <Bar />\n                ]\n            }\n        </div>\n      `,\n      output: `\n        <div>\n            {\n                [\n                    <Foo />,\n                    <Bar />\n                ]\n            }\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 20,\n            type: 'space',\n            characters: 'characters',\n            gotten: 16,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div>\n            {foo &&\n                [\n                    <Foo />,\n                <Bar />\n                ]\n            }\n        </div>\n      `,\n      output: `\n        <div>\n            {foo &&\n                [\n                    <Foo />,\n                    <Bar />\n                ]\n            }\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 20,\n            type: 'space',\n            characters: 'characters',\n            gotten: 16,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression)\n      code: `\n        foo ?\n            <Foo /> :\n        <Bar />\n      `,\n      output: `\n        foo ?\n            <Foo /> :\n            <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ?\n            <Foo /> :\n        <></>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ?\n            <Foo /> :\n            <></>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line)\n      code: `\n        foo ?\n            <Foo />\n        :\n        <Bar />\n      `,\n      output: `\n        foo ?\n            <Foo />\n        :\n            <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the end of the first expression)\n      code: `\n        foo ? <Foo /> :\n            <Bar />\n      `,\n      output: `\n        foo ? <Foo /> :\n        <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 8,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ?\n            <Foo />\n        :\n        <></>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ?\n            <Foo />\n        :\n            <></>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon on its own line)\n      code: `\n        foo ? <Foo />\n        :\n              <Bar />\n      `,\n      output: `\n        foo ? <Foo />\n        :\n        <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 8,\n            type: 'space',\n            characters: 'characters',\n            gotten: 14,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, parenthesized first expression)\n      code: `\n        foo ? (\n            <Foo />\n        ) :\n        <Bar />\n      `,\n      output: `\n        foo ? (\n            <Foo />\n        ) :\n            <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ? (\n            <Foo />\n        ) :\n        <></>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ? (\n            <Foo />\n        ) :\n            <></>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, parenthesized first expression)\n      code: `\n        foo ? (\n            <Foo />\n        )\n        :\n        <Bar />\n      `,\n      output: `\n        foo ? (\n            <Foo />\n        )\n        :\n            <Bar />\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo /> : (\n            <Bar />\n            )\n      `,\n      output: `\n        foo ?\n            <Foo /> : (\n                <Bar />\n            )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ?\n            <Foo /> : (\n            <></>\n            )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ?\n            <Foo /> : (\n                <></>\n            )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo />\n        : (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ?\n            <Foo />\n        : (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon indented on its own line, parenthesized second expression)\n      code: `\n        foo ?\n            <Foo />\n            : (\n            <Bar />\n            )\n      `,\n      output: `\n        foo ?\n            <Foo />\n            : (\n                <Bar />\n            )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ?\n            <Foo />\n            : (\n            <></>\n            )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ?\n            <Foo />\n            : (\n                <></>\n            )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon at the end of the first expression, both expression parenthesized)\n      code: `\n        foo ? (\n        <Foo />\n        ) : (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ? (\n            <Foo />\n        ) : (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ? (\n        <></>\n        ) : (\n        <></>\n        )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ? (\n            <></>\n        ) : (\n            <></>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, both expression parenthesized)\n      code: `\n        foo ? (\n        <Foo />\n        )\n        : (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ? (\n            <Foo />\n        )\n        : (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (colon on its own line, both expression parenthesized)\n      code: `\n        foo ? (\n        <Foo />\n        )\n        :\n        (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ? (\n            <Foo />\n        )\n        :\n        (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ? (\n        <></>\n        )\n        :\n        (\n        <></>\n        )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ? (\n            <></>\n        )\n        :\n        (\n            <></>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n    // Multiline ternary\n    // (first expression on test line, colon at the end of the first expression, parenthesized second expression)\n      code: `\n        foo ? <Foo /> : (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ? <Foo /> : (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ? <Foo /> : (\n        <></>\n        )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ? <Foo /> : (\n            <></>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      // Multiline ternary\n      // (first expression on test line, colon on its own line, parenthesized second expression)\n      code: `\n        foo ? <Foo />\n        : (\n        <Bar />\n        )\n      `,\n      output: `\n        foo ? <Foo />\n        : (\n            <Bar />\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        foo ? <Foo />\n        : (\n        <></>\n        )\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      output: `\n        foo ? <Foo />\n        : (\n            <></>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <p>\n            <div>\n                <SelfClosingTag />Text\n          </div>\n        </p>\n      `,\n      output: `\n        <p>\n            <div>\n                <SelfClosingTag />Text\n            </div>\n        </p>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n        )}\n          />\n        );\n      `,\n      output: `\n        const Component = () => (\n          <View\n            ListFooterComponent={(\n              <View\n                rowSpan={3}\n                placeholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n              />\n            )}\n          />\n        );\n      `,\n      options: [2, { checkAttributes: true }],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n)}\n\\t/>\n);\n    `,\n      output: `\nconst Component = () => (\n\\t<View\n\\t\\tListFooterComponent={(\n\\t\\t\\t<View\n\\t\\t\\t\\trowSpan={3}\n\\t\\t\\t\\tplaceholder=\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\"\n\\t\\t\\t/>\n\\t\\t)}\n\\t/>\n);\n    `,\n      options: ['tab', { checkAttributes: true }],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 2,\n            type: 'tab',\n            characters: 'characters',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo() {\n          return (\n            <div>\n              {condition && (\n              <p>Bar</p>\n              )}\n            </div>\n          );\n        }\n      `,\n      output: `\n        function Foo() {\n          return (\n            <div>\n              {condition && (\n                <p>Bar</p>\n              )}\n            </div>\n          );\n        }\n      `,\n      options: [2, { indentLogicalExpressions: true }],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 14,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <span>\n            {do {\n                const num = rollDice();\n                    <Thing num={num} />;\n            }}\n        </span>\n      `,\n      output: `\n        <span>\n            {do {\n                const num = rollDice();\n                <Thing num={num} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 20,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n                const num = rollDice();\n                    <Thing num={num} />;\n            })}\n        </span>\n      `,\n      output: `\n        <span>\n            {(do {\n                const num = rollDice();\n                <Thing num={num} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 20,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <span>\n            {do {\n            <Thing num={getPurposeOfLife()} />;\n            }}\n        </span>\n      `,\n      features: ['do expressions'],\n      output: `\n        <span>\n            {do {\n                <Thing num={getPurposeOfLife()} />;\n            }}\n        </span>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <span>\n            {(do {\n            <Thing num={getPurposeOfLife()} />;\n            })}\n        </span>\n      `,\n      output: `\n        <span>\n            {(do {\n                <Thing num={getPurposeOfLife()} />;\n            })}\n        </span>\n      `,\n      features: ['do expressions'],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 16,\n            type: 'space',\n            characters: 'characters',\n            gotten: 12,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div>\n        text\n        </div>\n      `,\n      output: `\n        <div>\n            text\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: `\n        <div>\n          text\n        text\n        </div>\n      `,\n      output: `\n        <div>\n            text\n            text\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: `\n        <div>\n        \\t  text\n          \\t  text\n        </div>\n      `,\n      output: `\n        <div>\n            text\n            text\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 10,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div>\n        \\t\\ttext\n        </div>\n      `,\n      options: ['tab'],\n      output: `\n        <div>\n\\ttext\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 1,\n            type: 'tab',\n            characters: 'character',\n            gotten: 0,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <>\n        aaa\n        </>\n      `,\n      features: ['fragment'],\n      output: `\n        <>\n            aaa\n        </>\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const StatelessComponent = () => {\n          if (new Date() % 2) {\n              return (\n        <div>Hello</div>\n              );\n          }\n          return null;\n        };\n      `,\n      output: `\n        const StatelessComponent = () => {\n          if (new Date() % 2) {\n              return (\n                  <div>Hello</div>\n              );\n          }\n          return null;\n        };\n      `,\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 18,\n            gotten: 8,\n            type: 'space',\n            characters: 'characters',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <App />\n            );\n        }\n      `,\n      output: `\n        function App() {\n          return (\n            <App />\n          );\n        }\n      `,\n      options: [2],\n      parserOptions,\n      errors: [{ message: 'Expected indentation of 10 space characters but found 12.' }],\n    },\n    {\n      code: `\n        function App() {\n          return (\n            <App />\n        );\n        }\n      `,\n      output: `\n        function App() {\n          return (\n            <App />\n          );\n        }\n      `,\n      options: [2],\n      parserOptions,\n      errors: [{ message: 'Expected indentation of 10 space characters but found 8.' }],\n    },\n    {\n      code: `\n        {condition && [\n            <Tag key=\"a\" onClick={() => {\n              // some code\n            }} />,\n            <Tag key=\"b\" onClick={() => {\n              // some code\n            }} />,\n          ]\n        }\n      `,\n      output: `\n        {condition && [\n          <Tag key=\"a\" onClick={() => {\n              // some code\n            }} />,\n          <Tag key=\"b\" onClick={() => {\n              // some code\n            }} />,\n          ]\n        }\n      `,\n      options: [2],\n      errors: [\n        {\n          message: 'Expected indentation of 10 space characters but found 12.',\n          line: 3,\n        },\n        {\n          message: 'Expected indentation of 10 space characters but found 12.',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const IndexPage = () => (\n          <h1>\n        {\"Hi people\"}\n        <button/>\n        </h1>\n        );\n      `,\n      output: `\n        const IndexPage = () => (\n          <h1>\n            {\"Hi people\"}\n            <button/>\n          </h1>\n        );\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    // Would be nice to handle in one pass, but multipass works fine.\n    {\n      code: `\n        const IndexPage = () => (\n          <h1>\n        Hi people\n        <button/>\n        </h1>\n        );\n      `,\n\n      output: `\n        const IndexPage = () => (\n          <h1>\n            Hi people\n        <button/>\n          </h1>\n        );\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 10,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        const IndexPage = () => (\n          <h1>\n            Hi people\n        <button/>\n          </h1>\n        );\n      `,\n\n      output: `\n        const IndexPage = () => (\n          <h1>\n            Hi people\n            <button/>\n          </h1>\n        );\n      `,\n      options: [2],\n      errors: [\n        {\n          messageId: 'wrongIndent',\n          data: {\n            needed: 12,\n            type: 'space',\n            characters: 'characters',\n            gotten: 8,\n          },\n        },\n      ],\n    },\n    semver.satisfies(eslintVersion, '> 4') ? {\n      code: `\n        import React from 'react';\n\n        export default function () {\n            return (\n                <div>\n                            Test1\n\n                      <p>Test2</p>\n                </div>\n            );\n        }\n      `,\n      // TODO: remove two spaces from the Test2 output line\n      output: `\n        import React from 'react';\n\n        export default function () {\n            return (\n                <div>\n                    Test1\n\n                      <p>Test2</p>\n                </div>\n            );\n        }\n      `,\n      options: [4],\n      errors: [\n        { messageId: 'wrongIndent', line: 6 },\n        { messageId: 'wrongIndent', line: 9 },\n      ],\n    } : []\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-key.js",
    "content": "/**\n * @fileoverview Report missing `key` props in iterators/collection literals.\n * @author Ben Mosher\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-key');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    pragma: 'Act',\n    fragment: 'Frag',\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-key', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        [1, 2, 3].map((item) => {\n         return item === 'bar' ? <div key={item}>{item}</div> : <span key={item}>{item}</span>;\n        })`,\n    },\n    { code: 'fn()' },\n    { code: '[1, 2, 3].map(function () {})' },\n    { code: '<App />;' },\n    { code: '[<App key={0} />, <App key={1} />];' },\n    { code: '[1, 2, 3].map(function(x) { return <App key={x} /> });' },\n    { code: '[1, 2, 3].map(x => <App key={x} />);' },\n    { code: '[1, 2 ,3].map(x => x && <App x={x} key={x} />);' },\n    { code: '[1, 2 ,3].map(x => x ? <App x={x} key=\"1\" /> : <OtherApp x={x} key=\"2\" />);' },\n    { code: '[1, 2, 3].map(x => { return <App key={x} /> });' },\n    { code: 'Array.from([1, 2, 3], function(x) { return <App key={x} /> });' },\n    { code: 'Array.from([1, 2, 3], (x => <App key={x} />));' },\n    { code: 'Array.from([1, 2, 3], (x => {return <App key={x} />}));' },\n    { code: 'Array.from([1, 2, 3], someFn);' },\n    { code: 'Array.from([1, 2, 3]);' },\n    { code: '[1, 2, 3].foo(x => <App />);' },\n    { code: 'var App = () => <div />;' },\n    { code: '[1, 2, 3].map(function(x) { return; });' },\n    { code: 'foo(() => <div />);' },\n    {\n      code: 'foo(() => <></>);',\n      features: ['fragment'],\n    },\n    {\n      code: '<></>;',\n      features: ['fragment'],\n    },\n    {\n      code: '<App {...{}} />;',\n    },\n    {\n      code: '<App key=\"keyBeforeSpread\" {...{}} />;',\n      options: [{ checkKeyMustBeforeSpread: true }],\n    },\n    {\n      code: '<div key=\"keyBeforeSpread\" {...{}} />;',\n      options: [{ checkKeyMustBeforeSpread: true }],\n    },\n    {\n      code: `\n        const spans = [\n          <span key=\"notunique\"/>,\n          <span key=\"notunique\"/>,\n        ];\n      `,\n    },\n    {\n      code: `\n        function Component(props) {\n          return hasPayment ? (\n            <div className=\"stuff\">\n              <BookingDetailSomething {...props} />\n              {props.modal && props.calculatedPrice && (\n                <SomeOtherThing items={props.something} discount={props.discount} />\n              )}\n            </div>\n          ) : null;\n        }\n      `,\n    },\n    {\n      code: `\n        import React, { FC, useRef, useState } from 'react';\n\n        import './ResourceVideo.sass';\n        import VimeoVideoPlayInModal from '../vimeoVideoPlayInModal/VimeoVideoPlayInModal';\n\n        type Props = {\n          videoUrl: string;\n          videoTitle: string;\n        };\n        const ResourceVideo: FC<Props> = ({\n          videoUrl,\n          videoTitle,\n        }: Props): JSX.Element => {\n          return (\n            <div className=\"resource-video\">\n              <VimeoVideoPlayInModal videoUrl={videoUrl} />\n              <h3>{videoTitle}</h3>\n            </div>\n          );\n        };\n\n        export default ResourceVideo;\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        // testrule.jsx\n        const trackLink = () => {};\n        const getAnalyticsUiElement = () => {};\n\n        const onTextButtonClick = (e, item) => trackLink([, getAnalyticsUiElement(item), item.name], e);\n      `,\n    },\n    {\n      code: `\n        function Component({ allRatings }) {\n          return (\n            <RatingDetailsStyles>\n              {Object.entries(allRatings)?.map(([key, value], index) => {\n                const rate = value?.split(/(?=[%, /])/);\n\n                if (!rate) return null;\n\n                return (\n                  <li key={\\`\\${entertainment.tmdbId}\\${index}\\`}>\n                    <img src={\\`/assets/rating/\\${key}.png\\`} />\n                    <span className=\"rating-details--rate\">{rate?.[0]}</span>\n                    <span className=\"rating-details--rate-suffix\">{rate?.[1]}</span>\n                  </li>\n                );\n              })}\n            </RatingDetailsStyles>\n          );\n        }\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        const baz = foo?.bar?.()?.[1] ?? 'qux';\n\n        qux()?.map()\n\n        const directiveRanges = comments?.map(tryParseTSDirective)\n      `,\n      features: ['optional chaining', 'nullish coalescing'],\n    },\n    {\n      code: `\n        import { observable } from \"mobx\";\n\n        export interface ClusterFrameInfo {\n          frameId: number;\n          processId: number;\n        }\n\n        export const clusterFrameMap = observable.map<string, ClusterFrameInfo>();\n      `,\n      features: ['types', 'no-babel-old'],\n    },\n    { code: 'React.Children.toArray([1, 2 ,3].map(x => <App />));' },\n    {\n      code: `\n        import { Children } from \"react\";\n        Children.toArray([1, 2 ,3].map(x => <App />));\n      `,\n    },\n    {\n      // TODO: uncomment the commented lines below\n      code: `\n        import Act from 'react';\n        import { Children as ReactChildren } from 'react';\n\n        const { Children } = Act;\n        const { toArray } = Children;\n\n        Act.Children.toArray([1, 2 ,3].map(x => <App />));\n        Act.Children.toArray(Array.from([1, 2 ,3], x => <App />));\n        Children.toArray([1, 2 ,3].map(x => <App />));\n        Children.toArray(Array.from([1, 2 ,3], x => <App />));\n        // ReactChildren.toArray([1, 2 ,3].map(x => <App />));\n        // ReactChildren.toArray(Array.from([1, 2 ,3], x => <App />));\n        // toArray([1, 2 ,3].map(x => <App />));\n        // toArray(Array.from([1, 2 ,3], x => <App />));\n      `,\n      settings,\n    },\n    { code: '[1, 2, 3].map(x => { return x && <App key={x} />; });' },\n    { code: '[1, 2, 3].map(x => { return x && y && <App key={x} />; });' },\n    { code: '[1, 2, 3].map(x => { return x && foo(); });' },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        [1, 2, 3].map((item) => {\n          return item === 'bar' ? <div>{item}</div> : <span>{item}</span>;\n        })`,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        [1, 2, 3].map(function(item) {\n          return item === 'bar' ? <div>{item}</div> : <span>{item}</span>;\n        })`,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        Array.from([1, 2, 3], (item) => {\n          return item === 'bar' ? <div>{item}</div> : <span>{item}</span>;\n        })`,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        import { Fragment } from 'react';\n\n        const ITEMS = ['bar', 'foo'];\n\n        export default function BugIssue() {\n          return (\n            <Fragment>\n              {ITEMS.map((item) => {\n                return item === 'bar' ? <div>{item}</div> : <span>{item}</span>;\n              })}\n            </Fragment>\n          );\n        }\n      `,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: '[<App />];',\n      errors: [{ messageId: 'missingArrayKey' }],\n    },\n    {\n      code: '[<App {...key} />];',\n      errors: [{ messageId: 'missingArrayKey' }],\n    },\n    {\n      code: '[<App key={0}/>, <App />];',\n      errors: [{ messageId: 'missingArrayKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(function(x) { return <App /> });',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(x => <App />);',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(x => x && <App x={x} />);',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(x => x ? <App x={x} key=\"1\" /> : <OtherApp x={x} />);',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(x => x ? <App x={x} /> : <OtherApp x={x} key=\"2\" />);',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2 ,3].map(x => { return <App /> });',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: 'Array.from([1, 2 ,3], function(x) { return <App /> });',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: 'Array.from([1, 2 ,3], (x => { return <App /> }));',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: 'Array.from([1, 2 ,3], (x => <App />));',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2, 3]?.map(x => <BabelEslintApp />)',\n      features: ['no-default'],\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2, 3]?.map(x => <TypescriptEslintApp />)',\n      features: ['ts'],\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2, 3].map(x => <>{x}</>);',\n      features: ['fragment'],\n      options: [{ checkFragmentShorthand: true }],\n      settings,\n      errors: [\n        {\n          messageId: 'missingIterKeyUsePrag',\n          data: {\n            reactPrag: 'Act',\n            fragPrag: 'Frag',\n          },\n        },\n      ],\n    },\n    {\n      code: '[<></>];',\n      features: ['fragment'],\n      options: [{ checkFragmentShorthand: true }],\n      settings,\n      errors: [\n        {\n          messageId: 'missingArrayKeyUsePrag',\n          data: {\n            reactPrag: 'Act',\n            fragPrag: 'Frag',\n          },\n        },\n      ],\n    },\n    {\n      code: '[<App {...obj} key=\"keyAfterSpread\" />];',\n      options: [{ checkKeyMustBeforeSpread: true }],\n      settings,\n      errors: [{ messageId: 'keyBeforeSpread' }],\n    },\n    {\n      code: '[<div {...obj} key=\"keyAfterSpread\" />];',\n      options: [{ checkKeyMustBeforeSpread: true }],\n      settings,\n      errors: [{ messageId: 'keyBeforeSpread' }],\n    },\n    {\n      code: `\n        const spans = [\n          <span key=\"notunique\"/>,\n          <span key=\"notunique\"/>,\n        ];\n      `,\n      options: [{ warnOnDuplicates: true }],\n      errors: [\n        { messageId: 'nonUniqueKeys', line: 3 },\n        { messageId: 'nonUniqueKeys', line: 4 },\n      ],\n    },\n    {\n      code: `\n        const div = (\n          <div>\n            <span key=\"notunique\"/>\n            <span key=\"notunique\"/>\n          </div>\n        );\n      `,\n      options: [{ warnOnDuplicates: true }],\n      errors: [\n        { messageId: 'nonUniqueKeys', line: 4 },\n        { messageId: 'nonUniqueKeys', line: 5 },\n      ],\n    },\n    {\n      code: `\n        const Test = () => {\n          const list = [1, 2, 3, 4, 5];\n\n          return (\n            <div>\n              {list.map(item => {\n                if (item < 2) {\n                  return <div>{item}</div>;\n                }\n\n                return <div />;\n              })}\n            </div>\n          );\n        };\n      `,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        const TestO = () => {\n          const list = [1, 2, 3, 4, 5];\n\n          return (\n            <div>\n              {list.map(item => {\n                if (item < 2) {\n                  return <div>{item}</div>;\n                } else if (item < 5) {\n                  return <div></div>\n                }  else {\n                  return <div></div>\n                }\n\n                return <div />;\n              })}\n            </div>\n          );\n        };\n      `,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        const TestCase = () => {\n          const list = [1, 2, 3, 4, 5];\n\n          return (\n            <div>\n              {list.map(item => {\n                if (item < 2) return <div>{item}</div>;\n                else if (item < 5) return <div />;\n                else return <div />;\n              })}\n            </div>\n          );\n        };\n      `,\n      errors: [\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n        { messageId: 'missingIterKey' },\n      ],\n    },\n    {\n      code: `\n        const TestCase = () => {\n          const list = [1, 2, 3, 4, 5];\n\n          return (\n            <div>\n              {list.map(x => <div {...spread} key={x} />)}\n            </div>\n          );\n        };\n      `,\n      options: [{ checkKeyMustBeforeSpread: true }],\n      errors: [{ messageId: 'keyBeforeSpread' }],\n    },\n    {\n      code: '[1, 2, 3].map(x => { return x && <App />; });',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n    {\n      code: '[1, 2, 3].map(x => { return x || y || <App />; });',\n      errors: [{ messageId: 'missingIterKey' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-max-depth.js",
    "content": "/**\n * @fileoverview Validate JSX maximum depth\n * @author Chris<wfsr@foxmail.com>\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-max-depth');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  sourceType: 'module',\n  ecmaVersion: 2015,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-max-depth', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <App />\n      `,\n    },\n    {\n      code: `\n        <App>\n          <foo />\n        </App>\n      `,\n      options: [{ max: 1 }],\n    },\n    {\n      code: `\n        <App>\n          <foo>\n            <bar />\n          </foo>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <foo>\n            <bar />\n          </foo>\n        </App>\n      `,\n      options: [{ max: 2 }],\n    },\n    {\n      code: `\n        const x = <div><em>x</em></div>;\n        <div>{x}</div>\n      `,\n      options: [{ max: 2 }],\n    },\n    {\n      code: 'const foo = (x) => <div><em>{x}</em></div>;',\n      options: [{ max: 2 }],\n    },\n    {\n      code: `\n        <></>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>\n          <foo />\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ max: 1 }],\n    },\n    {\n      code: `\n        const x = <><em>x</em></>;\n        <>{x}</>\n      `,\n      features: ['fragment'],\n      options: [{ max: 2 }],\n    },\n    {\n      code: `\n        const x = (\n          <tr>\n            <td>1</td>\n            <td>2</td>\n          </tr>\n        );\n        <tbody>\n          {x}\n        </tbody>\n      `,\n      options: [{ max: 2 }],\n    },\n    {\n      code: `\n        const Example = props => {\n          for (let i = 0; i < length; i++) {\n            return <Text key={i} />;\n          }\n        };\n      `,\n      options: [{ max: 1 }],\n    },\n    {\n      code: `\n        export function MyComponent() {\n          const A = <React.Fragment>{<div />}</React.Fragment>;\n          return <div>{A}</div>;\n        }\n      `,\n    },\n    {\n    // Validates circular references don't get rule stuck\n      code: `\n        function Component() {\n          let first = \"\";\n          const second = first;\n          first = second;\n          return <div id={first} />;\n        };\n      `,\n    },\n    {\n    // Validates circular references are checked at multiple levels\n      code: `\n        function Component() {\n          let first = \"\";\n          let second = \"\";\n          let third = \"\";\n          let fourth = \"\";\n          const fifth = first;\n          first = second;\n          second = third;\n          third = fourth;\n          fourth = fifth;\n          return <div id={first} />;\n        };\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App>\n          <foo />\n        </App>\n      `,\n      options: [{ max: 0 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 0, found: 1 },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <foo>{bar}</foo>\n        </App>\n      `,\n      options: [{ max: 0 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 0, found: 1 },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>\n          <foo>\n            <bar />\n          </foo>\n        </App>\n      `,\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        const x = <div><span /></div>;\n        <div>{x}</div>\n      `,\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        const x = <div><span /></div>;\n        let y = x;\n        <div>{y}</div>\n      `,\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        const x = <div><span /></div>;\n        let y = x;\n        <div>{x}-{y}</div>\n      `,\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        <div>\n        {<div><div><span /></div></div>}\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 2, found: 3 },\n        },\n      ],\n    },\n    {\n      code: `\n        <>\n          <foo />\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ max: 0 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 0, found: 1 },\n        },\n      ],\n    },\n    {\n      code: `\n        <>\n          <>\n            <bar />\n          </>\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        const x = <><span /></>;\n        let y = x;\n        <>{x}-{y}</>\n      `,\n      features: ['fragment'],\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        const x = (\n          <tr>\n            <td>1</td>\n            <td>2</td>\n          </tr>\n        );\n        <tbody>\n          {x}\n        </tbody>\n      `,\n      options: [{ max: 1 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 1, found: 2 },\n        },\n      ],\n    },\n    {\n      code: `\n        <div className=\"custom_modal\">\n          <Modal className={classes.modal} open={isOpen} closeAfterTransition>\n            <Fade in={isOpen}>\n              <DialogContent>\n                <Icon icon=\"cancel\" onClick={onClose} popoverText=\"Close Modal\" />\n                <div className=\"modal_content\">{children}</div>\n                <div className={clxs('modal_buttons', classes.buttons)}>\n                  <Button className=\"modal_buttons--cancel\" onClick={onCancel}>\n                    {cancelMsg ? cancelMsg : 'Cancel'}\n                  </Button>\n                </div>\n              </DialogContent>\n            </Fade>\n          </Modal>\n        </div>\n      `,\n      options: [{ max: 4 }],\n      errors: [\n        {\n          messageId: 'wrongDepth',\n          data: { needed: 4, found: 5 },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-max-props-per-line.js",
    "content": "/**\n * @fileoverview Limit maximum of props on a single line in JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-max-props-per-line');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-max-props-per-line', rule, {\n  valid: parsers.all([\n    {\n      code: '<App />',\n    },\n    {\n      code: '<App foo />',\n    },\n    {\n      code: '<App foo bar />',\n      options: [{ maximum: 2 }],\n    },\n    {\n      code: '<App foo bar />',\n      options: [{ when: 'multiline' }],\n    },\n    {\n      code: '<App foo {...this.props} />',\n      options: [{ when: 'multiline' }],\n    },\n    {\n      code: '<App foo bar baz />',\n      options: [{ maximum: 2, when: 'multiline' }],\n    },\n    {\n      code: '<App {...this.props} bar />',\n      options: [{ maximum: 2 }],\n    },\n    {\n      code: `\n        <App\n          foo\n          bar\n        />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo bar\n          baz\n        />\n      `,\n      options: [{ maximum: 2 }],\n    },\n    {\n      code: `\n        <App\n          foo bar\n          baz\n        />\n      `,\n      options: [{ maximum: { multi: 2 } }],\n    },\n    {\n      code: `\n        <App\n          bar\n          baz\n        />\n      `,\n      options: [{ maximum: { multi: 2, single: 1 } }],\n    },\n    {\n      code: '<App foo baz bar />',\n      options: [{ maximum: { multi: 2, single: 3 } }],\n    },\n    {\n      code: '<App {...this.props} bar />',\n      options: [{ maximum: { single: 2 } }],\n    },\n    {\n      code: `\n        <App\n          foo bar\n          baz bor\n        />\n      `,\n      options: [{ maximum: { multi: 2, single: 1 } }],\n    },\n    {\n      code: '<App foo baz bar />',\n      options: [{ maximum: { multi: 2 } }],\n    },\n    {\n      code: `\n        <App\n          foo bar\n          baz bor\n        />\n      `,\n      options: [{ maximum: { single: 1 } }],\n    },\n    {\n      code: `\n        <App foo bar\n          baz bor\n        />\n      `,\n      options: [{ maximum: { single: 2, multi: 2 } }],\n    },\n    {\n      code: `\n        <App foo bar\n          baz bor\n        />\n      `,\n      options: [{ maximum: 2 }],\n    },\n    {\n      code: `\n        <App foo\n          bar\n        />\n      `,\n      options: [{ maximum: 1, when: 'multiline' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App foo bar baz />;\n      `,\n      output: `\n        <App foo\nbar\nbaz />;\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App foo bar baz />;\n      `,\n      output: `\n        <App foo bar\nbaz />;\n      `,\n      options: [{ maximum: 2 }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App {...this.props} bar />;\n      `,\n      output: `\n        <App {...this.props}\nbar />;\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App bar {...this.props} />;\n      `,\n      output: `\n        <App bar\n{...this.props} />;\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'this.props' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n          foo bar\n          baz\n        />\n      `,\n      output: `\n        <App\n          foo\nbar\n          baz\n        />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n          foo {...this.props}\n          baz\n        />\n      `,\n      output: `\n        <App\n          foo\n{...this.props}\n          baz\n        />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'this.props' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n          foo={{\n          }} bar\n        />\n      `,\n      output: `\n        <App\n          foo={{\n          }}\nbar\n        />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App foo={{\n        }} bar />\n      `,\n      output: `\n        <App foo={{\n        }}\nbar />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App foo bar={{\n        }} baz />\n      `,\n      output: `\n        <App foo bar={{\n        }}\nbaz />\n      `,\n      options: [{ maximum: 2 }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo={{\n        }} {...rest} />\n      `,\n      output: `\n        <App foo={{\n        }}\n{...rest} />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'rest' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App {\n          ...this.props\n        } bar />\n      `,\n      output: `\n        <App {\n          ...this.props\n        }\nbar />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App {\n          ...this.props\n        } {\n          ...rest\n        } />\n      `,\n      output: `\n        <App {\n          ...this.props\n        }\n{\n          ...rest\n        } />\n      `,\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'rest' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n          foo={{\n          }} bar baz bor\n        />\n      `,\n      output: `\n        <App\n          foo={{\n          }} bar\nbaz bor\n        />\n      `,\n      options: [{ maximum: 2 }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo bar baz />\n      `,\n      output: `\n        <App foo\nbar\nbaz />\n      `,\n      options: [{ maximum: { single: 1, multi: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo bar baz\n        />\n      `,\n      output: `\n        <App\n          foo\nbar\nbaz\n        />\n      `,\n      options: [{ maximum: { single: 1, multi: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo\n          bar baz\n        />\n      `,\n      output: `\n        <App foo\n          bar\nbaz\n        />\n      `,\n      options: [{ maximum: { single: 1, multi: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo bar\n          bar baz bor\n        />\n      `,\n      output: `\n        <App foo bar\n          bar baz\nbor\n        />\n      `,\n      options: [{ maximum: { single: 1, multi: 2 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bor' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo bar baz bor />\n      `,\n      output: `\n        <App foo bar baz\nbor />\n      `,\n      options: [{ maximum: { single: 3, multi: 2 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'bor' },\n        }],\n    },\n    {\n      code: `\n        <App\n          foo={{\n          }} bar baz bor\n        />\n      `,\n      output: `\n        <App\n          foo={{\n          }} bar\nbaz bor\n        />\n      `,\n      options: [{ maximum: { multi: 2 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App boz fuz\n          foo={{\n          }} bar baz bor\n        />\n      `,\n      output: `\n        <App boz fuz\n          foo={{\n          }} bar\nbaz bor\n        />\n      `,\n      options: [{ maximum: { multi: 2, single: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <DataTable<Items> fullscreen keyField=\"id\" items={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      features: ['ts', 'no-babel-old'],\n      output: `\n        <DataTable<Items> fullscreen\nkeyField=\"id\"\nitems={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      options: [{ maximum: { multi: 1, single: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'keyField' },\n        },\n      ],\n    },\n    {\n      code: `\n        <DataTable<Items>\nfullscreen keyField=\"id\" items={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      features: ['ts', 'no-babel-old'],\n      output: `\n        <DataTable<Items>\nfullscreen\nkeyField=\"id\"\nitems={items}\n          activeSortableColumn={sorting}\n          onSortClick={handleSortedClick}\n          rowActions={[\n          ]}\n        />\n      `,\n      options: [{ maximum: { multi: 1, single: 1 } }],\n      errors: [\n        {\n          messageId: 'newLine',\n          data: { prop: 'keyField' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-newline.js",
    "content": "/**\n * @fileoverview Require or prevent a new line after jsx elements and expressions\n * @author Johnny Zabala\n * @author Joseph Stiles\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-newline');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nnew RuleTester({ parserOptions }).run('jsx-newline', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n\n          <List />\n\n          <Button>\n            <IconPreview />\n            Button 2\n\n            <span></span>\n          </Button>\n\n          {showSomething === true && <Something />}\n\n          <Button>Button 3</Button>\n\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n    },\n    {\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n          <List />\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n          {showSomething === true && <Something />}\n          <Button>Button 3</Button>\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      options: [{ prevent: true }],\n    },\n    {\n      code: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n\n          <span>Should be in new line</span>\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n          <span>Should be in new line</span>\n        </>\n      `,\n      options: [{ prevent: true }],\n      features: ['fragment'],\n    },\n    {\n      code: `\n        {/* fake-eslint-disable-next-line react/forbid-component-props */}\n        <Button popoverOpen='#settings-popover' style={{ width: 'fit-content' }}>\n          <Icon f7='gear' />\n        </Button>\n      `,\n    },\n    {\n      code: `\n        <Button popoverOpen='#settings-popover' style={{ width: 'fit-content' }}>\n          {/* fake-eslint-disable-next-line should also work inside a component */}\n          <Icon f7='gear' />\n        </Button>\n      `,\n    },\n    {\n      code: `\n        <Button popoverOpen='#settings-popover' style={{ width: 'fit-content' }}>\n          {/* should work inside a component */}\n          {/* and it should work when using multiple comments */}\n          <Icon f7='gear' />\n        </Button>\n      `,\n    },\n    {\n      code: `\n        <Button popoverOpen='#settings-popover' style={{ width: 'fit-content' }}>\n          {/* this is a multiline\n              block comment */}\n          <Icon f7='gear' />\n        </Button>\n      `,\n    },\n    {\n      code: `\n        <>\n          {/* does this */}\n          <Icon f7='gear' />\n\n          {/* also work with multiple components and inside a fragment? */}\n          <OneLineComponent />\n        </>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>\n          <OneLineComponent />\n          <AnotherOneLineComponent prop={prop} />\n\n          <MultilineComponent\n            prop1={prop1}\n            prop2={prop2}\n          />\n\n          <OneLineComponent />\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n    {\n      code: `\n        <div>\n          {/* this does not have a newline */}\n          <Icon f7='gear' />\n          {/* neither does this */}\n          <OneLineComponent />\n\n          {/* but this one needs one */}\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n        </div>\n      `,\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n    {\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n          <List />\n\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n\n          {showSomething === true && <Something />}\n          <Button>Button 3</Button>\n\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n\n        </div>\n      `,\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n          <List />\n        </div>\n      `,\n      output: `\n        <div>\n          <Button>{data.label}</Button>\n\n          <List />\n        </div>\n      `,\n      errors: [{\n        messageId: 'require',\n      }],\n    },\n    {\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n          {showSomething === true && <Something />}\n        </div>\n      `,\n      output: `\n        <div>\n          <Button>{data.label}</Button>\n\n          {showSomething === true && <Something />}\n        </div>\n      `,\n      errors: [{ messageId: 'require' }],\n    },\n    {\n      code: `\n        <div>\n          {showSomething === true && <Something />}\n          <Button>{data.label}</Button>\n        </div>\n      `,\n      output: `\n        <div>\n          {showSomething === true && <Something />}\n\n          <Button>{data.label}</Button>\n        </div>\n      `,\n      errors: [{ messageId: 'require' }],\n    },\n    {\n      code: `\n        <div>\n          {showSomething === true && <Something />}\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      output: `\n        <div>\n          {showSomething === true && <Something />}\n\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      errors: [{ messageId: 'require' }],\n    },\n    {\n      code: `\n        <div>\n          {/* This should however still not work*/}\n          <Icon f7='gear' />\n\n          <OneLineComponent />\n          {/* Comments between components still need a newLine */}\n          <OneLineComponent />\n        </div>\n      `,\n      output: `\n        <div>\n          {/* This should however still not work*/}\n          <Icon f7='gear' />\n\n          <OneLineComponent />\n\n          {/* Comments between components still need a newLine */}\n          <OneLineComponent />\n        </div>\n      `,\n      errors: [{ messageId: 'require' }],\n    },\n    {\n      code: `\n        <div>\n          {/* this does not have a newline */}\n          <Icon f7='gear' />\n          {/* neither does this */}\n          <OneLineComponent />\n          {/* but this one needs one */}\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n        </div>\n      `,\n      output: `\n        <div>\n          {/* this does not have a newline */}\n          <Icon f7='gear' />\n          {/* neither does this */}\n          <OneLineComponent />\n\n          {/* but this one needs one */}\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n        </div>\n      `,\n      options: [{ prevent: true, allowMultilines: true }],\n      errors: [{ messageId: 'allowMultilines' }],\n    },\n    {\n      code: `\n        <div>\n          {/* this does not have a newline */}\n          <Icon f7='gear' />\n          {/* neither does this */}\n          <OneLineComponent />\n          {/* Multiline */}\n          {/* Block comments */}\n          {/* Stick to MultilineComponent */}\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n        </div>\n      `,\n      output: `\n        <div>\n          {/* this does not have a newline */}\n          <Icon f7='gear' />\n          {/* neither does this */}\n          <OneLineComponent />\n\n          {/* Multiline */}\n          {/* Block comments */}\n          {/* Stick to MultilineComponent */}\n          <Button>\n            <IconPreview />\n            Button 2\n            <span></span>\n          </Button>\n        </div>\n      `,\n      options: [{ prevent: true, allowMultilines: true }],\n      errors: [{ messageId: 'allowMultilines' }],\n    },\n    {\n      code: `\n        <div>\n          <div>\n            <button></button>\n            <button></button>\n          </div>\n          <div>\n            <span></span>\n            <span></span>\n          </div>\n        </div>\n      `,\n      output: `\n        <div>\n          <div>\n            <button></button>\n\n            <button></button>\n          </div>\n\n          <div>\n            <span></span>\n\n            <span></span>\n          </div>\n        </div>\n      `,\n      errors: [\n        { messageId: 'require' },\n        { messageId: 'require' },\n        { messageId: 'require' },\n      ],\n    },\n    {\n      output: `\n        <div>\n          <Button>{data.label}</Button>\n          <List />\n        </div>\n      `,\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n\n          <List />\n        </div>\n      `,\n      errors: [{ messageId: 'prevent' }],\n      options: [{ prevent: true }],\n    },\n    {\n      output: `\n        <div>\n          <Button>{data.label}</Button>\n          {showSomething === true && <Something />}\n        </div>\n      `,\n      code: `\n        <div>\n          <Button>{data.label}</Button>\n\n          {showSomething === true && <Something />}\n        </div>\n      `,\n      errors: [{ messageId: 'prevent' }],\n      options: [{ prevent: true }],\n    },\n    {\n      output: `\n        <div>\n          {showSomething === true && <Something />}\n          <Button>{data.label}</Button>\n        </div>\n      `,\n      code: `\n        <div>\n          {showSomething === true && <Something />}\n\n          <Button>{data.label}</Button>\n        </div>\n      `,\n      errors: [{ messageId: 'prevent' }],\n      options: [{ prevent: true }],\n    },\n    {\n      output: `\n        <div>\n          {showSomething === true && <Something />}\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      code: `\n        <div>\n          {showSomething === true && <Something />}\n\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      errors: [{ messageId: 'prevent' }],\n      options: [{ prevent: true }],\n    },\n    {\n      output: `\n        <div>\n          <div>\n            <button></button>\n            <button></button>\n          </div>\n          <div>\n            <span></span>\n            <span></span>\n          </div>\n        </div>\n      `,\n      code: `\n        <div>\n          <div>\n            <button></button>\n\n            <button></button>\n          </div>\n\n          <div>\n            <span></span>\n\n            <span></span>\n          </div>\n        </div>\n      `,\n      errors: [\n        { messageId: 'prevent' },\n        { messageId: 'prevent' },\n        { messageId: 'prevent' },\n      ],\n      options: [{ prevent: true }],\n    },\n    {\n      code: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n          <span>Should be in new line</span>\n        </>\n      `,\n      output: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n\n          <span>Should be in new line</span>\n        </>\n      `,\n      errors: [{ messageId: 'require' }],\n      features: ['fragment'],\n    },\n    {\n      output: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n          <span>Should be in new line</span>\n        </>\n      `,\n      code: `\n        <>\n          <Button>{data.label}</Button>\n          Test\n\n          <span>Should be in new line</span>\n        </>\n      `,\n      errors: [{ messageId: 'prevent' }],\n      options: [{ prevent: true }],\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>\n          <OneLineComponent />\n          <AnotherOneLineComponent prop={prop} />\n          <MultilineComponent\n            prop1={prop1}\n            prop2={prop2}\n          />\n          <OneLineComponent />\n        </>\n      `,\n      output: `\n        <>\n          <OneLineComponent />\n          <AnotherOneLineComponent prop={prop} />\n\n          <MultilineComponent\n            prop1={prop1}\n            prop2={prop2}\n          />\n\n          <OneLineComponent />\n        </>\n      `,\n      features: ['fragment'],\n      errors: [\n        { messageId: 'allowMultilines' },\n        { messageId: 'allowMultilines' },\n      ],\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n    {\n      code: `\n        <div>\n          {showSomething === true && <Something />}\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      output: `\n        <div>\n          {showSomething === true && <Something />}\n\n          {showSomethingElse === true ? (\n            <SomethingElse />\n          ) : (\n            <ErrorMessage />\n          )}\n        </div>\n      `,\n      errors: [{ messageId: 'allowMultilines' }],\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n    {\n      output: `\n        <div>\n          <div>\n            <button></button>\n            <button></button>\n          </div>\n\n          <div>\n            <span></span>\n            <span></span>\n          </div>\n        </div>\n      `,\n      code: `\n        <div>\n          <div>\n            <button></button>\n\n            <button></button>\n          </div>\n          <div>\n            <span></span>\n\n            <span></span>\n          </div>\n        </div>\n      `,\n      errors: [\n        { messageId: 'prevent' },\n        { messageId: 'allowMultilines' },\n        { messageId: 'prevent' },\n      ],\n      options: [{ prevent: true, allowMultilines: true }],\n    },\n    {\n      code: `\n        const frag: DocumentFragment = (\n          <Fragment>\n            <sni-sequence-editor-tool\n              name=\"forward\"\n              direction=\"forward\"\n              type=\"control\"\n              onClick={ () => this.onClickNavigate('forward') }\n            />\n            <sni-sequence-editor-tool\n              name=\"rotate\"\n              direction=\"left\"\n              type=\"control\"\n              onClick={ () => this.onClickNavigate('left') }\n            />\n    \n            <sni-sequence-editor-tool\n              name=\"rotate\"\n              direction=\"right\"\n              type=\"control\"\n              onClick={ (): void => this.onClickNavigate('right') }\n            />\n    \n            <div className=\"sni-sequence-editor-control-panel__delete\" data-name=\"delete\" onClick={ this.onDeleteCommand } />\n    \n            {\n              ...Array.from(this.children)\n            }\n          </Fragment>\n        )\n      `,\n      output: `\n        const frag: DocumentFragment = (\n          <Fragment>\n            <sni-sequence-editor-tool\n              name=\"forward\"\n              direction=\"forward\"\n              type=\"control\"\n              onClick={ () => this.onClickNavigate('forward') }\n            />\n\n            <sni-sequence-editor-tool\n              name=\"rotate\"\n              direction=\"left\"\n              type=\"control\"\n              onClick={ () => this.onClickNavigate('left') }\n            />\n${'    '}\n            <sni-sequence-editor-tool\n              name=\"rotate\"\n              direction=\"right\"\n              type=\"control\"\n              onClick={ (): void => this.onClickNavigate('right') }\n            />\n    \n            <div className=\"sni-sequence-editor-control-panel__delete\" data-name=\"delete\" onClick={ this.onDeleteCommand } />\n    \n            {\n              ...Array.from(this.children)\n            }\n          </Fragment>\n        )\n      `,\n      features: ['types'],\n      options: [{ prevent: true, allowMultilines: true }],\n      errors: [\n        { messageId: 'allowMultilines', line: 10 },\n        { messageId: 'prevent', line: 26 },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-bind.js",
    "content": "/**\n * @fileoverview Prevents usage of Function.prototype.bind and arrow functions\n *               in React component definition.\n * @author Daniel Lo Nigro <dan.cx>\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-bind');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-no-bind', rule, {\n  valid: parsers.all([\n    // Not covered by the rule\n    {\n      code: '<div onClick={this._handleClick}></div>',\n    },\n    {\n      code: '<div onClick={this._handleClick}></div>',\n      options: [{}],\n    },\n    {\n      code: '<Foo onClick={this._handleClick} />',\n    },\n    {\n      code: '<Foo onClick={this._handleClick} />',\n      options: [{}],\n    },\n    {\n      code: '<div meaningOfLife={42}></div>',\n    },\n    {\n      code: '<div onClick={getHandler()}></div>',\n    },\n\n    // bind() and arrow functions in refs explicitly ignored\n    {\n      code: '<div ref={c => this._input = c}></div>',\n      options: [{ ignoreRefs: true }],\n    },\n    {\n      code: '<div ref={this._refCallback.bind(this)}></div>',\n      options: [{ ignoreRefs: true }],\n    },\n    {\n      code: '<div ref={function (c) {this._input = c}}></div>',\n      options: [{ ignoreRefs: true }],\n    },\n\n    // bind() explicitly allowed\n    {\n      code: '<div onClick={this._handleClick.bind(this)}></div>',\n      options: [{ allowBind: true }],\n    },\n\n    // Arrow functions explicitly allowed\n    {\n      code: '<div onClick={() => alert(\"1337\")}></div>',\n      options: [{ allowArrowFunctions: true }],\n    },\n    {\n      code: '<div onClick={async () => alert(\"1337\")}></div>',\n      options: [{ allowArrowFunctions: true }],\n    },\n\n    // Functions explicitly allowed\n    {\n      code: '<div onClick={function () { alert(\"1337\") }}></div>',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: '<div onClick={function * () { alert(\"1337\") }}></div>',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: '<div onClick={async function () { alert(\"1337\") }}></div>',\n      options: [{ allowFunctions: true }],\n    },\n\n    // Redux connect\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        export default connect()(Hello);\n      `,\n      options: [{ allowBind: true }],\n    },\n\n    // Backbone view with a bind\n    {\n      code: `\n        var DocumentRow = Backbone.View.extend({\n          tagName: \"li\",\n          render: function() {\n            this.onTap.bind(this);\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        const foo = {\n          render: function() {\n            this.onTap.bind(this);\n            return true;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        const foo = {\n          render() {\n            this.onTap.bind(this);\n            return true;\n          }\n        };\n      `,\n    },\n\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            const click = this.onTap.bind(this);\n            return <div onClick={onClick}>Hello</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            foo.onClick = this.onTap.bind(this);\n            return <div onClick={onClick}>Hello</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            return (<div>{\n              this.props.list.map(this.wrap.bind(this, \"span\"))\n            }</div>);\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            const click = () => true;\n            return <div onClick={onClick}>Hello</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            return (<div>{\n              this.props.list.map(item => <item hello=\"true\"/>)\n            }</div>);\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            const click = this.bar::baz\n            return <div onClick={onClick}>Hello</div>;\n          }\n        };\n      `,\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          render() {\n            return (<div>{\n              this.props.list.map(this.bar::baz)\n            }</div>);\n          }\n        };\n      `,\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            return (<div>{\n              this.props.list.map(this.wrap.bind(this, \"span\"))\n            }</div>);\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const click = this.bar::baz\n            return <div onClick={onClick}>Hello</div>;\n          }\n        });\n      `,\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const click = () => true\n            return <div onClick={onClick}>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const onClick = this.doSomething.bind(this, \"no\")\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            return (<div>{\n              this.props.list.map(this.wrap.bind(this, \"span\"))\n            }</div>);\n          }\n        };\n      `,\n      features: ['class fields'],\n    },\n    {\n      // issue #1543: don't crash on uninitialized variables\n      code: `\n        class Hello extends Component {\n          render() {\n            let click;\n            return <div onClick={onClick}>Hello</div>;\n          }\n        }\n      `,\n    },\n\n    // ignore DOM components\n    {\n      code: '<div onClick={this._handleClick.bind(this)}></div>',\n      options: [{ ignoreDOMComponents: true }],\n    },\n    {\n      code: '<div onClick={() => alert(\"1337\")}></div>',\n      options: [{ ignoreDOMComponents: true }],\n    },\n    {\n      code: '<div onClick={function () { alert(\"1337\") }}></div>',\n      options: [{ ignoreDOMComponents: true }],\n    },\n    {\n      code: '<div foo={::this.onChange} />',\n      options: [{ ignoreDOMComponents: true }],\n      features: ['bind operator'],\n    },\n\n    // Local function declaration\n    {\n      code: `\n        function click() { return true; }\n        class Hello23 extends React.Component {\n          renderDiv() {\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [],\n    },\n  ]),\n\n  invalid: parsers.all([\n    // .bind()\n    {\n      code: '<div onClick={this._handleClick.bind(this)}></div>',\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: '<div onClick={someGlobalFunction.bind(this)}></div>',\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: '<div onClick={window.lol.bind(this)}></div>',\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: '<div ref={this._refCallback.bind(this)}></div>',\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            const click = this.someMethod.bind(this);\n            return <div onClick={click}>Hello {this.state.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          render() {\n            const click = this.someMethod.bind(this);\n            return <div onClick={click}>Hello {this.state.name}</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv() {\n            const click = this.doSomething.bind(this, \"no\")\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = this.doSomething.bind(this, \"no\")\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = this.doSomething.bind(this, \"no\")\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        const foo = {\n          render: ({onClick}) => (\n            <div onClick={onClick.bind(this)}>Hello</div>\n          )\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={this.doSomething.bind(this, \"hey\")} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = this.doSomething.bind(this, \"hey\")\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = () => true\n            const renderStuff = () => {\n              const click = this.doSomething.bind(this, \"hey\")\n              return <div onClick={click} />\n            }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [\n        { messageId: 'bindCall' },\n        { messageId: 'arrowFunc' },\n      ],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        const foo = {\n          render: ({onClick}) => (\n            <div onClick={(returningBoolean()) ? onClick.bind(this) : onClick.bind(this)}>Hello</div>\n          )\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        const foo = {\n          render: ({onClick}) => (\n            <div onClick={(returningBoolean()) ? onClick.bind(this) : handleClick()}>Hello</div>\n          )\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        const foo = {\n          render: ({onClick}) => (\n            <div onClick={(returningBoolean()) ? handleClick() : this.onClick.bind(this)}>Hello</div>\n          )\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n    {\n      code: `\n        const foo = {\n          render: ({onClick}) => (\n            <div onClick={returningBoolean.bind(this) ? handleClick() : onClick()}>Hello</div>\n          )\n        };\n      `,\n      errors: [{ messageId: 'bindCall' }],\n    },\n\n    // Arrow functions\n    {\n      code: '<div onClick={() => alert(\"1337\")}></div>',\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: '<div onClick={async () => alert(\"1337\")}></div>',\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: '<div onClick={() => 42}></div>',\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: '<div onClick={param => { first(); second(); }}></div>',\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: '<div ref={c => this._input = c}></div>',\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = () => true\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = () => true\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = async () => true\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={() => true} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={async () => true} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = () => true\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = async () => true\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'arrowFunc' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = ::this.onChange\n            const renderStuff = () => {\n              const click = () => true\n              return <div onClick={click} />\n            }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [\n        { messageId: 'arrowFunc' },\n        { messageId: 'bindExpression' },\n      ],\n      features: ['bind operator'],\n    },\n\n    // Functions\n    {\n      code: '<div onClick={function () { alert(\"1337\") }}></div>',\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: '<div onClick={function * () { alert(\"1337\") }}></div>',\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: '<div onClick={async function () { alert(\"1337\") }}></div>',\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: '<div ref={function (c) { this._input = c }}></div>',\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = function () { return true }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'func' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = function * () { return true }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'func' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = function () { return true }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'func' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = async function () { return true }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'func' }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={function () { return true }} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={function * () { return true }} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n          return <div onClick={async function () { return true }} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = function () { return true }\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = async function () { return true }\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          render: function() {\n            const doThing = function * () { return true }\n            return <div onClick={doThing} />\n          }\n        });\n      `,\n      errors: [{ messageId: 'func' }],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = ::this.onChange\n            const renderStuff = () => {\n              const click = function () { return true }\n              return <div onClick={click} />\n            }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [\n        { messageId: 'func' },\n        { messageId: 'bindExpression' },\n      ],\n      features: ['bind operator'],\n    },\n\n    // Bind expression\n    {\n      code: '<div foo={::this.onChange} />',\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: '<div foo={foo.bar::baz} />',\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: '<div foo={foo::bar} />',\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv() {\n            const click = ::this.onChange\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv() {\n            const click = this.bar::baz\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = async () => {\n            const click = this.bar::baz\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv = () => {\n            const click = true\n            const renderStuff = () => {\n              const click = this.bar::baz\n              return <div onClick={click} />\n            }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'bindExpression' }],\n      features: ['bind operator'],\n    },\n\n    // Local function declaration\n    {\n      code: `\n        class Hello23 extends React.Component {\n          renderDiv() {\n            function click() { return true; }\n            return <div onClick={click}>Hello</div>;\n          }\n        };\n      `,\n      errors: [\n        { messageId: 'func' },\n      ],\n    },\n\n    // ignore DOM components\n    {\n      code: '<Foo onClick={this._handleClick.bind(this)} />',\n      options: [{ ignoreDOMComponents: true }],\n      errors: [{ messageId: 'bindCall' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-comment-textnodes.js",
    "content": "/**\n * @fileoverview Tests for jsx-no-comment-textnodes\n * @author Ben Vinegar\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-comment-textnodes');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-no-comment-textnodes', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                {/* valid */}\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <>\n                {/* valid */}\n              </>\n            );\n          }\n        }\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<div>{/* valid */}</div>);\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            const bar = (<div>{/* valid */}</div>);\n            return bar;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          foo: (<div>{/* valid */}</div>),\n          render() {\n            return this.foo;\n          },\n        });\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                {/* valid */}\n                {/* valid 2 */}\n                {/* valid 3 */}\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var foo = require('foo');\n      `,\n    },\n    {\n      code: `\n        <Foo bar='test'>\n          {/* valid */}\n        </Foo>\n      `,\n    },\n    {\n      code: `\n        <strong>\n          &nbsp;https://www.example.com/attachment/download/1\n        </strong>\n      `,\n    },\n\n    // inside element declarations\n    {\n      code: `\n        <Foo /* valid */ placeholder={'foo'}/>\n      `,\n    },\n    {\n      code: `\n        </* valid */></>\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <></* valid *//>\n      `,\n      features: ['fragment', 'no-ts'], // TODO: FIXME: figure out why both TS parsers fail on this\n    },\n    {\n      code: `\n        <Foo title={'foo' /* valid */}/>\n      `,\n    },\n    {\n      code: '<pre>&#x2F;&#x2F; TODO: Write perfect code</pre>',\n    },\n    {\n      code: '<pre>&#x2F;&#42; TODO: Write perfect code &#42;&#x2F;</pre>',\n    },\n    {\n      code: `\n        <div>\n          <span className=\"pl-c\"><span className=\"pl-c\">&#47;&#47;</span> ...</span><br />\n        </div>\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<div>// invalid</div>);\n          }\n        }\n      `,\n      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<>// invalid</>);\n          }\n        }\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<div>/* invalid */</div>);\n          }\n        }\n      `,\n      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                // invalid\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                asdjfl\n                /* invalid */\n                foo\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                {'asdjfl'}\n                // invalid\n                {'foo'}\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n    {\n      code: `\n        const Component2 = () => {\n          return <span>/*</span>;\n        };\n      `,\n      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here\n      errors: [{ messageId: 'putCommentInBraces' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-constructed-context-values.js",
    "content": "/**\n * @fileoverview Prevents jsx context provider values from taking values that\n *               will cause needless rerenders.\n * @author Dylan Oshima\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-constructed-context-values');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('react-no-constructed-context-values', rule, {\n  valid: parsers.all([\n    {\n      code: 'const Component = () => <Context.Provider value={props}></Context.Provider>',\n    },\n    {\n      code: 'const Component = () => <Context.Provider value={100}></Context.Provider>',\n    },\n    {\n      code: 'const Component = () => <Context.Provider value=\"Some string\"></Context.Provider>',\n    },\n    {\n      code: 'function Component() { const foo = useMemo(() => { return {} }, []); return (<Context.Provider value={foo}></Context.Provider>)}',\n      options: [{ allowArrowFunctions: true }],\n    },\n    {\n      code: `\n        function Component({oneProp, twoProp, redProp, blueProp,}) {\n          return (\n            <NewContext.Provider value={twoProp}></NewContext.Provider>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo(section) {\n          const foo = section.section_components?.edges;\n\n          return (\n            <Context.Provider value={foo}></Context.Provider>\n          )\n        }\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        import foo from 'foo';\n        function innerContext() {\n          return (\n            <Context.Provider value={foo.something}></Context.Provider>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        // Passes because the lint rule doesn't handle JSX spread attributes\n        function innerContext() {\n          const foo = {value: 'something'}\n          return (\n            <Context.Provider {...foo}></Context.Provider>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        // Passes because the lint rule doesn't handle JSX spread attributes\n        function innerContext() {\n          const foo = useMemo(() => {\n            return bar;\n          })\n          return (\n            <Context.Provider value={foo}></Context.Provider>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        // Passes because we can't statically check if it's using the default value\n        function Component({ a = {} }) {\n          return (<Context.Provider value={a}></Context.Provider>);\n        }\n      `,\n    },\n    {\n      code: `\n          import React from 'react';\n          import MyContext from './MyContext';\n\n          const value = '';\n\n          function ContextProvider(props) {\n              return (\n                  <MyContext.Provider value={value as any}>\n                      {props.children}\n                  </MyContext.Provider>\n              )\n          }\n        `,\n      features: ['types', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        import BooleanContext from './BooleanContext';\n\n        function ContextProvider(props) {\n            return (\n                <BooleanContext.Provider value>\n                    {props.children}\n                </BooleanContext.Provider>\n            )\n        }\n      `,\n    },\n    {\n      code: `\n        const root = ReactDOM.createRoot(document.getElementById('root'));\n        root.render(\n          <AppContext.Provider value={{}}>\n            <AppView />\n          </AppContext.Provider>\n        );\n      `,\n    },\n    {\n      code: `\n        // Passes because the context is not a provider\n        function Component() {\n          return <MyContext.Consumer value={{ foo: 'bar' }} />;\n        }\n      `,\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const MyContext = React.createContext();\n        const Component = () => <MyContext value={props}></MyContext>;\n      `,\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const MyContext = React.createContext();\n        const Component = () => <MyContext value={100}></MyContext>;\n      `,\n    },\n    {\n      code: `\n        const SomeContext = createContext();\n        const Component = () => <SomeContext value=\"Some string\"></SomeContext>;\n      `,\n    },\n    {\n      code: `\n        // Passes because MyContext is not a variable declarator\n        function Component({ MyContext }) {\n          return <MyContext value={{ foo: \"bar\" }} />;\n        }\n      `,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      // Invalid because object construction creates a new identity\n      code: 'function Component() { const foo = {}; return (<Context.Provider value={foo}></Context.Provider>) }',\n      errors: [{\n        messageId: 'withIdentifierMsg',\n        data: {\n          variableName: 'foo',\n          type: 'object',\n          nodeLine: '1',\n          usageLine: '1',\n        },\n      }],\n    },\n    {\n      // Invalid because array construction creates a new identity\n      code: 'function Component() { const foo = []; return (<Context.Provider value={foo}></Context.Provider>) }',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'array',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because arrow Function creates a new identity\n      code: 'function Component() { const foo = () => {}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsgFunc',\n          data: {\n            variableName: 'foo',\n            type: 'function expression',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because function expression creates a new identity\n      code: 'function Component() { const foo = function bar(){}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsgFunc',\n          data: {\n            variableName: 'foo',\n            type: 'function expression',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because class expression creates a new identity\n      code: 'function Component() { const foo = class SomeClass{}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'class expression',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because new expression creates a new identity\n      code: 'function Component() { const foo = new SomeClass(); return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'new expression',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // // Invalid because function declaration creates a new identity\n      code: 'function Component() { function foo() {}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsgFunc',\n          data: {\n            variableName: 'foo',\n            type: 'function declaration',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value of the ternrary will create a new identity\n      code: 'function Component() { const foo = true ? {} : \"fine\"; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value of the logical OR will create a new identity\n      code: 'function Component() { const foo = bar || {}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value of the logical AND will create a new identity\n      code: 'function Component() { const foo = bar && {}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value of the nested ternary will create a new identity\n      code:\n        'function Component() { const foo = bar ? baz ? {} : null : null; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [{\n        messageId: 'withIdentifierMsg',\n        data: {\n          variableName: 'foo',\n          type: 'object',\n          nodeLine: '1',\n          usageLine: '1',\n        },\n      }],\n    },\n    {\n      // Invalid because the object value will create a new identity\n      code: 'function Component() { let foo = {}; return (<Context.Provider value={foo}></Context.Provider>) }',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value will create a new identity\n      code: 'function Component() { var foo = {}; return (<Context.Provider value={foo}></Context.Provider>)}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Valid, but currently not handled at the moment.\n      code: `\n        function Component() {\n          let a = {};\n          a = 10;\n          return (<Context.Provider value={a}></Context.Provider>);\n        }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'a',\n            type: 'object',\n            nodeLine: '3',\n            usageLine: '5',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid variable reassignment from parameter because bar is an object identity\n      code: `\n        function Component() {\n          const foo = {};\n          const bar = foo;\n          return (<Context.Provider value={bar}></Context.Provider>);\n        }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'bar',\n            type: 'object',\n            nodeLine: '3',\n            usageLine: '5',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object expression possibly returned from the ternary will create a new identity\n      code: `\n        function Component(foo) {\n          let bar = true ? foo : {};\n          return (<Context.Provider value={bar}></Context.Provider>);\n        }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'bar',\n            type: 'object',\n            nodeLine: '3',\n            usageLine: '4',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because inline object construction will create a new identity\n      code: 'function Component() { return (<Context.Provider value={{foo: \"bar\"}}></Context.Provider>);}',\n      errors: [\n        {\n          messageId: 'defaultMsg',\n          data: {\n            type: 'object',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because Wrapper returns JSX which has a new identity\n      code: 'function Component() { const Wrapper = (<SomeComp />); return (<Context.Provider value={Wrapper}></Context.Provider>);}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'Wrapper',\n            type: 'JSX element',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because RegEx returns a new object which has will be a new identity\n      code: 'function Component() { const someRegex = /HelloWorld/; return (<Context.Provider value={someRegex}></Context.Provider>);}',\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'someRegex',\n            type: 'regular expression',\n            nodeLine: '1',\n            usageLine: '1',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the right hand side of the assignment expression contains a function which will create a new identity\n      code: `\n        function Component() {\n          let foo = null;\n          let bar = x = () => {};\n          return (<Context.Provider value={bar}></Context.Provider>);\n        }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'bar',\n            type: 'assignment expression',\n            nodeLine: '4',\n            usageLine: '5',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because function declaration creates a new identity\n      code: `\n        import React from 'react';\n\n        const Context = React.createContext();\n        function Component() {\n          function foo() {};\n          return (<Context value={foo}></Context>)\n        }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsgFunc',\n          data: {\n            variableName: 'foo',\n            type: 'function declaration',\n            nodeLine: '6',\n            usageLine: '7',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because the object value will create a new identity\n      code: `\n        const MyContext = createContext();\n        function Component() { const foo = {}; return (<MyContext value={foo}></MyContext>) }\n      `,\n      errors: [\n        {\n          messageId: 'withIdentifierMsg',\n          data: {\n            variableName: 'foo',\n            type: 'object',\n            nodeLine: '3',\n            usageLine: '3',\n          },\n        },\n      ],\n    },\n    {\n      // Invalid because inline object construction will create a new identity\n      code: `\n        const MyContext = createContext();\n        function Component() { return (<MyContext value={{foo: \"bar\"}}></MyContext>); }\n      `,\n      errors: [\n        {\n          messageId: 'defaultMsg',\n          data: {\n            type: 'object',\n            nodeLine: '3',\n            usageLine: '3',\n          },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-duplicate-props.js",
    "content": "/**\n * @fileoverview Enforce no duplicate props\n * @author Markus Ånöstam\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-duplicate-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nconst expectedError = {\n  messageId: 'noDuplicateProps',\n  type: 'JSXAttribute',\n};\n\nconst ignoreCaseArgs = [{\n  ignoreCase: true,\n}];\n\nruleTester.run('jsx-no-duplicate-props', rule, {\n  valid: parsers.all([\n    { code: '<App />;' },\n    { code: '<App {...this.props} />;' },\n    { code: '<App a b c />;' },\n    { code: '<App a b c A />;' },\n    { code: '<App {...this.props} a b c />;' },\n    { code: '<App c {...this.props} a b />;' },\n    { code: '<App a=\"c\" b=\"b\" c=\"a\" />;' },\n    { code: '<App {...this.props} a=\"c\" b=\"b\" c=\"a\" />;' },\n    { code: '<App c=\"a\" {...this.props} a=\"c\" b=\"b\" />;' },\n    { code: '<App A a />;' },\n    { code: '<App A b a />;' },\n    { code: '<App A=\"a\" b=\"b\" B=\"B\" />;' },\n    {\n      code: '<App a:b=\"c\" />;',\n      options: ignoreCaseArgs,\n      features: ['jsx namespace'],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<App a a />;',\n      errors: [expectedError],\n    },\n    {\n      code: '<App A b c A />;',\n      errors: [expectedError],\n    },\n    {\n      code: '<App a=\"a\" b=\"b\" a=\"a\" />;',\n      errors: [expectedError],\n    },\n    {\n      code: '<App A a />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError],\n    },\n    {\n      code: '<App a b c A />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError],\n    },\n    {\n      code: '<App A=\"a\" b=\"b\" B=\"B\" />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-leaked-render.js",
    "content": "/**\n * @fileoverview Prevent problematic leaked values from being rendered\n * @author Mario Beltrán\n */\n\n'use strict';\n\n//------------------------------------------------------------------------------\n// Requirements\n//------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-leaked-render');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n//------------------------------------------------------------------------------\n// Tests\n//------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-no-leaked-render', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        const Component = () => {\n          return <div>{customTitle || defaultTitle}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>There are {elements.length} elements</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{!count && 'No results found'}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{!!elements.length && <List elements={elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{Boolean(elements.length) && <List elements={elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length > 0 && <List elements={elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{count ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{count ? <List elements={elements}/> : null}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{!!count && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{count ? <List elements={elements}/> : null}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{!!count && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n    },\n\n    // Fixes for:\n    // - https://github.com/jsx-eslint/eslint-plugin-react/issues/3292\n    // - https://github.com/jsx-eslint/eslint-plugin-react/issues/3297\n    {\n      // It shouldn't delete valid alternate from ternary expressions when \"coerce\" is the only valid strategy\n      code: `\n        const Component = ({ elements, count }) => {\n          return (\n            <div>\n              <div> {direction ? (direction === \"down\" ? \"▼\" : \"▲\") : \"\"} </div>\n              <div>{ containerName.length > 0 ? \"Loading several stuff\" : \"Loading\" }</div>\n            </div>\n          )\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n    {\n      // It shouldn't delete valid branches from ternary expressions when [\"coerce\", \"ternary\"] are only valid strategies\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{direction ? (direction === \"down\" ? \"▼\" : \"▲\") : \"\"}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n    },\n    {\n      // It shouldn't report nested logical expressions when \"coerce\" is the only valid strategy\n      code: `\n        const Component = ({ direction }) => {\n          return (\n            <div>\n              <div>{!!direction && direction === \"down\" && \"▼\"}</div>\n              <div>{direction === \"down\" && !!direction && \"▼\"}</div>\n              <div>{direction === \"down\" || !!direction && \"▼\"}</div>\n              <div>{(!display || display === DISPLAY.WELCOME) && <span>foo</span>}</div>\n            </div>\n          )\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n    // Fixes for:\n    // - https://github.com/jsx-eslint/eslint-plugin-react/issues/3354\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{count ? <List elements={elements}/> : <EmptyList />}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n    },\n    {\n      code: `\n        const Component = ({ elements, count }) => {\n          return <div>{count ? <List elements={elements}/> : <EmptyList />}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n    {\n      code: `\n        const isOpen = true;\n        const Component = () => {\n          return <Popover open={isOpen && items.length > 0} />\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n    {\n      code: `\n        const isOpen = false;\n        const Component = () => {\n          return <Popover open={isOpen && items.length > 0} />\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n    },\n\n    // See #3292\n    {\n      code: `\n        const Component = ({ enabled, checked }) => {\n          return <CheckBox checked={enabled && checked} />\n        }\n      `,\n      options: [{ ignoreAttributes: true }],\n    },\n  ]) || [],\n\n  invalid: parsers.all([].concat(\n    // Common invalid cases with default options\n    {\n      code: `\n        const Example = () => {\n          return (\n            <>\n              {0 && <Something/>}\n              {'' && <Something/>}\n              {NaN && <Something/>}\n            </>\n          )\n        }\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n          line: 5,\n          column: 16,\n        },\n        {\n          message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n          line: 6,\n          column: 16,\n        },\n        {\n          message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n          line: 7,\n          column: 16,\n        },\n      ],\n      output: `\n        const Example = () => {\n          return (\n            <>\n              {0 ? <Something/> : null}\n              {'' ? <Something/> : null}\n              {NaN ? <Something/> : null}\n            </>\n          )\n        }\n      `,\n      settings: { react: { version: '17.999.999' } },\n    },\n\n    {\n      code: `\n        const Example = () => {\n          return (\n            <>\n              {0 && <Something/>}\n              {'' && <Something/>}\n              {NaN && <Something/>}\n            </>\n          )\n        }\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n          line: 5,\n          column: 16,\n        },\n        {\n          message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n          line: 7,\n          column: 16,\n        },\n      ],\n      output: `\n        const Example = () => {\n          return (\n            <>\n              {0 ? <Something/> : null}\n              {'' && <Something/>}\n              {NaN ? <Something/> : null}\n            </>\n          )\n        }\n      `,\n      settings: { react: { version: '18.0.0' } },\n    },\n\n    // Invalid tests with both strategies enabled (default)\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{count && title}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{count ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count }) => {\n          return <div>{count && <span>There are {count} results</span>}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count }) => {\n          return <div>{count ? <span>There are {count} results</span> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length && <List elements={elements}/>}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{nestedCollection.elements.length && <List elements={nestedCollection.elements}/>}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{nestedCollection.elements.length ? <List elements={nestedCollection.elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements[0] && <List elements={elements}/>}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{elements[0] ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) ? <Results>{numberA+numberB}</Results> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{!!(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n    },\n\n    // Invalid tests only with \"ternary\" strategy enabled\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{count && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{count ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count }) => {\n          return <div>{count && <span>There are {count} results</span>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count }) => {\n          return <div>{count ? <span>There are {count} results</span> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{nestedCollection.elements.length && <List elements={nestedCollection.elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{nestedCollection.elements.length ? <List elements={nestedCollection.elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements[0] && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{elements[0] ? <List elements={elements}/> : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) ? <Results>{numberA+numberB}</Results> : null}</div>\n        }\n      `,\n    },\n\n    // cases: boolean coerce isn't valid if strategy is only \"ternary\"\n    {\n      code: `\n        const Component = ({ someCondition, title }) => {\n          return <div>{!someCondition && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ someCondition, title }) => {\n          return <div>{!someCondition ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{!!count && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{count ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{count > 0 && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{count > 0 ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{0 != count && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{0 != count ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, total, title }) => {\n          return <div>{count < total && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, total, title }) => {\n          return <div>{count < total ? title : null}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, title, somethingElse }) => {\n          return <div>{!!(count && somethingElse) && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title, somethingElse }) => {\n          return <div>{count && somethingElse ? title : null}</div>\n        }\n      `,\n    },\n\n    // Invalid tests only with \"coerce\" strategy enabled\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{count && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{!!count && title}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count }) => {\n          return <div>{count && <span>There are {count} results</span>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count }) => {\n          return <div>{!!count && <span>There are {count} results</span>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements.length && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{!!elements.length && <List elements={elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{nestedCollection.elements.length && <List elements={nestedCollection.elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ nestedCollection }) => {\n          return <div>{!!nestedCollection.elements.length && <List elements={nestedCollection.elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ elements }) => {\n          return <div>{elements[0] && <List elements={elements}/>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ elements }) => {\n          return <div>{!!elements[0] && <List elements={elements}/>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ numberA, numberB }) => {\n          return <div>{!!(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ connection, hasError, hasErrorUpdate}) => {\n          return <div>{connection && (hasError || hasErrorUpdate)}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ connection, hasError, hasErrorUpdate}) => {\n          return <div>{!!connection && (hasError || hasErrorUpdate)}</div>\n        }\n      `,\n    },\n\n    // cases: ternary isn't valid if strategy is only \"coerce\"\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{count ? title : null}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{!!count && title}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, title }) => {\n          return <div>{!count ? title : null}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, title }) => {\n          return <div>{!count && title}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ count, somethingElse, title }) => {\n          return <div>{count && somethingElse ? title : null}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ count, somethingElse, title }) => {\n          return <div>{!!count && !!somethingElse && title}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const Component = ({ items, somethingElse, title }) => {\n          return <div>{items.length > 0 && somethingElse && title}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n      output: `\n        const Component = ({ items, somethingElse, title }) => {\n          return <div>{items.length > 0 && !!somethingElse && title}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        const MyComponent = () => {\n          const items = []\n          const breakpoint = { phones: true }\n\n          return <div>{items.length > 0 && breakpoint.phones && <span />}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n      output: `\n        const MyComponent = () => {\n          const items = []\n          const breakpoint = { phones: true }\n\n          return <div>{items.length > 0 && !!breakpoint.phones && <span />}</div>\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 6,\n        column: 24,\n      }],\n    },\n    {\n      code: `\n        const MyComponent = () => {\n          return <div>{maybeObject && (isFoo ? <Aaa /> : <Bbb />)}</div>\n        }\n      `,\n      output: `\n        const MyComponent = () => {\n          return <div>{!!maybeObject && (isFoo ? <Aaa /> : <Bbb />)}</div>\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 24,\n      }],\n    },\n\n    // See #3292\n    {\n      code: `\n        const Component = ({ enabled, checked }) => {\n          return <CheckBox checked={enabled && checked} />\n        }\n      `,\n      output: `\n        const Component = ({ enabled, checked }) => {\n          return <CheckBox checked={enabled ? checked : null} />\n        }\n      `,\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 37,\n      }],\n    },\n    {\n      code: `\n        const MyComponent = () => {\n          return <Something checked={isIndeterminate ? false : isChecked} />\n        }\n      `,\n      output: semver.satisfies(eslintPkg.version, '> 4') ? `\n        const MyComponent = () => {\n          return <Something checked={!isIndeterminate && isChecked} />\n        }\n      ` : null,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 38,\n      }],\n    },\n    {\n      code: `\n        const MyComponent = () => {\n          return <Something checked={cond && isIndeterminate ? false : isChecked} />\n        }\n      `,\n      output: semver.satisfies(eslintPkg.version, '> 4') ? `\n        const MyComponent = () => {\n          return <Something checked={!!cond && !!isIndeterminate ? false : isChecked} />\n        }\n      ` : null,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 3,\n        column: 38,\n      }],\n    },\n    semver.satisfies(eslintPkg.version, '> 4') ? {\n      code: `\n        const MyComponent = () => {\n          return (\n            <>\n              {someCondition && (\n                <div>\n                  <p>hello</p>\n                </div>\n              )}\n            </>\n          )\n        }\n      `,\n      output: `\n        const MyComponent = () => {\n          return (\n            <>\n              {!!someCondition && (\n                <div>\n                  <p>hello</p>\n                </div>\n              )}\n            </>\n          )\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 5,\n        column: 16,\n      }],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 4') ? {\n      code: `\n        const MyComponent = () => {\n          return (\n            <>\n              {someCondition && (\n                <SomeComponent\n                  prop1={val1}\n                  prop2={val2}\n                />\n              )}\n            </>\n          )\n        }\n      `,\n      output: `\n        const MyComponent = () => {\n          return (\n            <>\n              {!!someCondition && (\n                <SomeComponent\n                  prop1={val1}\n                  prop2={val2}\n                />\n              )}\n            </>\n          )\n        }\n      `,\n      options: [{ validStrategies: ['coerce', 'ternary'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 5,\n        column: 16,\n      }],\n    } : [],\n    {\n      code: `\n        const isOpen = 0;\n        const Component = () => {\n          return <Popover open={isOpen && items.length > 0} />\n        }\n      `,\n      output: `\n        const isOpen = 0;\n        const Component = () => {\n          return <Popover open={!!isOpen && items.length > 0} />\n        }\n      `,\n      options: [{ validStrategies: ['coerce'] }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 4,\n        column: 33,\n      }],\n    },\n    {\n      code: `\n        const Component = ({ enabled }) => {\n          return (\n            <Foo bar={\n              <Something>{enabled && <MuchWow />}</Something>\n            } />\n          )\n        }\n      `,\n      output: `\n        const Component = ({ enabled }) => {\n          return (\n            <Foo bar={\n              <Something>{enabled ? <MuchWow /> : null}</Something>\n            } />\n          )\n        }\n      `,\n      options: [{ ignoreAttributes: true }],\n      errors: [{\n        message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes',\n        line: 5,\n        column: 27,\n      }],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-literals.js",
    "content": "/**\n * @fileoverview Prevent using unwrapped literals in a React component definition\n * @author Caleb morris\n * @author David Buchan-Swanson\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-literals');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-no-literals', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                <button type=\"button\"></button>\n              </div>\n            );\n          }\n        }\n      `,\n      options: [\n        {\n          noStrings: true,\n          allowedStrings: ['button', 'submit'],\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp2 extends Component {\n          render() {\n            return (\n              <div>\n                {'asdjfl'}\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <>\n                {'asdjfl'}\n              </>\n            );\n          }\n        }\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<div>{'test'}</div>);\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            const bar = (<div>{'hello'}</div>);\n            return bar;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          foo: (<div>{'hello'}</div>),\n          render() {\n            return this.foo;\n          },\n        });\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                {'asdjfl'}\n                {'test'}\n                {'foo'}\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var foo = require('foo');\n      `,\n    },\n    {\n      code: `\n        <Foo bar='test'>\n          {'blarg'}\n        </Foo>\n      `,\n    },\n    {\n      code: `\n        <Foo bar=\"test\">\n          {intl.formatText(message)}\n        </Foo>\n      `,\n      options: [{ noStrings: true, ignoreProps: true }],\n    },\n    {\n      code: `\n        <Foo bar=\"test\">\n          {translate('my.translate.key')}\n        </Foo>\n      `,\n      options: [{ noStrings: true, ignoreProps: true }],\n    },\n    {\n      code: '<Foo bar={true} />',\n      options: [{ noStrings: true }],\n    },\n    {\n      code: '<Foo bar={false} />',\n      options: [{ noStrings: true }],\n    },\n    {\n      code: '<Foo bar={100} />',\n      options: [{ noStrings: true }],\n    },\n    {\n      code: '<Foo bar={null} />',\n      options: [{ noStrings: true }],\n    },\n    {\n      code: '<Foo bar={{}} />',\n      options: [{ noStrings: true }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          asdf() {}\n          render() {\n            return <Foo bar={this.asdf} class='xx' />;\n          }\n        }\n      `,\n      options: [{ noStrings: true, ignoreProps: true }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            let foo = \\`bar\\`;\n            return <div />;\n          }\n        }\n      `,\n      options: [{ noStrings: true }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div>asdf</div>\n          }\n        }\n      `,\n      options: [{ allowedStrings: ['asdf'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div>asdf</div>\n          }\n        }\n      `,\n      options: [{ noStrings: false, allowedStrings: ['asdf'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div>&nbsp;</div>\n          }\n        }\n      `,\n      options: [{ noStrings: true, allowedStrings: ['&nbsp;'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                &nbsp;\n              </div>\n            );\n          }\n        }\n      `,\n      options: [{ noStrings: true, allowedStrings: ['&nbsp;'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div>foo: {bar}*</div>\n          }\n        }\n      `,\n      options: [{ noStrings: true, allowedStrings: ['foo: ', '*'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div>foo</div>\n          }\n        }\n      `,\n      options: [{ noStrings: true, allowedStrings: ['   foo   '] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          asdf() {}\n          render() {\n            const xx = 'xx';\n\n            return <Foo bar={this.asdf} class={xx} />;\n          }\n        }\n      `,\n      options: [{ noStrings: true, ignoreProps: false }],\n    },\n    {\n      code: `\n        <img alt='blank image'></img>\n      `,\n    },\n    {\n      code: `\n        <div>&mdash;</div>\n      `,\n      options: [{ noStrings: true, allowedStrings: ['&mdash;', '—'] }],\n    },\n    {\n      code: `\n        <div>—</div>\n      `,\n      options: [{ noStrings: true, allowedStrings: ['&mdash;', '—'] }],\n    },\n    {\n      code: `\n        <img src=\"image.jpg\" alt=\"text\" />\n      `,\n      options: [{ restrictedAttributes: ['className', 'id'] }],\n    },\n    {\n      code: `\n        <div className=\"allowed\" />\n      `,\n      options: [{ restrictedAttributes: ['className'], allowedStrings: ['allowed'] }],\n    },\n    {\n      code: `\n        <div className=\"test\" title=\"hello\" />\n      `,\n      options: [{\n        noStrings: true,\n        ignoreProps: true,\n        restrictedAttributes: ['className'],\n        allowedStrings: ['test'],\n      }],\n    },\n    {\n      code: `\n        <div className=\"test\" id=\"foo\" />\n      `,\n      options: [{ restrictedAttributes: [] }],\n    },\n    {\n      code: `\n        <T>foo</T>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        <T>foo <div>bar</div></T>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        <T>foo <div>{'bar'}</div></T>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true, applyToNestedElements: false } } }],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>{2}</T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true } } }],\n    },\n    {\n      code: `\n        <T>{2}<div>{2}</div></T>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true } } }],\n    },\n    {\n      code: `\n        <T>{2}<div>{'foo'}</div></T>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true, applyToNestedElements: false } } }],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>foo</T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { allowedStrings: ['foo'] } } }],\n    },\n    {\n      code: `\n        <T>foo<div>foo</div></T>\n      `,\n      options: [{ elementOverrides: { T: { allowedStrings: ['foo'] } } }],\n    },\n    {\n      code: `\n        <T>foo<div>{'foo'}</div></T>\n      `,\n      options: [{ elementOverrides: { T: { allowedStrings: ['foo'], applyToNestedElements: false } } }],\n    },\n    {\n      code: `\n        <div>\n          <div foo={2} />\n          <T foo=\"bar\" />\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true } } }],\n    },\n    {\n      code: `\n        <T foo=\"bar\"><div foo=\"bar\" /></T>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true } } }],\n    },\n    {\n      code: `\n        <T foo=\"bar\"><div foo={2} /></T>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true, applyToNestedElements: false } } }],\n    },\n    {\n      code: `\n        <div>\n          <div foo=\"foo\" />\n          <T foo={2} />\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true } } }],\n    },\n    {\n      code: `\n        <T foo={2}><div foo={2} /></T>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true } } }],\n    },\n    {\n      code: `\n        <T foo={2}><div foo=\"foo\" /></T>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true, applyToNestedElements: false } } }],\n    },\n    {\n      code: `\n        <T>foo<U>foo</U></T>\n      `,\n      options: [{ elementOverrides: { T: { allowedStrings: ['foo'] }, U: { allowedStrings: ['foo'] } } }],\n    },\n    {\n      code: `\n        import { T } from 'foo';\n        <T>{'foo'}</T>\n      `,\n    },\n    {\n      code: `\n        import { T as U } from 'foo';\n        <U>foo</U>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        const { T: U } = require('foo');\n        <U>foo</U>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        const { T: U } = require('foo').Foo;\n        <U>foo</U>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        const { T: U } = require('foo').Foo.Foo;\n        <U>foo</U>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        const foo = 2;\n        <T>foo</T>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n    },\n    {\n      code: `\n        <T.U>foo</T.U>\n      `,\n      options: [{ elementOverrides: { 'T.U': { allowElement: true } } }],\n    },\n    {\n      code: `\n        import { T as U } from 'foo';\n        <U.U>foo</U.U>\n      `,\n      options: [{ elementOverrides: { 'T.U': { allowElement: true } } }],\n    },\n    {\n      code: `\n        <React.Fragment>foo</React.Fragment>\n      `,\n      options: [{ elementOverrides: { Fragment: { allowElement: true } } }],\n    },\n    {\n      code: `\n        <React.Fragment>foo</React.Fragment>\n      `,\n      options: [{ elementOverrides: { 'React.Fragment': { allowElement: true } } }],\n    },\n    {\n      code: `\n        <div>{'foo'}</div>\n      `,\n      options: [{ elementOverrides: { div: { allowElement: true } } }],\n    },\n    {\n      code: `\n        <div>\n          <Input type=\"text\" />\n          <Button className=\"primary\" />\n          <Image src=\"photo.jpg\" />\n        </div>\n      `,\n      options: [{\n        elementOverrides: {\n          Input: { restrictedAttributes: ['placeholder'] },\n          Button: { restrictedAttributes: ['type'] },\n        },\n      }],\n    },\n    {\n      code: `\n        <div title=\"container\">\n          <Button className=\"btn\" />\n        </div>\n      `,\n      options: [{\n        restrictedAttributes: ['className'],\n        elementOverrides: {\n          Button: { restrictedAttributes: ['disabled'] },\n        },\n      }],\n    },\n    {\n      code: `\n        <Button className=\"btn\" />\n      `,\n      options: [{\n        noAttributeStrings: true,\n        elementOverrides: {\n          Button: { restrictedAttributes: ['type'] },\n        },\n      }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<div>test</div>);\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (<>test</>);\n          }\n        }\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            const foo = (<div>test</div>);\n            return foo;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            const varObjectTest = { testKey : (<div>test</div>) };\n            return varObjectTest.testKey;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          foo: (<div>hello</div>),\n          render() {\n            return this.foo;\n          },\n        });\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'hello' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                asdjfl\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'asdjfl' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                asdjfl\n                test\n                foo\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: {\n            text: `asdjfl\n                test\n                foo`,\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return (\n              <div>\n                {'asdjfl'}\n                test\n                {'foo'}\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        <Foo bar=\"test\">\n          {'Test'}\n        </Foo>\n      `,\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'invalidPropValue',\n          data: { text: 'bar=\"test\"' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'Test\\'' },\n        },\n      ],\n    },\n    {\n      code: `\n        <Foo bar=\"test\">\n          {'Test' + name}\n        </Foo>\n      `,\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'invalidPropValue',\n          data: { text: 'bar=\"test\"' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'Test\\'' },\n        },\n      ],\n    },\n    {\n      code: `\n        <Foo bar=\"test\">\n          Test\n        </Foo>\n      `,\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'invalidPropValue',\n          data: { text: 'bar=\"test\"' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: 'Test' },\n        },\n      ],\n    },\n    {\n      code: `\n        <Foo>\n          {\\`Test\\`}\n        </Foo>\n      `,\n      options: [{ noStrings: true }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`Test`' },\n        },\n      ],\n    },\n    {\n      code: '<Foo bar={`Test`} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`Test`' },\n        },\n      ],\n    },\n    /* eslint-disable no-template-curly-in-string */\n    {\n      code: '<Foo bar={`${baz}`} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`${baz}`' },\n        },\n      ],\n    },\n    {\n      code: '<Foo bar={`Test ${baz}`} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`Test ${baz}`' },\n        },\n      ],\n    },\n    /* eslint-enable no-template-curly-in-string */\n    {\n      code: '<Foo bar={`foo` + \\'bar\\'} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`foo`' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'bar\\'' },\n        },\n      ],\n    },\n    {\n      code: '<Foo bar={`foo` + `bar`} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`foo`' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`bar`' },\n        },\n      ],\n    },\n    {\n      code: '<Foo bar={\\'foo\\' + `bar`} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'foo\\'' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '`bar`' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <div bar={'foo'}>asdf</div>\n          }\n        }\n      `,\n      options: [{ noStrings: true, allowedStrings: ['asd'], ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'foo\\'' },\n        },\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: 'asdf' },\n        },\n      ],\n    },\n    {\n      code: '<Foo bar={\\'bar\\'} />',\n      options: [{ noStrings: true, ignoreProps: false }],\n      errors: [\n        {\n          messageId: 'noStringsInJSX',\n          data: { text: '\\'bar\\'' },\n        },\n      ],\n    },\n    {\n      code: `\n        <img alt='blank image'></img>\n      `,\n      options: [{ noAttributeStrings: true }],\n      errors: [\n        {\n          messageId: 'noStringsInAttributes',\n          data: { text: '\\'blank image\\'' },\n        },\n      ],\n    },\n    {\n      code: 'export const WithChildren = ({}) => <div>baz bob</div>;',\n      options: [{ noAttributeStrings: true }],\n      errors: [\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'baz bob' },\n        },\n      ],\n    },\n    {\n      code: 'export const WithAttributes = ({}) => <div title=\"foo bar\" />;',\n      options: [{ noAttributeStrings: true }],\n      errors: [\n        {\n          messageId: 'noStringsInAttributes',\n          data: { text: '\"foo bar\"' },\n        },\n      ],\n    },\n    {\n      code: `\n        export const WithAttributesAndChildren = ({}) => (\n          <div title=\"foo bar\">baz bob</div>\n        );\n      `,\n      options: [{ noAttributeStrings: true }],\n      errors: [\n        {\n          messageId: 'noStringsInAttributes',\n          data: { text: '\"foo bar\"' },\n        },\n        {\n          messageId: 'literalNotInJSXExpression',\n          data: { text: 'baz bob' },\n        },\n      ],\n    },\n    {\n      code: `\n        <div className=\"test\" />\n      `,\n      options: [{ restrictedAttributes: ['className'] }],\n      errors: [{\n        messageId: 'restrictedAttributeString',\n        data: { text: '\"test\"', attribute: 'className' },\n      }],\n    },\n    {\n      code: `\n        <div className=\"test\" id=\"foo\" title=\"bar\" />\n      `,\n      options: [{ restrictedAttributes: ['className', 'id'] }],\n      errors: [\n        { messageId: 'restrictedAttributeString', data: { text: '\"test\"', attribute: 'className' } },\n        { messageId: 'restrictedAttributeString', data: { text: '\"foo\"', attribute: 'id' } },\n      ],\n    },\n    {\n      code: `\n        <div src=\"image.jpg\" />\n      `,\n      options: [{\n        noAttributeStrings: true,\n        restrictedAttributes: ['className'],\n      }],\n      errors: [{ messageId: 'noStringsInAttributes', data: { text: '\"image.jpg\"' } }],\n    },\n    {\n      code: `\n        <div title=\"text\">test</div>\n      `,\n      options: [{\n        restrictedAttributes: ['title'],\n        noStrings: true,\n      }],\n      errors: [\n        { messageId: 'restrictedAttributeString', data: { text: '\"text\"', attribute: 'title' } },\n        { messageId: 'noStringsInJSX', data: { text: 'test' } },\n      ],\n    },\n    {\n      code: `\n        <div className=\"test\" title=\"hello\" />\n      `,\n      options: [{ noStrings: true, ignoreProps: false, restrictedAttributes: ['className'] }],\n      errors: [\n        { messageId: 'restrictedAttributeString', data: { text: '\"test\"', attribute: 'className' } },\n        { messageId: 'invalidPropValue', data: { text: 'title=\"hello\"' } },\n      ],\n    },\n    {\n      code: `\n        <div className=\"test\" title=\"hello\" />\n      `,\n      options: [{ noStrings: true, ignoreProps: true, restrictedAttributes: ['className'] }],\n      errors: [\n        { messageId: 'restrictedAttributeString', data: { text: '\"test\"', attribute: 'className' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>bar</T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: {} } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpression', data: { text: 'foo' } },\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'bar', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>bar</T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpression', data: { text: 'foo' } },\n      ],\n    },\n    {\n      code: `\n        <T>foo <div>bar</div></T>\n      `,\n      options: [{ elementOverrides: { T: { allowElement: true, applyToNestedElements: false } } }],\n      errors: [{ messageId: 'literalNotInJSXExpression', data: { text: 'bar' } }],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>{'bar'}</T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpression', data: { text: 'foo' } },\n        { messageId: 'noStringsInJSXInElement', data: { text: '\\'bar\\'', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>{'bar'}<div>{'baz'}</div></T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpression', data: { text: 'foo' } },\n        { messageId: 'noStringsInJSXInElement', data: { text: '\\'bar\\'', element: 'T' } },\n        { messageId: 'noStringsInJSXInElement', data: { text: '\\'baz\\'', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>{'bar'}<div>{'baz'}</div></T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true, applyToNestedElements: false } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpression', data: { text: 'foo' } },\n        { messageId: 'noStringsInJSXInElement', data: { text: '\\'bar\\'', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>{'foo'}</T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, allowedStrings: ['foo'] } } }],\n      errors: [\n        { messageId: 'noStringsInJSX', data: { text: '\\'foo\\'' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>{'foo'}<div>{'foo'}</div></T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, allowedStrings: ['foo'] } } }],\n      errors: [\n        { messageId: 'noStringsInJSX', data: { text: '\\'foo\\'' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>{'foo'}<div>{'foo'}</div></T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, allowedStrings: ['foo'], applyToNestedElements: false } } }],\n      errors: [\n        { messageId: 'noStringsInJSX', data: { text: '\\'foo\\'' } },\n        { messageId: 'noStringsInJSX', data: { text: '\\'foo\\'' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar\" />\n          <T foo2=\"bar\" />\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true } } }],\n      errors: [\n        { messageId: 'invalidPropValue', data: { text: 'foo1=\"bar\"' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar\" />\n          <T foo2=\"bar\"><div foo3=\"bar\" /></T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true } } }],\n      errors: [\n        { messageId: 'invalidPropValue', data: { text: 'foo1=\"bar\"' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar\" />\n          <T foo2=\"bar\"><div foo3=\"bar\" /></T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: { noStrings: true, ignoreProps: true, applyToNestedElements: false } } }],\n      errors: [\n        { messageId: 'invalidPropValue', data: { text: 'foo1=\"bar\"' } },\n        { messageId: 'invalidPropValue', data: { text: 'foo3=\"bar\"' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\" />\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true } } }],\n      errors: [\n        { messageId: 'noStringsInAttributesInElement', data: { text: '\"bar2\"', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\"><div foo3=\"bar3\" /></T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true } } }],\n      errors: [\n        { messageId: 'noStringsInAttributesInElement', data: { text: '\"bar2\"', element: 'T' } },\n        { messageId: 'noStringsInAttributesInElement', data: { text: '\"bar3\"', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\"><div foo3=\"bar3\" /></T>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: { noAttributeStrings: true, applyToNestedElements: false } } }],\n      errors: [\n        { messageId: 'noStringsInAttributesInElement', data: { text: '\"bar2\"', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>{'foo'}</div>\n          <T>{'bar'}</T>\n        </div>\n      `,\n      options: [{ noStrings: true, elementOverrides: { T: {} } }],\n      errors: [\n        { messageId: 'noStringsInJSX', data: { text: '\\'foo\\'' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>foo</T>\n        </div>\n      `,\n      options: [{ allowedStrings: ['foo'], elementOverrides: { T: {} } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div>foo</div>\n          <T>foo</T>\n          <T>bar</T>\n          <T>baz</T>\n        </div>\n      `,\n      options: [{ allowedStrings: ['foo'], elementOverrides: { T: { allowedStrings: ['bar'] } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'baz', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\" />\n        </div>\n      `,\n      options: [{ noStrings: true, ignoreProps: true, elementOverrides: { T: { noStrings: true } } }],\n      errors: [\n        { messageId: 'invalidPropValueInElement', data: { text: 'foo2=\"bar2\"', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\" />\n        </div>\n      `,\n      options: [{ noAttributeStrings: true, elementOverrides: { T: {} } }],\n      errors: [\n        { messageId: 'noStringsInAttributes', data: { text: '\"bar1\"' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <T>foo</T>\n          <U>bar</U>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: {}, U: {} } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'bar', element: 'U' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <T>foo</T>\n          <U>bar</U>\n        </div>\n      `,\n      options: [{ elementOverrides: { T: {}, U: { allowElement: true } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <T>foo <U>bar</U></T>\n      `,\n      options: [{ elementOverrides: { T: {}, U: { allowElement: true } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <T>{'foo'}<U>{'bar'}</U></T>\n      `,\n      options: [{ elementOverrides: { T: { noStrings: true }, U: {} } }],\n      errors: [\n        { messageId: 'noStringsInJSXInElement', data: { text: '\\'foo\\'', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <T>foo<U>foo</U></T>\n      `,\n      options: [{ elementOverrides: { T: { allowedStrings: ['foo'] }, U: {} } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'U' } },\n      ],\n    },\n    {\n      code: `\n        <T>foo<U>foo</U></T>\n      `,\n      options: [{ elementOverrides: { T: {}, U: { allowedStrings: ['foo'] } } }],\n      errors: [\n        { messageId: 'literalNotInJSXExpressionInElement', data: { text: 'foo', element: 'T' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <Fragment>foo</Fragment>\n          <React.Fragment>foo</React.Fragment>\n        </div>\n      `,\n      options: [{ elementOverrides: { 'React.Fragment': { allowElement: true } } }],\n      errors: [{ messageId: 'literalNotInJSXExpression', data: { text: 'foo' } }],\n    },\n    {\n      code: `\n        <div>foo</div>\n      `,\n      options: [{ elementOverrides: { div: { allowElement: true } } }],\n      errors: [{ messageId: 'literalNotInJSXExpression', data: { text: 'foo' } }],\n    },\n    {\n      code: `\n        <div>\n          <div type=\"text\" />\n          <Button type=\"submit\" />\n        </div>\n      `,\n      options: [{\n        elementOverrides: {\n          Button: { restrictedAttributes: ['type'] },\n        },\n      }],\n      errors: [\n        { messageId: 'restrictedAttributeStringInElement', data: { text: '\"submit\"', attribute: 'type', element: 'Button' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <Input placeholder=\"Enter text\" type=\"password\" />\n          <Button type=\"submit\" disabled=\"true\" />\n        </div>\n      `,\n      options: [{\n        elementOverrides: {\n          Input: { restrictedAttributes: ['placeholder'] },\n          Button: { restrictedAttributes: ['disabled'] },\n        },\n      }],\n      errors: [\n        { messageId: 'restrictedAttributeStringInElement', data: { text: '\"Enter text\"', attribute: 'placeholder', element: 'Input' } },\n        { messageId: 'restrictedAttributeStringInElement', data: { text: '\"true\"', attribute: 'disabled', element: 'Button' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div className=\"wrapper\" id=\"main\" />\n          <Button className=\"btn\" id=\"submit-btn\" />\n        </div>\n      `,\n      options: [{\n        restrictedAttributes: ['className'],\n        elementOverrides: {\n          Button: { restrictedAttributes: ['id'] },\n        },\n      }],\n      errors: [\n        { messageId: 'restrictedAttributeString', data: { text: '\"wrapper\"', attribute: 'className' } },\n        { messageId: 'restrictedAttributeStringInElement', data: { text: '\"submit-btn\"', attribute: 'id', element: 'Button' } },\n      ],\n    },\n    {\n      code: `\n        <div>\n          <div foo1=\"bar1\" />\n          <T foo2=\"bar2\" />\n        </div>\n      `,\n      options: [{\n        noAttributeStrings: true,\n        elementOverrides: {\n          T: { restrictedAttributes: ['foo2'] },\n        },\n      }],\n      errors: [\n        { messageId: 'noStringsInAttributes', data: { text: '\"bar1\"' } },\n        { messageId: 'restrictedAttributeStringInElement', data: { text: '\"bar2\"', attribute: 'foo2', element: 'T' } },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-script-url.js",
    "content": "/**\n * @fileoverview Prevent usage of `javascript:` URLs\n * @author Sergei Startsev\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-script-url');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nruleTester.run('jsx-no-script-url', rule, {\n  valid: parsers.all([\n    { code: '<a href=\"https://reactjs.org\"></a>' },\n    { code: '<a href=\"mailto:foo@bar.com\"></a>' },\n    { code: '<a href=\"#\"></a>' },\n    { code: '<a href=\"\"></a>' },\n    { code: '<a name=\"foo\"></a>' },\n    { code: '<a href={\"javascript:\"}></a>' },\n    { code: '<Foo href=\"javascript:\"></Foo>' },\n    { code: '<a href />' },\n    {\n      code: '<Foo other=\"javascript:\"></Foo>',\n      options: [[{ name: 'Foo', props: ['to', 'href'] }]],\n    },\n    {\n      code: '<Foo href=\"javascript:\"></Foo>',\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n    {\n      code: '<Foo href=\"javascript:\"></Foo>',\n      options: [[], { includeFromSettings: false }],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n    {\n      code: '<Foo other=\"javascript:\"></Foo>',\n      options: [[], { includeFromSettings: true }],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n  ]),\n  invalid: parsers.all([\n    // defaults\n    {\n      code: '<a href=\"javascript:\"></a>',\n      errors: [{ messageId: 'noScriptURL' }],\n    },\n    {\n      code: '<a href=\"javascript:void(0)\"></a>',\n      errors: [{ messageId: 'noScriptURL' }],\n    },\n    {\n      code: '<a href=\"j\\n\\n\\na\\rv\\tascript:\"></a>',\n      errors: [{ messageId: 'noScriptURL' }],\n    },\n\n    // with component passed by options\n    {\n      code: '<Foo to=\"javascript:\"></Foo>',\n      errors: [{ messageId: 'noScriptURL' }],\n      options: [\n        [{ name: 'Foo', props: ['to', 'href'] }],\n      ],\n    },\n    {\n      code: '<Foo href=\"javascript:\"></Foo>',\n      errors: [{ messageId: 'noScriptURL' }],\n      options: [\n        [{ name: 'Foo', props: ['to', 'href'] }],\n      ],\n    },\n    { // make sure it still uses defaults when passed options\n      code: '<a href=\"javascript:void(0)\"></a>',\n      errors: [{ messageId: 'noScriptURL' }],\n      options: [\n        [{ name: 'Foo', props: ['to', 'href'] }],\n      ],\n    },\n\n    // with components passed by settings\n    {\n      code: '<Foo to=\"javascript:\"></Foo>',\n      errors: [{ messageId: 'noScriptURL' }],\n      options: [\n        [{ name: 'Bar', props: ['to', 'href'] }],\n        { includeFromSettings: true },\n      ],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: 'to' }],\n      },\n    },\n    {\n      code: '<Foo href=\"javascript:\"></Foo>',\n      errors: [{ messageId: 'noScriptURL' }],\n      options: [{ includeFromSettings: true }],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n    {\n      code: `\n      <div>\n        <Foo href=\"javascript:\"></Foo>\n        <Bar link=\"javascript:\"></Bar>\n      </div>\n    `,\n      errors: [\n        { messageId: 'noScriptURL' },\n        { messageId: 'noScriptURL' },\n      ],\n      options: [\n        [{ name: 'Bar', props: ['link'] }],\n        { includeFromSettings: true },\n      ],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n    {\n      code: `\n      <div>\n        <Foo href=\"javascript:\"></Foo>\n        <Bar link=\"javascript:\"></Bar>\n      </div>\n    `,\n      errors: [\n        { messageId: 'noScriptURL' },\n      ],\n      options: [\n        [{ name: 'Bar', props: ['link'] }],\n      ],\n      settings: {\n        linkComponents: [{ name: 'Foo', linkAttribute: ['to', 'href'] }],\n      },\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-target-blank.js",
    "content": "/**\n * @fileoverview Forbid target='_blank' attribute\n * @author Kevin Miller\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-target-blank');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst defaultErrors = [{ messageId: 'noTargetBlankWithoutNoreferrer' }];\nconst allowReferrerErrors = [{ messageId: 'noTargetBlankWithoutNoopener' }];\n\nruleTester.run('jsx-no-target-blank', rule, {\n  valid: parsers.all([\n    { code: '<a href=\"foobar\"></a>' },\n    { code: '<a randomTag></a>' },\n    { code: '<a target />' },\n    { code: '<a href=\"foobar\" target=\"_blank\" rel=\"noopener noreferrer\"></a>' },\n    { code: '<a href=\"foobar\" target=\"_blank\" rel=\"noreferrer\"></a>' },\n    { code: '<a href=\"foobar\" target=\"_blank\" rel={\"noopener noreferrer\"}></a>' },\n    { code: '<a href=\"foobar\" target=\"_blank\" rel={\"noreferrer\"}></a>' },\n    { code: '<a href={\"foobar\"} target={\"_blank\"} rel={\"noopener noreferrer\"}></a>' },\n    { code: '<a href={\"foobar\"} target={\"_blank\"} rel={\"noreferrer\"}></a>' },\n    { code: '<a href={\\'foobar\\'} target={\\'_blank\\'} rel={\\'noopener noreferrer\\'}></a>' },\n    { code: '<a href={\\'foobar\\'} target={\\'_blank\\'} rel={\\'noreferrer\\'}></a>' },\n    { code: '<a href={`foobar`} target={`_blank`} rel={`noopener noreferrer`}></a>' },\n    { code: '<a href={`foobar`} target={`_blank`} rel={`noreferrer`}></a>' },\n    { code: '<a target=\"_blank\" {...spreadProps} rel=\"noopener noreferrer\"></a>' },\n    { code: '<a target=\"_blank\" {...spreadProps} rel=\"noreferrer\"></a>' },\n    { code: '<a {...spreadProps} target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://example.com\">s</a>' },\n    { code: '<a {...spreadProps} target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com\">s</a>' },\n    { code: '<a target=\"_blank\" rel=\"noopener noreferrer\" {...spreadProps}></a>' },\n    { code: '<a target=\"_blank\" rel=\"noreferrer\" {...spreadProps}></a>' },\n    { code: '<p target=\"_blank\"></p>' },\n    { code: '<a href=\"foobar\" target=\"_BLANK\" rel=\"NOOPENER noreferrer\"></a>' },\n    { code: '<a href=\"foobar\" target=\"_BLANK\" rel=\"NOREFERRER\"></a>' },\n    { code: '<a target=\"_blank\" rel={relValue}></a>' },\n    { code: '<a target={targetValue} rel=\"noopener noreferrer\"></a>' },\n    { code: '<a target={targetValue} rel=\"noreferrer\"></a>' },\n    { code: '<a target={targetValue} rel={\"noopener noreferrer\"}></a>' },\n    { code: '<a target={targetValue} rel={\"noreferrer\"}></a>' },\n    { code: '<a target={targetValue} href=\"relative/path\"></a>' },\n    { code: '<a target={targetValue} href=\"/absolute/path\"></a>' },\n    { code: '<a target={\\'targetValue\\'} href=\"/absolute/path\"></a>' },\n    { code: '<a target={\"targetValue\"} href=\"/absolute/path\"></a>' },\n    { code: '<a target={null} href=\"//example.com\"></a>' },\n    {\n      code: '<a {...someObject} href=\"/absolute/path\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a {...someObject} rel=\"noreferrer\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a {...someObject} rel=\"noreferrer\" target=\"_blank\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a {...someObject} href=\"foobar\" target=\"_blank\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a target=\"_blank\" href={ dynamicLink }></a>',\n      options: [{ enforceDynamicLinks: 'never' }],\n    },\n    {\n      code: '<a target={\"_blank\"} href={ dynamicLink }></a>',\n      options: [{ enforceDynamicLinks: 'never' }],\n    },\n    {\n      code: '<a target={\\'_blank\\'} href={ dynamicLink }></a>',\n      options: [{ enforceDynamicLinks: 'never' }],\n    },\n    {\n      code: '<Link target=\"_blank\" href={ dynamicLink }></Link>',\n      options: [{ enforceDynamicLinks: 'never' }],\n      settings: { linkComponents: ['Link'] },\n    },\n    {\n      code: '<Link target=\"_blank\" to={ dynamicLink }></Link>',\n      options: [{ enforceDynamicLinks: 'never' }],\n      settings: { linkComponents: { name: 'Link', linkAttribute: 'to' } },\n    },\n    {\n      code: '<Link target=\"_blank\" to={ dynamicLink }></Link>',\n      options: [{ enforceDynamicLinks: 'never' }],\n      settings: { linkComponents: { name: 'Link', linkAttribute: ['to'] } },\n    },\n    {\n      code: '<a href=\"foobar\" target=\"_blank\" rel=\"noopener\"></a>',\n      options: [{ allowReferrer: true }],\n    },\n    {\n      code: '<a href=\"foobar\" target=\"_blank\" rel=\"noreferrer\"></a>',\n      options: [{ allowReferrer: true }],\n    },\n    {\n      code: '<a target={3} />',\n    },\n    {\n      code: '<a href=\"some-link\" {...otherProps} target=\"some-non-blank-target\"></a>',\n    },\n    {\n      code: '<a href=\"some-link\" target=\"some-non-blank-target\" {...otherProps}></a>',\n    },\n    {\n      code: '<a target=\"_blank\" href=\"/absolute/path\"></a>',\n      options: [{ forms: false }],\n    },\n    {\n      code: '<a target=\"_blank\" href=\"/absolute/path\"></a>',\n      options: [{ forms: false, links: true }],\n    },\n    {\n      code: '<form action=\"https://example.com\" target=\"_blank\"></form>',\n      options: [],\n    },\n    {\n      code: '<form action=\"https://example.com\" target=\"_blank\" rel=\"noopener noreferrer\"></form>',\n      options: [{ forms: true }],\n    },\n    {\n      code: '<form action=\"https://example.com\" target=\"_blank\" rel=\"noopener noreferrer\"></form>',\n      options: [{ forms: true, links: false }],\n    },\n    {\n      code: '<a href target=\"_blank\"/>',\n    },\n    {\n      code: '<a href={href} target={isExternal ? \"_blank\" : undefined} rel=\"noopener noreferrer\" />',\n    },\n    {\n      code: '<a href={href} target={isExternal ? undefined : \"_blank\"} rel={isExternal ? \"noreferrer\" : \"noopener noreferrer\"} />',\n    },\n    {\n      code: '<a href={href} target={isExternal ? undefined : \"_blank\"} rel={isExternal ? \"noreferrer noopener\" : \"noreferrer\"} />',\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"noreferrer\" : \"noopener\"} />',\n      options: [{ allowReferrer: true }],\n    },\n    {\n      code: '<a href={href} target={isExternal ? \"_blank\" : undefined} rel={isExternal ? \"noreferrer\" : undefined} />',\n    },\n    {\n      code: '<a href={href} target={isSelf ? \"_self\" : \"_blank\"} rel={isSelf ? undefined : \"noreferrer\"} />',\n    },\n    {\n      code: '<a href={href} target={isSelf ? \"_self\" : \"\"} rel={isSelf ? undefined : \"\"} />',\n    },\n    {\n      code: '<a href={href} target={isExternal ? \"_blank\" : undefined} rel={isExternal ? \"noopener noreferrer\" : undefined} />',\n    },\n    {\n      code: '<form action={action} />',\n      options: [{ forms: true }],\n    },\n    {\n      code: '<form action={action} {...spread} />',\n      options: [{ forms: true }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<a target=\"_blank\" href=\"https://example.com/1\"></a>',\n      output: '<a target=\"_blank\" href=\"https://example.com/1\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel=\"\" href=\"https://example.com/2\"></a>',\n      output: '<a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com/2\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel={0} href=\"https://example.com/3\"></a>',\n      output: '<a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com/3\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel={1} href=\"https://example.com/3\"></a>',\n      output: '<a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com/3\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel={false} href=\"https://example.com/4\"></a>',\n      output: '<a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com/4\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel={null} href=\"https://example.com/5\"></a>',\n      output: '<a target=\"_blank\" rel=\"noreferrer\" href=\"https://example.com/5\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel=\"noopenernoreferrer\" href=\"https://example.com/6\"></a>',\n      output: '<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://example.com/6\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" rel=\"no referrer\" href=\"https://example.com/7\"></a>',\n      output: '<a target=\"_blank\" rel=\"no referrer noreferrer\" href=\"https://example.com/7\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_BLANK\" href=\"https://example.com/8\"></a>',\n      output: '<a target=\"_BLANK\" href=\"https://example.com/8\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/9\"></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/9\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/10\" rel={true}></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/10\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/11\" rel={3}></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/11\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/12\" rel={null}></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/12\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/13\" rel={getRel()}></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/14\" rel={\"noopenernoreferrer\"}></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/14\" rel={\"noopener noreferrer\"}></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target={\"_blank\"} href={\"//example.com/15\"} rel={\"noopenernoreferrer\"}></a>',\n      output: '<a target={\"_blank\"} href={\"//example.com/15\"} rel={\"noopener noreferrer\"}></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target={\"_blank\"} href={\"//example.com/16\"} rel={\"noopenernoreferrernoreferrernoreferrernoreferrernoreferrer\"}></a>',\n      output: '<a target={\"_blank\"} href={\"//example.com/16\"} rel={\"noopener noreferrer\"}></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com/17\" rel></a>',\n      output: '<a target=\"_blank\" href=\"//example.com/17\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href={ dynamicLink }></a>',\n      output: '<a target=\"_blank\" href={ dynamicLink } rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target={\\'_blank\\'} href=\"//example.com/18\"></a>',\n      output: '<a target={\\'_blank\\'} href=\"//example.com/18\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target={\"_blank\"} href=\"//example.com/19\"></a>',\n      output: '<a target={\"_blank\"} href=\"//example.com/19\" rel=\"noreferrer\"></a>',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href=\"https://example.com/20\" target=\"_blank\" rel></a>',\n      output: '<a href=\"https://example.com/20\" target=\"_blank\" rel=\"noopener\"></a>',\n      options: [{ allowReferrer: true }],\n      errors: allowReferrerErrors,\n    },\n    {\n      code: '<a href=\"https://example.com/20\" target=\"_blank\"></a>',\n      output: '<a href=\"https://example.com/20\" target=\"_blank\" rel=\"noopener\"></a>',\n      options: [{ allowReferrer: true }],\n      errors: allowReferrerErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href={ dynamicLink }></a>',\n      output: '<a target=\"_blank\" href={ dynamicLink } rel=\"noreferrer\"></a>',\n      options: [{ enforceDynamicLinks: 'always' }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a {...someObject}></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a {...someObject} target=\"_blank\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href=\"foobar\" {...someObject} target=\"_blank\"></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href=\"foobar\" target=\"_blank\" rel=\"noreferrer\" {...someObject}></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href=\"foobar\" target=\"_blank\" {...someObject}></a>',\n      options: [{ enforceDynamicLinks: 'always', warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<Link target=\"_blank\" href={ dynamicLink }></Link>',\n      output: '<Link target=\"_blank\" href={ dynamicLink } rel=\"noreferrer\"></Link>',\n      options: [{ enforceDynamicLinks: 'always' }],\n      settings: { linkComponents: ['Link'] },\n      errors: defaultErrors,\n    },\n    {\n      code: '<Link target=\"_blank\" to={ dynamicLink }></Link>',\n      output: '<Link target=\"_blank\" to={ dynamicLink } rel=\"noreferrer\"></Link>',\n      options: [{ enforceDynamicLinks: 'always' }],\n      settings: { linkComponents: { name: 'Link', linkAttribute: 'to' } },\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href=\"some-link\" {...otherProps} target=\"some-non-blank-target\"></a>',\n      errors: defaultErrors,\n      options: [{ warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a href=\"some-link\" target=\"some-non-blank-target\" {...otherProps}></a>',\n      errors: defaultErrors,\n      options: [{ warnOnSpreadAttributes: true }],\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com\" rel></a>',\n      output: '<a target=\"_blank\" href=\"//example.com\" rel=\"noreferrer\"></a>',\n      options: [{ links: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com\" rel></a>',\n      output: '<a target=\"_blank\" href=\"//example.com\" rel=\"noreferrer\"></a>',\n      options: [{ links: true, forms: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a target=\"_blank\" href=\"//example.com\" rel></a>',\n      output: '<a target=\"_blank\" href=\"//example.com\" rel=\"noreferrer\"></a>',\n      options: [{ links: true, forms: false }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<form method=\"POST\" action=\"https://example.com\" target=\"_blank\"></form>',\n      options: [{ forms: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<form method=\"POST\" action=\"https://example.com\" rel=\"\" target=\"_blank\"></form>',\n      options: [{ forms: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<form method=\"POST\" action=\"https://example.com\" rel=\"noopenernoreferrer\" target=\"_blank\"></form>',\n      options: [{ forms: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<form method=\"POST\" action=\"https://example.com\" rel=\"noopenernoreferrer\" target=\"_blank\"></form>',\n      options: [{ forms: true, links: false }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"undefined\" : \"undefined\"} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"noopener\" : undefined} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"undefined\" : \"noopener\"} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target={isExternal ? \"_blank\" : undefined} rel={isExternal ? undefined : \"noopener noreferrer\"} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? 3 : \"noopener noreferrer\"} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"noopener noreferrer\" : \"3\"} />',\n      errors: defaultErrors,\n    },\n    {\n      code: '<a href={href} target=\"_blank\" rel={isExternal ? \"noopener\" : \"2\"} />',\n      options: [{ allowReferrer: true }],\n      errors: allowReferrerErrors,\n    },\n    {\n      code: '<form action={action} target=\"_blank\" />',\n      options: [{ allowReferrer: true, forms: true }],\n      errors: allowReferrerErrors,\n    },\n    {\n      code: '<form action={action} target=\"_blank\" />',\n      options: [{ forms: true }],\n      errors: defaultErrors,\n    },\n    {\n      code: '<form action={action} {...spread} />',\n      options: [{ forms: true, warnOnSpreadAttributes: true }],\n      errors: defaultErrors,\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-undef.js",
    "content": "/**\n * @fileoverview Tests for jsx-no-undef\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst getRuleDefiner = require('../../helpers/getRuleDefiner');\nconst getESLintCoreRule = require('../../helpers/getESLintCoreRule');\nconst rule = require('../../../lib/rules/jsx-no-undef');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n  jsxPragma: null,\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\n// In ESLint >= 9, it isn't possible to redefine a core rule, but it isn't necessary anyway since the core rules are certainly already available in the RuleTester/Linter\nif (semver.major(eslintPkg.version) < 9) {\n  const ruleDefiner = getRuleDefiner(ruleTester);\n  ruleDefiner.defineRule('no-undef', getESLintCoreRule('no-undef'));\n}\n\nruleTester.run('jsx-no-undef', rule, {\n  valid: parsers.all([\n    {\n      code: '/*eslint no-undef:1*/ var React, App; React.render(<App />);',\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<img />);',\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<x-gif />);',\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React, app; React.render(<app.Foo />);',\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React, app; React.render(<app.foo.Bar />);',\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<Apppp:Foo />);',\n      features: ['jsx namespace'],\n    },\n    {\n      code: `\n        /*eslint no-undef:1*/\n        var React;\n        class Hello extends React.Component {\n          render() {\n            return <this.props.tag />\n          }\n        }\n      `,\n    },\n    {\n      code: 'var React; React.render(<Text />);',\n      globals: {\n        Text: true,\n      },\n      features: ['no-babel'], // TODO: FIXME: remove `no-babel` and fix\n    },\n    {\n      code: `\n        import Text from \"cool-module\";\n        const TextWrapper = function (props) {\n          return (\n            <Text />\n          );\n        };\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n      options: [{ allowGlobals: false }],\n    },\n  ].map(parsers.disableNewTS)),\n\n  invalid: parsers.all([\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<App />);',\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'App' },\n        },\n      ],\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<Appp.Foo />);',\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'Appp' },\n        },\n      ],\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<appp.Foo />);',\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'appp' },\n        },\n      ],\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<appp.foo.Bar />);',\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'appp' },\n        },\n      ],\n    },\n    {\n      code: `\n        const TextWrapper = function (props) {\n          return (\n            <Text />\n          );\n        };\n        export default TextWrapper;\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'Text' },\n        },\n      ],\n      options: [{ allowGlobals: false }],\n      globals: {\n        Text: true,\n      },\n    },\n    {\n      code: '/*eslint no-undef:1*/ var React; React.render(<Foo />);',\n      errors: [\n        {\n          messageId: 'undefined',\n          data: { identifier: 'Foo' },\n        },\n      ],\n    },\n  ].map(parsers.disableNewTS)),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-no-useless-fragment.js",
    "content": "/**\n * @fileoverview Test file for jsx-no-useless-fragment\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-no-useless-fragment');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nruleTester.run('jsx-no-useless-fragment', rule, {\n  valid: parsers.all([\n    {\n      code: '<><Foo /><Bar /></>',\n      features: ['fragment'],\n    },\n    {\n      code: '<>foo<div /></>',\n      features: ['fragment'],\n    },\n    {\n      code: '<> <div /></>',\n      features: ['fragment'],\n    },\n    {\n      code: '<>{\"moo\"} </>',\n      features: ['fragment'],\n    },\n    {\n      code: '<NotFragment />',\n    },\n    {\n      code: '<React.NotFragment />',\n    },\n    {\n      code: '<NotReact.Fragment />',\n    },\n    {\n      code: '<Foo><><div /><div /></></Foo>',\n      features: ['fragment'],\n    },\n    {\n      code: '<div p={<>{\"a\"}{\"b\"}</>} />',\n      features: ['fragment'],\n    },\n    {\n      code: '<Fragment key={item.id}>{item.value}</Fragment>',\n    },\n    {\n      code: '<Fooo content={<>eeee ee eeeeeee eeeeeeee</>} />',\n      features: ['fragment'],\n    },\n    {\n      code: '<>{foos.map(foo => foo)}</>',\n      features: ['fragment'],\n    },\n    {\n      code: '<>{moo}</>',\n      features: ['fragment'],\n      options: [{ allowExpressions: true }],\n    },\n    {\n      code: `\n        <>\n          {moo}\n        </>\n      `,\n      features: ['fragment'],\n      options: [{ allowExpressions: true }],\n    },\n  ]),\n  invalid: parsers.all([].concat(\n    {\n      code: '<></>',\n      output: null,\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      features: ['fragment'],\n    },\n    {\n      code: '<>{}</>',\n      output: null,\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      features: ['fragment'],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<p>moo<>foo</></p>',\n      output: '<p>moofoo</p>',\n      errors: [\n        { messageId: 'NeedsMoreChildren', type: 'JSXFragment' },\n        { messageId: 'ChildOfHtmlElement', type: 'JSXFragment' },\n      ],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<>{meow}</>',\n      output: null,\n      errors: [{ messageId: 'NeedsMoreChildren' }],\n      features: ['fragment'],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<p><>{meow}</></p>',\n      output: '<p>{meow}</p>',\n      errors: [\n        { messageId: 'NeedsMoreChildren', type: 'JSXFragment' },\n        { messageId: 'ChildOfHtmlElement', type: 'JSXFragment' },\n      ],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<><div/></>',\n      output: '<div/>',\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: `\n        <>\n          <div/>\n        </>\n      `,\n      output: `\n        <div/>\n      `,\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<Fragment />',\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXElement' }],\n    },\n    {\n      code: `\n        <React.Fragment>\n          <Foo />\n        </React.Fragment>\n      `,\n      output: `\n        <Foo />\n      `,\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXElement' }],\n    },\n    {\n      code: `\n        <SomeReact.SomeFragment>\n          {foo}\n        </SomeReact.SomeFragment>\n      `,\n      settings: {\n        react: {\n          pragma: 'SomeReact',\n          fragment: 'SomeFragment',\n        },\n      },\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXElement' }],\n    },\n    {\n      // Not safe to fix this case because `Eeee` might require child be ReactElement\n      code: '<Eeee><>foo</></Eeee>',\n      output: null,\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<div><>foo</></div>',\n      output: '<div>foo</div>',\n      errors: [\n        { messageId: 'NeedsMoreChildren', type: 'JSXFragment' },\n        { messageId: 'ChildOfHtmlElement', type: 'JSXFragment' },\n      ],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<div><>{\"a\"}{\"b\"}</></div>',\n      output: '<div>{\"a\"}{\"b\"}</div>',\n      errors: [{ messageId: 'ChildOfHtmlElement', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and next test case\n    },\n    {\n      code: '<div><>{\"a\"}{\"b\"}</></div>',\n      output: null,\n      errors: [{ messageId: 'ChildOfHtmlElement', type: 'JSXFragment' }],\n      features: ['fragment', 'ts-old', 'no-ts-new', 'no-babel', 'no-default'],\n    },\n    {\n      code: `\n        <section>\n          <Eeee />\n          <Eeee />\n          <>{\"a\"}{\"b\"}</>\n        </section>`,\n      output: `\n        <section>\n          <Eeee />\n          <Eeee />\n          {\"a\"}{\"b\"}\n        </section>`,\n      errors: [{ messageId: 'ChildOfHtmlElement', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<div><Fragment>{\"a\"}{\"b\"}</Fragment></div>',\n      output: '<div>{\"a\"}{\"b\"}</div>',\n      errors: [{ messageId: 'ChildOfHtmlElement', type: 'JSXElement' }],\n    },\n    {\n      // whitepace tricky case\n      code: `\n        <section>\n          git<>\n            <b>hub</b>.\n          </>\n\n          git<> <b>hub</b></>\n        </section>`,\n      output: `\n        <section>\n          git<b>hub</b>.\n\n          git <b>hub</b>\n        </section>`,\n      errors: [\n        { messageId: 'ChildOfHtmlElement', type: 'JSXFragment', line: 3 },\n        { messageId: 'ChildOfHtmlElement', type: 'JSXFragment', line: 7 },\n      ],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    {\n      code: '<div>a <>{\"\"}{\"\"}</> a</div>',\n      output: '<div>a {\"\"}{\"\"} a</div>',\n      errors: [{ messageId: 'ChildOfHtmlElement', type: 'JSXFragment' }],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: `\n        const Comp = () => (\n          <html>\n            <React.Fragment />\n          </html>\n        );\n      `,\n      output: `\n        const Comp = () => (\n          <html>\n            ${/* eslint-disable-line template-curly-spacing *//* the trailing whitespace here is intentional */ ''}\n          </html>\n        );\n      `,\n      errors: [\n        { messageId: 'NeedsMoreChildren', type: 'JSXElement', line: 4 },\n        { messageId: 'ChildOfHtmlElement', type: 'JSXElement', line: 4 },\n      ],\n    },\n    // Ensure allowExpressions still catches expected violations\n    {\n      code: '<><Foo>{moo}</Foo></>',\n      options: [{ allowExpressions: true }],\n      errors: [{ messageId: 'NeedsMoreChildren', type: 'JSXFragment' }],\n      output: '<Foo>{moo}</Foo>',\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-one-expression-per-line.js",
    "content": "/**\n * @fileoverview Limit to one expression per line in JSX\n * @author Mark Ivan Allen <Vydia.com>\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-one-expression-per-line');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-one-expression-per-line', rule, {\n  valid: parsers.all([\n    {\n      code: '<App />',\n    },\n    {\n      code: `\n\\t\\t\\t\\t<AllTabs>\n\\t\\t\\t\\t\\tFail\n\\t\\t\\t\\t</AllTabs>\n      `,\n    },\n    {\n      code: `\n\\t\\t\\t\\t<TagsWithTabs>\n          Fail\n\\t\\t\\t\\t</TagsWithTabs>\n      `,\n    },\n    {\n      code: `\n        <ClosedTagWithTabs>\n          Fail\n\\t\\t\\t\\t</ClosedTagWithTabs>\n      `,\n    },\n    {\n      code: `\n\\t\\t\\t\\t<OpenTagWithTabs>\n          OK\n        </OpenTagWithTabs>\n      `,\n    },\n    {\n      code: `\n        <TextWithTabs>\n\\t\\t\\t\\t\\t\\tOK\n        </TextWithTabs>\n      `,\n    },\n    {\n      code: `\n        <AllSpaces>\n          OK\n        </AllSpaces>\n      `,\n    },\n    {\n      code: '<App></App>',\n    },\n    {\n      code: '<App foo=\"bar\" />',\n    },\n    {\n      code: `\n        <App>\n          <Foo />\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <Foo />\n          <Bar />\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <Foo></Foo>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          foo bar baz  whatever\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App>\n          <Foo>\n          </Foo>\n        </App>\n      `,\n    },\n    {\n      code: `\n        <App\n          foo=\"bar\"\n        >\n        <Foo />\n        </App>\n      `,\n    },\n    {\n      code: `\n        <\n        App\n        >\n          <\n            Foo\n          />\n        </\n        App\n        >\n      `,\n    },\n    {\n      code: '<App>foo</App>',\n      options: [{ allow: 'literal' }],\n    },\n    {\n      code: '<App>123</App>',\n      options: [{ allow: 'literal' }],\n    },\n    {\n      code: '<App>foo</App>',\n      options: [{ allow: 'single-child' }],\n    },\n    {\n      code: '<App>{\"foo\"}</App>',\n      options: [{ allow: 'single-child' }],\n    },\n    {\n      code: '<App>123</App>',\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: '<App>foo</App>',\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: '<App>{\"foo\"}</App>',\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: '<App>{<Bar />}</App>',\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: '<App>{foo && <Bar />}</App>',\n      options: [{ allow: 'single-child' }],\n    },\n    {\n      code: '<App><Foo /></App>',\n      options: [{ allow: 'single-child' }],\n    },\n    {\n      code: '<></>',\n      features: ['fragment'],\n    },\n    {\n      code: `\n        <>\n          <Foo />\n        </>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        <>\n          <Foo />\n          <Bar />\n        </>\n      `,\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: '<App>Hello {name}</App>',\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: `\n        <App>\n          Hello {name} there!\n        </App>`,\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: `\n        <App>\n          Hello {<Bar />} there!\n        </App>`,\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: `\n        <App>\n          Hello {(<Bar />)} there!\n        </App>`,\n      options: [{ allow: 'non-jsx' }],\n    },\n    {\n      code: `\n        <App>\n          Hello {(() => <Bar />)()} there!\n        </App>`,\n      options: [{ allow: 'non-jsx' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App>{\"foo\"}</App>\n      `,\n      output: `\n        <App>\n{\"foo\"}\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"foo\"}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>foo</App>\n      `,\n      output: `\n        <App>\nfoo\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          foo {\"bar\"}\n        </div>\n      `,\n      output: `\n        <div>\n          foo${' '/* intentional trailing space */}\n{' '}\n{\"bar\"}\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"bar\"}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          {\"foo\"} bar\n        </div>\n      `,\n      output: `\n        <div>\n          {\"foo\"}\n{' '}\nbar\n</div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' bar        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo /><Bar />\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo />\n<Bar />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <span />foo\n        </div>\n      `,\n      output: `\n        <div>\n          <span />\nfoo\n</div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'foo        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <span />{\"foo\"}\n        </div>\n      `,\n      output: `\n        <div>\n          <span />\n{\"foo\"}\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"foo\"}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          {\"foo\"} { I18n.t('baz') }\n        </div>\n      `,\n      output: `\n        <div>\n          {\"foo\"}${' '/* intentional trailing space */}\n{' '}\n{ I18n.t('baz') }\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{ I18n.t(\\'baz\\') }' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}>{ bar } <Text/> { I18n.t('baz') }</Text>\n      `,\n      output: `\n        <Text style={styles.foo}>\n{ bar }${' '/* intentional trailing space */}\n{' '}\n<Text/>${' '/* intentional trailing space */}\n{' '}\n{ I18n.t('baz') }\n</Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{ bar }' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Text' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{ I18n.t(\\'baz\\') }' },\n        },\n      ],\n      parserOptions,\n\n    },\n    {\n      code: `\n        <Text style={styles.foo}> <Bar/> <Baz/></Text>\n      `,\n      output: `\n        <Text style={styles.foo}>${' '/* intentional trailing space */}\n{' '}\n<Bar/>${' '/* intentional trailing space */}\n{' '}\n<Baz/>\n</Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Baz' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}> <Bar/> <Baz/> <Bunk/> <Bruno/> </Text>\n      `,\n      output: `\n        <Text style={styles.foo}>${' '/* intentional trailing space */}\n{' '}\n<Bar/>${' '/* intentional trailing space */}\n{' '}\n<Baz/>${' '/* intentional trailing space */}\n{' '}\n<Bunk/>${' '/* intentional trailing space */}\n{' '}\n<Bruno/>\n{' '}\n </Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Baz' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bunk' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bruno' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}> <Bar /></Text>\n      `,\n      output: `\n        <Text style={styles.foo}>${' '/* intentional trailing space */}\n{' '}\n<Bar />\n</Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}> <Bar />\n        </Text>\n      `,\n      output: `\n        <Text style={styles.foo}>${' '/* intentional trailing space */}\n{' '}\n<Bar />\n        </Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}>\n          <Bar /> <Baz />\n        </Text>\n      `,\n      output: `\n        <Text style={styles.foo}>\n          <Bar />${' '/* intentional trailing space */}\n{' '}\n<Baz />\n        </Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Baz' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}>\n          <Bar /> <Baz />\n        </Text>\n      `,\n      output: `\n        <Text style={styles.foo}>\n          <Bar />${' '/* intentional trailing space */}\n{' '}\n<Baz />\n        </Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Baz' },\n        },\n      ],\n      options: [{ allow: 'non-jsx' }],\n      parserOptions,\n    },\n    {\n      code: `\n        <Text style={styles.foo}>\n          { bar } { I18n.t('baz') }\n        </Text>\n      `,\n      output: `\n        <Text style={styles.foo}>\n          { bar }${' '/* intentional trailing space */}\n{' '}\n{ I18n.t('baz') }\n        </Text>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{ I18n.t(\\'baz\\') }' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          foo<input />\n        </div>\n      `,\n      output: `\n        <div>\n          foo\n<input />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'input' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          {\"foo\"}<span />\n        </div>\n      `,\n      output: `\n        <div>\n          {\"foo\"}\n<span />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'span' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          foo <input />\n        </div>\n      `,\n      output: `\n        <div>\n          foo${' '/* intentional trailing space */}\n{' '}\n<input />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'input' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <input /> foo\n        </div>\n      `,\n      output: `\n        <div>\n          <input />\n{' '}\nfoo\n</div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' foo        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <span /> <input />\n        </div>\n      `,\n      output: `\n        <div>\n          <span />${' '/* intentional trailing space */}\n{' '}\n<input />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'input' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <span />\n        {' '}<input />\n        </div>\n      `,\n      output: `\n        <div>\n          <span />\n        {' '}\n<input />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'input' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          {\"foo\"} <input />\n        </div>\n      `,\n      output: `\n        <div>\n          {\"foo\"}${' '/* intentional trailing space */}\n{' '}\n<input />\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'input' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n          <input /> {\"foo\"}\n        </div>\n      `,\n      output: `\n        <div>\n          <input />${' '/* intentional trailing space */}\n{' '}\n{\"foo\"}\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"foo\"}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo></Foo><Bar></Bar>\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo></Foo>\n<Bar></Bar>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n        <Foo></Foo></App>\n      `,\n      output: `\n        <App>\n        <Foo></Foo>\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App><Foo />\n        </App>\n      `,\n      output: `\n        <App>\n<Foo />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n        <Foo/></App>\n      `,\n      output: `\n        <App>\n        <Foo/>\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App><Foo\n        />\n        </App>\n      `,\n      output: `\n        <App>\n<Foo\n        />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n        >\n        <Foo /></App>\n      `,\n      output: `\n        <App\n        >\n        <Foo />\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n        >\n        <Foo\n        /></App>\n      `,\n      output: `\n        <App\n        >\n        <Foo\n        />\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App\n        ><Foo />\n        </App>\n      `,\n      output: `\n        <App\n        >\n<Foo />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo></Foo\n        ></App>\n      `,\n      output: `\n        <App>\n          <Foo></Foo\n        >\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo></\n        Foo></App>\n      `,\n      output: `\n        <App>\n          <Foo></\n        Foo>\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo></\n        Foo><Bar />\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo></\n        Foo>\n<Bar />\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo>\n            <Bar /></Foo>\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo>\n            <Bar />\n</Foo>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo>\n            <Bar> baz </Bar>\n          </Foo>\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo>\n            <Bar>\n{' '}\nbaz\n{' '}\n</Bar>\n          </Foo>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' baz ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // Would be nice to handle in one pass, but multipass works fine.\n      code: `\n        <App>\n          foo {\"bar\"} baz\n        </App>\n      `,\n      output: `\n        <App>\n          foo${' '/* intentional trailing space */}\n{' '}\n{\"bar\"} baz\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"bar\"}' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' baz        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // Would be nice to handle in one pass, but multipass works fine.\n      code: `\n        <App>\n          foo {\"bar\"}\n        </App>\n      `,\n      output: `\n        <App>\n          foo${' '/* intentional trailing space */}\n{' '}\n{\"bar\"}\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"bar\"}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // Would be nice to handle in one pass, but multipass works fine.\n      code: `\n        <App>\n          foo\n        {' '}\n        {\"bar\"} baz\n        </App>\n      `,\n      output: `\n        <App>\n          foo\n        {' '}\n        {\"bar\"}\n{' '}\nbaz\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' baz        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // Would be nice to handle in one pass, but multipass works fine.\n      code: `\n        <App>\n\n          foo {\"bar\"} baz\n\n        </App>\n      `,\n      output: `\n        <App>\n\n          foo${' '/* intentional trailing space */}\n{' '}\n{\"bar\"} baz\n\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"bar\"}' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' baz        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // Would be nice to handle in one pass, but multipass works fine.\n      code: `\n        <App>\n\n          foo\n        {' '}\n        {\"bar\"} baz\n\n        </App>\n      `,\n      output: `\n        <App>\n\n          foo\n        {' '}\n        {\"bar\"}\n{' '}\nbaz\n\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: ' baz        ' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>{\n          foo\n        }</App>\n      `,\n      output: `\n        <App>\n{\n          foo\n        }\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{          foo        }' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App> {\n          foo\n        } </App>\n      `,\n      output: `\n        <App>${' '/* intentional trailing space */}\n{' '}\n{\n          foo\n        }\n{' '}\n </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{          foo        }' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n        {' '}\n        {\n          foo\n        } </App>\n      `,\n      output: `\n        <App>\n        {' '}\n        {\n          foo\n        }\n{' '}\n </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{          foo        }' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <App><Foo /></App>\n      `,\n      output: `\n        <App>\n<Foo />\n</App>\n      `,\n      options: [{ allow: 'none' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>foo</App>\n      `,\n      output: `\n        <App>\nfoo\n</App>\n      `,\n      options: [{ allow: 'none' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>{\"foo\"}</App>\n      `,\n      output: `\n        <App>\n{\"foo\"}\n</App>\n      `,\n      options: [{ allow: 'none' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"foo\"}' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>foo\n        </App>\n      `,\n      output: `\n        <App>\nfoo\n</App>\n      `,\n      options: [{ allow: 'literal' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'foo        ' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App><Foo /></App>\n      `,\n      output: `\n        <App>\n<Foo />\n</App>\n      `,\n      options: [{ allow: 'literal' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App><Foo /></App>\n      `,\n      output: `\n        <App>\n<Foo />\n</App>\n      `,\n      options: [{ allow: 'non-jsx' }],\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App\n          foo=\"1\"\n          bar=\"2\"\n        >baz</App>\n      `,\n      options: [{ allow: 'literal' }],\n      output: `\n        <App\n          foo=\"1\"\n          bar=\"2\"\n        >\nbaz\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App>foo\n        bar\n        </App>\n      `,\n      options: [{ allow: 'literal' }],\n      output: `\n        <App>\nfoo\n        bar\n</App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'foo        bar        ' },\n        },\n      ],\n    },\n    {\n      code: `\n        <>{\"foo\"}</>\n      `,\n      output: `\n        <>\n{\"foo\"}\n</>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"foo\"}' },\n        },\n      ],\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      parserOptions,\n    },\n    {\n      code: `\n        <App>\n          <Foo /><></>\n        </App>\n      `,\n      output: `\n        <App>\n          <Foo />\n<></>\n        </App>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '<></>' },\n        },\n      ],\n      features: ['fragment'],\n      parserOptions,\n    },\n    {\n      code: `\n        <\n        ><Foo />\n        </>\n      `,\n      output: `\n        <\n        >\n<Foo />\n        </>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Foo' },\n        },\n      ],\n      features: ['fragment', 'no-ts-old'],\n      parserOptions,\n    },\n    {\n      code: `\n        <div>\n        <MyComponent>a</MyComponent>\n        <MyOther>{a}</MyOther>\n        </div>\n      `,\n      output: `\n        <div>\n        <MyComponent>\na\n</MyComponent>\n        <MyOther>\n{a}\n</MyOther>\n        </div>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'a' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{a}' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n    // TODO: handle in a single pass\n      code: `\n        const IndexPage = () => (\n          <h1>{\"Hi people\"}<button/></h1>\n        );\n      `,\n      output: `\n        const IndexPage = () => (\n          <h1>\n{\"Hi people\"}<button/></h1>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: '{\"Hi people\"}' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'button' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        const IndexPage = () => (\n          <h1>\n{\"Hi people\"}<button/></h1>\n        );\n      `,\n      output: `\n        const IndexPage = () => (\n          <h1>\n{\"Hi people\"}\n<button/>\n</h1>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'button' },\n        },\n      ],\n      parserOptions,\n    },\n    // TODO: handle in a single pass (see above)\n    {\n      code: `\n        <Layout>\n        <p>Welcome to your new Gatsby site.</p>\n        <p>Now go build something great.</p>\n        <h1>Hi people<button/></h1>\n        </Layout>\n      `,\n      output: `\n        <Layout>\n        <p>\nWelcome to your new Gatsby site.\n</p>\n        <p>\nNow go build something great.\n</p>\n        <h1>\nHi people<button/></h1>\n        </Layout>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Welcome to your new Gatsby site.' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Now go build something great.' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Hi people' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'button' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Layout>\n        <p>\nWelcome to your new Gatsby site.\n</p>\n        <p>\nNow go build something great.\n</p>\n        <h1>\nHi people<button/></h1>\n        </Layout>\n      `,\n      output: `\n        <Layout>\n        <p>\nWelcome to your new Gatsby site.\n</p>\n        <p>\nNow go build something great.\n</p>\n        <h1>\nHi people\n<button/>\n</h1>\n        </Layout>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'button' },\n        },\n      ],\n      parserOptions,\n    },\n    // TODO: handle in a single pass\n    {\n      code: `\n        <Layout>\n          <div style={{ maxWidth: \\`300px\\`, marginBottom: \\`1.45rem\\` }}>\n            <Image />\n          </div><Link to=\"/page-2/\">Go to page 2</Link>\n        </Layout>\n      `,\n      output: `\n        <Layout>\n          <div style={{ maxWidth: \\`300px\\`, marginBottom: \\`1.45rem\\` }}>\n            <Image />\n          </div>\n<Link to=\"/page-2/\">Go to page 2</Link>\n        </Layout>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Link' },\n        },\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Go to page 2' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        <Layout>\n          <div style={{ maxWidth: \\`300px\\`, marginBottom: \\`1.45rem\\` }}>\n            <Image />\n          </div>\n<Link to=\"/page-2/\">Go to page 2</Link>\n        </Layout>\n      `,\n      output: `\n        <Layout>\n          <div style={{ maxWidth: \\`300px\\`, marginBottom: \\`1.45rem\\` }}>\n            <Image />\n          </div>\n<Link to=\"/page-2/\">\nGo to page 2\n</Link>\n        </Layout>\n      `,\n      errors: [\n        {\n          messageId: 'moveToNewLine',\n          data: { descriptor: 'Go to page 2' },\n        },\n      ],\n      parserOptions,\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-pascal-case.js",
    "content": "/**\n * @fileoverview Tests for jsx-pascal-case\n * @author Jake Marsh\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-pascal-case');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-pascal-case', rule, {\n  valid: parsers.all([\n    {\n    // The rule must not warn on components that start with a lowercase\n    // because they are interpreted as HTML elements by React\n      code: '<testcomponent />',\n    },\n    {\n      code: '<testComponent />',\n    },\n    {\n      code: '<test_component />',\n    },\n    {\n      code: '<TestComponent />',\n    },\n    {\n      code: '<CSSTransitionGroup />',\n    },\n    {\n      code: '<BetterThanCSS />',\n    },\n    {\n      code: '<TestComponent><div /></TestComponent>',\n    },\n    {\n      code: '<Test1Component />',\n    },\n    {\n      code: '<TestComponent1 />',\n    },\n    {\n      code: '<T3StComp0Nent />',\n    },\n    {\n      code: '<Éurströmming />',\n    },\n    {\n      code: '<Año />',\n    },\n    {\n      code: '<Søknad />',\n    },\n    {\n      code: '<T />',\n    },\n    {\n      code: '<YMCA />',\n      options: [{ allowAllCaps: true }],\n    },\n    {\n      code: '<TEST_COMPONENT />',\n      options: [{ allowAllCaps: true }],\n    },\n    {\n      code: '<Modal.Header />',\n    },\n    {\n      code: '<qualification.T3StComp0Nent />',\n    },\n    {\n      code: '<Modal:Header />',\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<IGNORED />',\n      options: [{ ignore: ['IGNORED'] }],\n    },\n    {\n      code: '<Foo_DEPRECATED />',\n      options: [{ ignore: ['*_D*D'] }],\n    },\n    {\n      code: '<Foo_DEPRECATED />',\n      options: [{ ignore: ['*_+(DEPRECATED|IGNORED)'] }],\n    },\n    {\n      code: '<$ />',\n    },\n    {\n      code: '<_ />',\n    },\n    {\n      code: '<H1>Hello!</H1>',\n    },\n    {\n      code: '<Typography.P />',\n    },\n    {\n      code: '<Styled.h1 />',\n      options: [{ allowNamespace: true }],\n    },\n    {\n      code: '<_TEST_COMPONENT />',\n      options: [{ allowAllCaps: true, allowLeadingUnderscore: true }],\n    },\n    {\n      code: '<_TestComponent />',\n      options: [{ allowLeadingUnderscore: true }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<Test_component />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'Test_component' },\n        },\n      ],\n    },\n    {\n      code: '<TEST_COMPONENT />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'TEST_COMPONENT' },\n        },\n      ],\n    },\n    {\n      code: '<YMCA />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'YMCA' },\n        },\n      ],\n    },\n    {\n      code: '<_TEST_COMPONENT />',\n      options: [{ allowAllCaps: true }],\n      errors: [\n        {\n          messageId: 'usePascalOrSnakeCase',\n          data: { name: '_TEST_COMPONENT' },\n        },\n      ],\n    },\n    {\n      code: '<TEST_COMPONENT_ />',\n      options: [{ allowAllCaps: true }],\n      errors: [\n        {\n          messageId: 'usePascalOrSnakeCase',\n          data: { name: 'TEST_COMPONENT_' },\n        },\n      ],\n    },\n    {\n      code: '<TEST-COMPONENT />',\n      options: [{ allowAllCaps: true }],\n      errors: [\n        {\n          messageId: 'usePascalOrSnakeCase',\n          data: { name: 'TEST-COMPONENT' },\n        },\n      ],\n    },\n    {\n      code: '<__ />',\n      options: [{ allowAllCaps: true }],\n      errors: [\n        {\n          messageId: 'usePascalOrSnakeCase',\n          data: { name: '__' },\n        },\n      ],\n    },\n    {\n      code: '<_div />',\n      options: [{ allowLeadingUnderscore: true }],\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: '_div' },\n        },\n      ],\n    },\n    {\n      code: '<__ />',\n      options: [{ allowAllCaps: true, allowLeadingUnderscore: true }],\n      errors: [\n        {\n          messageId: 'usePascalOrSnakeCase',\n          data: { name: '__' },\n        },\n      ],\n    },\n    {\n      code: '<$a />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: '$a' },\n        },\n      ],\n    },\n    {\n      code: '<Foo_DEPRECATED />',\n      options: [{ ignore: ['*_FOO'] }],\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'Foo_DEPRECATED' },\n        },\n      ],\n    },\n    {\n      code: '<Styled.h1 />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'h1' },\n        },\n      ],\n    },\n    {\n      code: '<$Typography.P />',\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: '$Typography' },\n        },\n      ],\n    },\n    {\n      code: '<STYLED.h1 />',\n      options: [{ allowNamespace: true }],\n      errors: [\n        {\n          messageId: 'usePascalCase',\n          data: { name: 'STYLED' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-props-no-multi-spaces.js",
    "content": "/**\n * @fileoverview Disallow multiple spaces between inline JSX props\n * @author Adrian Moennich\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-props-no-multi-spaces');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-props-no-multi-spaces', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        <App />\n      `,\n    },\n    {\n      code: `\n        <App foo />\n      `,\n    },\n    {\n      code: `\n        <App foo bar />\n      `,\n    },\n    {\n      code: `\n        <App foo=\"with  spaces   \" bar />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo bar />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo\n          bar />\n      `,\n    },\n    {\n      code: `\n        <App\n          foo {...test}\n          bar />\n      `,\n    },\n    {\n      code: '<App<T> foo bar />',\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: '<Foo.Bar baz=\"quux\" />',\n    },\n    {\n      code: '<Foobar.Foo.Bar.Baz.Qux.Quux.Quuz.Corge.Grault.Garply.Waldo.Fred.Plugh xyzzy=\"thud\" />',\n    },\n    {\n      code: `\n        <button\n          title=\"Some button 8\"\n          type=\"button\"\n        />\n      `,\n    },\n    {\n      code: `\n        <button\n          title=\"Some button 8\"\n          onClick={(value) => {\n            console.log(value);\n          }}\n          type=\"button\"\n        />\n      `,\n    },\n    (semver.satisfies(eslintPkg.version, '> 3') ? [\n      {\n        code: `\n          <button\n            title=\"Some button 2\"\n            // this is a comment\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n      },\n      {\n        code: `\n          <button\n            title=\"Some button 2\"\n            // this is a comment\n            // this is a second comment\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n      },\n      {\n        code: `\n          <App\n            foo=\"Some button 3\" // comment\n            // comment\n            bar=\"\"\n          />\n        `,\n      },\n      {\n        code: `\n          <button\n            title=\"Some button 3\"\n            /* this is a multiline comment\n                ...\n                ... */\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n      },\n    ] : [])\n  )),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        <App  foo />\n      `,\n      output: `\n        <App foo />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'App', prop2: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo=\"with  spaces   \"   bar />\n      `,\n      output: `\n        <App foo=\"with  spaces   \" bar />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'foo', prop2: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo  bar />\n      `,\n      output: `\n        <App foo bar />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'foo', prop2: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App  foo   bar />\n      `,\n      output: `\n        <App foo bar />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'App', prop2: 'foo' },\n        },\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'foo', prop2: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        <App foo  {...test}  bar />\n      `,\n      output: `\n        <App foo {...test} bar />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'foo', prop2: 'test' },\n        },\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'test', prop2: 'bar' },\n        },\n      ],\n    },\n    {\n      code: '<Foo.Bar  baz=\"quux\" />',\n      output: '<Foo.Bar baz=\"quux\" />',\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'Foo.Bar', prop2: 'baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        <Foobar.Foo.Bar.Baz.Qux.Quux.Quuz.Corge.Grault.Garply.Waldo.Fred.Plugh  xyzzy=\"thud\" />\n      `,\n      output: `\n        <Foobar.Foo.Bar.Baz.Qux.Quux.Quuz.Corge.Grault.Garply.Waldo.Fred.Plugh xyzzy=\"thud\" />\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneSpace',\n          data: { prop1: 'Foobar.Foo.Bar.Baz.Qux.Quux.Quuz.Corge.Grault.Garply.Waldo.Fred.Plugh', prop2: 'xyzzy' },\n        },\n      ],\n    },\n    {\n      code: `\n        <button\n          title='Some button'\n\n          type=\"button\"\n        />\n      `,\n      output: `\n        <button\n          title='Some button'${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\\n'}\n          type=\"button\"\n        />\n      `,\n      errors: [\n        {\n          messageId: 'noLineGap',\n          data: { prop1: 'title', prop2: 'type' },\n        },\n      ],\n    },\n    {\n      code: `\n        <button\n          title=\"Some button 4\"\n\n          onClick={(value) => {\n            console.log(value);\n          }}\n\n          type=\"button\"\n        />\n      `,\n      output: `\n        <button\n          title=\"Some button 4\"${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\\n'}\n          onClick={(value) => {\n            console.log(value);\n          }}${semver.satisfies(eslintPkg.version, '> 3') ? '' : '\\n'}\n          type=\"button\"\n        />\n      `,\n      errors: [\n        {\n          messageId: 'noLineGap',\n          data: { prop1: 'title', prop2: 'onClick' },\n        },\n        {\n          messageId: 'noLineGap',\n          data: { prop1: 'onClick', prop2: 'type' },\n        },\n      ],\n    },\n    (semver.satisfies(eslintPkg.version, '> 3') ? [\n      {\n        code: `\n          <button\n            title=\"Some button 5\"\n            // this is a comment\n            onClick={(value) => {\n              console.log(value);\n            }}\n\n            type=\"button\"\n          />\n        `,\n        output: `\n          <button\n            title=\"Some button 5\"\n            // this is a comment\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n        errors: [\n          {\n            messageId: 'noLineGap',\n            data: { prop1: 'onClick', prop2: 'type' },\n          },\n        ],\n      },\n      {\n        code: `\n          <button\n            title=\"Some button 6\"\n            // this is a comment\n            // second comment\n\n            onClick={(value) => {\n              console.log(value);\n            }}\n\n            type=\"button\"\n          />\n        `,\n        output: `\n          <button\n            title=\"Some button 6\"\n            // this is a comment\n            // second comment\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n        errors: [\n          {\n            messageId: 'noLineGap',\n            data: { prop1: 'title', prop2: 'onClick' },\n          },\n          {\n            messageId: 'noLineGap',\n            data: { prop1: 'onClick', prop2: 'type' },\n          },\n        ],\n      },\n      {\n        code: `\n          <button\n            title=\"Some button 7\"\n            /*this is a\n              multiline\n              comment\n            */\n\n            onClick={(value) => {\n              console.log(value);\n            }}\n\n            type=\"button\"\n          />\n        `,\n        output: `\n          <button\n            title=\"Some button 7\"\n            /*this is a\n              multiline\n              comment\n            */\n            onClick={(value) => {\n              console.log(value);\n            }}\n            type=\"button\"\n          />\n        `,\n        errors: [\n          {\n            messageId: 'noLineGap',\n            data: { prop1: 'title', prop2: 'onClick' },\n          },\n          {\n            messageId: 'noLineGap',\n            data: { prop1: 'onClick', prop2: 'type' },\n          },\n        ],\n      },\n    ] : [])\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-props-no-spread-multi.js",
    "content": "/**\n * @fileoverview Tests for jsx-props-no-spread-multi\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-props-no-spread-multi');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst expectedError = { messageId: 'noMultiSpreading' };\n\nruleTester.run('jsx-props-no-spread-multi', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        const a = {};\n        <App {...a} />\n      `,\n    },\n    {\n      code: `\n        const a = {};\n        const b = {};\n        <App {...a} {...b} />\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        const props = {};\n        <App {...props} {...props} />\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {};\n        <div {...props} a=\"a\" {...props} />\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {};\n        <div {...props} {...props} {...props} />\n      `,\n      errors: [expectedError, expectedError],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-props-no-spreading.js",
    "content": "/**\n * @fileoverview Tests for jsx-props-no-spreading\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-props-no-spreading');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst expectedError = { messageId: 'noSpreading' };\n\nruleTester.run('jsx-props-no-spreading', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        const {one_prop, two_prop} = props;\n        <App one_prop={one_prop} two_prop={two_prop}/>\n      `,\n    },\n    {\n      code: `\n        const {one_prop, two_prop} = props;\n        <div one_prop={one_prop} two_prop={two_prop}></div>\n      `,\n    },\n    {\n      code: `\n        const newProps = {...props};\n        <App one_prop={newProps.one_prop} two_prop={newProps.two_prop} style={{...styles}}/>\n      `,\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        <App>\n           <Image {...props}/>\n           <img {...props}/>\n        </App>\n      `,\n      options: [{ exceptions: ['Image', 'img'] }],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <Image {...props}/>\n           <img src={src} alt={alt}/>\n        </App>\n      `,\n      options: [{ custom: 'ignore' }],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <Image {...props}/>\n           <img {...props}/>\n        </App>\n      `,\n      options: [{ custom: 'enforce', html: 'ignore', exceptions: ['Image'] }],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <img {...props}/>\n           <Image src={src} alt={alt}/>\n           <div {...someOtherProps}/>\n        </App>\n      `,\n      options: [{ html: 'ignore' }],\n    },\n    {\n      code: `\n        <App>\n          <Foo {...{ prop1, prop2, prop3 }} />\n        </App>\n      `,\n      options: [{ explicitSpread: 'ignore' }],\n    },\n    {\n      code: `\n        const props = {};\n        <App>\n           <components.Group {...props}/>\n           <Nav.Item {...props}/>\n        </App>\n      `,\n      options: [{ exceptions: ['components.Group', 'Nav.Item'] }],\n    },\n    {\n      code: `\n        const props = {};\n        <App>\n           <components.Group {...props}/>\n           <Nav.Item {...props}/>\n        </App>\n      `,\n      options: [{ custom: 'ignore' }],\n    },\n    {\n      code: `\n        const props = {};\n        <App>\n           <components.Group {...props}/>\n           <Nav.Item {...props}/>\n        </App>\n      `,\n      options: [\n        {\n          custom: 'enforce',\n          html: 'ignore',\n          exceptions: ['components.Group', 'Nav.Item'],\n        },\n      ],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        <App {...props}/>\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <div {...props}></div>\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <App {...props} some_other_prop={some_other_prop}/>\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        <App>\n           <Image {...props}/>\n           <span {...props}/>\n        </App>\n      `,\n      options: [{ exceptions: ['Image', 'img'] }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <Image {...props}/>\n           <img {...props}/>\n        </App>\n      `,\n      options: [{ custom: 'ignore' }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <Image {...props}/>\n           <img {...props}/>\n        </App>\n      `,\n      options: [{ html: 'ignore', exceptions: ['Image', 'img'] }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <Image {...props}/>\n           <img {...props}/>\n           <div {...props}/>\n        </App>\n      `,\n      options: [{ custom: 'ignore', html: 'ignore', exceptions: ['Image', 'img'] }],\n      errors: [expectedError, expectedError],\n    },\n    {\n      code: `\n        const props = {src: \"dummy.jpg\", alt: \"dummy\"};\n        const { src, alt } = props;\n        <App>\n           <img {...props}/>\n           <Image {...props}/>\n        </App>\n      `,\n      options: [{ html: 'ignore' }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <App>\n          <Foo {...{ prop1, prop2, prop3 }} />\n        </App>\n      `,\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <App>\n          <Foo {...{ prop1, ...rest }} />\n        </App>\n      `,\n      options: [{ explicitSpread: 'ignore' }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <App>\n          <Foo {...{ ...props }} />\n        </App>\n      `,\n      options: [{ explicitSpread: 'ignore' }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        <App>\n          <Foo {...props } />\n        </App>\n      `,\n      options: [{ explicitSpread: 'ignore' }],\n      errors: [expectedError],\n    },\n    {\n      code: `\n        const props = {};\n        <App>\n           <components.Group {...props}/>\n           <Nav.Item {...props}/>\n        </App>\n      `,\n      options: [{ exceptions: ['components.DropdownIndicator', 'Nav.Item'] }],\n      errors: [expectedError],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-sort-default-props.js",
    "content": "/**\n * @fileoverview Tests for jsx-sort-default-props\n * @author Vladimir Kattsov\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst semver = require('semver');\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/jsx-sort-default-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-sort-default-props', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            A: PropTypes.any,\n            Z: PropTypes.string,\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              A: \"A\",\n              Z: \"Z\",\n              a: \"a\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            A: PropTypes.any,\n            z: PropTypes.string,\n            Z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              a: \"a\",\n              A: \"A\",\n              z: \"z\",\n              Z: \"Z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              a: \"a\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            AA: PropTypes.any,\n            ZZ: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              AA: \"AA\",\n              ZZ: \"ZZ\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.string,\n          z: PropTypes.string\n        };\n        First.propTypes.justforcheck = PropTypes.string;\n        First.defaultProps = {\n          a: a,\n          z: z\n        };\n        First.defaultProps.justforcheck = \"justforcheck\";\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.any,\n          A: PropTypes.any,\n          z: PropTypes.string,\n          Z: PropTypes.string\n        };\n        First.defaultProps = {\n          a: \"a\",\n          A: \"A\",\n          z: \"z\",\n          Z: \"Z\"\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"aria-controls\": \"aria-controls\"\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n    // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          propTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          defaultProps: {\n            a: \"a\",\n            c: \"c\",\n            b: \"b\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            barRequired: PropTypes.func.isRequired,\n            onBar: PropTypes.func,\n            z: PropTypes.any\n          },\n          getDefaultProps: function() {\n            return {\n              barRequired: \"barRequired\",\n              onBar: \"onBar\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            ...c.defaultProps,\n            a: \"a\"\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps,\n            e: \"e\",\n            f: \"f\",\n            ...d.defaultProps\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          c: \"c\",\n          ...defaults,\n          a: \"a\"\n        };\n      `,\n    },\n    {\n      code: `\n        const propTypes = require('./externalPropTypes')\n        const defaultProps = require('./externalDefaultProps')\n        const TextFieldLabel = (props) => {\n          return <div />;\n        };\n        TextFieldLabel.propTypes = propTypes;\n        TextFieldLabel.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        export const propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n        };\n        export const defaultProps = {\n            a: \"a\",\n            z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const First = (props) => <div />;\n        export const propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            z: PropTypes.string,\n        };\n        export const defaultProps = {\n            ...defaults,\n            a: \"a\",\n            z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n\n        First.defaultProps = {\n            a: PropTypes.any,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func,\n            z: PropTypes.string,\n        };\n      `,\n    }\n  )),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            c: \"c\",\n            b: \"b\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 11,\n          column: 13,\n          type: 'Property',\n        },\n      ], /* ,\n      output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      ` */\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            c: \"c\",\n            b: \"b\",\n            a: \"a\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any\n          };\n          static defaultProps = {\n            Z: \"Z\",\n            a: \"a\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            Z: \"Z\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            Z: \"Z\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.any\n          };\n          static defaultProps = {\n            Z: \"Z\",\n            a: \"a\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"b\": \"b\",\n          \"a\": \"a\"\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"b\": \"b\"\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string,\n          \"c\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"c\": \"c\",\n          \"b\": \"b\",\n          \"a\": \"a\"\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string,\n          \"c\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"b\": \"b\",\n          \"c\": \"c\"\n        };\n      `, */\n      errors: 2,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"B\": \"B\",\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"B\": \"B\",\n          \"a\": \"a\",\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    // {\n    // Disabled test for comments -- fails\n    //   code: `\n    //     class Hello extends React.Component {\n    //       render() {\n    //         return <div>Hello</div>;\n    //       }\n    //     }\n    //     Hello.propTypes = {\n    //       \"a\": PropTypes.string,\n    //       \"B\": PropTypes.string,\n    //     };\n    //     Hello.defaultProps = {\n    //       /* a */\n    //       \"a\": \"a\",\n    //       /* B */\n    //       \"B\": \"B\",\n    //     };\n    //   `,\n    //   errors: [\n    //     {\n    //       messageId: 'propsNotSorted',\n    //       line: 14,\n    //       column: 3,\n    //       type: 'Property'\n    //     }\n    //   ],\n    //   output: `\n    //     class Hello extends React.Component {\n    //       render() {\n    //         return <div>Hello</div>;\n    //       }\n    //     }\n    //     Hello.propTypes = {\n    //       \"a\": PropTypes.string,\n    //       \"B\": PropTypes.string,\n    //     };\n    //     Hello.defaultProps = {\n    //       /* B */\n    //       \"B\": \"B\",\n    //       /* a */\n    //       \"a\": \"a\",\n    //     };\n    //   `\n    // },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"B\": \"B\",\n          \"a\": \"a\",\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"B\": \"B\",\n        };\n      `, */\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        const propTypes = {\n          z: PropTypes.string,\n          a: PropTypes.any,\n        };\n        const defaultProps = {\n          z: \"z\",\n          a: \"a\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n      /* output: `\n        const First = (props) => <div />;\n        const propTypes = {\n          z: PropTypes.string,\n          a: PropTypes.any,\n        };\n        const defaultProps = {\n          a: \"a\",\n          z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            a: \"a\",\n            ...c.defaultProps\n          }\n        }\n      `,\n      /* output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 10,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            a: \"a\",\n            ...c.defaultProps,\n            f: \"f\",\n            e: \"e\",\n            ...d.defaultProps\n          }\n        }\n      `,\n      /* output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps,\n            e: \"e\",\n            f: \"f\",\n            ...d.defaultProps\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          c: \"c\",\n          a: \"a\",\n          ...defaults,\n        };\n      `,\n      /* output: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          a: \"a\",\n          c: \"c\",\n          ...defaults,\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 16,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n\n        First.defaultProps = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func,\n        };\n      `,\n      errors: [\n        { messageId: 'propsNotSorted', line: 11 },\n        { messageId: 'propsNotSorted', line: 12 },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-sort-props.js",
    "content": "/**\n * @fileoverview Enforce props alphabetical sorting\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-sort-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nconst expectedError = {\n  messageId: 'sortPropsByAlpha',\n  type: 'JSXIdentifier',\n};\nconst expectedCallbackError = {\n  messageId: 'listCallbacksLast',\n  type: 'JSXIdentifier',\n};\nconst expectedShorthandFirstError = {\n  messageId: 'listShorthandFirst',\n  type: 'JSXIdentifier',\n};\nconst expectedShorthandLastError = {\n  messageId: 'listShorthandLast',\n  type: 'JSXIdentifier',\n};\nconst expectedMultilineFirstError = {\n  messageId: 'listMultilineFirst',\n  type: 'JSXIdentifier',\n};\nconst expectedMultilineLastError = {\n  messageId: 'listMultilineLast',\n  type: 'JSXIdentifier',\n};\nconst expectedReservedFirstError = {\n  messageId: 'listReservedPropsFirst',\n  type: 'JSXIdentifier',\n};\nconst expectedSortFirstError = {\n  messageId: 'listSortFirstPropsFirst',\n  type: 'JSXIdentifier',\n};\nconst expectedEmptyReservedFirstError = {\n  messageId: 'listIsEmpty',\n};\nconst expectedInvalidReservedFirstError = {\n  messageId: 'noUnreservedProps',\n  data: { unreservedWords: 'notReserved' },\n};\nconst callbacksLastArgs = [{ callbacksLast: true }];\nconst ignoreCaseAndCallbackLastArgs = [\n  {\n    callbacksLast: true,\n    ignoreCase: true,\n  },\n];\nconst reservedFirstAndCallbacksLastArgs = [\n  {\n    callbacksLast: true,\n    reservedFirst: true,\n  },\n];\nconst shorthandFirstArgs = [{ shorthandFirst: true }];\nconst shorthandLastArgs = [{ shorthandLast: true }];\nconst shorthandAndCallbackLastArgs = [\n  {\n    callbacksLast: true,\n    shorthandLast: true,\n  },\n];\nconst ignoreCaseArgs = [{ ignoreCase: true }];\nconst noSortAlphabeticallyArgs = [{ noSortAlphabetically: true }];\nconst sortAlphabeticallyArgs = [{ noSortAlphabetically: false }];\nconst reservedFirstAsBooleanArgs = [{ reservedFirst: true }];\nconst reservedFirstAsArrayArgs = [{ reservedFirst: ['children', 'dangerouslySetInnerHTML', 'key'] }];\nconst reservedFirstWithNoSortAlphabeticallyArgs = [\n  {\n    noSortAlphabetically: true,\n    reservedFirst: true,\n  },\n];\nconst reservedFirstWithShorthandLast = [\n  {\n    reservedFirst: true,\n    shorthandLast: true,\n  },\n];\nconst reservedFirstAsEmptyArrayArgs = [{ reservedFirst: [] }];\nconst reservedFirstAsInvalidArrayArgs = [{ reservedFirst: ['notReserved'] }];\nconst multilineFirstArgs = [{ multiline: 'first' }];\nconst multilineAndShorthandFirstArgs = [\n  {\n    multiline: 'first',\n    shorthandFirst: true,\n  },\n];\nconst multilineLastArgs = [{ multiline: 'last' }];\nconst multilineAndShorthandAndCallbackLastArgs = [\n  {\n    multiline: 'last',\n    shorthandLast: true,\n    callbacksLast: true,\n  },\n];\nconst sortFirstArgs = [{ sortFirst: ['className'] }];\nconst sortFirstMultipleArgs = [{ sortFirst: ['className', 'id'] }];\nconst sortFirstWithIgnoreCaseArgs = [{ sortFirst: ['className'], ignoreCase: true }];\nconst sortFirstWithReservedFirstArgs = [\n  {\n    sortFirst: ['className'],\n    reservedFirst: true,\n  },\n];\nconst sortFirstWithShorthandFirstArgs = [\n  {\n    sortFirst: ['className'],\n    shorthandFirst: true,\n  },\n];\nconst sortFirstWithCallbacksLastArgs = [\n  {\n    sortFirst: ['className'],\n    callbacksLast: true,\n  },\n];\nconst sortFirstWithMultilineFirstArgs = [\n  {\n    sortFirst: ['className'],\n    multiline: 'first',\n  },\n];\n\nruleTester.run('jsx-sort-props', rule, {\n  valid: parsers.all([].concat(\n    { code: '<App />;' },\n    { code: '<App {...this.props} />;' },\n    { code: '<App a b c />;' },\n    { code: '<App {...this.props} a b c />;' },\n    { code: '<App c {...this.props} a b />;' },\n    { code: '<App a=\"c\" b=\"b\" c=\"a\" />;' },\n    { code: '<App {...this.props} a=\"c\" b=\"b\" c=\"a\" />;' },\n    { code: '<App c=\"a\" {...this.props} a=\"c\" b=\"b\" />;' },\n    { code: '<App A a />;' },\n    { code: '<App aB aa/>;' },\n    { code: '<App aA aB />;' },\n    { code: '<App aB aaa />;' },\n    { code: '<App a aB aa />;' },\n    { code: '<App Number=\"2\" name=\"John\" />;' },\n    // Ignoring case\n    { code: '<App a A />;', options: ignoreCaseArgs },\n    { code: '<App aa aB />;', options: ignoreCaseArgs },\n    { code: '<App a B c />;', options: ignoreCaseArgs },\n    { code: '<App A b C />;', options: ignoreCaseArgs },\n    { code: '<App name=\"John\" Number=\"2\" />;', options: ignoreCaseArgs },\n    // Sorting callbacks below all other props\n    { code: '<App a z onBar onFoo />;', options: callbacksLastArgs },\n    { code: '<App z onBar onFoo />;', options: ignoreCaseAndCallbackLastArgs },\n    // Sorting shorthand props before others\n    { code: '<App a b=\"b\" />;', options: shorthandFirstArgs },\n    { code: '<App z a=\"a\" />;', options: shorthandFirstArgs },\n    { code: '<App x y z a=\"a\" b=\"b\" />;', options: shorthandFirstArgs },\n    { code: '<App a=\"a\" b=\"b\" x y z />;', options: shorthandLastArgs },\n    {\n      code: '<App a=\"a\" b=\"b\" x y z onBar onFoo />;',\n      options: shorthandAndCallbackLastArgs,\n    },\n    // Sorting multiline props before others\n    {\n      code: `\n        <App\n          a={{\n            aA: 1,\n          }}\n          b\n        />\n      `,\n      options: multilineFirstArgs,\n    },\n    {\n      code: `\n        <App\n          a={{\n            aA: 1,\n          }}\n          b={[\n            1,\n          ]}\n          c\n          d\n        />\n      `,\n      options: multilineFirstArgs,\n    },\n    {\n      code: `\n        <App\n          a\n          b\n          c={{\n            cC: 1,\n          }}\n          d={[\n            1,\n          ]}\n          e=\"1\"\n        />\n      `,\n      options: multilineAndShorthandFirstArgs,\n    },\n    // Sorting multiline props after others\n    {\n      code: `\n        <App\n          a\n          b={{\n            bB: 1,\n          }}\n        />\n      `,\n      options: multilineLastArgs,\n    },\n    {\n      code: `\n        <App\n          a\n          b\n          c=\"1\"\n          d={{\n            dD: 1,\n          }}\n          e={[\n            1,\n          ]}\n        />\n      `,\n      options: multilineLastArgs,\n    },\n    {\n      code: `\n        <App\n          a={1}\n          b=\"1\"\n          c={{\n            cC: 1,\n          }}\n          d={() => (\n            1\n          )}\n          e\n          f\n          onClick={() => ({\n            gG: 1,\n          })}\n        />\n      `,\n      options: multilineAndShorthandAndCallbackLastArgs,\n    },\n    // noSortAlphabetically\n    { code: '<App a b />;', options: noSortAlphabeticallyArgs },\n    { code: '<App b a />;', options: noSortAlphabeticallyArgs },\n    // reservedFirst\n    {\n      code: '<App children={<App />} key={0} ref=\"r\" a b c />',\n      options: reservedFirstAsBooleanArgs,\n    },\n    {\n      code: '<App children={<App />} key={0} ref=\"r\" a b c dangerouslySetInnerHTML={{__html: \"EPR\"}} />',\n      options: reservedFirstAsBooleanArgs,\n    },\n    {\n      code: '<App children={<App />} key={0} a ref=\"r\" />',\n      options: reservedFirstAsArrayArgs,\n    },\n    {\n      code: '<App children={<App />} key={0} a dangerouslySetInnerHTML={{__html: \"EPR\"}} ref=\"r\" />',\n      options: reservedFirstAsArrayArgs,\n    },\n    {\n      code: '<App ref=\"r\" key={0} children={<App />} b a c />',\n      options: reservedFirstWithNoSortAlphabeticallyArgs,\n    },\n    {\n      code: '<div ref=\"r\" dangerouslySetInnerHTML={{__html: \"EPR\"}} key={0} children={<App />} b a c />',\n      options: reservedFirstWithNoSortAlphabeticallyArgs,\n    },\n    {\n      code: '<App key=\"key\" c=\"c\" b />',\n      options: reservedFirstWithShorthandLast,\n    },\n    {\n      code: `\n        <RawFileField\n          onChange={handleChange}\n          onFileRemove={asMedia ? null : handleRemove}\n          {...props}\n        />\n      `,\n    },\n    semver.satisfies(process.version, '>= 13') ? {\n      code: `\n        <RawFileField\n          onFileRemove={asMedia ? null : handleRemove}\n          onChange={handleChange}\n          {...props}\n        />\n      `,\n      options: [{ locale: 'sk-SK' }],\n    } : [],\n    // sortFirst\n    { code: '<App className=\"test\" name=\"John\" />;', options: sortFirstArgs },\n    { code: '<App className=\"test\" id=\"test\" name=\"John\" />;', options: sortFirstMultipleArgs },\n    { code: '<App className=\"test\" id=\"test\" />;', options: sortFirstMultipleArgs },\n    { code: '<App className=\"test\" a b c />;', options: sortFirstArgs },\n    { code: '<App className=\"test\" id=\"test\" a b c />;', options: sortFirstMultipleArgs },\n    { code: '<App className=\"test\" key={0} name=\"John\" />;', options: sortFirstWithReservedFirstArgs },\n    { code: '<App className=\"test\" a name=\"John\" />;', options: sortFirstWithShorthandFirstArgs },\n    { code: '<App className=\"test\" name=\"John\" onClick={handleClick} />;', options: sortFirstWithCallbacksLastArgs },\n    {\n      code: `\n        <App\n          className=\"test\"\n          data={{\n            test: 1,\n          }}\n          name=\"John\"\n        />\n      `,\n      options: sortFirstWithMultilineFirstArgs,\n    },\n    { code: '<App classname=\"test\" a=\"test2\" />;', options: sortFirstWithIgnoreCaseArgs }\n  )),\n  invalid: parsers.all([].concat(\n    {\n      code: '<App b a />;',\n      errors: [expectedError],\n      output: '<App a b />;',\n    },\n    {\n      code: '<App aB a />;',\n      errors: [expectedError],\n      output: '<App a aB />;',\n    },\n    {\n      code: '<App fistName=\"John\" tel={5555555} name=\"John Smith\" lastName=\"Smith\" Number=\"2\" />;',\n      errors: [expectedError, expectedError, expectedError],\n      output: '<App Number=\"2\" fistName=\"John\" lastName=\"Smith\" name=\"John Smith\" tel={5555555} />;',\n    },\n    {\n      code: '<App aa aB />;',\n      errors: [expectedError],\n      output: '<App aB aa />;',\n    },\n    {\n      code: '<App aB aA />;',\n      errors: [expectedError],\n      output: '<App aA aB />;',\n    },\n    {\n      code: '<App aaB aA />;',\n      errors: [expectedError],\n      output: '<App aA aaB />;',\n    },\n    {\n      code: '<App aaB aaa aA a />;',\n      errors: [expectedError, expectedError],\n      output: '<App a aA aaB aaa />;',\n    },\n    {\n      code: '<App {...this.props} b a />;',\n      errors: [expectedError],\n      output: '<App {...this.props} a b />;',\n    },\n    {\n      code: '<App c {...this.props} b a />;',\n      errors: [expectedError],\n      output: '<App c {...this.props} a b />;',\n    },\n    {\n      code: '<App fistName=\"John\" tel={5555555} name=\"John Smith\" lastName=\"Smith\" Number=\"2\" />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError, expectedError, expectedError],\n      output: '<App fistName=\"John\" lastName=\"Smith\" name=\"John Smith\" Number=\"2\" tel={5555555} />;',\n    },\n    {\n      code: '<App B a />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError],\n      output: '<App a B />;',\n    },\n    {\n      code: '<App B A c />;',\n      options: ignoreCaseArgs,\n      errors: [expectedError],\n      output: '<App A B c />;',\n    },\n    {\n      code: '<App c=\"a\" a=\"c\" b=\"b\" />;',\n      output: '<App a=\"c\" b=\"b\" c=\"a\" />;',\n      errors: 2,\n    },\n    {\n      code: '<App {...this.props} c=\"a\" a=\"c\" b=\"b\" />;',\n      output: '<App {...this.props} a=\"c\" b=\"b\" c=\"a\" />;',\n      errors: 2,\n    },\n    {\n      code: '<App d=\"d\" b=\"b\" {...this.props} c=\"a\" a=\"c\" />;',\n      output: '<App b=\"b\" d=\"d\" {...this.props} a=\"c\" c=\"a\" />;',\n      errors: 2,\n    },\n    {\n      code: `\n        <App\n          a={true}\n          z\n          r\n          _onClick={function(){}}\n          onHandle={function(){}}\n          {...this.props}\n          b={false}\n          {...otherProps}\n        >\n          {test}\n        </App>\n      `,\n      output: `\n        <App\n          _onClick={function(){}}\n          a={true}\n          onHandle={function(){}}\n          r\n          z\n          {...this.props}\n          b={false}\n          {...otherProps}\n        >\n          {test}\n        </App>\n      `,\n      errors: 3,\n    },\n    {\n      code: '<App b={2} c={3} d={4} e={5} f={6} g={7} h={8} i={9} j={10} k={11} a={1} />',\n      output: '<App a={1} b={2} c={3} d={4} e={5} f={6} g={7} h={8} i={9} j={10} k={11} />',\n      errors: 1,\n    },\n    {\n      code: `\n        <List\n          className={className}\n          onStageAnswer={onStageAnswer}\n          onCommitAnswer={onCommitAnswer}\n          isFocused={isFocused}\n          direction={direction}\n          allowMultipleSelection={allowMultipleSelection}\n          measureLongestChildNode={measureLongestChildNode}\n          layoutItemsSize={layoutItemsSize}\n          handleAppScroll={handleAppScroll}\n          isActive={isActive}\n          resetSelection={resetSelection}\n          onKeyboardChoiceHovered={onKeyboardChoiceHovered}\n          keyboardShortcutType\n        />\n      `,\n      output: `\n        <List\n          allowMultipleSelection={allowMultipleSelection}\n          className={className}\n          direction={direction}\n          handleAppScroll={handleAppScroll}\n          isActive={isActive}\n          isFocused={isFocused}\n          keyboardShortcutType\n          layoutItemsSize={layoutItemsSize}\n          measureLongestChildNode={measureLongestChildNode}\n          onCommitAnswer={onCommitAnswer}\n          onKeyboardChoiceHovered={onKeyboardChoiceHovered}\n          onStageAnswer={onStageAnswer}\n          resetSelection={resetSelection}\n        />\n      `,\n      errors: 10,\n    },\n    {\n      code: `\n        <CreateNewJob\n          closed={false}\n          flagOptions={flagOptions}\n          jobHeight={300}\n          jobWidth={200}\n          campaign='Some Campaign name'\n          campaignStart={moment('2018-07-28 00:00:00')}\n          campaignFinish={moment('2018-09-01 00:00:00')}\n          jobNumber={'Job Number can be a String'}\n          jobTemplateOptions={jobTemplateOptions}\n          numberOfPages={30}\n          onChange={onChange}\n          onClose={onClose}\n          spreadSheetTemplateOptions={spreadSheetTemplateOptions}\n          stateMachineOptions={stateMachineOptions}\n          workflowTemplateOptions={workflowTemplateOptions}\n          workflowTemplateSteps={workflowTemplateSteps}\n          description='Some description for this job'\n\n          jobTemplate='1'\n          stateMachine='1'\n          flag='1'\n          spreadSheetTemplate='1'\n          workflowTemplate='1'\n          validation={validation}\n          onSubmit={onSubmit}\n        />\n      `,\n      output: `\n        <CreateNewJob\n          campaign='Some Campaign name'\n          campaignFinish={moment('2018-09-01 00:00:00')}\n          campaignStart={moment('2018-07-28 00:00:00')}\n          closed={false}\n          description='Some description for this job'\n          flag='1'\n          flagOptions={flagOptions}\n          jobHeight={300}\n          jobNumber={'Job Number can be a String'}\n          jobTemplate='1'\n          jobTemplateOptions={jobTemplateOptions}\n          jobWidth={200}\n          numberOfPages={30}\n          onChange={onChange}\n          onClose={onClose}\n          onSubmit={onSubmit}\n          spreadSheetTemplate='1'\n\n          spreadSheetTemplateOptions={spreadSheetTemplateOptions}\n          stateMachine='1'\n          stateMachineOptions={stateMachineOptions}\n          validation={validation}\n          workflowTemplate='1'\n          workflowTemplateOptions={workflowTemplateOptions}\n          workflowTemplateSteps={workflowTemplateSteps}\n        />\n      `,\n      errors: 13,\n    },\n    {\n      code: '<App key=\"key\" b c=\"c\" />',\n      errors: [expectedShorthandLastError],\n      options: reservedFirstWithShorthandLast,\n      output: '<App key=\"key\" c=\"c\" b />',\n    },\n    {\n      code: '<App ref=\"ref\" key=\"key\" isShorthand veryLastAttribute=\"yes\" />',\n      errors: [expectedError, expectedShorthandLastError],\n      options: reservedFirstWithShorthandLast,\n      output: '<App key=\"key\" ref=\"ref\" veryLastAttribute=\"yes\" isShorthand />',\n    },\n    {\n      code: '<App a z onFoo onBar />;',\n      errors: [expectedError],\n      options: callbacksLastArgs,\n      output: '<App a z onBar onFoo />;',\n    },\n    {\n      code: '<App a onBar onFoo z />;',\n      errors: [expectedCallbackError],\n      options: callbacksLastArgs,\n      output: '<App a z onBar onFoo />;',\n    },\n    {\n      code: '<App a=\"a\" b />;',\n      errors: [expectedShorthandFirstError],\n      options: shorthandFirstArgs,\n      output: '<App b a=\"a\" />;',\n    },\n    {\n      code: '<App z x a=\"a\" />;',\n      errors: [expectedError],\n      options: shorthandFirstArgs,\n      output: '<App x z a=\"a\" />;',\n    },\n    {\n      code: '<App b a=\"a\" />;',\n      errors: [expectedShorthandLastError],\n      options: shorthandLastArgs,\n      output: '<App a=\"a\" b />;',\n    },\n    {\n      code: '<App a=\"a\" onBar onFoo z x />;',\n      errors: [expectedError],\n      options: shorthandLastArgs,\n      output: '<App a=\"a\" onBar onFoo x z />;',\n    },\n    {\n      code: '<App b a />;',\n      errors: [expectedError],\n      options: sortAlphabeticallyArgs,\n      output: '<App a b />;',\n    },\n    // reservedFirst\n    {\n      code: '<App a key={1} />',\n      options: reservedFirstAsBooleanArgs,\n      errors: [expectedReservedFirstError],\n      output: '<App key={1} a />',\n    },\n    {\n      code: '<div a dangerouslySetInnerHTML={{__html: \"EPR\"}} />',\n      options: reservedFirstAsBooleanArgs,\n      errors: [expectedReservedFirstError],\n      output: '<div dangerouslySetInnerHTML={{__html: \"EPR\"}} a />',\n    },\n    {\n      code: '<App ref=\"r\" key={2} b />',\n      options: reservedFirstAsBooleanArgs,\n      errors: [expectedError],\n      output: '<App key={2} ref=\"r\" b />',\n    },\n    {\n      code: '<App key={2} b a />',\n      options: reservedFirstAsBooleanArgs,\n      output: '<App key={2} a b />',\n      errors: [expectedError],\n    },\n    {\n      code: '<App b a />',\n      options: reservedFirstAsBooleanArgs,\n      output: '<App a b />',\n      errors: [expectedError],\n    },\n    {\n      code: '<App dangerouslySetInnerHTML={{__html: \"EPR\"}} e key={2} b />',\n      options: reservedFirstAsBooleanArgs,\n      output: '<App key={2} b dangerouslySetInnerHTML={{__html: \"EPR\"}} e />',\n      errors: [expectedReservedFirstError, expectedError],\n    },\n    {\n      code: '<App key={3} children={<App />} />',\n      options: reservedFirstAsArrayArgs,\n      errors: [expectedError],\n      output: '<App children={<App />} key={3} />',\n    },\n    {\n      code: '<App z ref=\"r\" />',\n      options: reservedFirstWithNoSortAlphabeticallyArgs,\n      errors: [expectedReservedFirstError],\n      output: '<App ref=\"r\" z />',\n    },\n    {\n      code: '<App key={4} />',\n      options: reservedFirstAsEmptyArrayArgs,\n      errors: [expectedEmptyReservedFirstError],\n    },\n    {\n      code: '<App key={5} />',\n      options: reservedFirstAsInvalidArrayArgs,\n      errors: [expectedInvalidReservedFirstError],\n    },\n    {\n      code: '<App onBar z />;',\n      output: '<App z onBar />;',\n      options: reservedFirstAndCallbacksLastArgs,\n      errors: [expectedCallbackError],\n    // multiline first\n    },\n    {\n      code: `\n        <App\n          a\n          b={{\n            bB: 1,\n          }}\n        />\n      `,\n      options: multilineFirstArgs,\n      errors: [expectedMultilineFirstError],\n      output: `\n        <App\n          b={{\n            bB: 1,\n          }}\n          a\n        />\n      `,\n    },\n    {\n      code: `\n        <App\n          a={1}\n          b={{\n            bB: 1,\n          }}\n          c\n        />\n      `,\n      options: multilineAndShorthandFirstArgs,\n      errors: [expectedMultilineFirstError, expectedShorthandFirstError],\n      output: `\n        <App\n          c\n          b={{\n            bB: 1,\n          }}\n          a={1}\n        />\n      `,\n    },\n    // multiline last\n    {\n      code: `\n        <App\n          a={{\n            aA: 1,\n          }}\n          b\n        />\n      `,\n      options: multilineLastArgs,\n      errors: [expectedMultilineLastError],\n      output: `\n        <App\n          b\n          a={{\n            aA: 1,\n          }}\n        />\n      `,\n    },\n    {\n      code: `\n        <App\n          a={{\n            aA: 1,\n          }}\n          b\n          inline={1}\n          onClick={() => ({\n            c: 1\n          })}\n          d=\"dD\"\n          e={() => ({\n            eE: 1\n          })}\n          f\n        />\n      `,\n      options: multilineAndShorthandAndCallbackLastArgs,\n      errors: [\n        {\n          messageId: 'listShorthandLast',\n          line: 6,\n        },\n        {\n          messageId: 'listCallbacksLast',\n          line: 8,\n        },\n      ],\n      output: `\n        <App\n          d=\"dD\"\n          inline={1}\n          a={{\n            aA: 1,\n          }}\n          e={() => ({\n            eE: 1\n          })}\n          b\n          f\n          onClick={() => ({\n            c: 1\n          })}\n        />\n      `,\n    },\n    {\n      code: `\n        <Typography\n          float\n          className={classNames(classes.inputWidth, {\n            [classes.noBorder]: isActive === \"values\",\n          })}\n          disabled={isDisabled}\n          initialValue={computePercentage(number, count)}\n          InputProps={{\n            ...customInputProps,\n          }}\n          key={index}\n          isRequired\n          {...sharedTypographyProps}\n          ref={textRef}\n          min=\"0\"\n          name=\"fieldName\"\n          placeholder={getTranslation(\"field\")}\n          onValidate={validate}\n          inputProps={{\n            className: inputClassName,\n          }}\n          outlined\n          {...rest}\n        />\n      `,\n      options: [\n        {\n          multiline: 'last',\n          shorthandFirst: true,\n          callbacksLast: true,\n          reservedFirst: true,\n          ignoreCase: true,\n        },\n      ],\n      output: `\n        <Typography\n          key={index}\n          float\n          isRequired\n          disabled={isDisabled}\n          initialValue={computePercentage(number, count)}\n          className={classNames(classes.inputWidth, {\n            [classes.noBorder]: isActive === \"values\",\n          })}\n          InputProps={{\n            ...customInputProps,\n          }}\n          {...sharedTypographyProps}\n          ref={textRef}\n          outlined\n          min=\"0\"\n          name=\"fieldName\"\n          placeholder={getTranslation(\"field\")}\n          inputProps={{\n            className: inputClassName,\n          }}\n          onValidate={validate}\n          {...rest}\n        />\n      `,\n      errors: [\n        {\n          messageId: 'listMultilineLast',\n          line: 4,\n        },\n        {\n          messageId: 'listReservedPropsFirst',\n          line: 12,\n        },\n        {\n          messageId: 'listShorthandFirst',\n          line: 13,\n        },\n        {\n          messageId: 'listCallbacksLast',\n          line: 19,\n        },\n      ],\n    },\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <foo\n          m={0}\n          n={0} // this is n\n          o={0}\n          c={0} // this is c\n          // fofof\n          f={0} // this is f\n          a={0}\n          b={0}\n          d={0}\n        />\n      `,\n      output: `\n        <foo\n          a={0}\n          b={0}\n          d={0}\n          m={0}\n          n={0} // this is n\n          o={0}\n          c={0} // this is c\n          // fofof\n          f={0} // this is f\n        />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 6,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 8,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 9,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 10,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 11,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <foo\n          m={0}\n          n={0} // this is n\n          o={0}\n          c={0} // this is c\n          f={0} // this is f\n          e={0}\n          a={0}\n          b={0}\n          d={0}\n        />\n      `,\n      output: `\n        <foo\n          a={0}\n          b={0}\n          c={0} // this is c\n          d={0}\n          e={0}\n          f={0} // this is f\n          m={0}\n          n={0} // this is n\n          o={0}\n        />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 6,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 7,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 8,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 9,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 10,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 11,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <foo\n          a1={0}\n          g={0}\n          d={0} // comment for d\n          // comment for d and aa\n          aa={0}\n          c={0} // comment for c\n          // comment for c and e\n          e={1}\n          ab={1} // comment for ab\n          f={0}\n        />\n      `,\n      output: `\n        <foo\n          a1={0}\n          ab={1} // comment for ab\n          f={0}\n          g={0}\n          c={0} // comment for c\n          // comment for c and e\n          e={1}\n          d={0} // comment for d\n          // comment for d and aa\n          aa={0}\n        />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 5,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 7,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 8,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 10,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 11,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 12,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <foo\n          a1={0}\n          ab={1}\n          // comment for ab and f\n          f={0}\n          g={0}\n          c={0} // comment for c\n          // comment for c and e\n          e={1}\n          d={0}\n          aa={1} // comment for aa\n        />\n      `,\n      output: `\n        <foo\n          a1={0}\n          aa={1} // comment for aa\n          d={0}\n          g={0}\n          ab={1}\n          // comment for ab and f\n          f={0}\n          c={0} // comment for c\n          // comment for c and e\n          e={1}\n        />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 8,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 10,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 11,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 12,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <foo a={0} b={1} /* comment for b and ab */ ab={1} aa={0} />\n      `,\n      output: `\n        <foo a={0} aa={0} b={1} /* comment for b and ab */ ab={1} />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        <ReactJson src={rowResult} name=\"data\" collapsed={4} collapseStringsAfterLength={60} onEdit={onEdit} /* onDelete={onEdit} */ />\n      `,\n      output: `\n        <ReactJson collapseStringsAfterLength={60} collapsed={4} name=\"data\" src={rowResult} onEdit={onEdit} /* onDelete={onEdit} */ />\n      `,\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 2,\n        },\n      ],\n    } : [],\n    {\n      code: `\n        <Page\n          // Pass all the props to the Page component.\n          {...props}\n          // Use the platform specific props from the doc.ts file.\n          {...TemplatePageProps[platform]}\n          // Use the getSubTitle helper function to get the page header subtitle from the active platform.\n          subTitle={getSubTitle(platform)}\n          // You can define custom sections using the \\`otherSections\\` prop.\n          // Here it is using a method that takes the platform as an argument to return the correct array of section props.\n          otherSections={_otherSections(platform) as IPageSectionProps[]}\n\n          // You can hide the side rail by setting \\`showSideRail\\` to false.\n          // showSideRail={false}\n\n          // You can pass a custom className to the page wrapper if needed.\n          // className=\"customPageClassName\"\n        />\n      `,\n      features: ['ts', 'no-babel-old'],\n      errors: [\n        {\n          messageId: 'sortPropsByAlpha',\n          line: 11,\n        },\n      ],\n    },\n    // sortFirst\n    {\n      code: '<App name=\"John\" className=\"test\" />;',\n      options: sortFirstArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" name=\"John\" />;',\n    },\n    {\n      code: '<App id=\"test\" className=\"test\" name=\"John\" />;',\n      options: sortFirstMultipleArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" id=\"test\" name=\"John\" />;',\n    },\n    {\n      code: '<App a className=\"test\" b />;',\n      options: sortFirstArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" a b />;',\n    },\n    {\n      code: '<App key={0} className=\"test\" name=\"John\" />;',\n      options: sortFirstWithReservedFirstArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" key={0} name=\"John\" />;',\n    },\n    {\n      code: '<App a className=\"test\" name=\"John\" />;',\n      options: sortFirstWithShorthandFirstArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" a name=\"John\" />;',\n    },\n    {\n      code: '<App name=\"John\" onClick={handleClick} className=\"test\" />;',\n      options: sortFirstWithCallbacksLastArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" name=\"John\" onClick={handleClick} />;',\n    },\n    {\n      code: `\n        <App\n          name=\"John\"\n          className=\"test\"\n          data={{\n            test: 1,\n          }}\n        />\n      `,\n      options: sortFirstWithMultilineFirstArgs,\n      errors: [expectedSortFirstError, expectedMultilineFirstError],\n      output: `\n        <App\n          className=\"test\"\n          data={{\n            test: 1,\n          }}\n          name=\"John\"\n        />\n      `,\n    },\n    {\n      code: '<App name=\"John\" classname=\"test\" />;',\n      options: sortFirstWithIgnoreCaseArgs,\n      errors: [expectedSortFirstError],\n      output: '<App classname=\"test\" name=\"John\" />;',\n    },\n    {\n      code: '<App className=\"test\" id=\"test\" tel={5555555} name=\"John\" />;',\n      options: sortFirstMultipleArgs,\n      errors: [expectedError],\n      output: '<App className=\"test\" id=\"test\" name=\"John\" tel={5555555} />;',\n    },\n    {\n      code: '<App id=\"test\" className=\"test\" id=\"test2\" />;',\n      options: sortFirstMultipleArgs,\n      errors: [expectedSortFirstError],\n      output: '<App className=\"test\" id=\"test\" id=\"test2\" />;',\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-space-before-closing.js",
    "content": "/**\n * @fileoverview Validate spacing before closing bracket in JSX.\n * @author ryym\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-space-before-closing');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-space-before-closing', rule, {\n  valid: parsers.all([\n    {\n      code: '<App />',\n    },\n    {\n      code: '<App foo />',\n    },\n    {\n      code: '<App foo={bar} />',\n    },\n    {\n      code: '<App {...props} />',\n    },\n    {\n      code: '<App></App>',\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n        />\n      `,\n    },\n    {\n      code: '<App/>',\n      options: ['never'],\n    },\n    {\n      code: '<App foo/>',\n      options: ['never'],\n    },\n    {\n      code: '<App foo={bar}/>',\n      options: ['never'],\n    },\n    {\n      code: '<App {...props}/>',\n      options: ['never'],\n    },\n    {\n      code: '<App></App>',\n      options: ['never'],\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n        />\n      `,\n      options: ['never'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<App/>',\n      output: '<App />',\n      errors: [{ messageId: 'needSpaceBeforeClose' }],\n    },\n    {\n      code: '<App foo/>',\n      output: '<App foo />',\n      errors: [{ messageId: 'needSpaceBeforeClose' }],\n    },\n    {\n      code: '<App foo={bar}/>',\n      output: '<App foo={bar} />',\n      errors: [{ messageId: 'needSpaceBeforeClose' }],\n    },\n    {\n      code: '<App {...props}/>',\n      output: '<App {...props} />',\n      errors: [{ messageId: 'needSpaceBeforeClose' }],\n    },\n    {\n      code: '<App />',\n      output: '<App/>',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceBeforeClose' }],\n    },\n    {\n      code: '<App foo />',\n      output: '<App foo/>',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceBeforeClose' }],\n    },\n    {\n      code: '<App foo={bar} />',\n      output: '<App foo={bar}/>',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceBeforeClose' }],\n    },\n    {\n      code: '<App {...props} />',\n      output: '<App {...props}/>',\n      options: ['never'],\n      errors: [{ messageId: 'noSpaceBeforeClose' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-tag-spacing.js",
    "content": "/**\n * @fileoverview Tests for jsx-tag-spacing\n * @author Diogo Franco (Kovensky)\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-tag-spacing');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------------\n\n// generate options object that disables checks other than the tested one\n\nfunction closingSlashOptions(option) {\n  return [\n    {\n      closingSlash: option,\n      beforeSelfClosing: 'allow',\n      afterOpening: 'allow',\n      beforeClosing: 'allow',\n    },\n  ];\n}\n\nfunction beforeSelfClosingOptions(option) {\n  return [\n    {\n      closingSlash: 'allow',\n      beforeSelfClosing: option,\n      afterOpening: 'allow',\n      beforeClosing: 'allow',\n    },\n  ];\n}\n\nfunction afterOpeningOptions(option) {\n  return [\n    {\n      closingSlash: 'allow',\n      beforeSelfClosing: 'allow',\n      afterOpening: option,\n      beforeClosing: 'allow',\n    },\n  ];\n}\n\nfunction beforeClosingOptions(option) {\n  return [\n    {\n      closingSlash: 'allow',\n      beforeSelfClosing: 'allow',\n      afterOpening: 'allow',\n      beforeClosing: option,\n    },\n  ];\n}\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-tag-spacing', rule, {\n  valid: parsers.all([\n    {\n      code: '<App />',\n    },\n    {\n      code: '<App />',\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: '<App foo />',\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: '<App foo={bar} />',\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: '<App {...props} />',\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: '<App></App>',\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n        />\n      `,\n      options: beforeSelfClosingOptions('always'),\n    },\n    {\n      code: '<App/>',\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: '<App />',\n      options: beforeSelfClosingOptions('proportional-always'),\n    },\n    {\n      code: '<App foo />',\n      options: beforeSelfClosingOptions('proportional-always'),\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n          blat\n        >\n          hello\n        </App>\n      `,\n      options: beforeClosingOptions('proportional-always'),\n    },\n    {\n      code: `\n        <App foo={bar}>\n          hello\n        </App>\n      `,\n      options: beforeClosingOptions('proportional-always'),\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n        />\n      `,\n      options: beforeSelfClosingOptions('proportional-always'),\n    },\n    {\n      code: '<App foo/>',\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: '<App foo={bar}/>',\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: '<App {...props}/>',\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: '<App></App>',\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n        />\n      `,\n      options: beforeSelfClosingOptions('never'),\n    },\n    {\n      code: '<App/>;',\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: '<App />;',\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: '<div className=\"bar\"></div>;',\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: '<div className=\"bar\"></ div>;',\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: '<App prop=\"foo\">< /App>',\n      options: closingSlashOptions('always'),\n      features: ['no-ts'],\n    },\n    {\n      code: '<p/ >',\n      options: closingSlashOptions('always'),\n    },\n    {\n      code: '<App/>',\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '<App></App>',\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '< App></ App>',\n      options: afterOpeningOptions('always'),\n      features: ['no-ts'],\n    },\n    {\n      code: '< App/>',\n      options: afterOpeningOptions('always'),\n    },\n    {\n      code: `\n        <\n        App/>\n      `,\n      options: afterOpeningOptions('allow-multiline'),\n    },\n    {\n      code: '<App />',\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: '<App></App>',\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: `\n        <App\n        foo=\"bar\"\n        >\n        </App>\n      `,\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: `\n        <App\n           foo=\"bar\"\n        >\n        </App>\n      `,\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: '<App ></App >',\n      options: beforeClosingOptions('always'),\n    },\n    {\n      code: `\n        <App\n        foo=\"bar\"\n        >\n        </App >\n      `,\n      options: beforeClosingOptions('always'),\n    },\n    {\n      code: `\n        <App\n            foo=\"bar\"\n        >\n        </App >\n      `,\n      options: beforeClosingOptions('always'),\n    },\n    {\n      code: '<App/>',\n      options: [\n        {\n          closingSlash: 'never',\n          beforeSelfClosing: 'never',\n          afterOpening: 'never',\n          beforeClosing: 'never',\n        },\n      ],\n    },\n    {\n      code: '< App / >',\n      options: [\n        {\n          closingSlash: 'always',\n          beforeSelfClosing: 'always',\n          afterOpening: 'always',\n          beforeClosing: 'always',\n        },\n      ],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<App/>',\n      output: '<App />',\n      options: beforeSelfClosingOptions('always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: '<App foo/>',\n      output: '<App foo />',\n      options: beforeSelfClosingOptions('always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: '<App foo={bar}/>',\n      output: '<App foo={bar} />',\n      options: beforeSelfClosingOptions('always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: '<App {...props}/>',\n      output: '<App {...props} />',\n      options: beforeSelfClosingOptions('always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: '<App />',\n      output: '<App/>',\n      options: beforeSelfClosingOptions('never'),\n      errors: [{ messageId: 'beforeSelfCloseNoSpace' }],\n    },\n    {\n      code: '<App foo />',\n      output: '<App foo/>',\n      options: beforeSelfClosingOptions('never'),\n      errors: [{ messageId: 'beforeSelfCloseNoSpace' }],\n    },\n    {\n      code: '<App foo={bar} />',\n      output: '<App foo={bar}/>',\n      options: beforeSelfClosingOptions('never'),\n      errors: [{ messageId: 'beforeSelfCloseNoSpace' }],\n    },\n    {\n      code: '<App/>',\n      output: '<App />',\n      options: beforeSelfClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: '<App foo/>',\n      output: '<App foo />',\n      options: beforeSelfClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedSpace' }],\n    },\n    {\n      code: `\n        <App\n          foo={bar}/>`,\n      output: `\n        <App\n          foo={bar}\n/>`,\n      options: beforeSelfClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedNewline' }],\n    },\n    {\n      code: `\n        <App\n          foo={bar} />`,\n      output: `\n        <App\n          foo={bar}${' '}\n/>`,\n      options: beforeSelfClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeSelfCloseNeedNewline' }],\n    },\n    {\n      code: `\n        <App\n          foo={bar}\n          blat >\n          hello\n        </App>\n      `,\n      output: `\n        <App\n          foo={bar}\n          blat${' '}\n>\n          hello\n        </App>\n      `,\n      options: beforeClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeCloseNeedNewline' }],\n    },\n    {\n      code: `\n        <App\n          foo={bar}>\n          hello\n        </App>\n      `,\n      output: `\n        <App\n          foo={bar}\n>\n          hello\n        </App>\n      `,\n      options: beforeClosingOptions('proportional-always'),\n      errors: [{ messageId: 'beforeCloseNeedNewline' }],\n    },\n    {\n      code: '<App {...props} />',\n      output: '<App {...props}/>',\n      options: beforeSelfClosingOptions('never'),\n      errors: [{ messageId: 'beforeSelfCloseNoSpace' }],\n    },\n    {\n      code: '<App/ >;',\n      output: '<App/>;',\n      errors: [{ messageId: 'selfCloseSlashNoSpace' }],\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: `\n        <App_selfCloseSlashNoSpace/\n        >\n      `,\n      output: `\n        <App_selfCloseSlashNoSpace/>\n      `,\n      errors: [{ messageId: 'selfCloseSlashNoSpace' }],\n      options: closingSlashOptions('never'),\n    },\n    {\n      code: '<div className=\"bar\">< /div>;',\n      output: '<div className=\"bar\"></div>;',\n      errors: [{ messageId: 'closeSlashNoSpace' }],\n      options: closingSlashOptions('never'),\n      features: ['no-ts'],\n    },\n    {\n      code: `\n        <div className=\"bar\"><\n        /div>;\n      `,\n      output: `\n        <div className=\"bar\"></div>;\n      `,\n      errors: [{ messageId: 'closeSlashNoSpace' }],\n      options: closingSlashOptions('never'),\n      features: ['no-ts'],\n    },\n    {\n      code: '<App prop=\"foo\"></App>',\n      output: '<App prop=\"foo\">< /App>',\n      errors: [{ messageId: 'closeSlashNeedSpace' }],\n      options: closingSlashOptions('always'),\n      features: ['no-ts'],\n    },\n    {\n      code: '<p/>',\n      output: '<p/ >',\n      errors: [{ messageId: 'selfCloseSlashNeedSpace' }],\n      options: closingSlashOptions('always'),\n    },\n    {\n      code: '< App/>',\n      output: '<App/>',\n      errors: [{ messageId: 'afterOpenNoSpace' }],\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '< App></App>',\n      output: '<App></App>',\n      errors: [{ messageId: 'afterOpenNoSpace' }],\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '<App></ App>',\n      output: '<App></App>',\n      errors: [{ messageId: 'afterOpenNoSpace' }],\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '< App></ App>',\n      output: '<App></App>',\n      errors: [\n        { messageId: 'afterOpenNoSpace' },\n        { messageId: 'afterOpenNoSpace' },\n      ],\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: `\n        <\n        App1/>\n      `,\n      output: `\n        <App1/>\n      `,\n      errors: [{ messageId: 'afterOpenNoSpace' }],\n      options: afterOpeningOptions('never'),\n    },\n    {\n      code: '<App2></ App2>',\n      output: '< App2></ App2>',\n      errors: [{ messageId: 'afterOpenNeedSpace' }],\n      options: afterOpeningOptions('always'),\n    },\n    {\n      code: '< App3></App3>',\n      output: '< App3></ App3>',\n      errors: [{ messageId: 'afterOpenNeedSpace' }],\n      options: afterOpeningOptions('always'),\n    },\n    {\n      code: '<App4></App4>',\n      output: '< App4></ App4>',\n      errors: [\n        { messageId: 'afterOpenNeedSpace' },\n        { messageId: 'afterOpenNeedSpace' },\n      ],\n      options: afterOpeningOptions('always'),\n    },\n    {\n      code: '<App5/>',\n      output: '< App5/>',\n      errors: [{ messageId: 'afterOpenNeedSpace' }],\n      options: afterOpeningOptions('always'),\n    },\n    {\n      code: '< App6/>',\n      output: '<App6/>',\n      errors: [{ messageId: 'afterOpenNoSpace' }],\n      options: afterOpeningOptions('allow-multiline'),\n    },\n    {\n      code: '<App7 ></App7>',\n      output: '<App7></App7>',\n      errors: [{ messageId: 'beforeCloseNoSpace' }],\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: '<App8></App8 >',\n      output: '<App8></App8>',\n      errors: [{ messageId: 'beforeCloseNoSpace' }],\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: `\n        <App9\n        foo=\"bar\"\n        >\n        </App9 >\n      `,\n      output: `\n        <App9\n        foo=\"bar\"\n        >\n        </App9>\n      `,\n      errors: [{ messageId: 'beforeCloseNoSpace' }],\n      options: beforeClosingOptions('never'),\n    },\n    {\n      code: '<App10></App10 >',\n      output: '<App10 ></App10 >',\n      errors: [{ messageId: 'beforeCloseNeedSpace' }],\n      options: beforeClosingOptions('always'),\n    },\n    {\n      code: '<App11 ></App11>',\n      output: '<App11 ></App11 >',\n      errors: [{ messageId: 'beforeCloseNeedSpace' }],\n      options: beforeClosingOptions('always'),\n    },\n    {\n      code: `\n        <App12\n        foo=\"bar\"\n        >\n        </App12>\n      `,\n      output: `\n        <App12\n        foo=\"bar\"\n        >\n        </App12 >\n      `,\n      errors: [{ messageId: 'beforeCloseNeedSpace' }],\n      options: beforeClosingOptions('always'),\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-uses-react.js",
    "content": "/**\n * @fileoverview Tests for jsx-uses-react\n * @author Glen Mailer\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst rule = require('../../helpers/getESLintCoreRule')('no-unused-vars');\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst getRuleDefiner = require('../../helpers/getRuleDefiner');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    pragma: 'Foo',\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst ruleDefiner = getRuleDefiner(ruleTester);\nruleDefiner.defineRule('react/jsx-uses-react', require('../../../lib/rules/jsx-uses-react'));\n\nruleTester.run('no-unused-vars', rule, {\n  valid: parsers.all([\n    { code: '/*eslint react/jsx-uses-react:1*/ var React; <div />;' },\n    { code: '/*eslint react/jsx-uses-react:1*/ var React; (function () { <div /> })();' },\n    { code: '/*eslint react/jsx-uses-react:1*/ /** @jsx Foo */ var Foo; <div />;' },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var Foo; <div />;',\n      settings,\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var Frag; <></>;',\n      settings: { react: { fragment: 'Frag' } },\n      features: ['fragment'],\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var React; <></>;',\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: fix for typescript-eslint\n    },\n  ].map(parsers.disableNewTS)),\n  invalid: parsers.all([\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var React;',\n      errors: [{\n        message: '\\'React\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/*eslint react/jsx-uses-react:1*/ ',\n        }],\n      }],\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ /** @jsx Foo */ var React; <div />;',\n      errors: [{\n        message: '\\'React\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/*eslint react/jsx-uses-react:1*/ /** @jsx Foo */  <div />;',\n        }],\n      }],\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var React; <div />;',\n      errors: [{\n        message: '\\'React\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/*eslint react/jsx-uses-react:1*/  <div />;',\n        }],\n      }],\n      settings,\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var Frag; <></>;',\n      errors: [{\n        message: '\\'Frag\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/*eslint react/jsx-uses-react:1*/  <></>;',\n        }],\n      }],\n      features: ['fragment'],\n      settings: { react: { fragment: 'Fragment' } },\n    },\n    {\n      code: '/*eslint react/jsx-uses-react:1*/ var React; <></>;',\n      features: ['fragment'],\n      errors: [{\n        message: '\\'React\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/*eslint react/jsx-uses-react:1*/  <></>;',\n        }],\n      }],\n      settings,\n    },\n  ].map(parsers.disableNewTS).map((test) => {\n    if (!rule.meta.hasSuggestions) {\n      test.errors = test.errors.map((error) => {\n        // https://github.com/eslint/eslint/pull/18352 added suggestions to no-unused-vars in eslint v9.17.0\n        delete error.suggestions;\n        return error;\n      });\n    }\n    return test;\n  })),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-uses-vars.js",
    "content": "/**\n * @fileoverview Tests for jsx-uses-vars\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst ruleNoUnusedVars = require('../../helpers/getESLintCoreRule')('no-unused-vars');\n\nconst rulePreferConst = require('../../helpers/getESLintCoreRule')('prefer-const');\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst getRuleDefiner = require('../../helpers/getRuleDefiner');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst ruleDefiner = getRuleDefiner(ruleTester);\nruleDefiner.defineRule('react/jsx-uses-vars', require('../../../lib/rules/jsx-uses-vars'));\n\nruleTester.run('no-unused-vars', ruleNoUnusedVars, {\n  valid: parsers.all([\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        function foo() {\n          var App;\n          var bar = React.render(<App/>);\n          return bar;\n        };\n        foo()\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        React.render(<App/>);\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var a = 1;\n        React.render(<img src={a} />);\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        function f() {\n          return <App />;\n        }\n        f();\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        <App.Hello />\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        class HelloMessage {};\n        <HelloMessage />\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        class HelloMessage {\n          render() {\n            var HelloMessage = <div>Hello</div>;\n            return HelloMessage;\n          }\n        };\n        <HelloMessage />\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        function foo() {\n          var App = { Foo: { Bar: {} } };\n          var bar = React.render(<App.Foo.Bar/>);\n          return bar;\n        };\n        foo()\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        function foo() {\n          var App = { Foo: { Bar: { Baz: {} } } };\n          var bar = React.render(<App.Foo.Bar.Baz/>);\n          return bar;\n        };\n        foo()\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var object;\n        React.render(<object.Tag />);\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var object;\n        React.render(<object.tag />);\n      `,\n    },\n  ].map(parsers.disableNewTS)),\n  invalid: parsers.all([\n    {\n      code: '/* eslint react/jsx-uses-vars: 1 */ var App;',\n      errors: [{\n        message: '\\'App\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: '/* eslint react/jsx-uses-vars: 1 */ ',\n        }],\n      }],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        var unused;\n        React.render(<App unused=\"\"/>);\n      `,\n      errors: [{\n        message: '\\'unused\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        ${''}\n        React.render(<App unused=\"\"/>);\n      `,\n        }],\n      }],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        var Hello;\n        React.render(<App:Hello/>);\n      `,\n      errors: [\n        {\n          message: '\\'App\\' is defined but never used.',\n          suggestions: [{\n            messageId: 'removeVar',\n            output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        ${''}\n        var Hello;\n        React.render(<App:Hello/>);\n      `,\n          }],\n        },\n        {\n          message: '\\'Hello\\' is defined but never used.',\n          suggestions: [{\n            messageId: 'removeVar',\n            output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var App;\n        ${''}\n        React.render(<App:Hello/>);\n      `,\n          }],\n        },\n      ],\n      features: ['jsx namespace'],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var Button;\n        var Input;\n        React.render(<Button.Input unused=\"\"/>);\n      `,\n      errors: [{\n        message: '\\'Input\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var Button;\n        ${''}\n        React.render(<Button.Input unused=\"\"/>);\n      `,\n        }],\n      }],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        class unused {}\n      `,\n      errors: [{\n        message: '\\'unused\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        ${''}\n      `,\n        }],\n      }],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        class HelloMessage {\n          render() {\n            var HelloMessage = <div>Hello</div>;\n            return HelloMessage;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: '\\'HelloMessage\\' is defined but never used.',\n          line: 3,\n          suggestions: [{\n            messageId: 'removeVar',\n            output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        ${''}\n      `,\n          }],\n        },\n      ],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        import {Hello} from 'Hello';\n        function Greetings() {\n          const Hello = require('Hello').default;\n          return <Hello />;\n        }\n        Greetings();\n      `,\n      errors: [\n        {\n          message: '\\'Hello\\' is defined but never used.',\n          line: 3,\n          suggestions: [{\n            messageId: 'removeVar',\n            output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        ${''}\n        function Greetings() {\n          const Hello = require('Hello').default;\n          return <Hello />;\n        }\n        Greetings();\n      `,\n          }],\n        },\n      ],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        var lowercase;\n        React.render(<lowercase />);\n      `,\n      errors: [{\n        message: '\\'lowercase\\' is defined but never used.',\n        suggestions: [{\n          messageId: 'removeVar',\n          output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        ${''}\n        React.render(<lowercase />);\n      `,\n        }],\n      }],\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars: 1 */\n        function Greetings(div) {\n          return <div />;\n        }\n        Greetings();\n      `,\n      errors: [\n        {\n          message: '\\'div\\' is defined but never used.',\n          line: 3,\n          suggestions: [{\n            messageId: 'removeVar',\n            output: `\n        /* eslint react/jsx-uses-vars: 1 */\n        function Greetings() {\n          return <div />;\n        }\n        Greetings();\n      `,\n          }],\n        },\n      ],\n    },\n  ].map((test) => {\n    if (!ruleNoUnusedVars.meta.hasSuggestions) {\n      test.errors = test.errors.map((error) => {\n        // https://github.com/eslint/eslint/pull/18352 added suggestions to no-unused-vars in eslint v9.17.0\n        delete error.suggestions;\n        return error;\n      });\n    }\n    return test;\n  })),\n});\n\n// Check compatibility with eslint prefer-const rule (#716)\nruleTester.run('prefer-const', rulePreferConst, {\n  valid: [],\n  invalid: parsers.all([\n    {\n      code: `\n        /* eslint react/jsx-uses-vars:1 */\n        let App = <div />;\n        <App />;\n      `,\n      errors: [{ message: '\\'App\\' is never reassigned. Use \\'const\\' instead.' }],\n      output: `\n        /* eslint react/jsx-uses-vars:1 */\n        const App = <div />;\n        <App />;\n      `,\n    },\n    {\n      code: `\n        /* eslint react/jsx-uses-vars:1 */\n        let filters = 'foo';\n        <div>{filters}</div>;\n      `,\n      errors: [{ message: '\\'filters\\' is never reassigned. Use \\'const\\' instead.' }],\n      output: `\n        /* eslint react/jsx-uses-vars:1 */\n        const filters = 'foo';\n        <div>{filters}</div>;\n      `,\n    },\n  ].map(parsers.disableNewTS)),\n});\n"
  },
  {
    "path": "tests/lib/rules/jsx-wrap-multilines.js",
    "content": "/**\n * @fileoverview Prevent missing parentheses around multilines JSX\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/jsx-wrap-multilines');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Constants/Code Snippets\n// ------------------------------------------------------------------------------\n\nconst OPTIONS_ALL_NEW_LINES = {\n  declaration: 'parens-new-line',\n  assignment: 'parens-new-line',\n  return: 'parens-new-line',\n  arrow: 'parens-new-line',\n  condition: 'parens-new-line',\n  logical: 'parens-new-line',\n  prop: 'parens-new-line',\n};\n\nconst OPTIONS_ALL_NEVER = {\n  declaration: 'never',\n  assignment: 'never',\n  return: 'never',\n  arrow: 'never',\n  condition: 'never',\n  logical: 'never',\n  prop: 'never',\n};\n\nconst RETURN_SINGLE_LINE = `\n  var Hello = createReactClass({\n    render: function() {\n      return <p>Hello {this.props.name}</p>;\n    }\n  });\n`;\n\nconst RETURN_PAREN = `\n  var Hello = createReactClass({\n    render: function() {\n      return (<div>\n        <p>Hello {this.props.name}</p>\n      </div>);\n    }\n  });\n`;\n\nconst RETURN_PAREN_FRAGMENT = `\n  var Hello = createReactClass({\n    render: function() {\n      return (<>\n        <p>Hello {this.props.name}</p>\n      </>);\n    }\n  });\n`;\n\nconst RETURN_NO_PAREN = `\n  var Hello = createReactClass({\n    render: function() {\n      return <div>\n        <p>Hello {this.props.name}</p>\n      </div>;\n    }\n  });\n`;\n\nconst RETURN_NO_PAREN_FRAGMENT = `\n  var Hello = createReactClass({\n    render: function() {\n      return <>\n        <p>Hello {this.props.name}</p>\n      </>;\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE = `\n  var Hello = createReactClass({\n    render: function() {\n      return (\n        <div>\n          <p>Hello {this.props.name}</p>\n        </div>\n      );\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE_OPENING = `\n  var Hello = createReactClass({\n    render: function() {\n      return (\n\n      <div>\n        <p>Hello {this.props.name}</p>\n      </div>);\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE_OPENING_FIXED = `\n  var Hello = createReactClass({\n    render: function() {\n      return (\n\n      <div>\n        <p>Hello {this.props.name}</p>\n      </div>\n);\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE_CLOSING = `\n  var Hello = createReactClass({\n    render: function() {\n      return (<div>\n        <p>Hello {this.props.name}</p>\n      </div>\n\n      );\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE_CLOSING_FIXED = `\n  var Hello = createReactClass({\n    render: function() {\n      return (\n<div>\n        <p>Hello {this.props.name}</p>\n      </div>\n\n      );\n    }\n  });\n`;\n\nconst RETURN_PAREN_NEW_LINE_FRAGMENT = `\n  var Hello = createReactClass({\n    render: function() {\n      return (\n        <>\n          <p>Hello {this.props.name}</p>\n        </>\n      );\n    }\n  });\n`;\n\nconst RETURN_SINGLE_LINE_FRAGMENT = `\n  var Hello = createReactClass({\n    render: function() {\n      return <>Hello {this.props.name}</>;\n    }\n  });\n`;\n\nconst DECLARATION_TERNARY_SINGLE_LINE = 'var hello = foo ? <p>Hello</p> : <p>Hi</p>;';\n\nconst DECLARATION_TERNARY_SINGLE_LINE_FRAGMENT = 'var hello = foo ? <>Hello</> : <>Hi</>;';\n\nconst DECLARATION_TERNARY_PAREN = `\n  var hello = foo ? (<div>\n    <p>Hello</p>\n  </div>) : (<div>\n    <p>Hi</p>\n  </div>);\n`;\n\nconst DECLARATION_TERNARY_PAREN_FRAGMENT = `\n  var hello = foo ? (<>\n    <p>Hello</p>\n  </>) : (<>\n    <p>Hi</p>\n  </>);\n`;\n\nconst DECLARATION_TERNARY_NO_PAREN = `\n  var hello = foo ? <div>\n    <p>Hello</p>\n  </div> : <div>\n    <p>Hi</p>\n  </div>;\n`;\n\nconst DECLARATION_TERNARY_NO_PAREN_FRAGMENT = `\n  var hello = foo ? <>\n    <p>Hello</p>\n  </> : <>\n    <p>Hi</p>\n  </>;\n`;\n\nconst DECLARATION_TERNARY_PAREN_NEW_LINE = `\n  var hello = foo ? (\n    <div>\n    <p>Hello</p>\n    </div>\n  ) : (\n    <div>\n      <p>Hi</p>\n    </div>\n  );\n`;\n\nconst ASSIGNMENT_TERNARY_SINGLE_LINE = 'var hello; hello = foo ? <p>Hello</p> : <p>Hi</p>;';\n\nconst ASSIGNMENT_TERNARY_PAREN = `\n  var hello;\n  hello = foo ? (<div>\n    <p>Hello</p>\n  </div>) : (<div>\n    <p>Hi</p>\n  </div>);\n`;\n\nconst ASSIGNMENT_TERNARY_PAREN_FRAGMENT = `\n  var hello;\n  hello = foo ? (<>\n    <p>Hello</p>\n  </>) : (<>\n    <p>Hi</p>\n  </>);\n`;\n\nconst ASSIGNMENT_TERNARY_NO_PAREN = `\n  var hello;\n  hello = foo ? <div>\n    <p>Hello</p>\n  </div> : <div>\n    <p>Hi</p>\n  </div>;\n`;\n\nconst ASSIGNMENT_TERNARY_NO_PAREN_FRAGMENT = `\n  var hello;\n  hello = foo ? <>\n    <p>Hello</p>\n  </> : <>\n    <p>Hi</p>\n  </>;\n`;\n\nconst ASSIGNMENT_TERNARY_PAREN_NEW_LINE = `\n  var hello;\n  hello = foo ? (\n    <div>\n      <p>Hello</p>\n    </div>\n  ) : (\n    <div>\n      <p>Hi</p>\n    </div>\n  );\n`;\n\nconst DECLARATION_SINGLE_LINE = 'var hello = <p>Hello</p>;';\n\nconst DECLARATION_PAREN = `\n  var hello = (<div>\n    <p>Hello</p>\n  </div>);\n`;\n\nconst DECLARATION_PAREN_FRAGMENT = `\n  var hello = (<>\n    <p>Hello</p>\n  </>);\n`;\n\nconst DECLARATION_NO_PAREN = `\n  var hello = <div>\n    <p>Hello</p>\n  </div>;\n`;\n\nconst DECLARATION_NO_PAREN_FRAGMENT = `\n  var hello = <>\n    <p>Hello</p>\n  </>;\n`;\n\nconst DECLARATION_PAREN_NEW_LINE = `\n  var hello = (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n`;\n\nconst ASSIGNMENT_SINGLE_LINE = 'var hello; hello = <p>Hello</p>;';\n\nconst ASSIGNMENT_PAREN = `\n  var hello;\n  hello = (<div>\n    <p>Hello</p>\n  </div>);\n`;\n\nconst ASSIGNMENT_PAREN_FRAGMENT = `\n  var hello;\n  hello = (<>\n    <p>Hello</p>\n  </>);\n`;\n\nconst ASSIGNMENT_NO_PAREN = `\n  var hello;\n  hello = <div>\n    <p>Hello</p>\n  </div>;\n`;\n\nconst ASSIGNMENT_NO_PAREN_FRAGMENT = `\n  var hello;\n  hello = <>\n    <p>Hello</p>\n  </>;\n`;\n\nconst ASSIGNMENT_PAREN_NEW_LINE = `\n  var hello;\n  hello = (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n`;\n\nconst ARROW_SINGLE_LINE = 'var hello = () => <p>Hello</p>;';\n\nconst ARROW_PAREN = `\n  var hello = () => (<div>\n    <p>Hello</p>\n  </div>);\n`;\n\nconst ARROW_PAREN_FRAGMENT = `\n  var hello = () => (<>\n    <p>Hello</p>\n  </>);\n`;\n\nconst ARROW_NO_PAREN = `\n  var hello = () => <div>\n    <p>Hello</p>\n  </div>;\n`;\n\nconst ARROW_NO_PAREN_FRAGMENT = `\n  var hello = () => <>\n    <p>Hello</p>\n  </>;\n`;\n\nconst ARROW_PAREN_NEW_LINE = `\n  var hello = () => (\n    <div>\n      <p>Hello</p>\n    </div>\n  );\n`;\n\nconst CONDITION_SINGLE_LINE = 'foo ? <p>Hello</p> : null;';\n\nconst CONDITION_PAREN = `\n  <div>\n    {foo ? (<div>\n        <p>Hello</p>\n      </div>) : null}\n  </div>\n`;\n\nconst CONDITION_PAREN_FRAGMENT = `\n  <div>\n    {foo ? (<>\n        <p>Hello</p>\n      </>) : null}\n  </div>\n`;\n\nconst CONDITION_NO_PAREN = `\n  <div>\n    {foo ? <div>\n        <p>Hello</p>\n      </div> : null}\n  </div>\n`;\n\nconst CONDITION_NO_PAREN_FRAGMENT = `\n  <div>\n    {foo ? <>\n        <p>Hello</p>\n      </> : null}\n  </div>\n`;\n\nconst CONDITION_PAREN_NEW_LINE = `\n  <div>\n    {foo ? (\n      <div>\n        <p>Hello</p>\n      </div>\n    ) : null}\n  </div>\n`;\n\nconst LOGICAL_SINGLE_LINE = 'foo && <p>Hello</p>;';\n\nconst LOGICAL_PAREN = `\n  <div>\n    {foo &&\n      (<div>\n        <p>Hello World</p>\n      </div>)\n    }\n  </div>\n`;\n\nconst LOGICAL_PAREN_FRAGMENT = `\n  <div>\n    {foo &&\n      (<>\n        <p>Hello World</p>\n      </>)\n    }\n  </div>\n`;\n\nconst LOGICAL_NO_PAREN = `\n  <div>\n    {foo &&\n      <div>\n        <p>Hello World</p>\n      </div>\n    }\n  </div>\n`;\n\nconst LOGICAL_NO_PAREN_FRAGMENT = `\n  <div>\n    {foo &&\n      <>\n        <p>Hello World</p>\n      </>\n    }\n  </div>\n`;\n\nconst LOGICAL_PAREN_NEW_LINE_AUTOFIX = `\n  <div>\n    {foo && (\n      <div>\n        <p>Hello World</p>\n      </div>\n    )}\n  </div>\n`;\n\nconst LOGICAL_PAREN_NEW_LINE_AUTOFIX_FRAGMENT = `\n  <div>\n    {foo && (\n      <>\n        <p>Hello World</p>\n      </>\n    )}\n  </div>\n`;\n\nconst LOGICAL_PAREN_NEW_LINE = `\n  <div>\n    {foo && (\n      <div>\n        <p>Hello World</p>\n      </div>\n    )}\n  </div>\n`;\n\nconst ATTR_SINGLE_LINE = '<div prop={<p>Hello</p>}></div>';\n\nconst ATTR_PAREN = `\n  <div prop={\n    (<div>\n      <p>Hello</p>\n    </div>)\n  }>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_PAREN_FRAGMENT = `\n  <div prop={\n    (<>\n      <p>Hello</p>\n    </>)\n  }>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_NO_PAREN = `\n  <div prop={\n    <div>\n      <p>Hello</p>\n    </div>\n  }>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_NO_PAREN_FRAGMENT = `\n  <div prop={\n    <>\n      <p>Hello</p>\n    </>\n  }>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_PAREN_NEW_LINE = `\n  <div prop={(\n    <div>\n      <p>Hello</p>\n    </div>\n  )}>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_PAREN_NEW_LINE_AUTOFIX = `\n  <div prop={(\n    <div>\n      <p>Hello</p>\n    </div>\n  )}>\n    <p>Hello</p>\n  </div>\n`;\n\nconst ATTR_PAREN_NEW_LINE_AUTOFIX_FRAGMENT = `\n  <div prop={(\n    <>\n      <p>Hello</p>\n    </>\n  )}>\n    <p>Hello</p>\n  </div>\n`;\n\nconst SFC_NO_PARENS_NO_NEWLINE = `\n  export default () =>\n    <div>\n        with newline without parentheses eslint crashes\n    </div>`;\n\nconst SFC_NO_PARENS_AUTOFIX = `\n  export default () => (\n    <div>\n        with newline without parentheses eslint crashes\n    </div>\n  )`;\n\nconst ARROW_WITH_EXPORT = `\n  const Component = () =>\n    <div>\n      <p>Some text</p>\n    </div>\n\n  export { Component as default }\n`;\n\nconst ARROW_WITH_EXPORT_AUTOFIX = `\n  const Component = () => (\n    <div>\n      <p>Some text</p>\n    </div>\n  )\n\n  export { Component as default }\n`;\n\nconst ARROW_WITH_LOGICAL = `\nconst Component = props => (\n  <div>\n    {true &&\n      <div>\n        <p>Some text</p>\n      </div>\n    }\n  </div>\n)\n`;\n\nconst ARROW_WITH_LOGICAL_AUTOFIX = `\nconst Component = props => (\n  <div>\n    {true && (\n      <div>\n        <p>Some text</p>\n      </div>\n    )}\n  </div>\n)\n`;\n\nfunction addNewLineSymbols(code) {\n  return code.replace(/\\(</g, '(\\n<').replace(/>\\)/g, '>\\n)');\n}\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('jsx-wrap-multilines', rule, {\n  valid: parsers.all([\n    {\n      code: RETURN_SINGLE_LINE,\n    },\n    {\n      code: RETURN_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: RETURN_SINGLE_LINE_FRAGMENT,\n      features: ['fragment'],\n    },\n    {\n      code: RETURN_SINGLE_LINE_FRAGMENT,\n      features: ['fragment'],\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: RETURN_PAREN,\n    },\n    {\n      code: RETURN_SINGLE_LINE,\n      options: [{ return: true }],\n    },\n    {\n      code: RETURN_SINGLE_LINE_FRAGMENT,\n      features: ['fragment'],\n      options: [{ return: true }],\n    },\n    {\n      code: RETURN_PAREN,\n      options: [{ return: true }],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      options: [{ return: 'ignore' }],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      options: [{ return: false }],\n    },\n    {\n      code: DECLARATION_TERNARY_SINGLE_LINE,\n    },\n    {\n      code: DECLARATION_TERNARY_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: DECLARATION_TERNARY_SINGLE_LINE_FRAGMENT,\n      features: ['fragment'],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN,\n    },\n    {\n      code: DECLARATION_TERNARY_SINGLE_LINE,\n      options: [{ declaration: true }],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN,\n      options: [{ declaration: true }],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      options: [{ declaration: 'ignore' }],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      options: [{ declaration: false }],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_SINGLE_LINE,\n    },\n    {\n      code: ASSIGNMENT_TERNARY_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN,\n    },\n    {\n      code: ASSIGNMENT_TERNARY_SINGLE_LINE,\n      options: [{ assignment: true }],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN,\n      options: [{ assignment: true }],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      options: [{ assignment: 'ignore' }],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      options: [{ assignment: false }],\n    },\n    {\n      code: DECLARATION_SINGLE_LINE,\n    },\n    {\n      code: DECLARATION_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: DECLARATION_PAREN,\n    },\n    {\n      code: DECLARATION_PAREN_FRAGMENT,\n      features: ['fragment'],\n    },\n    {\n      code: DECLARATION_SINGLE_LINE,\n      options: [{ declaration: true }],\n    },\n    {\n      code: DECLARATION_PAREN,\n      options: [{ declaration: true }],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      options: [{ declaration: 'ignore' }],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: DECLARATION_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ declaration: 'ignore' }],\n    },\n    {\n      code: DECLARATION_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      options: [{ declaration: false }],\n    },\n    {\n      code: ASSIGNMENT_SINGLE_LINE,\n      options: [{ declaration: 'ignore' }],\n    },\n    {\n      code: ASSIGNMENT_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ASSIGNMENT_SINGLE_LINE,\n      options: [{ declaration: false }],\n    },\n    {\n      code: ASSIGNMENT_PAREN,\n    },\n    {\n      code: ASSIGNMENT_PAREN_FRAGMENT,\n      features: ['fragment'],\n    },\n    {\n      code: ASSIGNMENT_PAREN,\n      options: [{ assignment: true }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      options: [{ assignment: 'ignore' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ assignment: 'ignore' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      options: [{ assignment: false }],\n    },\n    {\n      code: ARROW_PAREN,\n    },\n    {\n      code: ARROW_PAREN_FRAGMENT,\n      features: ['fragment'],\n    },\n    {\n      code: ARROW_SINGLE_LINE,\n    },\n    {\n      code: ARROW_PAREN,\n      options: [{ arrow: true }],\n    },\n    {\n      code: ARROW_SINGLE_LINE,\n      options: [{ arrow: true }],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      options: [{ arrow: 'ignore' }],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ARROW_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ arrow: 'ignore' }],\n    },\n    {\n      code: ARROW_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      options: [{ arrow: false }],\n    },\n    {\n      code: CONDITION_SINGLE_LINE,\n    },\n    {\n      code: CONDITION_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: CONDITION_SINGLE_LINE,\n      options: [{ condition: true }],\n    },\n    {\n      code: CONDITION_NO_PAREN,\n    },\n    {\n      code: CONDITION_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: CONDITION_PAREN,\n      options: [{ condition: true }],\n    },\n    {\n      code: CONDITION_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ condition: true }],\n    },\n    {\n      code: LOGICAL_SINGLE_LINE,\n    },\n    {\n      code: LOGICAL_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: LOGICAL_NO_PAREN,\n    },\n    {\n      code: LOGICAL_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: LOGICAL_PAREN,\n      options: [{ logical: true }],\n    },\n    {\n      code: LOGICAL_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ logical: true }],\n    },\n    {\n      code: ATTR_SINGLE_LINE,\n    },\n    {\n      code: ATTR_SINGLE_LINE,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ATTR_NO_PAREN,\n    },\n    {\n      code: ATTR_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n    },\n    {\n      code: ATTR_PAREN,\n      options: [{ prop: true }],\n    },\n    {\n      code: ATTR_PAREN_FRAGMENT,\n      features: ['fragment'],\n      options: [{ prop: true }],\n    },\n    {\n      code: RETURN_PAREN_NEW_LINE,\n      options: [{ return: 'parens-new-line' }],\n    },\n    {\n      code: RETURN_PAREN_NEW_LINE_FRAGMENT,\n      features: ['fragment'],\n      options: [{ return: 'parens-new-line' }],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN_NEW_LINE,\n      options: [{ declaration: 'parens-new-line' }],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN_NEW_LINE,\n      options: [{ assignment: 'parens-new-line' }],\n    },\n    {\n      code: DECLARATION_PAREN_NEW_LINE,\n      options: [{ declaration: 'parens-new-line' }],\n    },\n    {\n      code: ASSIGNMENT_PAREN_NEW_LINE,\n      options: [{ assignment: 'parens-new-line' }],\n    },\n    {\n      code: ARROW_PAREN_NEW_LINE,\n      options: [{ arrow: 'parens-new-line' }],\n    },\n    {\n      code: CONDITION_PAREN_NEW_LINE,\n      options: [{ condition: 'parens-new-line' }],\n    },\n    {\n      code: LOGICAL_PAREN_NEW_LINE,\n      options: [{ logical: 'parens-new-line' }],\n    },\n    {\n      code: ATTR_PAREN_NEW_LINE,\n      options: [{ prop: 'parens-new-line' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: RETURN_PAREN,\n      output: RETURN_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      output: RETURN_PAREN,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: RETURN_PAREN_FRAGMENT,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: RETURN_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      output: RETURN_PAREN,\n      options: [{ return: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: RETURN_PAREN_FRAGMENT,\n      options: [{ return: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      output: DECLARATION_TERNARY_PAREN,\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN,\n      output: DECLARATION_TERNARY_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [\n        { messageId: 'extraParens' },\n        { messageId: 'extraParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: DECLARATION_TERNARY_PAREN_FRAGMENT,\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: DECLARATION_TERNARY_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [\n        { messageId: 'extraParens' },\n        { messageId: 'extraParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      output: DECLARATION_TERNARY_PAREN,\n      options: [{ declaration: true }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: DECLARATION_TERNARY_PAREN_FRAGMENT,\n      options: [{ declaration: true }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      output: ASSIGNMENT_TERNARY_PAREN,\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN,\n      output: ASSIGNMENT_TERNARY_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [\n        { messageId: 'extraParens' },\n        { messageId: 'extraParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ASSIGNMENT_TERNARY_PAREN_FRAGMENT,\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ASSIGNMENT_TERNARY_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [\n        { messageId: 'extraParens' },\n        { messageId: 'extraParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      output: ASSIGNMENT_TERNARY_PAREN,\n      options: [{ assignment: true }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ASSIGNMENT_TERNARY_PAREN_FRAGMENT,\n      options: [{ assignment: true }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      output: DECLARATION_PAREN,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: DECLARATION_PAREN,\n      output: DECLARATION_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: DECLARATION_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: DECLARATION_PAREN_FRAGMENT,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: DECLARATION_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: DECLARATION_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      output: DECLARATION_PAREN,\n      options: [{ declaration: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      output: ASSIGNMENT_PAREN,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ASSIGNMENT_PAREN_FRAGMENT,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      output: ASSIGNMENT_PAREN,\n      options: [{ assignment: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ASSIGNMENT_PAREN,\n      output: ASSIGNMENT_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      output: ARROW_PAREN,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ARROW_PAREN,\n      output: ARROW_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: ARROW_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ARROW_PAREN_FRAGMENT,\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ARROW_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ARROW_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      output: ARROW_PAREN,\n      options: [{ arrow: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: CONDITION_NO_PAREN,\n      output: CONDITION_PAREN,\n      options: [{ condition: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: CONDITION_PAREN,\n      output: CONDITION_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: CONDITION_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: CONDITION_PAREN_FRAGMENT,\n      options: [{ condition: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: CONDITION_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: CONDITION_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: CONDITION_NO_PAREN,\n      output: CONDITION_PAREN,\n      options: [{ condition: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: LOGICAL_NO_PAREN,\n      output: LOGICAL_PAREN,\n      options: [{ logical: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: LOGICAL_PAREN,\n      output: LOGICAL_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: LOGICAL_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: LOGICAL_PAREN_FRAGMENT,\n      options: [{ logical: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: LOGICAL_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: LOGICAL_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: LOGICAL_NO_PAREN,\n      output: LOGICAL_PAREN,\n      options: [{ logical: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ATTR_NO_PAREN,\n      output: ATTR_PAREN,\n      options: [{ prop: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ATTR_PAREN,\n      output: ATTR_NO_PAREN,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: ATTR_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ATTR_PAREN_FRAGMENT,\n      options: [{ prop: 'parens' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ATTR_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ATTR_NO_PAREN_FRAGMENT,\n      options: [OPTIONS_ALL_NEVER],\n      errors: [{ messageId: 'extraParens' }],\n    },\n    {\n      code: ATTR_NO_PAREN,\n      output: ATTR_PAREN,\n      options: [{ prop: true }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN,\n      output: addNewLineSymbols(RETURN_PAREN),\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(RETURN_PAREN_FRAGMENT),\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: RETURN_PAREN,\n      output: addNewLineSymbols(RETURN_PAREN),\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: RETURN_PAREN_NEW_LINE_OPENING,\n      output: RETURN_PAREN_NEW_LINE_OPENING_FIXED,\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: RETURN_PAREN_NEW_LINE_CLOSING,\n      output: RETURN_PAREN_NEW_LINE_CLOSING_FIXED,\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: RETURN_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(RETURN_PAREN_FRAGMENT),\n      options: [{ return: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN,\n      output: addNewLineSymbols(DECLARATION_TERNARY_PAREN),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(DECLARATION_TERNARY_PAREN_FRAGMENT),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(DECLARATION_TERNARY_PAREN_FRAGMENT),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [\n        { messageId: 'parensOnNewLines' },\n        { messageId: 'parensOnNewLines' },\n      ],\n    },\n    {\n      code: DECLARATION_TERNARY_PAREN,\n      output: addNewLineSymbols(DECLARATION_TERNARY_PAREN),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [\n        { messageId: 'parensOnNewLines' },\n        { messageId: 'parensOnNewLines' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN,\n      output: addNewLineSymbols(ASSIGNMENT_TERNARY_PAREN),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(ASSIGNMENT_TERNARY_PAREN_FRAGMENT),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [\n        { messageId: 'missingParens' },\n        { messageId: 'missingParens' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN,\n      output: addNewLineSymbols(ASSIGNMENT_TERNARY_PAREN),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [\n        { messageId: 'parensOnNewLines' },\n        { messageId: 'parensOnNewLines' },\n      ],\n    },\n    {\n      code: ASSIGNMENT_TERNARY_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(ASSIGNMENT_TERNARY_PAREN_FRAGMENT),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [\n        { messageId: 'parensOnNewLines' },\n        { messageId: 'parensOnNewLines' },\n      ],\n    },\n    {\n      code: DECLARATION_NO_PAREN,\n      output: addNewLineSymbols(DECLARATION_PAREN),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: DECLARATION_PAREN,\n      output: addNewLineSymbols(DECLARATION_PAREN),\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ASSIGNMENT_NO_PAREN,\n      output: addNewLineSymbols(ASSIGNMENT_PAREN),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ASSIGNMENT_PAREN,\n      output: addNewLineSymbols(ASSIGNMENT_PAREN),\n      options: [{ assignment: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ARROW_PAREN,\n      output: addNewLineSymbols(ARROW_PAREN),\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ARROW_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(ARROW_PAREN_FRAGMENT),\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ARROW_NO_PAREN,\n      output: addNewLineSymbols(ARROW_PAREN),\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ARROW_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(ARROW_PAREN_FRAGMENT),\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: CONDITION_PAREN,\n      output: addNewLineSymbols(CONDITION_PAREN),\n      options: [{ condition: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: CONDITION_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(CONDITION_PAREN_FRAGMENT),\n      options: [{ condition: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: CONDITION_NO_PAREN,\n      output: addNewLineSymbols(CONDITION_PAREN),\n      options: [{ condition: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: CONDITION_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(CONDITION_PAREN_FRAGMENT),\n      options: [{ condition: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: LOGICAL_PAREN,\n      output: addNewLineSymbols(LOGICAL_PAREN),\n      options: [{ logical: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: LOGICAL_NO_PAREN,\n      output: LOGICAL_PAREN_NEW_LINE_AUTOFIX,\n      options: [{ logical: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: LOGICAL_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: LOGICAL_PAREN_NEW_LINE_AUTOFIX_FRAGMENT,\n      options: [{ logical: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ATTR_PAREN,\n      output: addNewLineSymbols(ATTR_PAREN),\n      options: [{ prop: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ATTR_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: addNewLineSymbols(ATTR_PAREN_FRAGMENT),\n      options: [{ prop: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n    {\n      code: ATTR_NO_PAREN,\n      output: ATTR_PAREN_NEW_LINE_AUTOFIX,\n      options: [{ prop: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ATTR_NO_PAREN_FRAGMENT,\n      features: ['fragment'],\n      output: ATTR_PAREN_NEW_LINE_AUTOFIX_FRAGMENT,\n      options: [{ prop: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: SFC_NO_PARENS_NO_NEWLINE,\n      output: SFC_NO_PARENS_AUTOFIX,\n      options: [OPTIONS_ALL_NEW_LINES],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ARROW_WITH_EXPORT,\n      output: ARROW_WITH_EXPORT_AUTOFIX,\n      options: [\n        {\n          declaration: 'parens-new-line',\n          assignment: 'parens-new-line',\n          return: 'parens-new-line',\n          arrow: 'parens-new-line',\n          condition: 'parens-new-line',\n          logical: 'ignore',\n          prop: 'ignore',\n        },\n      ],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: ARROW_WITH_LOGICAL,\n      output: ARROW_WITH_LOGICAL_AUTOFIX,\n      options: [{ logical: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const A =\n        <div>\n            B\n        </div>;\n      `,\n      output: `\n        import React from 'react';\n\n        const A = (\n        <div>\n            B\n        </div>\n      );\n      `,\n      options: [{ declaration: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: `\n        export default () => <h1>\n            <span>\n                hello\n            </span>\n        </h1>;\n      `,\n      output: `\n        export default () => (\n<h1>\n            <span>\n                hello\n            </span>\n        </h1>\n);\n      `,\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'missingParens' }],\n    },\n    {\n      code: `\n        export default () => (<h1>\n            <span>\n                hello\n            </span>\n        </h1>);\n      `,\n      output: `\n        export default () => (\n<h1>\n            <span>\n                hello\n            </span>\n        </h1>\n);\n      `,\n      options: [{ arrow: 'parens-new-line' }],\n      errors: [{ messageId: 'parensOnNewLines' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-access-state-in-setstate.js",
    "content": "/**\n * @fileoverview Prevent usage of this.state within setState\n * @author Rolf Erik Lekang, Jørgen Aaberg\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst parsers = require('../../helpers/parsers');\nconst rule = require('../../../lib/rules/no-access-state-in-setstate');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    createClass: 'createClass',\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ settings });\nruleTester.run('no-access-state-in-setstate', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState(state => ({value: state.value + 1}))\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          multiplyValue: function(obj) {\n            return obj.value*2\n          },\n          onClick: function() {\n            var value = this.state.value\n            this.multiplyValue({ value: value })\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n    // issue 1559: don't crash\n      code: `\n        var SearchForm = createReactClass({\n          render: function () {\n            return (\n              <div>\n                {(function () {\n                  if (this.state.prompt) {\n                    return <div>{this.state.prompt}</div>\n                  }\n                }).call(this)}\n              </div>\n            );\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n    // issue 1604: allow this.state in callback\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState({}, () => console.log(this.state));\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState({}, () => 1 + 1);\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            var nextValueNotUsed = this.state.value + 1\n            var nextValue = 2\n            this.setState({value: nextValue})\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      // https://github.com/jsx-eslint/eslint-plugin-react/pull/1611\n      code: `\n        function testFunction({a, b}) {\n        };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class ComponentA extends React.Component {\n          state = {\n            greeting: 'hello',\n          };\n\n          myFunc = () => {\n            this.setState({ greeting: 'hi' }, () => this.doStuff());\n          };\n\n          doStuff = () => {\n            console.log(this.state.greeting);\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends Abstract {\n          update = () => {\n            const result = this.getResult ( this.state.foo );\n            return this.setState ({ result });\n          };\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class StateContainer extends Container {\n          anything() {\n            return this.setState({value: this.state.value + 1})\n          }\n        };\n      `,\n      parserOptions,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState({value: this.state.value + 1})\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState(() => ({value: this.state.value + 1}))\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            var nextValue = this.state.value + 1\n            this.setState({value: nextValue})\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            var {state, ...rest} = this\n            this.setState({value: state.value + 1})\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        function nextState(state) {\n          return {value: state.value + 1}\n        }\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState(nextState(this.state))\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState(this.state, () => 1 + 1);\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          onClick: function() {\n            this.setState(this.state, () => console.log(this.state));\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        var Hello = React.createClass({\n          nextState: function() {\n            return {value: this.state.value + 1}\n          },\n          onClick: function() {\n            this.setState(nextState())\n          }\n        });\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          onClick() {\n            this.setState(this.state, () => console.log(this.state));\n          }\n        }\n      `,\n      parserOptions,\n      errors: [{ messageId: 'useCallback' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-adjacent-inline-elements.js",
    "content": "/**\n * @fileoverview Tests for no-adjacent-inline-elements\n * @author Sean Hayes\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-adjacent-inline-elements');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 6,\n  ecmaFeatures: {\n    experimentalObjectRestSpread: true,\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester();\nruleTester.run('no-adjacent-inline-elements', rule, {\n  valid: parsers.all([\n    {\n      code: '<div />;',\n      parserOptions,\n    },\n    {\n      code: '<div><div></div><div></div></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><p></p><div></div></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><p></p><a></a></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><a></a>&nbsp;<a></a></div>;',\n      parserOptions,\n      features: ['no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: '<div><a></a>&nbsp;some text &nbsp; <a></a></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><a></a>&nbsp;some text <a></a></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><a></a> <a></a></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><ul><li><a></a></li><li><a></a></li></ul></div>;',\n      parserOptions,\n    },\n    {\n      code: '<div><a></a> some text <a></a></div>;',\n      parserOptions,\n    },\n    {\n      code: 'React.createElement(\"div\", null, \"some text\");',\n      parserOptions,\n    },\n    {\n      code: ('React.createElement(\"div\", undefined, [React.createElement(\"a\"), \" some text \", React.createElement(\"a\")]);'),\n      parserOptions,\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, [React.createElement(\"a\"), \" \", React.createElement(\"a\")]);',\n      parserOptions,\n    },\n    {\n      code: 'React.createElement(a, b);',\n      parserOptions,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<div><a></a><a></a></div>;',\n      errors: [{ messageId: 'inlineElement' }],\n      parserOptions,\n    },\n    {\n      code: '<div><a></a><span></span></div>;',\n      errors: [{ messageId: 'inlineElement' }],\n      parserOptions,\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, [React.createElement(\"a\"), React.createElement(\"span\")]);',\n      errors: [{ messageId: 'inlineElement' }],\n      parserOptions,\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-array-index-key.js",
    "content": "/**\n * @fileoverview Tests for no-array-index-key\n * @author Joe Lencioni\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst parsers = require('../../helpers/parsers');\nconst rule = require('../../../lib/rules/no-array-index-key');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-array-index-key', rule, {\n  valid: parsers.all([\n    { code: '<Foo key=\"foo\" />;' },\n    { code: '<Foo key={i} />;' },\n    { code: '<Foo key />;' },\n    { code: '<Foo key={`foo-${i}`} />;' },\n    { code: '<Foo key={\\'foo-\\' + i} />;' },\n    {\n      code: 'foo.bar((baz, i) => <Foo key={i} />)',\n    },\n    {\n      code: 'foo.bar((bar, i) => <Foo key={`foo-${i}`} />)',\n    },\n    {\n      code: 'foo.bar((bar, i) => <Foo key={\\'foo-\\' + i} />)',\n    },\n    {\n      code: 'foo.map((baz) => <Foo key={baz.id} />)',\n    },\n    {\n      code: 'foo.map((baz, i) => <Foo key={baz.id} />)',\n    },\n    {\n      code: 'foo.map((baz, i) => <Foo key={\\'foo\\' + baz.id} />)',\n    },\n    {\n      code: 'foo.map((baz, i) => React.cloneElement(someChild, { ...someChild.props }))',\n    },\n    {\n      code: 'foo.map((baz, i) => cloneElement(someChild, { ...someChild.props }))',\n    },\n    {\n      code: `\n        foo.map((item, i) => {\n          return React.cloneElement(someChild, {\n            key: item.id\n          })\n        })\n      `,\n    },\n    {\n      code: `\n        foo.map((item, i) => {\n          return cloneElement(someChild, {\n            key: item.id\n          })\n        })\n      `,\n    },\n    {\n      code: 'foo.map((baz, i) => <Foo key />)',\n    },\n    {\n      code: 'foo.reduce((a, b) => a.concat(<Foo key={b.id} />), [])',\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={i.baz.toString()} />)',\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={i.toString} />)',\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={String()} />)',\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={String(baz)} />)',\n    },\n    {\n      code: 'foo.flatMap((a) => <Foo key={a} />)',\n    },\n    {\n      code: 'foo.reduce((a, b, i) => a.concat(<Foo key={b.id} />), [])',\n    },\n    {\n      code: 'foo.reduceRight((a, b) => a.concat(<Foo key={b.id} />), [])',\n    },\n    {\n      code: 'foo.reduceRight((a, b, i) => a.concat(<Foo key={b.id} />), [])',\n    },\n    {\n      code: `\n        React.Children.map(this.props.children, (child, index, arr) => {\n          return React.cloneElement(child, { key: child.id });\n        })\n      `,\n    },\n    {\n      code: `\n        React.Children.map(this.props.children, (child, index, arr) => {\n          return cloneElement(child, { key: child.id });\n        })\n      `,\n    },\n    {\n      code: `\n        Children.forEach(this.props.children, (child, index, arr) => {\n          return React.cloneElement(child, { key: child.id });\n        })\n      `,\n    },\n    {\n      code: `\n        Children.forEach(this.props.children, (child, index, arr) => {\n          return cloneElement(child, { key: child.id });\n        })\n      `,\n    },\n    {\n      code: 'foo?.map(child => <Foo key={child.i} />)',\n      features: ['optional chaining'],\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    {\n      code: 'foo.map((bar, i) => <Foo key={i} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: '[{}, {}].map((bar, i) => <Foo key={i} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, anything) => <Foo key={anything} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={`foo-${i}`} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={\\'foo-\\' + i} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => <Foo key={\\'foo-\\' + i + \\'-bar\\'} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((baz, i) => React.cloneElement(someChild, { ...someChild.props, key: i }))',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        foo.map((baz, i) => cloneElement(someChild, { ...someChild.props, key: i }))\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        foo.map((item, i) => {\n          return React.cloneElement(someChild, {\n            key: i\n          })\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        foo.map((item, i) => {\n          return cloneElement(someChild, {\n            key: i\n          })\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.forEach((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.filter((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.some((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.every((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.find((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.findIndex((bar, i) => { baz.push(<Foo key={i} />); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.reduce((a, b, i) => a.concat(<Foo key={i} />), [])',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.flatMap((a, i) => <Foo key={i} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.reduceRight((a, b, i) => a.concat(<Foo key={i} />), [])',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => React.createElement(\\'Foo\\', { key: i }))',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => React.createElement(\\'Foo\\', { key: `foo-${i}` }))',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => React.createElement(\\'Foo\\', { key: \\'foo-\\' + i }))',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.map((bar, i) => React.createElement(\\'Foo\\', { key: \\'foo-\\' + i + \\'-bar\\' }))',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.forEach((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.filter((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.some((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.every((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.find((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo.findIndex((bar, i) => { baz.push(React.createElement(\\'Foo\\', { key: i })); })',\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        Children.map(this.props.children, (child, index) => {\n          return React.cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        Children.map(this.props.children, (child, index) => {\n          return cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        React.Children.map(this.props.children, (child, index) => {\n          return React.cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        React.Children.map(this.props.children, (child, index) => {\n          return cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        Children.forEach(this.props.children, (child, index) => {\n          return React.cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        Children.forEach(this.props.children, (child, index) => {\n          return cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        React.Children.forEach(this.props.children, (child, index) => {\n          return React.cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        import { cloneElement } from 'react';\n\n        React.Children.forEach(this.props.children, (child, index) => {\n          return cloneElement(child, { key: index });\n        })\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: 'foo?.map((child, i) => <Foo key={i} />)',\n      errors: [{ messageId: 'noArrayIndex' }],\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        foo.map((bar, index) => (\n          <Element key={index.toString()} bar={bar} />\n        ))\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        foo.map((bar, index) => (\n          <Element key={String(index)} bar={bar} />\n        ))\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    },\n    {\n      code: `\n        foo.map((bar, index) => (\n          <Element key={index} bar={bar} />\n        ))\n      `,\n      errors: [{ messageId: 'noArrayIndex' }],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-arrow-function-lifecycle.js",
    "content": "/**\n * @fileoverview It is not necessary to use arrow function for lifecycle methods\n * @author Tan Nguyen\n */\n\n'use strict';\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-arrow-function-lifecycle');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-arrow-function-lifecycle', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getDefaultProps: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getInitialState: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getChildContext: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getDerivedStateFromProps: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillReceiveProps: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillReceiveProps: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          shouldComponentUpdate: function() { return true; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getSnapshotBeforeUpdate: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidCatch: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUnmount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getDefaultProps() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getInitialState() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getChildContext() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getDerivedStateFromProps() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillMount() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillMount() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidMount() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillReceiveProps() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillReceiveProps() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          shouldComponentUpdate() { return true; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUpdate() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillUpdate() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getSnapshotBeforeUpdate() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidUpdate() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidCatch() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUnmount() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getDerivedStateFromProps = () => { return {}; } // not a lifecycle method\n          static getDerivedStateFromProps() {}\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getDerivedStateFromProps: () => { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          onChange: () => void;\n        }\n      `,\n      features: ['types'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: () => { return <div />; }\n        });\n      `,\n      errors: [{ message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getDefaultProps: () => { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'getDefaultProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          getDefaultProps: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getInitialState: () => { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'getInitialState is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          getInitialState: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getChildContext: () => { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'getChildContext is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          getChildContext: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillMount: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentWillMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentWillMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillMount: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'UNSAFE_componentWillMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentDidMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentDidMount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillReceiveProps: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentWillReceiveProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentWillReceiveProps: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillReceiveProps: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'UNSAFE_componentWillReceiveProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillReceiveProps: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          shouldComponentUpdate: () => { return true; },\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'shouldComponentUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          shouldComponentUpdate: function() { return true; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentWillUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillUpdate: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'UNSAFE_componentWillUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          getSnapshotBeforeUpdate: () => { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'getSnapshotBeforeUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          getSnapshotBeforeUpdate: function() { return {}; },\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentDidUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidCatch: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentDidCatch is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentDidCatch: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUnmount: () => {},\n          render: function() { return <div />; }\n        });\n      `,\n      errors: [{ message: 'componentWillUnmount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        var Hello = createReactClass({\n          componentWillUnmount: function() {},\n          render: function() { return <div />; }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getDefaultProps = () => { return {}; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'getDefaultProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getDefaultProps() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getInitialState = () => { return {}; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'getInitialState is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getInitialState() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getChildContext = () => { return {}; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'getChildContext is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getChildContext() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          static getDerivedStateFromProps = () => { return {}; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'getDerivedStateFromProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          static getDerivedStateFromProps() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillMount = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentWillMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillMount() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillMount = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'UNSAFE_componentWillMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillMount() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidMount = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentDidMount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidMount() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillReceiveProps = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentWillReceiveProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillReceiveProps() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillReceiveProps = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'UNSAFE_componentWillReceiveProps is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillReceiveProps() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          shouldComponentUpdate = () => { return true; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'shouldComponentUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          shouldComponentUpdate() { return true; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUpdate = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentWillUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUpdate() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillUpdate = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'UNSAFE_componentWillUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          UNSAFE_componentWillUpdate() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getSnapshotBeforeUpdate = () => { return {}; }\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'getSnapshotBeforeUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          getSnapshotBeforeUpdate() { return {}; }\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidUpdate = (prevProps) => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentDidUpdate is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidUpdate(prevProps) {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidCatch = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentDidCatch is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentDidCatch() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUnmount = () => {}\n          render = () => { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: 'componentWillUnmount is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n        { message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' },\n      ],\n      output: `\n        class Hello extends React.Component {\n          handleEventMethods = () => {}\n          componentWillUnmount() {}\n          render() { return <div />; }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render = () => <div />\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: semver.satisfies(eslintPkg.version, '> 3') ? `\n        class Hello extends React.Component {\n          render() { return <div />; }\n        }\n      ` : `\n        class Hello extends React.Component {\n          render = () => <div />\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render = () => /*first*/<div />/*second*/\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: 'render is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: semver.satisfies(eslintPkg.version, '> 3') ? `\n        class Hello extends React.Component {\n          render() { return /*first*/<div />/*second*/; }\n        }\n      ` : `\n        class Hello extends React.Component {\n          render = () => /*first*/<div />/*second*/\n        }\n      `,\n    },\n    {\n      code: `\n        export default class Root extends Component {\n          getInitialState = () => ({\n            errorImporting: null,\n            errorParsing: null,\n            errorUploading: null,\n            file: null,\n            fromExtension: false,\n            importSuccess: false,\n            isImporting: false,\n            isParsing: false,\n            isUploading: false,\n            parsedResults: null,\n            showLongRunningMessage: false,\n          });\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: 'getInitialState is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }],\n      output: semver.satisfies(eslintPkg.version, '> 3') ? `\n        export default class Root extends Component {\n          getInitialState() { return {\n            errorImporting: null,\n            errorParsing: null,\n            errorUploading: null,\n            file: null,\n            fromExtension: false,\n            importSuccess: false,\n            isImporting: false,\n            isParsing: false,\n            isUploading: false,\n            parsedResults: null,\n            showLongRunningMessage: false,\n          }; }\n        }\n      ` : `\n        export default class Root extends Component {\n          getInitialState = () => ({\n            errorImporting: null,\n            errorParsing: null,\n            errorUploading: null,\n            file: null,\n            fromExtension: false,\n            importSuccess: false,\n            isImporting: false,\n            isParsing: false,\n            isUploading: false,\n            parsedResults: null,\n            showLongRunningMessage: false,\n          });\n        }\n      `,\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-children-prop.js",
    "content": "/**\n * @fileoverview Tests for no-children-prop\n * @author Benjamin Stepp\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-children-prop');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-children-prop', rule, {\n  valid: parsers.all([\n    {\n      code: '<div />;',\n    },\n    {\n      code: '<div></div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", {});',\n    },\n    {\n      code: 'React.createElement(\"div\", undefined);',\n    },\n    {\n      code: '<div className=\"class-name\"></div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", {className: \"class-name\"});',\n    },\n    {\n      code: '<div>Children</div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", \"Children\");',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, \"Children\");',\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, \"Children\");',\n    },\n    {\n      code: '<div className=\"class-name\">Children</div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", {className: \"class-name\"}, \"Children\");',\n    },\n    {\n      code: '<div><div /></div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", React.createElement(\"div\"));',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, React.createElement(\"div\"));',\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, React.createElement(\"div\"));',\n    },\n    {\n      code: '<div><div /><div /></div>;',\n    },\n    {\n      code: 'React.createElement(\"div\", React.createElement(\"div\"), React.createElement(\"div\"));',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, React.createElement(\"div\"), React.createElement(\"div\"));',\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, React.createElement(\"div\"), React.createElement(\"div\"));',\n    },\n    {\n      code: 'React.createElement(\"div\", [React.createElement(\"div\"), React.createElement(\"div\")]);',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, [React.createElement(\"div\"), React.createElement(\"div\")]);',\n    },\n    {\n      code: 'React.createElement(\"div\", undefined, [React.createElement(\"div\"), React.createElement(\"div\")]);',\n    },\n    {\n      code: '<MyComponent />',\n    },\n    {\n      code: 'React.createElement(MyComponent);',\n    },\n    {\n      code: 'React.createElement(MyComponent, {});',\n    },\n    {\n      code: 'React.createElement(MyComponent, undefined);',\n    },\n    {\n      code: '<MyComponent>Children</MyComponent>;',\n    },\n    {\n      code: 'React.createElement(MyComponent, \"Children\");',\n    },\n    {\n      code: 'React.createElement(MyComponent, {}, \"Children\");',\n    },\n    {\n      code: 'React.createElement(MyComponent, undefined, \"Children\");',\n    },\n    {\n      code: '<MyComponent className=\"class-name\"></MyComponent>;',\n    },\n    {\n      code: 'React.createElement(MyComponent, {className: \"class-name\"});',\n    },\n    {\n      code: '<MyComponent className=\"class-name\">Children</MyComponent>;',\n    },\n    {\n      code: 'React.createElement(MyComponent, {className: \"class-name\"}, \"Children\");',\n    },\n    {\n      code: '<MyComponent className=\"class-name\" {...props} />;',\n    },\n    {\n      code: 'React.createElement(MyComponent, {className: \"class-name\", ...props});',\n    },\n    {\n      code: '<MyComponent children={() => {}} />;',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: '<MyComponent children={function() {}} />;',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: '<MyComponent children={async function() {}} />;',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: '<MyComponent children={function* () {}} />;',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: () => {}});',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: function() {}});',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: async function() {}});',\n      options: [{ allowFunctions: true }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: function* () {}});',\n      options: [{ allowFunctions: true }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<div children />;', // not a valid use case but make sure we don't crash\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: '<div children=\"Children\" />;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: '<div children={<div />} />;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: '<div children={[<div />, <div />]} />;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: '<div children=\"Children\">Children</div>;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: 'React.createElement(\"div\", {children: \"Children\"});',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: 'React.createElement(\"div\", {children: \"Children\"}, \"Children\");',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: 'React.createElement(\"div\", {children: React.createElement(\"div\")});',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: 'React.createElement(\"div\", {children: [React.createElement(\"div\"), React.createElement(\"div\")]});',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: '<MyComponent children=\"Children\" />',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: \"Children\"});',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: '<MyComponent className=\"class-name\" children=\"Children\" />;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {children: \"Children\", className: \"class-name\"});',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: '<MyComponent {...props} children=\"Children\" />;',\n      errors: [{ messageId: 'nestChildren' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {...props, children: \"Children\"})',\n      errors: [{ messageId: 'passChildrenAsArgs' }],\n    },\n    {\n      code: '<MyComponent>{() => {}}</MyComponent>;',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'nestFunction' }],\n    },\n    {\n      code: '<MyComponent>{function() {}}</MyComponent>;',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'nestFunction' }],\n    },\n    {\n      code: '<MyComponent>{async function() {}}</MyComponent>;',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'nestFunction' }],\n    },\n    {\n      code: '<MyComponent>{function* () {}}</MyComponent>;',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'nestFunction' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {}, () => {});',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'passFunctionAsArgs' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {}, function() {});',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'passFunctionAsArgs' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {}, async function() {});',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'passFunctionAsArgs' }],\n    },\n    {\n      code: 'React.createElement(MyComponent, {}, function* () {});',\n      options: [{ allowFunctions: true }],\n      errors: [{ messageId: 'passFunctionAsArgs' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-danger-with-children.js",
    "content": "/**\n * @fileoverview Report when a DOM element is using both children and dangerouslySetInnerHTML\n * @author David Petersen\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-danger-with-children');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-danger-with-children', rule, {\n  valid: parsers.all([\n    {\n      code: '<div>Children</div>',\n    },\n    {\n      code: '<div {...props} />',\n      globals: {\n        props: true,\n      },\n    },\n    {\n      code: '<div dangerouslySetInnerHTML={{ __html: \"HTML\" }} />',\n    },\n    {\n      code: '<div children=\"Children\" />',\n    },\n    {\n      code: `\n        const props = { dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        const moreProps = { className: \"eslint\" };\n        const props = { children: \"Children\", ...moreProps };\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        const otherProps = { children: \"Children\" };\n        const { a, b, ...props } = otherProps;\n        <div {...props} />\n      `,\n    },\n    {\n      code: '<Hello>Children</Hello>',\n    },\n    {\n      code: '<Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }} />',\n    },\n    {\n      code: `\n        <Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }}>\n        </Hello>\n      `,\n    },\n    {\n      code: 'React.createElement(\"div\", { dangerouslySetInnerHTML: { __html: \"HTML\" } });',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, \"Children\");',\n    },\n    {\n      code: 'React.createElement(\"Hello\", { dangerouslySetInnerHTML: { __html: \"HTML\" } });',\n    },\n    {\n      code: 'React.createElement(\"Hello\", {}, \"Children\");',\n    },\n    {\n      code: '<Hello {...undefined}>Children</Hello>',\n    },\n    {\n      code: 'React.createElement(\"Hello\", undefined, \"Children\")',\n    },\n    {\n      code: `\n        const props = {...props, scratch: {mode: 'edit'}};\n        const component = shallow(<TaskEditableTitle {...props} />);\n      `,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        <div dangerouslySetInnerHTML={{ __html: \"HTML\" }}>\n          Children\n        </div>\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: '<div dangerouslySetInnerHTML={{ __html: \"HTML\" }} children=\"Children\" />',\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        const props = { dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        <div {...props}>Children</div>\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        const props = { children: \"Children\", dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        <div {...props} />\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        <Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }}>\n          Children\n        </Hello>\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: '<Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }} children=\"Children\" />',\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: '<Hello dangerouslySetInnerHTML={{ __html: \"HTML\" }}> </Hello>',\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        React.createElement(\n          \"div\",\n          { dangerouslySetInnerHTML: { __html: \"HTML\" } },\n          \"Children\"\n        );\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        React.createElement(\n          \"div\",\n          {\n            dangerouslySetInnerHTML: { __html: \"HTML\" },\n            children: \"Children\",\n          }\n        );\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        React.createElement(\n          \"Hello\",\n          { dangerouslySetInnerHTML: { __html: \"HTML\" } },\n          \"Children\"\n        );\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        React.createElement(\n          \"Hello\",\n          {\n            dangerouslySetInnerHTML: { __html: \"HTML\" },\n            children: \"Children\",\n          }\n        );\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        const props = { dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        React.createElement(\"div\", props, \"Children\");\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        const props = { children: \"Children\", dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        React.createElement(\"div\", props);\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n    {\n      code: `\n        const moreProps = { children: \"Children\" };\n        const otherProps = { ...moreProps };\n        const props = { ...otherProps, dangerouslySetInnerHTML: { __html: \"HTML\" } };\n        React.createElement(\"div\", props);\n      `,\n      errors: [{ messageId: 'dangerWithChildren' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-danger.js",
    "content": "/**\n * @fileoverview Tests for no-danger\n * @author Scott Andrews\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-danger');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-danger', rule, {\n  valid: parsers.all([\n    { code: '<App />;' },\n    { code: '<App dangerouslySetInnerHTML={{ __html: \"\" }} />;' },\n    { code: '<div className=\"bar\"></div>;' },\n    {\n      code: '<div className=\"bar\"></div>;',\n      options: [{ customComponentNames: ['*'] }],\n    },\n    {\n      code: `\n        function App() {\n          return <Title dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['Home'] }],\n    },\n    {\n      code: `\n        function App() {\n          return <TextMUI dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['MUI*'] }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<div dangerouslySetInnerHTML={{ __html: \"\" }}></div>;',\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: '<App dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;',\n      options: [{ customComponentNames: ['*'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return <Title dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['Title'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return <TextFoo dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['*Foo'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return <FooText dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['Foo*'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: `\n        function App() {\n          return <TextMUI dangerouslySetInnerHTML={{ __html: \"<span>hello</span>\" }} />;\n        }\n      `,\n      options: [{ customComponentNames: ['*MUI'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n        },\n      ],\n    },\n    {\n      code: `\n        import type { ComponentProps } from \"react\";\n\n        const Comp = \"div\";\n        const Component = () => <></>;\n\n        const NestedComponent = (_props: ComponentProps<\"div\">) => <></>;\n\n        Component.NestedComponent = NestedComponent;\n\n        function App() {\n          return (\n            <>\n              <div dangerouslySetInnerHTML={{ __html: \"<div>aaa</div>\" }} />\n              <Comp dangerouslySetInnerHTML={{ __html: \"<div>aaa</div>\" }} />\n\n              <Component.NestedComponent\n                dangerouslySetInnerHTML={{ __html: '<div>aaa</div>' }}\n              />\n            </>\n          );\n        }\n      `,\n      features: ['fragment', 'types'],\n      options: [{ customComponentNames: ['*'] }],\n      errors: [\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n          line: 14,\n        },\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n          line: 15,\n        },\n        {\n          messageId: 'dangerousProp',\n          data: { name: 'dangerouslySetInnerHTML' },\n          line: 18,\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-deprecated.js",
    "content": "/**\n * @fileoverview Prevent usage of deprecated methods\n * @author Yannick Croissant\n * @author Scott Feeney\n * @author Sergei Startsev\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-deprecated');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nfunction errorMessage(oldMethod, version, newMethod, refs, extraProps) {\n  return (\n    Object.assign({\n      messageId: 'deprecated',\n      data: {\n        oldMethod,\n        version,\n        newMethod: newMethod ? `, use ${newMethod} instead` : '',\n        refs: refs ? `, see ${refs}` : '',\n      },\n    }, extraProps)\n  );\n}\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-deprecated', rule, {\n  valid: parsers.all([\n    // Not deprecated\n    'var element = React.createElement(\\'p\\', {}, null);',\n    'var clone = React.cloneElement(element);',\n    'ReactDOM.cloneElement(child, container);',\n    'ReactDOM.findDOMNode(instance);',\n    'ReactDOM.createPortal(child, container);',\n    'ReactDOMServer.renderToString(element);',\n    'ReactDOMServer.renderToStaticMarkup(element);',\n    {\n      code: `\n        var Foo = createReactClass({\n          render: function() {}\n        })\n      `,\n    },\n    // Non-React\n    {\n      code: `\n        var Foo = createReactClassNonReact({\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {}\n        });\n      `,\n    },\n    {\n      code: `\n        var Foo = {\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {}\n        };\n      `,\n    },\n    {\n      code: `\n        class Foo {\n          constructor() {}\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n    },\n    // Deprecated in a later version\n    {\n      code: 'React.renderComponent()',\n      settings: { react: { version: '0.11.0' } },\n    },\n    {\n      code: 'React.createClass()',\n      settings: { react: { version: '15.4.0' } },\n    },\n    {\n      code: 'PropTypes',\n      settings: { react: { version: '15.4.0' } },\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.8.0' } },\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        let { default: defaultReactExport, ...allReactExports } = React;\n      `,\n    },\n    // React < 18\n    {\n      code: `\n        import { render, hydrate } from 'react-dom';\n        import { renderToNodeStream } from 'react-dom/server';\n        ReactDOM.render(element, container);\n        ReactDOM.unmountComponentAtNode(container);\n        ReactDOMServer.renderToNodeStream(element);\n      `,\n      settings: { react: { version: '17.999.999' } },\n    },\n    // React 18 API\n    {\n      code: `\n        import ReactDOM, { createRoot } from 'react-dom/client';\n        ReactDOM.createRoot(container);\n        const root = createRoot(container);\n        root.unmount();\n      `,\n    },\n    {\n      code: `\n        import ReactDOM, { hydrateRoot } from 'react-dom/client';\n        ReactDOM.hydrateRoot(container, <App/>);\n        hydrateRoot(container, <App/>);\n      `,\n    },\n    {\n      code: `\n        import ReactDOMServer, { renderToPipeableStream } from 'react-dom/server';\n        ReactDOMServer.renderToPipeableStream(<App />, {});\n        renderToPipeableStream(<App />, {});\n      `,\n    },\n    {\n      code: `\n        import { renderToString } from 'react-dom/server';\n      `,\n    },\n    {\n      code: `\n        const { renderToString } = require('react-dom/server');\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: 'React.renderComponent()',\n      errors: [errorMessage('React.renderComponent', '0.12.0', 'React.render')],\n    },\n    {\n      code: 'Foo.renderComponent()',\n      settings: { react: { pragma: 'Foo' } },\n      errors: [errorMessage('Foo.renderComponent', '0.12.0', 'Foo.render')],\n    },\n    {\n      code: '/** @jsx Foo */ Foo.renderComponent()',\n      errors: [errorMessage('Foo.renderComponent', '0.12.0', 'Foo.render')],\n    },\n    {\n      code: 'this.transferPropsTo()',\n      errors: [errorMessage('this.transferPropsTo', '0.12.0', 'spread operator ({...})')],\n    },\n    {\n      code: 'React.addons.TestUtils',\n      errors: [errorMessage('React.addons.TestUtils', '15.5.0', 'ReactDOM.TestUtils')],\n    },\n    {\n      code: 'React.addons.classSet()',\n      errors: [errorMessage('React.addons.classSet', '0.13.0', 'the npm module classnames')],\n    },\n    {\n      code: 'React.render(element, container);',\n      errors: [errorMessage('React.render', '0.14.0', 'ReactDOM.render')],\n    },\n    {\n      code: 'React.unmountComponentAtNode(container);',\n      errors: [errorMessage('React.unmountComponentAtNode', '0.14.0', 'ReactDOM.unmountComponentAtNode')],\n    },\n    {\n      code: 'React.findDOMNode(instance);',\n      errors: [errorMessage('React.findDOMNode', '0.14.0', 'ReactDOM.findDOMNode')],\n    },\n    {\n      code: 'React.renderToString(element);',\n      errors: [errorMessage('React.renderToString', '0.14.0', 'ReactDOMServer.renderToString')],\n    },\n    {\n      code: 'React.renderToStaticMarkup(element);',\n      errors: [errorMessage('React.renderToStaticMarkup', '0.14.0', 'ReactDOMServer.renderToStaticMarkup')],\n    },\n    {\n      code: 'React.createClass({});',\n      errors: [errorMessage('React.createClass', '15.5.0', 'the npm module create-react-class')],\n    },\n    {\n      code: 'Foo.createClass({});',\n      settings: { react: { pragma: 'Foo' } },\n      errors: [errorMessage('Foo.createClass', '15.5.0', 'the npm module create-react-class')],\n    },\n    {\n      code: 'React.PropTypes',\n      errors: [errorMessage('React.PropTypes', '15.5.0', 'the npm module prop-types')],\n    },\n    {\n      code: 'var {createClass} = require(\\'react\\');',\n      errors: [errorMessage('React.createClass', '15.5.0', 'the npm module create-react-class')],\n    },\n    {\n      code: 'var {createClass, PropTypes} = require(\\'react\\');',\n      errors: [\n        errorMessage(\n          'React.createClass',\n          '15.5.0',\n          'the npm module create-react-class',\n          null,\n          { type: 'Property', column: 6 }\n        ),\n        errorMessage(\n          'React.PropTypes',\n          '15.5.0',\n          'the npm module prop-types',\n          null,\n          { type: 'Property', column: 19 }\n        ),\n      ],\n    },\n    {\n      code: 'import {createClass} from \\'react\\';',\n      errors: [errorMessage('React.createClass', '15.5.0', 'the npm module create-react-class')],\n    },\n    {\n      code: 'import {createClass, PropTypes} from \\'react\\';',\n      errors: [\n        errorMessage('React.createClass', '15.5.0', 'the npm module create-react-class'),\n        errorMessage('React.PropTypes', '15.5.0', 'the npm module prop-types'),\n      ],\n    },\n    {\n      code: `\n      import React from 'react';\n      const {createClass, PropTypes} = React;\n    `,\n      errors: [\n        errorMessage(\n          'React.createClass',\n          '15.5.0',\n          'the npm module create-react-class',\n          null,\n          { type: 'Property', line: 3, column: 14 }\n        ),\n        errorMessage(\n          'React.PropTypes',\n          '15.5.0',\n          'the npm module prop-types',\n          null,\n          { type: 'Property', line: 3, column: 27 }\n        ),\n      ],\n    },\n    {\n      code: 'import {printDOM} from \\'react-addons-perf\\';',\n      errors: [errorMessage('ReactPerf.printDOM', '15.0.0', 'ReactPerf.printOperations')],\n    },\n    {\n      code: `\n        import ReactPerf from 'react-addons-perf';\n        const {printDOM} = ReactPerf;\n      `,\n      errors: [errorMessage('ReactPerf.printDOM', '15.0.0', 'ReactPerf.printOperations')],\n    },\n    {\n      code: 'React.DOM.div',\n      errors: [errorMessage('React.DOM', '15.6.0', 'the npm module react-dom-factories')],\n    },\n    {\n      code: `\n        class Bar extends React.PureComponent {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        };\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 3, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        function Foo() {\n          return class Bar extends React.PureComponent {\n            componentWillMount() {}\n            componentWillReceiveProps() {}\n            componentWillUpdate() {}\n          };\n        }\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 13 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 13 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 6, column: 13 }\n        ),\n      ],\n    },\n    {\n      code: `\n        class Bar extends PureComponent {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        };\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 3, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 3, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 3, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {}\n        })\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 3, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor() {}\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      errors: [\n        errorMessage(\n          'componentWillMount',\n          '16.9.0',\n          'UNSAFE_componentWillMount',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillmount. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 4, column: 11 }\n        ),\n        errorMessage(\n          'componentWillReceiveProps',\n          '16.9.0',\n          'UNSAFE_componentWillReceiveProps',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 5, column: 11 }\n        ),\n        errorMessage(\n          'componentWillUpdate',\n          '16.9.0',\n          'UNSAFE_componentWillUpdate',\n          'https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate. Use https://github.com/reactjs/react-codemod#rename-unsafe-lifecycles to automatically update your components.',\n          { type: 'Identifier', line: 6, column: 11 }\n        ),\n      ],\n    },\n    {\n      code: `\n        import { render } from 'react-dom';\n        ReactDOM.render(<div></div>, container);\n      `,\n      errors: [\n        errorMessage(\n          'ReactDOM.render',\n          '18.0.0',\n          'createRoot',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'ImportSpecifier', line: 2, column: 18 }\n        ),\n        errorMessage(\n          'ReactDOM.render',\n          '18.0.0',\n          'createRoot',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'MemberExpression', line: 3, column: 9 }\n        ),\n      ],\n    },\n    {\n      code: `\n        import { hydrate } from 'react-dom';\n        ReactDOM.hydrate(<div></div>, container);\n      `,\n      errors: [\n        errorMessage(\n          'ReactDOM.hydrate',\n          '18.0.0',\n          'hydrateRoot',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'ImportSpecifier', line: 2, column: 18 }\n        ),\n        errorMessage(\n          'ReactDOM.hydrate',\n          '18.0.0',\n          'hydrateRoot',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'MemberExpression', line: 3, column: 9 }\n        ),\n      ],\n    },\n    {\n      code: `\n        import { unmountComponentAtNode } from 'react-dom';\n        ReactDOM.unmountComponentAtNode(container);\n      `,\n      errors: [\n        errorMessage(\n          'ReactDOM.unmountComponentAtNode',\n          '18.0.0',\n          'root.unmount',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'ImportSpecifier', line: 2, column: 18 }\n        ),\n        errorMessage(\n          'ReactDOM.unmountComponentAtNode',\n          '18.0.0',\n          'root.unmount',\n          'https://reactjs.org/link/switch-to-createroot',\n          { type: 'MemberExpression', line: 3, column: 9 }\n        ),\n      ],\n    },\n    {\n      code: `\n        import { renderToNodeStream } from 'react-dom/server';\n        ReactDOMServer.renderToNodeStream(element);\n      `,\n      errors: [\n        errorMessage(\n          'ReactDOMServer.renderToNodeStream',\n          '18.0.0',\n          'renderToPipeableStream',\n          'https://reactjs.org/docs/react-dom-server.html#rendertonodestream',\n          { type: 'ImportSpecifier', line: 2, column: 18 }\n        ),\n        errorMessage(\n          'ReactDOMServer.renderToNodeStream',\n          '18.0.0',\n          'renderToPipeableStream',\n          'https://reactjs.org/docs/react-dom-server.html#rendertonodestream',\n          { type: 'MemberExpression', line: 3, column: 9 }\n        ),\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-did-mount-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentDidMount\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-did-mount-set-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst invalid = [\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidMount: function() {\n          this.setState({\n            data: data\n          });\n        }\n      });\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount() {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount = () => {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidMount: function() {\n          this.setState({\n            data: data\n          });\n        }\n      });\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount() {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidMount: function() {\n          someClass.onSomeEvent(function(data) {\n            this.setState({\n              data: data\n            });\n          })\n        }\n      });\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount() {\n          someClass.onSomeEvent(function(data) {\n            this.setState({\n              data: data\n            });\n          })\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidMount: function() {\n          if (true) {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      });\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount() {\n          if (true) {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      }\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidMount: function() {\n          someClass.onSomeEvent((data) => this.setState({data: data}));\n        }\n      });\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidMount() {\n          someClass.onSomeEvent((data) => this.setState({data: data}));\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidMount' },\n      },\n    ],\n  },\n];\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-did-mount-set-state', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {}\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            someNonMemberFunction(arg);\n            this.someHandler = this.setState;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            someClass.onSomeEvent(function(data) {\n              this.setState({\n                data: data\n              });\n            })\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            function handleEvent(data) {\n              this.setState({\n                data: data\n              });\n            }\n            someClass.onSomeEvent(handleEvent)\n          }\n        });\n      `,\n    },\n    invalid.map((test) => {\n      const newTest = Object.assign({}, test, {\n        settings: Object.assign({}, test.settings, {\n          react: {\n            version: '16.3.0',\n          },\n        }),\n      });\n      delete newTest.errors;\n      return newTest;\n    })\n  )),\n\n  invalid: parsers.all(invalid),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-did-update-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentDidUpdate\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-did-update-set-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst invalid = [\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidUpdate: function() {\n          this.setState({\n            data: data\n          });\n        }\n      });\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate() {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate = () => {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n    var Hello = createReactClass({\n      componentDidUpdate: function() {\n        this.setState({\n          data: data\n        });\n      }\n    });\n  `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate() {\n          this.setState({\n            data: data\n          });\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidUpdate: function() {\n          someClass.onSomeEvent(function(data) {\n            this.setState({\n              data: data\n            });\n          })\n        }\n      });\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate() {\n          someClass.onSomeEvent(function(data) {\n            this.setState({\n              data: data\n            });\n          })\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidUpdate: function() {\n          if (true) {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      });\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate() {\n          if (true) {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      }\n    `,\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      var Hello = createReactClass({\n        componentDidUpdate: function() {\n          someClass.onSomeEvent((data) => this.setState({data: data}));\n        }\n      });\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n  {\n    code: `\n      class Hello extends React.Component {\n        componentDidUpdate() {\n          someClass.onSomeEvent((data) => this.setState({data: data}));\n        }\n      }\n    `,\n    options: ['disallow-in-func'],\n    errors: [\n      {\n        messageId: 'noSetState',\n        data: { name: 'componentDidUpdate' },\n      },\n    ],\n  },\n];\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-did-update-set-state', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {}\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            someNonMemberFunction(arg);\n            this.someHandler = this.setState;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            someClass.onSomeEvent(function(data) {\n              this.setState({\n                data: data\n              });\n            })\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            function handleEvent(data) {\n              this.setState({\n                data: data\n              });\n            }\n            someClass.onSomeEvent(handleEvent)\n          }\n        });\n      `,\n    },\n    invalid.map((test) => {\n      const newTest = Object.assign({}, test, {\n        settings: Object.assign({}, test.settings, {\n          react: {\n            version: '16.3.0',\n          },\n        }),\n      });\n      delete newTest.errors;\n      return newTest;\n    })\n  )),\n\n  invalid: parsers.all(invalid),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-direct-mutation-state.js",
    "content": "/**\n * @fileoverview Prevent direct mutation of this.state\n * @author David Petersen\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-direct-mutation-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-direct-mutation-state', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var obj = {state: {}};\n            obj.state.name = \"foo\";\n            return <div>Hello {obj.state.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = \"foo\";\n        module.exports = {};\n      `,\n    },\n    {\n      code: `\n        class Hello {\n          getFoo() {\n            this.state.foo = 'bar'\n            return this.state.foo;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor() {\n            this.state.foo = 1;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class OneComponent extends Component {\n          constructor() {\n            super();\n            class AnotherComponent extends Component {\n              constructor() {\n                super();\n              }\n            }\n            this.state = {};\n          }\n        }\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            this.state.foo = \"bar\"\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            this.state.foo++;\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            this.state.person.name= \"bar\"\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            this.state.person.name.first = \"bar\"\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            this.state.person.name.first = \"bar\"\n            this.state.person.name.last = \"baz\"\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [\n        {\n          message: 'Do not mutate state directly. Use setState().',\n          line: 4,\n          column: 13,\n        },\n        {\n          message: 'Do not mutate state directly. Use setState().',\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor() {\n            someFn()\n          }\n          someFn() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props) {\n            super(props)\n            doSomethingAsync(() => {\n              this.state = \"bad\";\n            });\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillMount() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentDidMount() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillReceiveProps() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          shouldComponentUpdate() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentDidUpdate() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUnmount() {\n            this.state.foo = \"bar\"\n          }\n        }\n      `,\n      errors: [{ messageId: 'noDirectMutation' }],\n    },\n    /**\n     * Would be nice to prevent this too\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var that = this;\n            that.state.person.name.first = \"bar\"\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [{messageId: 'noDirectMutation'}]\n    } */\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-find-dom-node.js",
    "content": "/**\n * @fileoverview Prevent usage of findDOMNode\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-find-dom-node');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-find-dom-node', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = function() {};\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            someNonMemberFunction(arg);\n            this.someFunc = React.findDOMNode;\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            React.someFunc(this);\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            React.findDOMNode(this).scrollIntoView();\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noFindDOMNode' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            ReactDOM.findDOMNode(this).scrollIntoView();\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noFindDOMNode' }],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentDidMount() {\n            findDOMNode(this).scrollIntoView();\n          }\n          render() {\n            return <div>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'noFindDOMNode' }],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentDidMount() {\n            this.node = findDOMNode(this);\n          }\n          render() {\n            return <div>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'noFindDOMNode' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-invalid-html-attribute.js",
    "content": "/**\n * @fileoverview Forbid target='_blank' attribute\n * @author Kevin Miller\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-invalid-html-attribute');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\n\nruleTester.run('no-invalid-html-attribute', rule, {\n  valid: parsers.all([\n    { code: '<a rel=\"alternate\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"alternate\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"alternate\"] })' },\n    { code: '<a rel=\"author\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"author\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"author\"] })' },\n    { code: '<a rel=\"bookmark\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"bookmark\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"bookmark\"] })' },\n    { code: '<a rel=\"external\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"external\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"external\"] })' },\n    { code: '<a rel=\"help\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"help\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"help\"] })' },\n    { code: '<a rel=\"license\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"license\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"license\"] })' },\n    { code: '<a rel=\"next\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"next\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"next\"] })' },\n    { code: '<a rel=\"nofollow\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"nofollow\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"nofollow\"] })' },\n    { code: '<a rel=\"noopener\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"noopener\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"noopener\"] })' },\n    { code: '<a rel=\"noreferrer\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"noreferrer\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"noreferrer\"] })' },\n    { code: '<a rel=\"opener\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"opener\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"opener\"] })' },\n    { code: '<a rel=\"prev\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"prev\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"prev\"] })' },\n    { code: '<a rel=\"search\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"search\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"search\"] })' },\n    { code: '<a rel=\"tag\"></a>' },\n    { code: 'React.createElement(\"a\", { rel: \"tag\" })' },\n    { code: 'React.createElement(\"a\", { rel: [\"tag\"] })' },\n    { code: '<area rel=\"alternate\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"alternate\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"alternate\"] })' },\n    { code: '<area rel=\"author\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"author\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"author\"] })' },\n    { code: '<area rel=\"bookmark\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"bookmark\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"bookmark\"] })' },\n    { code: '<area rel=\"external\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"external\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"external\"] })' },\n    { code: '<area rel=\"help\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"help\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"help\"] })' },\n    { code: '<area rel=\"license\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"license\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"license\"] })' },\n    { code: '<area rel=\"next\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"next\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"next\"] })' },\n    { code: '<area rel=\"nofollow\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"nofollow\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"nofollow\"] })' },\n    { code: '<area rel=\"noopener\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"noopener\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"noopener\"] })' },\n    { code: '<area rel=\"noreferrer\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"noreferrer\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"noreferrer\"] })' },\n    { code: '<area rel=\"opener\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"opener\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"opener\"] })' },\n    { code: '<area rel=\"prev\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"prev\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"prev\"] })' },\n    { code: '<area rel=\"search\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"search\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"search\"] })' },\n    { code: '<area rel=\"tag\"></area>' },\n    { code: 'React.createElement(\"area\", { rel: \"tag\" })' },\n    { code: 'React.createElement(\"area\", { rel: [\"tag\"] })' },\n    { code: '<link rel=\"alternate\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"alternate\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"alternate\"] })' },\n    { code: '<link rel=\"author\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"author\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"author\"] })' },\n    { code: '<link rel=\"canonical\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"canonical\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"canonical\"] })' },\n    { code: '<link rel=\"dns-prefetch\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"dns-prefetch\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"dns-prefetch\"] })' },\n    { code: '<link rel=\"help\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"help\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"help\"] })' },\n    { code: '<link rel=\"icon\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"icon\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"icon\"] })' },\n    { code: '<link rel=\"shortcut icon\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"shortcut icon\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"shortcut icon\"] })' },\n    { code: '<link rel=\"license\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"license\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"license\"] })' },\n    { code: '<link rel=\"manifest\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"manifest\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"manifest\"] })' },\n    { code: '<link rel=\"modulepreload\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"modulepreload\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"modulepreload\"] })' },\n    { code: '<link rel=\"next\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"next\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"next\"] })' },\n    { code: '<link rel=\"pingback\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"pingback\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"pingback\"] })' },\n    { code: '<link rel=\"preconnect\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"preconnect\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"preconnect\"] })' },\n    { code: '<link rel=\"prefetch\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"prefetch\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"prefetch\"] })' },\n    { code: '<link rel=\"preload\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"preload\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"preload\"] })' },\n    { code: '<link rel=\"prerender\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"prerender\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"prerender\"] })' },\n    { code: '<link rel=\"prev\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"prev\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"prev\"] })' },\n    { code: '<link rel=\"search\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"search\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"search\"] })' },\n    { code: '<link rel=\"stylesheet\"></link>' },\n    { code: 'React.createElement(\"link\", { rel: \"stylesheet\" })' },\n    { code: 'React.createElement(\"link\", { rel: [\"stylesheet\"] })' },\n    { code: '<form rel=\"external\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"external\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"external\"] })' },\n    { code: '<form rel=\"help\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"help\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"help\"] })' },\n    { code: '<form rel=\"license\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"license\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"license\"] })' },\n    { code: '<form rel=\"next\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"next\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"next\"] })' },\n    { code: '<form rel=\"nofollow\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"nofollow\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"nofollow\"] })' },\n    { code: '<form rel=\"noopener\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"noopener\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"noopener\"] })' },\n    { code: '<form rel=\"noreferrer\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"noreferrer\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"noreferrer\"] })' },\n    { code: '<form rel=\"opener\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"opener\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"opener\"] })' },\n    { code: '<form rel=\"prev\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"prev\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"prev\"] })' },\n    { code: '<form rel=\"search\"></form>' },\n    { code: 'React.createElement(\"form\", { rel: \"search\" })' },\n    { code: 'React.createElement(\"form\", { rel: [\"search\"] })' },\n    { code: '<form rel={callFoo()}></form>' },\n    { code: 'React.createElement(\"form\", { rel: callFoo() })' },\n    { code: 'React.createElement(\"form\", { rel: [callFoo()] })' },\n    { code: '<a rel={{a: \"noreferrer\"}[\"a\"]}></a>' },\n    { code: '<a rel={{a: \"noreferrer\"}[\"b\"]}></a>' },\n    { code: '<Foo rel></Foo>' },\n    { code: 'React.createElement(\"Foo\", { rel: true })' },\n    {\n      code: `\n        React.createElement('a', {\n          ...rest,\n          href: to,\n        })\n      `,\n    },\n    {\n      code: '<link rel=\"apple-touch-icon\" sizes=\"60x60\" href=\"apple-touch-icon-60x60.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"apple-touch-icon-76x76.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"apple-touch-icon-120x120.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"apple-touch-icon-152x152.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"apple-touch-icon-180x180.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-startup-image\" href=\"launch.png\" />',\n    },\n    {\n      code: '<link rel=\"apple-touch-startup-image\" href=\"iphone5.png\" media=\"(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)\" />',\n    },\n    {\n      code: '<link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#fff\" />',\n    },\n  ]),\n  invalid: parsers.all([].concat(\n    {\n      code: '<a rel=\"alternatex\"></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'alternatex',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: \"alternatex\" })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'alternatex',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex' },\n              output: 'React.createElement(\"a\", { rel: \"\" })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: [\"alternatex\"] })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'alternatex',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex' },\n              output: 'React.createElement(\"a\", { rel: [\"\"] })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"alternatex alternate\"></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'alternatex',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex' },\n              output: '<a rel=\" alternate\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: \"alternatex alternate\" })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'alternatex alternate',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex alternate' },\n              output: 'React.createElement(\"a\", { rel: \"\" })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: [\"alternatex alternate\"] })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'alternatex alternate',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex alternate' },\n              output: 'React.createElement(\"a\", { rel: [\"\"] })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"alternate alternatex\"></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'alternatex',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternatex' },\n              output: '<a rel=\"alternate \"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: \"alternate alternatex\" })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'alternate alternatex',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternate alternatex' },\n              output: 'React.createElement(\"a\", { rel: \"\" })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: [\"alternate alternatex\"] })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'alternate alternatex',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternate alternatex' },\n              output: 'React.createElement(\"a\", { rel: [\"\"] })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<html rel></html>',\n      errors: [\n        {\n          messageId: 'onlyMeaningfulFor',\n          data: {\n            attributeName: 'rel',\n            tagNames: '\"<link>\", \"<a>\", \"<area>\", \"<form>\"',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveDefault',\n              data: { attributeName: 'rel' },\n              output: '<html ></html>',\n            },\n          ],\n          type: 'JSXIdentifier',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"html\", { rel: 1 })',\n      errors: [\n        {\n          messageId: 'onlyMeaningfulFor',\n          data: {\n            attributeName: 'rel',\n            tagNames: '\"<link>\", \"<a>\", \"<area>\", \"<form>\"',\n          },\n          // suggestions: [\n          //   {\n          //     messageId: 'suggestRemoveDefault',\n          //     data: { attributeName: 'rel' },\n          //     output: 'React.createElement(\"html\", { })',\n          //   },\n          // ],\n          column: 31,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: '<a rel></a>',\n      errors: [\n        {\n          messageId: 'emptyIsMeaningless',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveEmpty',\n              data: { attributeName: 'rel' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'JSXIdentifier',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: 1 })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 1,\n          },\n\n          // FIXME: this suggestion produces invalid code\n          // In ESLint > 9, RuleTester doesn't allow suggestions with parsing errors.\n          suggestions: semver.major(eslintPkg.version) < 9\n            ? [\n              {\n                messageId: 'suggestRemoveInvalid',\n                data: { reportingValue: '1' },\n                output: 'React.createElement(\"a\", { rel:  })',\n              },\n            ]\n            : 1,\n\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel() { return 1; } })',\n      errors: [\n        {\n          messageId: 'noMethod',\n          data: { attributeName: 'rel' },\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: '<span rel></span>',\n      errors: [\n        {\n          messageId: 'onlyMeaningfulFor',\n          data: {\n            attributeName: 'rel',\n            tagNames: '\"<link>\", \"<a>\", \"<area>\", \"<form>\"',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveDefault',\n              data: { attributeName: 'rel' },\n              output: '<span ></span>',\n            },\n          ],\n          type: 'JSXIdentifier',\n        },\n      ],\n    },\n    {\n      code: '<a rel={null}></a>',\n      errors: [\n        {\n          messageId: 'onlyStrings',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveNonString',\n              data: { attributeName: 'rel' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={5}></a>',\n      errors: [\n        {\n          messageId: 'onlyStrings',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveNonString',\n              data: { attributeName: 'rel' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={true}></a>',\n      errors: [\n        {\n          messageId: 'onlyStrings',\n          data: { attributeName: 'rel', reportingValue: 'true' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveNonString',\n              data: { attributeName: 'rel', reportingValue: 'true' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={{}}></a>',\n      errors: [\n        {\n          messageId: 'onlyStrings',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveDefault',\n              data: { attributeName: 'rel' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'JSXExpressionContainer',\n        },\n      ],\n    },\n    {\n      code: '<a rel={undefined}></a>',\n      errors: [\n        {\n          messageId: 'onlyStrings',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveDefault',\n              data: { attributeName: 'rel' },\n              output: '<a ></a>',\n            },\n          ],\n          type: 'JSXExpressionContainer',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"noreferrer noopener foobar\"></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'foobar',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'foobar' },\n              output: '<a rel=\"noreferrer noopener \"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"noreferrer noopener   \"></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel=\"noreferrer noopener\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"noreferrer        noopener\"></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel=\"noreferrer noopener\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"noreferrer\\xa0\\xa0noopener\"></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel=\"noreferrer noopener\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={\"noreferrer noopener foobar\"}></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'foobar',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'foobar' },\n              output: '<a rel={\"noreferrer noopener \"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"a\", { rel: [\"noreferrer\", \"noopener\", \"foobar\" ] })',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'foobar',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'foobar' },\n              output: 'React.createElement(\"a\", { rel: [\"noreferrer\", \"noopener\", \"\" ] })',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={\"foobar noreferrer noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'foobar',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'foobar' },\n              output: '<a rel={\" noreferrer noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<a rel={\"foobar batgo       noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'foobar',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'foobar' },\n              output: '<a rel={\" batgo       noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'batgo',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'batgo' },\n              output: '<a rel={\"foobar        noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel={\"foobar batgo noopener\"}></a>',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: '<a rel={\"        noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel={\"noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={\"noopener        \"}></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel={\"noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<a rel={\" batgo noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'batgo',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'batgo' },\n              output: '<a rel={\"  noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel={\"batgo noopener\"}></a>',\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: '<a rel={\"batgo noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            reportingValue: 'batgo',\n            attributeName: 'rel',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'batgo' },\n              output: '<a rel={\" noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel={\" noopener\"}></a>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<a rel={\"noopener\"}></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"canonical\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'canonical',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'canonical' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"dns-prefetch\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'dns-prefetch',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'dns-prefetch' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"icon\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'icon',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'icon' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"shortcut\"></link>',\n      errors: [\n        {\n          messageId: 'notAlone',\n          data: {\n            reportingValue: 'shortcut',\n            missingValue: 'icon',\n          },\n          type: 'Literal',\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<link rel=\"shortcut foo\"></link>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'foo',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: {\n                attributeName: 'rel',\n                reportingValue: 'foo',\n              },\n              output: '<link rel=\"shortcut \"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n        {\n          messageId: 'notPaired',\n          data: {\n            reportingValue: 'shortcut',\n            secondValue: 'foo',\n            missingValue: 'icon',\n          },\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"shortcut  icon\"></link>',\n      errors: [\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<link rel=\"shortcut icon\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: '<link rel=\"shortcut  foo\"></link>',\n      errors: [\n        {\n          messageId: 'neverValid',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'foo',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: {\n                attributeName: 'rel',\n                reportingValue: 'foo',\n              },\n              output: '<link rel=\"shortcut  \"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n        {\n          messageId: 'notAlone',\n          data: {\n            attributeName: 'rel',\n            reportingValue: 'shortcut',\n            missingValue: 'icon',\n          },\n        },\n        {\n          messageId: 'spaceDelimited',\n          data: { attributeName: 'rel' },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveWhitespaces',\n              data: { attributeName: 'rel' },\n              output: '<link rel=\"shortcut foo\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"manifest\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'manifest',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'manifest' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"modulepreload\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'modulepreload',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'modulepreload' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"pingback\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'pingback',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'pingback' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"preconnect\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preconnect',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preconnect' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"prefetch\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prefetch',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prefetch' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"preload\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preload',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preload' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"prerender\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prerender',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prerender' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<a rel=\"stylesheet\"></a>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'stylesheet',\n            attributeName: 'rel',\n            elementName: 'a',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'stylesheet' },\n              output: '<a rel=\"\"></a>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"canonical\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'canonical',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'canonical' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"dns-prefetch\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'dns-prefetch',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'dns-prefetch' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"icon\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'icon',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'icon' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"manifest\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'manifest',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'manifest' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"modulepreload\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'modulepreload',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'modulepreload' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"pingback\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'pingback',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'pingback' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"preconnect\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preconnect',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preconnect' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"prefetch\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prefetch',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prefetch' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"preload\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preload',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preload' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"prerender\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prerender',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prerender' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<area rel=\"stylesheet\"></area>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'stylesheet',\n            attributeName: 'rel',\n            elementName: 'area',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'stylesheet' },\n              output: '<area rel=\"\"></area>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"bookmark\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'bookmark',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'bookmark' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"external\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'external',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'external' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"nofollow\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'nofollow',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'nofollow' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"noopener\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'noopener',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'noopener' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"noreferrer\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'noreferrer',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'noreferrer' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"opener\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'opener',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'opener' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<link rel=\"tag\"></link>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'tag',\n            attributeName: 'rel',\n            elementName: 'link',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'tag' },\n              output: '<link rel=\"\"></link>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"alternate\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'alternate',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'alternate' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"author\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'author',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'author' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"bookmark\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'bookmark',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'bookmark' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"canonical\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'canonical',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'canonical' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"dns-prefetch\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'dns-prefetch',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'dns-prefetch' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"icon\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'icon',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'icon' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"manifest\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'manifest',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'manifest' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"modulepreload\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'modulepreload',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'modulepreload' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"pingback\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'pingback',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'pingback' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"preconnect\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preconnect',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preconnect' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"prefetch\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prefetch',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prefetch' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"preload\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'preload',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'preload' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"prerender\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'prerender',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'prerender' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"stylesheet\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'stylesheet',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'stylesheet' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"tag\"></form>',\n      errors: [\n        {\n          messageId: 'notValidFor',\n          data: {\n            reportingValue: 'tag',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveInvalid',\n              data: { reportingValue: 'tag' },\n              output: '<form rel=\"\"></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    },\n    {\n      code: '<form rel=\"\"></form>',\n      errors: [\n        {\n          messageId: 'noEmpty',\n          data: {\n            reportingValue: 'tag',\n            attributeName: 'rel',\n            elementName: 'form',\n          },\n          suggestions: [\n            {\n              messageId: 'suggestRemoveEmpty',\n              data: { attributeName: 'rel' },\n              output: '<form ></form>',\n            },\n          ],\n          type: 'Literal',\n        },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-is-mounted.js",
    "content": "/**\n * @fileoverview Prevent usage of isMounted\n * @author Joe Lencioni\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-is-mounted');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-is-mounted', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = function() {\n        };\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            someNonMemberFunction(arg);\n            this.someFunc = this.isMounted;\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          notIsMounted() {}\n          render() {\n            this.notIsMounted();\n            return <div>Hello</div>;\n          }\n        };\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            if (!this.isMounted()) {\n              return;\n            }\n          },\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noIsMounted' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          someMethod: function() {\n            if (!this.isMounted()) {\n              return;\n            }\n          },\n          render: function() {\n            return <div onClick={this.someMethod.bind(this)}>Hello</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noIsMounted' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          someMethod() {\n            if (!this.isMounted()) {\n              return;\n            }\n          }\n          render() {\n            return <div onClick={this.someMethod.bind(this)}>Hello</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'noIsMounted' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-multi-comp.js",
    "content": "/**\n * @fileoverview Prevent multiple component definition per file\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-multi-comp');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-multi-comp', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = require('./components/Hello');\n        var HelloJohn = createReactClass({\n          render: function() {\n            return <Hello name=\"John\" />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Heading = createReactClass({\n          render: function() {\n            return (\n              <div>\n                {this.props.buttons.map(function(button, index) {\n                  return <Button {...button} key={index}/>;\n                })}\n              </div>\n            );\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        function HelloAgain(props) {\n          return <div>Hello again {props.name}</div>;\n        }\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        class HelloJohn extends React.Component {\n          render() {\n            return <Hello name=\"John\" />;\n          }\n        }\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n    // multiple non-components\n      code: `\n        import React, { createElement } from \"react\"\n        const helperFoo = () => {\n          return true;\n        };\n        function helperBar() {\n          return false;\n        };\n        function RealComponent() {\n          return createElement(\"img\");\n        };\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    {\n      code: `\n        const Hello = React.memo(function(props) {\n          return <div>Hello {props.name}</div>;\n        });\n        class HelloJohn extends React.Component {\n          render() {\n            return <Hello name=\"John\" />;\n          }\n        }\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n      code: `\n        class StoreListItem extends React.PureComponent {\n          // A bunch of stuff here\n        }\n        export default React.forwardRef((props, ref) => <StoreListItem {...props} forwardRef={ref} />);\n      `,\n      options: [{ ignoreStateless: false }],\n    },\n    {\n      code: `\n        class StoreListItem extends React.PureComponent {\n          // A bunch of stuff here\n        }\n        export default React.forwardRef((props, ref) => {\n          return <StoreListItem {...props} forwardRef={ref} />\n        });\n      `,\n      options: [{ ignoreStateless: false }],\n    },\n    {\n      code: `\n        const HelloComponent = (props) => {\n          return <div></div>;\n        }\n        export default React.forwardRef((props, ref) => <HelloComponent {...props} forwardRef={ref} />);\n      `,\n      options: [{ ignoreStateless: false }],\n    },\n    {\n      code: `\n        class StoreListItem extends React.PureComponent {\n          // A bunch of stuff here\n        }\n        export default React.forwardRef(\n          function myFunction(props, ref) {\n            return <StoreListItem {...props} forwardedRef={ref} />;\n          }\n        );\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n      code: `\n        const HelloComponent = (props) => {\n          return <div></div>;\n        }\n        class StoreListItem extends React.PureComponent {\n          // A bunch of stuff here\n        }\n        export default React.forwardRef(\n          function myFunction(props, ref) {\n            return <StoreListItem {...props} forwardedRef={ref} />;\n          }\n        );\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n      code: `\n        const HelloComponent = (props) => {\n          return <div></div>;\n        }\n        export default React.memo((props, ref) => <HelloComponent {...props} />);\n      `,\n      options: [{ ignoreStateless: true }],\n    },\n    {\n      code: `\n        import React from 'react';\n        function memo() {\n          var outOfScope = \"hello\"\n          return null;\n        }\n        class ComponentY extends React.Component {\n          memoCities = memo((cities) => cities.map((v) => ({ label: v })));\n          render() {\n            return (\n              <div>\n                <div>Counter</div>\n              </div>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const MenuList = forwardRef(({onClose, ...props}, ref) => {\n          const {t} = useTranslation();\n          const handleLogout = useLogoutHandler();\n\n          const onLogout = useCallback(() => {\n            onClose();\n            handleLogout();\n          }, [onClose, handleLogout]);\n\n          return (\n            <MuiMenuList ref={ref} {...props}>\n              <MuiMenuItem key=\"logout\" onClick={onLogout}>\n                {t('global-logout')}\n              </MuiMenuItem>\n            </MuiMenuList>\n          );\n        });\n\n        MenuList.displayName = 'MenuList';\n\n        MenuList.propTypes = {\n          onClose: PropTypes.func,\n        };\n\n        MenuList.defaultProps = {\n          onClose: () => null,\n        };\n\n        export default MenuList;\n      `,\n    },\n    {\n      code: `\n        const MenuList = forwardRef(({ onClose, ...props }, ref) => {\n          const onLogout = useCallback(() => {\n            onClose()\n          }, [onClose])\n\n          return (\n            <BlnMenuList ref={ref} {...props}>\n              <BlnMenuItem key=\"logout\" onClick={onLogout}>\n                Logout\n              </BlnMenuItem>\n            </BlnMenuList>\n          )\n        })\n\n        MenuList.displayName = 'MenuList'\n\n        MenuList.propTypes = {\n          onClose: PropTypes.func\n        }\n\n        MenuList.defaultProps = {\n          onClose: () => null\n        }\n\n        export default MenuList\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n        var HelloJohn = createReactClass({\n          render: function() {\n            return <Hello name=\"John\" />;\n          }\n        });\n      `.split('\\n').join('\\r'),\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 7,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        class HelloJohn extends React.Component {\n          render() {\n            return <Hello name=\"John\" />;\n          }\n        }\n        class HelloJohnny extends React.Component {\n          render() {\n            return <Hello name=\"Johnny\" />;\n          }\n        }\n      `.split('\\n').join('\\r'),\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 7,\n        },\n        {\n          messageId: 'onlyOneComponent',\n          line: 12,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        function HelloAgain(props) {\n          return <div>Hello again {props.name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        class HelloJohn extends React.Component {\n          render() {\n            return <Hello name=\"John\" />;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        export default {\n          RenderHello(props) {\n            let {name} = props;\n            return <div>{name}</div>;\n          },\n          RenderHello2(props) {\n            let {name} = props;\n            return <div>{name}</div>;\n          }\n        };\n      `,\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 7,\n        },\n      ],\n    },\n    {\n      code: `\n        exports.Foo = function Foo() {\n          return <></>\n        }\n\n        exports.createSomeComponent = function createSomeComponent(opts) {\n          return function Foo() {\n            return <>{opts.a}</>\n          }\n        }\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 7,\n        },\n      ],\n    },\n    {\n      code: `\n        class StoreListItem extends React.PureComponent {\n          // A bunch of stuff here\n        }\n        export default React.forwardRef((props, ref) => <div><StoreListItem {...props} forwardRef={ref} /></div>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        const HelloComponent = (props) => {\n          return <div></div>;\n        }\n        const HelloComponent2 = React.forwardRef((props, ref) => <div></div>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = React.forwardRef((props, ref) => <><HelloComponent></HelloComponent></>);\n      `,\n      options: [{ ignoreStateless: false }],\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        const forwardRef = React.forwardRef;\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = forwardRef((props, ref) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const memo = React.memo;\n        const HelloComponent = (props) => {\n          return <div></div>;\n        };\n        const HelloComponent2 = memo((props) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const {forwardRef} = React;\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = forwardRef((props, ref) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const {memo} = React;\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = memo((props) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        import React, { memo } from 'react';\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = memo((props) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        import {forwardRef} from 'react';\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = forwardRef((props, ref) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const { memo } = require('react');\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = memo((props) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const {forwardRef} = require('react');\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = forwardRef((props, ref) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const forwardRef = require('react').forwardRef;\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = forwardRef((props, ref) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        const memo = require('react').memo;\n        const HelloComponent = (0, (props) => {\n          return <div></div>;\n        });\n        const HelloComponent2 = memo((props) => <HelloComponent></HelloComponent>);\n      `,\n      options: [{ ignoreStateless: false }],\n      errors: [\n        {\n          messageId: 'onlyOneComponent',\n          line: 6,\n        },\n      ],\n    },\n    {\n      code: `\n        import Foo, { memo, forwardRef } from 'foo';\n        const Text = forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        })\n        const Label = memo(() => <Text />);\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [{ messageId: 'onlyOneComponent' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-namespace.js",
    "content": "/**\n * @fileoverview Tests for jsx-no-namespace\n * @author Yacine Hmito\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-namespace');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-namespace', rule, {\n  valid: parsers.all([\n    {\n      code: '<testcomponent />',\n    },\n    {\n      code: 'React.createElement(\"testcomponent\")',\n    },\n    {\n      code: '<testComponent />',\n    },\n    {\n      code: 'React.createElement(\"testComponent\")',\n    },\n    {\n      code: '<test_component />',\n    },\n    {\n      code: 'React.createElement(\"test_component\")',\n    },\n    {\n      code: '<TestComponent />',\n    },\n    {\n      code: 'React.createElement(\"TestComponent\")',\n    },\n    {\n      code: '<object.testcomponent />',\n    },\n    {\n      code: 'React.createElement(\"object.testcomponent\")',\n    },\n    {\n      code: '<object.testComponent />',\n    },\n    {\n      code: 'React.createElement(\"object.testComponent\")',\n    },\n    {\n      code: '<object.test_component />',\n    },\n    {\n      code: 'React.createElement(\"object.test_component\")',\n    },\n    {\n      code: '<object.TestComponent />',\n    },\n    {\n      code: 'React.createElement(\"object.TestComponent\")',\n    },\n    {\n      code: '<Object.testcomponent />',\n    },\n    {\n      code: 'React.createElement(\"Object.testcomponent\")',\n    },\n    {\n      code: '<Object.testComponent />',\n    },\n    {\n      code: 'React.createElement(\"Object.testComponent\")',\n    },\n    {\n      code: '<Object.test_component />',\n    },\n    {\n      code: 'React.createElement(\"Object.test_component\")',\n    },\n    {\n      code: '<Object.TestComponent />',\n    },\n    {\n      code: 'React.createElement(\"Object.TestComponent\")',\n    },\n    {\n      code: 'React.createElement(null)',\n    },\n    {\n      code: 'React.createElement(true)',\n    },\n    {\n      code: 'React.createElement({})',\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: '<ns:testcomponent />',\n      errors: [{ message: 'React component ns:testcomponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"ns:testcomponent\")',\n      errors: [{ message: 'React component ns:testcomponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<ns:testComponent />',\n      errors: [{ message: 'React component ns:testComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"ns:testComponent\")',\n      errors: [{ message: 'React component ns:testComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<ns:test_component />',\n      errors: [{ message: 'React component ns:test_component must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"ns:test_component\")',\n      errors: [{ message: 'React component ns:test_component must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<ns:TestComponent />',\n      errors: [{ message: 'React component ns:TestComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"ns:TestComponent\")',\n      errors: [{ message: 'React component ns:TestComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<Ns:testcomponent />',\n      errors: [{ message: 'React component Ns:testcomponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"Ns:testcomponent\")',\n      errors: [{ message: 'React component Ns:testcomponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<Ns:testComponent />',\n      errors: [{ message: 'React component Ns:testComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"Ns:testComponent\")',\n      errors: [{ message: 'React component Ns:testComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<Ns:test_component />',\n      errors: [{ message: 'React component Ns:test_component must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"Ns:test_component\")',\n      errors: [{ message: 'React component Ns:test_component must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: '<Ns:TestComponent />',\n      errors: [{ message: 'React component Ns:TestComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n    {\n      code: 'React.createElement(\"Ns:TestComponent\")',\n      errors: [{ message: 'React component Ns:TestComponent must not be in a namespace, as React does not support them' }],\n      features: ['jsx namespace'],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-object-type-as-default-prop.js",
    "content": "/**\n * @fileoverview Prevent usage of object type variables as default param in functional component\n * @author Chang Yan\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst parsers = require('../../helpers/parsers');\nconst rule = require('../../../lib/rules/no-object-type-as-default-prop');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nconst MESSAGE_ID = 'forbiddenTypeDefaultParam';\n\nconst expectedViolations = [\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'a',\n      forbiddenType: 'object literal',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'b',\n      forbiddenType: 'array literal',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'c',\n      forbiddenType: 'regex literal',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'd',\n      forbiddenType: 'arrow function',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'e',\n      forbiddenType: 'function expression',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'f',\n      forbiddenType: 'class expression',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'g',\n      forbiddenType: 'construction expression',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'h',\n      forbiddenType: 'JSX element',\n    },\n  },\n  {\n    messageId: MESSAGE_ID,\n    data: {\n      propName: 'i',\n      forbiddenType: 'Symbol literal',\n    },\n  },\n];\n\nruleTester.run('no-object-type-as-default-prop', rule, {\n  valid: parsers.all([].concat(\n    `\n      function Foo({\n        bar = emptyFunction,\n      }) {\n        return null;\n      }\n    `,\n    `\n      function Foo({\n        bar = emptyFunction,\n        ...rest\n      }) {\n        return null;\n      }\n    `,\n    `\n      function Foo({\n        bar = 1,\n        baz = 'hello',\n      }) {\n        return null;\n      }\n    `,\n    `\n      function Foo(props) {\n        return null;\n      }\n    `,\n    `\n      function Foo(props) {\n        return null;\n      }\n\n      Foo.defaultProps = {\n        bar: () => {}\n      }\n    `,\n    `\n      const Foo = () => {\n        return null;\n      };\n    `,\n    `\n      const Foo = ({bar = 1}) => {\n        return null;\n      };\n    `,\n    `\n      const Foo = ({bar = 1}, context) => {\n        return null;\n      };\n    `,\n    `\n      export default function NotAComponent({foo = {}}) {}\n    `\n  )),\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        function Foo({\n          a = {},\n          b = ['one', 'two'],\n          c = /regex/i,\n          d = () => {},\n          e = function() {},\n          f = class {},\n          g = new Thing(),\n          h = <Thing />,\n          i = Symbol('foo')\n        }) {\n          return null;\n        }\n      `,\n      errors: expectedViolations,\n    },\n    {\n      code: `\n        const Foo = ({\n          a = {},\n          b = ['one', 'two'],\n          c = /regex/i,\n          d = () => {},\n          e = function() {},\n          f = class {},\n          g = new Thing(),\n          h = <Thing />,\n          i = Symbol('foo')\n        }) => {\n          return null;\n        }\n      `,\n      errors: expectedViolations,\n    },\n    {\n      code: `\n        const Foo = ({\n          a = {},\n          b = ['one', 'two'],\n          c = /regex/i,\n          d = () => {},\n          e = function() {},\n          f = class {},\n          g = new Thing(),\n          h = <Thing />,\n          i = Symbol('foo')\n        }, context) => {\n          return null;\n        }\n      `,\n      errors: expectedViolations,\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-redundant-should-component-update.js",
    "content": "/**\n * @fileoverview Tests for no-redundant-should-component-update\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-redundant-should-component-update');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester();\nruleTester.run('no-redundant-should-component-update', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Foo extends React.Component {\n          shouldComponentUpdate() {\n            return true;\n          }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          shouldComponentUpdate = () => {\n            return true;\n          }\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        function Foo() {\n          return class Bar extends React.Component {\n            shouldComponentUpdate() {\n              return true;\n            }\n          };\n        }\n      `,\n      parserOptions,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Foo extends React.PureComponent {\n          shouldComponentUpdate() {\n            return true;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        class Foo extends PureComponent {\n          shouldComponentUpdate() {\n            return true;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        class Foo extends React.PureComponent {\n          shouldComponentUpdate = () => {\n            return true;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Foo' },\n        },\n      ],\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        function Foo() {\n          return class Bar extends React.PureComponent {\n            shouldComponentUpdate() {\n              return true;\n            }\n          };\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        function Foo() {\n          return class Bar extends PureComponent {\n            shouldComponentUpdate() {\n              return true;\n            }\n          };\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Bar' },\n        },\n      ],\n      parserOptions,\n    },\n    {\n      code: `\n        var Foo = class extends PureComponent {\n          shouldComponentUpdate() {\n            return true;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noShouldCompUpdate',\n          data: { component: 'Foo' },\n        },\n      ],\n      parserOptions,\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-render-return-value.js",
    "content": "/**\n * @fileoverview Prevent usage of setState\n * @author Mark Dalgleish\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-render-return-value');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-render-return-value', rule, {\n  valid: parsers.all([\n    {\n      code: 'ReactDOM.render(<div />, document.body);',\n    },\n    {\n      code: `\n        let node;\n        ReactDOM.render(<div ref={ref => node = ref}/>, document.body);\n      `,\n    },\n    {\n      code: 'ReactDOM.render(<div ref={ref => this.node = ref}/>, document.body);',\n      settings: { react: { version: '0.14.0' } },\n    },\n    {\n      code: 'React.render(<div ref={ref => this.node = ref}/>, document.body);',\n      settings: { react: { version: '0.14.0' } },\n    },\n    {\n      code: 'React.render(<div ref={ref => this.node = ref}/>, document.body);',\n      settings: { react: { version: '0.13.0' } },\n    },\n    {\n      code: 'var foo = React.render(<div />, root);',\n      settings: { react: { version: '0.0.1' } },\n    },\n    {\n      code: 'var foo = render(<div />, root)',\n    },\n    {\n      code: 'var foo = ReactDom.renderder(<div />, root)',\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: 'var Hello = ReactDOM.render(<div />, document.body);',\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: `\n        var o = {\n          inst: ReactDOM.render(<div />, document.body)\n        };\n      `,\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: `\n        function render () {\n          return ReactDOM.render(<div />, document.body)\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: 'var render = (a, b) => ReactDOM.render(a, b)',\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: 'this.o = ReactDOM.render(<div />, document.body);',\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: 'var v; v = ReactDOM.render(<div />, document.body);',\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: 'var inst = React.render(<div />, document.body);',\n      settings: { react: { version: '0.14.0' } },\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'React' },\n        },\n      ],\n    },\n    {\n      code: 'var inst = ReactDOM.render(<div />, document.body);',\n      settings: { react: { version: '0.14.0' } },\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'ReactDOM' },\n        },\n      ],\n    },\n    {\n      code: 'var inst = React.render(<div />, document.body);',\n      settings: { react: { version: '0.13.0' } },\n      errors: [\n        {\n          messageId: 'noReturnValue',\n          data: { node: 'React' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState\n * @author Mark Dalgleish\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-set-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-set-state', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = function() {\n          this.setState({})\n        };\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            someNonMemberFunction(arg);\n            this.someHandler = this.setState;\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidUpdate: function() {\n            this.setState({\n              name: this.props.name.toUpperCase()\n            });\n          },\n          render: function() {\n            return <div>Hello {this.state.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noSetState' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          someMethod: function() {\n            this.setState({\n              name: this.props.name.toUpperCase()\n            });\n          },\n          render: function() {\n            return <div onClick={this.someMethod.bind(this)}>Hello {this.state.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'noSetState' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          someMethod() {\n            this.setState({\n              name: this.props.name.toUpperCase()\n            });\n          }\n          render() {\n            return <div onClick={this.someMethod.bind(this)}>Hello {this.state.name}</div>;\n          }\n        };\n      `,\n      errors: [{ messageId: 'noSetState' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          someMethod = () => {\n            this.setState({\n              name: this.props.name.toUpperCase()\n            });\n          }\n          render() {\n            return <div onClick={this.someMethod.bind(this)}>Hello {this.state.name}</div>;\n          }\n        };\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove `no-ts-old` and fix\n      errors: [{ messageId: 'noSetState' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div onMouseEnter={() => this.setState({dropdownIndex: index})} />;\n          }\n        };\n      `,\n      errors: [{ messageId: 'noSetState' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-string-refs.js",
    "content": "/**\n * @fileoverview Prevent string definitions for references and prevent referencing this.refs\n * @author Tom Hastjarjanto\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-string-refs');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-refs', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            var component = this.hello;\n          },\n          render: function() {\n            return <div ref={c => this.hello = c}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div ref={\\`hello\\`}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div ref={\\`hello\\${index}\\`}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            var component = this.refs.hello;\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '18.3.0' } },\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            var component = this.refs.hello;\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '18.2.0' } },\n      errors: [{ messageId: 'thisRefsDeprecated' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div ref=\"hello\">Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '18.2.0' } },\n      errors: [{ messageId: 'stringInRefDeprecated' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div ref={'hello'}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '18.2.0' } },\n      errors: [{ messageId: 'stringInRefDeprecated' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n            var component = this.refs.hello;\n          },\n          render: function() {\n            return <div ref=\"hello\">Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '18.2.0' } },\n      errors: [\n        { messageId: 'thisRefsDeprecated' },\n        { messageId: 'stringInRefDeprecated' },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n          var component = this.refs.hello;\n          },\n          render: function() {\n            return <div ref={\\`hello\\`}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ noTemplateLiterals: true }],\n      settings: { react: { version: '18.2.0' } },\n      errors: [\n        { messageId: 'thisRefsDeprecated' },\n        { messageId: 'stringInRefDeprecated' },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n          var component = this.refs.hello;\n          },\n          render: function() {\n            return <div ref={\\`hello\\${index}\\`}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ noTemplateLiterals: true }],\n      settings: { react: { version: '18.2.0' } },\n      errors: [\n        { messageId: 'thisRefsDeprecated' },\n        { messageId: 'stringInRefDeprecated' },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentDidMount: function() {\n          var component = this.refs.hello;\n          },\n          render: function() {\n            return <div ref={\\`hello\\${index}\\`}>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ noTemplateLiterals: true }],\n      settings: { react: { version: '18.3.0' } },\n      errors: [\n        { messageId: 'stringInRefDeprecated' },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-this-in-sfc.js",
    "content": "/**\n * @fileoverview Report \"this\" being used in stateless functional components.\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-this-in-sfc');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-this-in-sfc', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        function Foo(props) {\n          const { foo } = props;\n          return <div bar={foo} />;\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo({ foo }) {\n          return <div bar={foo} />;\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            const { foo } = this.props;\n            return <div bar={foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        const Foo = createReactClass({\n          render: function() {\n            return <div>{this.props.foo}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        const Foo = React.createClass({\n          render: function() {\n            return <div>{this.props.foo}</div>;\n          }\n        });\n      `,\n      settings: { react: { createClass: 'createClass' } },\n    },\n    {\n      code: `\n        function foo(bar) {\n          this.bar = bar;\n          this.props = 'baz';\n          this.getFoo = function() {\n            return this.bar + this.props;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo(props) {\n          return props.foo ? <span>{props.bar}</span> : null;\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo(props) {\n          if (props.foo) {\n            return <div>{props.bar}</div>;\n          }\n          return null;\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo(props) {\n          if (props.foo) {\n            something();\n          }\n          return null;\n        }\n      `,\n    },\n    {\n      code: 'const Foo = (props) => <span>{props.foo}</span>',\n    },\n    {\n      code: 'const Foo = ({ foo }) => <span>{foo}</span>',\n    },\n    {\n      code: 'const Foo = (props) => props.foo ? <span>{props.bar}</span> : null;',\n    },\n    {\n      code: 'const Foo = ({ foo, bar }) => foo ? <span>{bar}</span> : null;',\n    },\n    {\n      code: `\n        class Foo {\n          bar() {\n            () => {\n              this.something();\n              return null;\n            };\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo {\n          bar = () => {\n            this.something();\n            return null;\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        export const Example = ({ prop }) => {\n          return {\n            handleClick: () => {},\n            renderNode() {\n              return <div onClick={this.handleClick} />;\n            },\n          };\n        };\n      `,\n    },\n    {\n      code: `\n        export const prepareLogin = new ValidatedMethod({\n          name: \"user.prepare\",\n          validate: new SimpleSchema({\n          }).validator(),\n          run({ remember }) {\n              if (Meteor.isServer) {\n                  const connectionId = this.connection.id; // react/no-this-in-sfc\n                  return Methods.prepareLogin(connectionId, remember);\n              }\n              return null;\n          },\n        });\n      `,\n    },\n    {\n      code: `\n        obj.notAComponent = function () {\n          return this.a || null;\n        };\n      `,\n    },\n    {\n      code: `\n        $.fn.getValueAsStringWeak = function (): string | null {\n          const val = this.length === 1 ? this.val() : null;\n\n          return typeof val === 'string' ? val : null;\n        };\n      `,\n      features: ['types'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        function Foo(props) {\n          const { foo } = this.props;\n          return <div>{foo}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          return <div>{this.props.foo}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          return <div>{this.state.foo}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          const { foo } = this.state;\n          return <div>{foo}</div>;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          return props.foo ? <div>{this.props.bar}</div> : null;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          if (props.foo) {\n            return <div>{this.props.bar}</div>;\n          }\n          return null;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          if (this.props.foo) {\n            something();\n          }\n          return null;\n        }\n      `,\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: 'const Foo = (props) => <span>{this.props.foo}</span>',\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: 'const Foo = (props) => this.props.foo ? <span>{props.bar}</span> : null;',\n      errors: [{ messageId: 'noThisInSFC' }],\n    },\n    {\n      code: `\n        function Foo(props) {\n          function onClick(bar) {\n            this.props.onClick();\n          }\n          return <div onClick={onClick}>{this.props.foo}</div>;\n        }\n      `,\n      errors: [\n        { messageId: 'noThisInSFC' },\n        { messageId: 'noThisInSFC' },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-typos.js",
    "content": "/**\n * @fileoverview Tests for no-typos\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst semver = require('semver');\nconst version = require('eslint/package.json').version;\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/no-typos');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n  sourceType: 'module',\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester();\nruleTester.run('no-typos', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n          import createReactClass from 'create-react-class'\n          function hello (extra = {}) {\n            return createReactClass({\n              noteType: 'hello',\n              renderItem () {\n                return null\n              },\n              ...extra\n            })\n          }\n      `,\n      parserOptions,\n      features: ['no-babel'], // TODO: FIXME: remove no-babel and fix crash\n    },\n    {\n      code: `\n        class First {\n          static PropTypes = {key: \"myValue\"};\n          static ContextTypes = {key: \"myValue\"};\n          static ChildContextTypes = {key: \"myValue\"};\n          static DefaultProps = {key: \"myValue\"};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class First {}\n        First.PropTypes = {key: \"myValue\"};\n        First.ContextTypes = {key: \"myValue\"};\n        First.ChildContextTypes = {key: \"myValue\"};\n        First.DefaultProps = {key: \"myValue\"};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          static propTypes = {key: \"myValue\"};\n          static contextTypes = {key: \"myValue\"};\n          static childContextTypes = {key: \"myValue\"};\n          static defaultProps = {key: \"myValue\"};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class First extends React.Component {}\n        First.propTypes = {key: \"myValue\"};\n        First.contextTypes = {key: \"myValue\"};\n        First.childContextTypes = {key: \"myValue\"};\n        First.defaultProps = {key: \"myValue\"};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          propTypes = {key: \"myValue\"};\n          contextTypes = {key: \"myValue\"};\n          childContextTypes = {key: \"myValue\"};\n          defaultProps = {key: \"myValue\"};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          PropTypes = {key: \"myValue\"};\n          ContextTypes = {key: \"myValue\"};\n          ChildContextTypes = {key: \"myValue\"};\n          DefaultProps = {key: \"myValue\"};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          proptypes = {key: \"myValue\"};\n          contexttypes = {key: \"myValue\"};\n          childcontextypes = {key: \"myValue\"};\n          defaultprops = {key: \"myValue\"};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          static PropTypes() {};\n          static ContextTypes() {};\n          static ChildContextTypes() {};\n          static DefaultProps() {};\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          static proptypes() {};\n          static contexttypes() {};\n          static childcontexttypes() {};\n          static defaultprops() {};\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {}\n        MyClass.prototype.PropTypes = function() {};\n        MyClass.prototype.ContextTypes = function() {};\n        MyClass.prototype.ChildContextTypes = function() {};\n        MyClass.prototype.DefaultProps = function() {};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {}\n        MyClass.PropTypes = function() {};\n        MyClass.ContextTypes = function() {};\n        MyClass.ChildContextTypes = function() {};\n        MyClass.DefaultProps = function() {};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        function MyRandomFunction() {}\n        MyRandomFunction.PropTypes = {};\n        MyRandomFunction.ContextTypes = {};\n        MyRandomFunction.ChildContextTypes = {};\n        MyRandomFunction.DefaultProps = {};\n      `,\n      parserOptions,\n    },\n    {\n      // This case is currently not supported\n      code: `\n        class First extends React.Component {}\n        First[\"prop\" + \"Types\"] = {};\n        First[\"context\" + \"Types\"] = {};\n        First[\"childContext\" + \"Types\"] = {};\n        First[\"default\" + \"Props\"] = {};\n      `,\n      parserOptions,\n    },\n    {\n      // This case is currently not supported\n      code: `\n        class First extends React.Component {}\n        First[\"PROP\" + \"TYPES\"] = {};\n        First[\"CONTEXT\" + \"TYPES\"] = {};\n        First[\"CHILDCONTEXT\" + \"TYPES\"] = {};\n        First[\"DEFAULT\" + \"PROPS\"] = {};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        const propTypes = \"PROPTYPES\"\n        const contextTypes = \"CONTEXTTYPES\"\n        const childContextTypes = \"CHILDCONTEXTTYPES\"\n        const defaultProps = \"DEFAULTPROPS\"\n\n        class First extends React.Component {}\n        First[propTypes] = {};\n        First[contextTypes] = {};\n        First[childContextTypes] = {};\n        First[defaultProps] = {};\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static getDerivedStateFromProps() { }\n          componentWillMount() { }\n          componentDidMount() { }\n          componentWillReceiveProps() { }\n          shouldComponentUpdate() { }\n          componentWillUpdate() { }\n          componentDidUpdate() { }\n          componentWillUnmount() { }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          \"componentDidMount\"() { }\n          \"my-method\"() { }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          componentWillMount() { }\n          componentDidMount() { }\n          componentWillReceiveProps() { }\n          shouldComponentUpdate() { }\n          componentWillUpdate() { }\n          componentDidUpdate() { }\n          componentWillUnmount() { }\n          render() { }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          componentwillmount() { }\n          componentdidmount() { }\n          componentwillreceiveprops() { }\n          shouldcomponentupdate() { }\n          componentwillupdate() { }\n          componentdidupdate() { }\n          componentwillUnmount() { }\n          render() { }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class MyClass {\n          Componentwillmount() { }\n          Componentdidmount() { }\n          Componentwillreceiveprops() { }\n          Shouldcomponentupdate() { }\n          Componentwillupdate() { }\n          Componentdidupdate() { }\n          ComponentwillUnmount() { }\n          Render() { }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      // https://github.com/jsx-eslint/eslint-plugin-react/issues/1353\n      code: `\n        function test(b) {\n          return a.bind(b);\n        }\n        function a() {}\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.number.isRequired\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          e: PropTypes.shape({\n            ea: PropTypes.string,\n          })\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string.isRequired,\n          c: PropTypes.shape({\n            d: PropTypes.string,\n            e: PropTypes.number.isRequired,\n          }).isRequired\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.string,\n            PropTypes.number\n          ])\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.oneOf([\n            'hello',\n            'hi'\n          ])\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string.isRequired,\n          c: PropTypes.shape({\n            d: PropTypes.string,\n            e: PropTypes.number.isRequired,\n          }).isRequired\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.contextTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string.isRequired,\n          c: PropTypes.shape({\n            d: PropTypes.string,\n            e: PropTypes.number.isRequired,\n          }).isRequired\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types'\n        import * as MyPropTypes from 'lib/my-prop-types'\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.string,\n          b: MyPropTypes.MYSTRING,\n          c: MyPropTypes.MYSTRING.isRequired,\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\"\n        import * as MyPropTypes from 'lib/my-prop-types'\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: PropTypes.string,\n          a: MyPropTypes.MYSTRING,\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import CustomReact from \"react\"\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: CustomReact.PropTypes.string,\n        }\n      `,\n      parserOptions,\n    },\n    {\n      // ensure that an absent arg to PropTypes.shape does not crash\n      code: `\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.shape(),\n        };\n        Component.contextTypes = {\n          a: PropTypes.shape(),\n        };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        const fn = (err, res) => {\n          const { body: data = {} } = { ...res };\n          data.time = data.time || {};\n        };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class Component extends React.Component {};\n        Component.propTypes = {\n          b: string.isRequired,\n          c: PropTypes.shape({\n            d: number.isRequired,\n          }).isRequired\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import React from 'react';\n        import PropTypes from 'prop-types';\n        const Component = React.createReactClass({\n          propTypes: {\n            a: PropTypes.string.isRequired,\n            b: PropTypes.shape({\n              c: PropTypes.number\n            }).isRequired\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import React from 'react';\n        import PropTypes from 'prop-types';\n        const Component = React.createReactClass({\n          childContextTypes: {\n            a: PropTypes.bool,\n            b: PropTypes.array,\n            c: PropTypes.func,\n            d: PropTypes.object,\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import React from 'react';\n        const Component = React.createReactClass({\n          propTypes: {},\n          childContextTypes: {},\n          contextTypes: {},\n          componentWillMount() { },\n          componentDidMount() { },\n          componentWillReceiveProps() { },\n          shouldComponentUpdate() { },\n          componentWillUpdate() { },\n          componentDidUpdate() { },\n          componentWillUnmount() { },\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import { string, element } from \"prop-types\";\n\n        class Sample extends React.Component {\n          render() { return null; }\n        }\n\n        Sample.propTypes = {\n          title: string.isRequired,\n          body: element.isRequired\n        };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const A = { B: 'C' };\n\n        export default class MyComponent extends React.Component {\n          [A.B] () {\n            return null\n          }\n        }\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        const MyComponent = React.forwardRef((props, ref) => <div />);\n        MyComponent.defaultProps = { value: \"\" };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        import styled from \"styled-components\";\n\n        const MyComponent = styled.div;\n        MyComponent.defaultProps = { value: \"\" };\n      `,\n      parserOptions,\n    },\n    {\n      code: `\n        class Editor extends React.Component {\n            #somethingPrivate() {\n              // ...\n            }\n\n            render() {\n            const { value = '' } = this.props;\n\n            return (\n              <textarea>\n                {value}\n              </textarea>\n            );\n          }\n        }\n      `,\n      features: [].concat('class fields', semver.satisfies(babelEslintVersion, '< 9') ? 'no-babel-old' : []),\n      parserOptions: Object.assign({}, parserOptions, {\n        babelOptions: {\n          // classPrivateMethods: true,\n        },\n        shippedProposals: true,\n      }),\n    }\n  )),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        class Component extends React.Component {\n          static PropTypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.PropTypes = {}\n      `,\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.PropTypes = {}\n      `,\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static proptypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.proptypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.proptypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static ContextTypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.ContextTypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.ContextTypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static contexttypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.contexttypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.contexttypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static ChildContextTypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.ChildContextTypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.ChildContextTypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static childcontexttypes = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.childcontexttypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.childcontexttypes = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static DefaultProps = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.DefaultProps = {}\n      `,\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.DefaultProps = {}\n      `,\n      parserOptions,\n      errors: [\n        { messageId: 'typoStaticClassProp', type: 'Identifier' },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static defaultprops = {};\n        }\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Component extends React.Component {}\n        Component.defaultprops = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        function MyComponent() { return (<div>{this.props.myProp}</div>) }\n        MyComponent.defaultprops = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        Component.defaultprops = {}\n        class Component extends React.Component {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        /** @extends React.Component */\n        class MyComponent extends BaseComponent {}\n        MyComponent.PROPTYPES = {}\n      `,\n      parserOptions,\n      errors: [{ messageId: 'typoStaticClassProp' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static GetDerivedStateFromProps()  { }\n          ComponentWillMount() { }\n          UNSAFE_ComponentWillMount() { }\n          ComponentDidMount() { }\n          ComponentWillReceiveProps() { }\n          UNSAFE_ComponentWillReceiveProps() { }\n          ShouldComponentUpdate() { }\n          ComponentWillUpdate() { }\n          UNSAFE_ComponentWillUpdate() { }\n          GetSnapshotBeforeUpdate() { }\n          ComponentDidUpdate() { }\n          ComponentDidCatch() { }\n          ComponentWillUnmount() { }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'GetDerivedStateFromProps',\n            expected: 'getDerivedStateFromProps',\n          },\n          type: 'MethodDefinition',\n          line: 3,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillMount',\n            expected: 'componentWillMount',\n          },\n          type: 'MethodDefinition',\n          line: 4,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_ComponentWillMount',\n            expected: 'UNSAFE_componentWillMount',\n          },\n          type: 'MethodDefinition',\n          line: 5,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentDidMount',\n            expected: 'componentDidMount',\n          },\n          type: 'MethodDefinition',\n          line: 6,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillReceiveProps',\n            expected: 'componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n          line: 7,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_ComponentWillReceiveProps',\n            expected: 'UNSAFE_componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n          line: 8,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ShouldComponentUpdate',\n            expected: 'shouldComponentUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 9,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillUpdate',\n            expected: 'componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 10,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_ComponentWillUpdate',\n            expected: 'UNSAFE_componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 11,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'GetSnapshotBeforeUpdate',\n            expected: 'getSnapshotBeforeUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 12,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentDidUpdate',\n            expected: 'componentDidUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 13,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentDidCatch',\n            expected: 'componentDidCatch',\n          },\n          type: 'MethodDefinition',\n          line: 14,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillUnmount',\n            expected: 'componentWillUnmount',\n          },\n          type: 'MethodDefinition',\n          line: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static Getderivedstatefromprops() { }\n          Componentwillmount() { }\n          UNSAFE_Componentwillmount() { }\n          Componentdidmount() { }\n          Componentwillreceiveprops() { }\n          UNSAFE_Componentwillreceiveprops() { }\n          Shouldcomponentupdate() { }\n          Componentwillupdate() { }\n          UNSAFE_Componentwillupdate() { }\n          Getsnapshotbeforeupdate() { }\n          Componentdidupdate() { }\n          Componentdidcatch() { }\n          Componentwillunmount() { }\n          Render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Getderivedstatefromprops',\n            expected: 'getDerivedStateFromProps',\n          },\n          type: 'MethodDefinition',\n          line: 3,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentwillmount',\n            expected: 'componentWillMount',\n          },\n          type: 'MethodDefinition',\n          line: 4,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_Componentwillmount',\n            expected: 'UNSAFE_componentWillMount',\n          },\n          type: 'MethodDefinition',\n          line: 5,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentdidmount',\n            expected: 'componentDidMount',\n          },\n          type: 'MethodDefinition',\n          line: 6,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentwillreceiveprops',\n            expected: 'componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n          line: 7,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_Componentwillreceiveprops',\n            expected: 'UNSAFE_componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n          line: 8,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Shouldcomponentupdate',\n            expected: 'shouldComponentUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 9,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentwillupdate',\n            expected: 'componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 10,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'UNSAFE_Componentwillupdate',\n            expected: 'UNSAFE_componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 11,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Getsnapshotbeforeupdate',\n            expected: 'getSnapshotBeforeUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 12,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentdidupdate',\n            expected: 'componentDidUpdate',\n          },\n          type: 'MethodDefinition',\n          line: 13,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentdidcatch',\n            expected: 'componentDidCatch',\n          },\n          type: 'MethodDefinition',\n          line: 14,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Componentwillunmount',\n            expected: 'componentWillUnmount',\n          },\n          type: 'MethodDefinition',\n          line: 15,\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'Render',\n            expected: 'render',\n          },\n          type: 'MethodDefinition',\n          line: 16,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static getderivedstatefromprops() { }\n          componentwillmount() { }\n          unsafe_componentwillmount() { }\n          componentdidmount() { }\n          componentwillreceiveprops() { }\n          unsafe_componentwillreceiveprops() { }\n          shouldcomponentupdate() { }\n          componentwillupdate() { }\n          unsafe_componentwillupdate() { }\n          getsnapshotbeforeupdate() { }\n          componentdidupdate() { }\n          componentdidcatch() { }\n          componentwillunmount() { }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'getderivedstatefromprops',\n            expected: 'getDerivedStateFromProps',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentwillmount',\n            expected: 'componentWillMount',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'unsafe_componentwillmount',\n            expected: 'UNSAFE_componentWillMount',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentdidmount',\n            expected: 'componentDidMount',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentwillreceiveprops',\n            expected: 'componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'unsafe_componentwillreceiveprops',\n            expected: 'UNSAFE_componentWillReceiveProps',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'shouldcomponentupdate',\n            expected: 'shouldComponentUpdate',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentwillupdate',\n            expected: 'componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'unsafe_componentwillupdate',\n            expected: 'UNSAFE_componentWillUpdate',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'getsnapshotbeforeupdate',\n            expected: 'getSnapshotBeforeUpdate',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentdidupdate',\n            expected: 'componentDidUpdate',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentdidcatch',\n            expected: 'componentDidCatch',\n          },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'componentwillunmount',\n            expected: 'componentWillUnmount',\n          },\n          type: 'MethodDefinition',\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n            a: PropTypes.Number.isRequired\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Number' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n            a: PropTypes.number.isrequired\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.number.isrequired\n          }\n        };\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.Number\n          }\n        };\n      `,\n      features: ['class fields'],\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Number' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n            a: PropTypes.Number\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Number' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.String,\n            c: PropTypes.number.isRequired,\n          })\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'String' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.bools,\n            PropTypes.number,\n          ])\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.bools,\n          b: PropTypes.Array,\n          c: PropTypes.function,\n          d: PropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from \"prop-types\";\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: PropTypes.bools,\n          b: PropTypes.Array,\n          c: PropTypes.function,\n          d: PropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: PropTypes.bools,\n          b: PropTypes.Array,\n          c: PropTypes.function,\n          d: PropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        class Component extends React.Component {};\n        Component.propTypes = {\n          a: PropTypes.string.isrequired,\n          b: PropTypes.shape({\n            c: PropTypes.number\n          }).isrequired\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import RealPropTypes from 'prop-types';\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: RealPropTypes.bools,\n          b: RealPropTypes.Array,\n          c: RealPropTypes.function,\n          d: RealPropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n      import React from 'react';\n      class Component extends React.Component {};\n      Component.propTypes = {\n        a: React.PropTypes.string.isrequired,\n        b: React.PropTypes.shape({\n          c: React.PropTypes.number\n        }).isrequired\n      }\n    `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: React.PropTypes.bools,\n          b: React.PropTypes.Array,\n          c: React.PropTypes.function,\n          d: React.PropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n      import { PropTypes } from 'react';\n      class Component extends React.Component {};\n      Component.propTypes = {\n        a: PropTypes.string.isrequired,\n        b: PropTypes.shape({\n          c: PropTypes.number\n        }).isrequired\n      }\n    `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n      import 'react';\n      class Component extends React.Component {};\n    `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'noReactBinding',\n        },\n      ],\n    },\n    {\n      code: `\n        import { PropTypes } from 'react';\n        class Component extends React.Component {};\n        Component.childContextTypes = {\n          a: PropTypes.bools,\n          b: PropTypes.Array,\n          c: PropTypes.function,\n          d: PropTypes.objectof,\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n      import PropTypes from 'prop-types';\n      class Component extends React.Component {};\n      Component.propTypes = {\n        a: PropTypes.string.isrequired,\n        b: PropTypes.shape({\n          c: PropTypes.number\n        }).isrequired\n      }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n      import PropTypes from 'prop-types';\n      class Component extends React.Component {};\n      Component.propTypes = {\n        a: PropTypes.string.isrequired,\n        b: PropTypes.shape({\n          c: PropTypes.number\n        }).isrequired\n      }\n    `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n        import PropTypes from 'prop-types';\n        const Component = React.createReactClass({\n          propTypes: {\n            a: PropTypes.string.isrequired,\n            b: PropTypes.shape({\n              c: PropTypes.number\n            }).isrequired\n          }\n        });\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n        {\n          messageId: 'typoPropTypeChain',\n          data: { name: 'isrequired' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n        import PropTypes from 'prop-types';\n        const Component = React.createReactClass({\n          childContextTypes: {\n            a: PropTypes.bools,\n            b: PropTypes.Array,\n            c: PropTypes.function,\n            d: PropTypes.objectof,\n          }\n        });\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropType',\n          data: { name: 'bools' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'Array' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'function' },\n        },\n        {\n          messageId: 'typoPropType',\n          data: { name: 'objectof' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from 'react';\n        const Component = React.createReactClass({\n          proptypes: {},\n          childcontexttypes: {},\n          contexttypes: {},\n          getdefaultProps() { },\n          getinitialState() { },\n          getChildcontext() { },\n          ComponentWillMount() { },\n          ComponentDidMount() { },\n          ComponentWillReceiveProps() { },\n          ShouldComponentUpdate() { },\n          ComponentWillUpdate() { },\n          ComponentDidUpdate() { },\n          ComponentWillUnmount() { },\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'typoPropDeclaration',\n          type: 'Identifier',\n        },\n        {\n          messageId: 'typoPropDeclaration',\n          type: 'Identifier',\n        },\n        {\n          messageId: 'typoPropDeclaration',\n          type: 'Identifier',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'getdefaultProps',\n            expected: 'getDefaultProps',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'getinitialState',\n            expected: 'getInitialState',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'getChildcontext',\n            expected: 'getChildContext',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillMount',\n            expected: 'componentWillMount',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentDidMount',\n            expected: 'componentDidMount',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillReceiveProps',\n            expected: 'componentWillReceiveProps',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ShouldComponentUpdate',\n            expected: 'shouldComponentUpdate',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillUpdate',\n            expected: 'componentWillUpdate',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentDidUpdate',\n            expected: 'componentDidUpdate',\n          },\n          type: 'Property',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'ComponentWillUnmount',\n            expected: 'componentWillUnmount',\n          },\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          getDerivedStateFromProps() { }\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'staticLifecycleMethod',\n          data: { method: 'getDerivedStateFromProps' },\n          type: 'MethodDefinition',\n        },\n      ],\n    },\n    parsers.skipDueToMultiErrorSorting ? [] : {\n      code: `\n        class Hello extends React.Component {\n          GetDerivedStateFromProps() { }\n        }\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'staticLifecycleMethod',\n          data: { method: 'GetDerivedStateFromProps' },\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'typoLifecycleMethod',\n          data: {\n            actual: 'GetDerivedStateFromProps',\n            expected: 'getDerivedStateFromProps',\n          },\n          type: 'MethodDefinition',\n        },\n      ],\n    },\n    semver.satisfies(version, '^5') ? {\n      // PropTypes declared on a component that is detected through JSDoc comments and is\n      // declared AFTER the PropTypes assignment\n      code: `\n        MyComponent.PROPTYPES = {}\n        /** @extends React.Component */\n        class MyComponent extends BaseComponent {}\n      `,\n      parserOptions,\n      errors: [\n        {\n          ruleId: 'no-typos',\n          messageId: 'typoStaticClassProp',\n        },\n      ],\n    } : [],\n    {\n      code: `\n        import 'prop-types'\n      `,\n      parserOptions,\n      errors: [{ messageId: 'noPropTypesBinding' }],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unescaped-entities.js",
    "content": "/**\n * @fileoverview Tests for no-unescaped-entities\n * @author Patrick Hayes\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst path = require('path');\n\nconst semver = require('semver');\nconst resolve = require('resolve');\n\nlet allowsInvalidJSX = false;\ntry {\n  // eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-dynamic-require\n  allowsInvalidJSX = semver.satisfies(require(resolve.sync('acorn-jsx/package.json', { basedir: path.dirname(require.resolve('eslint')) })).version, '< 5.2');\n} catch (e) { /**/ }\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unescaped-entities');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unescaped-entities', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return (\n              <div/>\n            );\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Here is some text!</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>I&rsquo;ve escaped some entities: &gt; &lt; &amp;</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>first line is ok\n            so is second\n            and here are some escaped entities: &gt; &lt; &amp;</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>{\">\" + \"<\" + \"&\" + '\"'}</div>;\n          },\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>Here is some text!</>;\n          }\n        });\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>I&rsquo;ve escaped some entities: &gt; &lt; &amp;</>;\n          }\n        });\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>{\">\" + \"<\" + \"&\" + '\"'}</>;\n          },\n        });\n      `,\n      features: ['fragment'],\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    allowsInvalidJSX ? [\n      {\n        code: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>> default parser</div>;\n            }\n          });\n        `,\n        errors: [\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '>', alts: '`&gt;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&gt;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>&gt; default parser</div>;\n            }\n          });\n        `,\n              },\n            ],\n          },\n        ],\n      },\n      {\n        code: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>first line is ok\n              so is second\n              and here are some bad entities: ></div>\n            }\n          });\n        `,\n        errors: [\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '>', alts: '`&gt;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&gt;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>first line is ok\n              so is second\n              and here are some bad entities: &gt;</div>\n            }\n          });\n        `,\n              },\n            ],\n          },\n        ],\n      },\n      {\n        code: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: '>> default parser</div>;\n            }\n          });\n        `,\n        errors: [\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '\\'', alts: '`&apos;`, `&lsquo;`, `&#39;`, `&rsquo;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&apos;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: &apos;>> default parser</div>;\n            }\n          });\n        `,\n              },\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&lsquo;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: &lsquo;>> default parser</div>;\n            }\n          });\n        `,\n              },\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&#39;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: &#39;>> default parser</div>;\n            }\n          });\n        `,\n              },\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&rsquo;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: &rsquo;>> default parser</div>;\n            }\n          });\n        `,\n              },\n            ],\n          },\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '>', alts: '`&gt;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&gt;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: '&gt;> default parser</div>;\n            }\n          });\n        `,\n              },\n            ],\n          },\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '>', alts: '`&gt;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&gt;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Multiple errors: '>&gt; default parser</div>;\n            }\n          });\n        `,\n              },\n            ],\n          },\n        ],\n      },\n      {\n        code: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>{\"Unbalanced braces - default parser\"}}</div>;\n            }\n          });\n        `,\n        errors: [\n          {\n            messageId: 'unescapedEntityAlts',\n            data: { entity: '}', alts: '`&#125;`' },\n            suggestions: [\n              {\n                messageId: 'replaceWithAlt',\n                data: { alt: '&#125;' },\n                output: `\n          var Hello = createReactClass({\n            render: function() {\n              return <div>{\"Unbalanced braces - default parser\"}&#125;</div>;\n            }\n          });\n        `,\n              },\n            ],\n          },\n        ],\n      },\n    ] : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>> babel-eslint</>;\n          }\n        });\n      `,\n      features: ['fragment', 'no-ts', 'no-default'],\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '>', alts: '`&gt;`' },\n          suggestions: [\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&gt;' },\n              output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>&gt; babel-eslint</>;\n          }\n        });\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>first line is ok\n            so is second\n            and here are some bad entities: ></>\n          }\n        });\n      `,\n      features: ['fragment', 'no-ts', 'no-default'],\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '>', alts: '`&gt;`' },\n          suggestions: [{\n            messageId: 'replaceWithAlt',\n            data: { alt: '&gt;' },\n            output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>first line is ok\n            so is second\n            and here are some bad entities: &gt;</>\n          }\n        });\n      `,\n          }],\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>'</div>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '\\'', alts: '`&apos;`, `&lsquo;`, `&#39;`, `&rsquo;`' },\n          suggestions: [\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&apos;' },\n              output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>&apos;</div>;\n          }\n        });\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&lsquo;' },\n              output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>&lsquo;</div>;\n          }\n        });\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&#39;' },\n              output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>&#39;</div>;\n          }\n        });\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&rsquo;' },\n              output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>&rsquo;</div>;\n          }\n        });\n      `,\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>{\"Unbalanced braces - babel-eslint\"}}</>;\n          }\n        });\n      `,\n      features: ['fragment', 'no-ts', 'no-default'],\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '}', alts: '`&#125;`' },\n          suggestions: [{\n            messageId: 'replaceWithAlt',\n            data: { alt: '&#125;' },\n            output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>{\"Unbalanced braces - babel-eslint\"}&#125;</>;\n          }\n        });\n      `,\n          }],\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <>foo & bar</>;\n          }\n        });\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'unescapedEntity',\n          data: { entity: '&' },\n        },\n      ],\n      options: [{ forbid: ['&'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <span>foo & bar</span>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unescapedEntity',\n          data: { entity: '&' },\n        },\n      ],\n      options: [{ forbid: ['&'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <span>foo & bar</span>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '&', alts: '`&amp;`' },\n          suggestions: [{\n            messageId: 'replaceWithAlt',\n            data: { alt: '&amp;' },\n            output: `\n        var Hello = createReactClass({\n          render: function() {\n            return <span>foo &amp; bar</span>;\n          }\n        });\n      `,\n          }],\n        },\n      ],\n      options: [\n        {\n          forbid: [\n            {\n              char: '&',\n              alternatives: ['&amp;'],\n            },\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        <script>window.foo = \"bar\"</script>\n      `,\n      errors: [\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '\"', alts: '`&quot;`, `&ldquo;`, `&#34;`, `&rdquo;`' },\n          line: 2,\n          column: 30,\n          suggestions: [\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&quot;' },\n              output: `\n        <script>window.foo = &quot;bar\"</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&ldquo;' },\n              output: `\n        <script>window.foo = &ldquo;bar\"</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&#34;' },\n              output: `\n        <script>window.foo = &#34;bar\"</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&rdquo;' },\n              output: `\n        <script>window.foo = &rdquo;bar\"</script>\n      `,\n            },\n          ],\n        },\n        {\n          messageId: 'unescapedEntityAlts',\n          data: { entity: '\"', alts: '`&quot;`, `&ldquo;`, `&#34;`, `&rdquo;`' },\n          line: 2,\n          column: 34,\n          suggestions: [\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&quot;' },\n              output: `\n        <script>window.foo = \"bar&quot;</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&ldquo;' },\n              output: `\n        <script>window.foo = \"bar&ldquo;</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&#34;' },\n              output: `\n        <script>window.foo = \"bar&#34;</script>\n      `,\n            },\n            {\n              messageId: 'replaceWithAlt',\n              data: { alt: '&rdquo;' },\n              output: `\n        <script>window.foo = \"bar&rdquo;</script>\n      `,\n            },\n          ],\n        },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unknown-property.js",
    "content": "/**\n * @fileoverview Tests for no-unknown-property\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unknown-property');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unknown-property', rule, {\n  valid: parsers.all([\n    // React components and their props/attributes should be fine\n    { code: '<App class=\"bar\" />;' },\n    { code: '<App for=\"bar\" />;' },\n    { code: '<App someProp=\"bar\" />;' },\n    { code: '<Foo.bar for=\"bar\" />;' },\n    { code: '<App accept-charset=\"bar\" />;' },\n    { code: '<App http-equiv=\"bar\" />;' },\n    {\n      code: '<App xlink:href=\"bar\" />;',\n      features: ['jsx namespace'],\n    },\n    { code: '<App clip-path=\"bar\" />;' },\n    {\n      code: '<App dataNotAnDataAttribute=\"yes\" />;',\n      options: [{ requireDataLowercase: true }],\n    },\n    // Some HTML/DOM elements with common attributes should work\n    { code: '<div className=\"bar\"></div>;' },\n    { code: '<div onMouseDown={this._onMouseDown}></div>;' },\n    { code: '<div onScrollEnd={this._onScrollEnd}></div>;' },\n    { code: '<div onScrollEndCapture={this._onScrollEndCapture}></div>;' },\n    { code: '<a href=\"someLink\" download=\"foo\">Read more</a>' },\n    { code: '<area download=\"foo\" />' },\n    { code: '<img src=\"cat_keyboard.jpeg\" alt=\"A cat sleeping on a keyboard\" align=\"top\" fetchPriority=\"high\" />' },\n    { code: '<input type=\"password\" required />' },\n    { code: '<input ref={this.input} type=\"radio\" />' },\n    { code: '<input type=\"file\" webkitdirectory=\"\" />' },\n    { code: '<input type=\"file\" webkitDirectory=\"\" />' },\n    { code: '<div inert children=\"anything\" />' },\n    { code: '<iframe scrolling=\"?\" onLoad={a} onError={b} align=\"top\" />' },\n    { code: '<input key=\"bar\" type=\"radio\" />' },\n    { code: '<button disabled>You cannot click me</button>;' },\n    { code: '<svg key=\"lock\" viewBox=\"box\" fill={10} d=\"d\" stroke={1} strokeWidth={2} strokeLinecap={3} strokeLinejoin={4} transform=\"something\" clipRule=\"else\" x1={5} x2=\"6\" y1=\"7\" y2=\"8\"></svg>' },\n    { code: '<g fill=\"#7B82A0\" fillRule=\"evenodd\"></g>' },\n    { code: '<mask fill=\"#7B82A0\"></mask>' },\n    { code: '<symbol fill=\"#7B82A0\"></symbol>' },\n    { code: '<meta property=\"og:type\" content=\"website\" />' },\n    { code: '<input type=\"checkbox\" checked={checked} disabled={disabled} id={id} onChange={onChange} />' },\n    { code: '<video playsInline />' },\n    { code: '<img onError={foo} onLoad={bar} />' },\n    { code: '<picture inert={false} onError={foo} onLoad={bar} />' },\n    { code: '<iframe onError={foo} onLoad={bar} />' },\n    { code: '<script onLoad={bar} onError={foo} />' },\n    { code: '<source onLoad={bar} onError={foo} />' },\n    { code: '<link onLoad={bar} onError={foo} />' },\n    { code: '<link rel=\"preload\" as=\"image\" href=\"someHref\" imageSrcSet=\"someImageSrcSet\" imageSizes=\"someImageSizes\" />' },\n    { code: '<object onLoad={bar} />' },\n    { code: '<body onLoad={bar} />' },\n    { code: '<video allowFullScreen webkitAllowFullScreen mozAllowFullScreen />' },\n    { code: '<iframe allowFullScreen webkitAllowFullScreen mozAllowFullScreen />' },\n    { code: '<table border=\"1\" />' },\n    { code: '<th abbr=\"abbr\" />' },\n    { code: '<td abbr=\"abbr\" />' },\n    { code: '<template shadowrootmode=\"open\" shadowrootclonable shadowrootdelegatesfocus shadowrootserializable />' },\n    {\n      code: '<div allowTransparency=\"true\" />',\n      settings: {\n        react: { version: '16.0.99' },\n      },\n    },\n    // React related attributes\n    { code: '<div onPointerDown={this.onDown} onPointerUp={this.onUp} />' },\n    { code: '<input type=\"checkbox\" defaultChecked={this.state.checkbox} />' },\n    { code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} onMouseMoveCapture={this.capture} onTouchCancelCapture={this.log} />' },\n    {\n      code: '<link precedence=\"medium\" href=\"https://foo.bar\" rel=\"canonical\" />',\n      settings: {\n        react: { version: '19.0.0' },\n      },\n    },\n    // Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863\n    { code: '<meta charset=\"utf-8\" />;' },\n    { code: '<meta charSet=\"utf-8\" />;' },\n    // Some custom web components that are allowed to use `class` instead of `className`\n    { code: '<div class=\"foo\" is=\"my-elem\"></div>;' },\n    { code: '<div {...this.props} class=\"foo\" is=\"my-elem\"></div>;' },\n    { code: '<atom-panel class=\"foo\"></atom-panel>;' },\n    // data-* attributes should work\n    { code: '<div data-foo=\"bar\"></div>;' },\n    { code: '<div data-foo-bar=\"baz\"></div>;' },\n    { code: '<div data-parent=\"parent\"></div>;' },\n    { code: '<div data-index-number=\"1234\"></div>;' },\n    { code: '<div data-e2e-id=\"5678\"></div>;' },\n    { code: '<div data-testID=\"bar\" data-under_sCoRe=\"bar\" />;' },\n    {\n      code: '<div data-testID=\"bar\" data-under_sCoRe=\"bar\" />;',\n      options: [{ requireDataLowercase: false }],\n    },\n    // Ignoring should work\n    {\n      code: '<div class=\"bar\"></div>;',\n      options: [{ ignore: ['class'] }],\n    },\n    {\n      code: '<div someProp=\"bar\"></div>;',\n      options: [{ ignore: ['someProp'] }],\n    },\n    {\n      code: '<div css={{flex: 1}}></div>;',\n      options: [{ ignore: ['css'] }],\n    },\n\n    // aria-* attributes should work\n    { code: '<button aria-haspopup=\"true\">Click me to open pop up</button>;' },\n    { code: '<button aria-label=\"Close\" onClick={someThing.close} />;' },\n    // Attributes on allowed elements should work\n    { code: '<script crossOrigin noModule />' },\n    { code: '<audio crossOrigin />' },\n    { code: '<svg focusable><image crossOrigin /></svg>' },\n    { code: '<details onToggle={this.onToggle}>Some details</details>' },\n    { code: '<path fill=\"pink\" d=\"M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z\"></path>' },\n    { code: '<line fill=\"pink\" x1=\"0\" y1=\"80\" x2=\"100\" y2=\"20\"></line>' },\n    { code: '<link as=\"audio\">Audio content</link>' },\n    { code: '<video controlsList=\"nodownload\" controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true} onResize={this.onResize}></video>' },\n    { code: '<audio controlsList=\"nodownload\" controls={this.controls} crossOrigin=\"anonymous\" disableRemotePlayback loop muted preload=\"none\" src=\"something\" onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onError={this.error} onResize={this.onResize}></audio>' },\n    { code: '<marker id={markerId} viewBox=\"0 0 2 2\" refX=\"1\" refY=\"1\" markerWidth=\"1\" markerHeight=\"1\" orient=\"auto\" />' },\n    { code: '<pattern id=\"pattern\" viewBox=\"0,0,10,10\" width=\"10%\" height=\"10%\" />' },\n    { code: '<symbol id=\"myDot\" width=\"10\" height=\"10\" viewBox=\"0 0 2 2\" />' },\n    { code: '<view id=\"one\" viewBox=\"0 0 100 100\" />' },\n    { code: '<hr align=\"top\" />' },\n    { code: '<applet align=\"top\" />' },\n    { code: '<marker fill=\"#000\" />' },\n    { code: '<dialog closedby=\"something\" onClose={handler} open id=\"dialog\" returnValue=\"something\" onCancel={handler2} />' },\n    {\n      code: `\n        <table align=\"top\">\n          <caption align=\"top\">Table Caption</caption>\n          <colgroup valign=\"top\" align=\"top\">\n            <col valign=\"top\" align=\"top\"/>\n          </colgroup>\n          <thead valign=\"top\" align=\"top\">\n            <tr valign=\"top\" align=\"top\">\n              <th valign=\"top\" align=\"top\">Header</th>\n              <td valign=\"top\" align=\"top\">Cell</td>\n            </tr>\n          </thead>\n          <tbody valign=\"top\" align=\"top\" />\n          <tfoot valign=\"top\" align=\"top\" />\n        </table>\n      `,\n    },\n\n    // fbt\n    { code: '<fbt desc=\"foo\" doNotExtract />;' },\n    // fbs\n    { code: '<fbs desc=\"foo\" doNotExtract />;' },\n    { code: '<math displaystyle=\"true\" />;' },\n    {\n      code: `\n        <div className=\"App\" data-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash=\"customValue\">\n          Hello, world!\n        </div>\n      `,\n    },\n    {\n      code: `\n        <div>\n          <button popovertarget=\"my-popover\" popovertargetaction=\"toggle\">Open Popover</button>\n\n          <div popover id=\"my-popover\">Greetings, one and all!</div>\n        </div>\n      `,\n    },\n    {\n      code: `\n        <div>\n          <button popoverTarget=\"my-popover\" popoverTargetAction=\"toggle\">Open Popover</button>\n\n          <div id=\"my-popover\" onBeforeToggle={this.onBeforeToggle} popover>Greetings, one and all!</div>\n        </div>\n      `,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<div allowTransparency=\"true\" />',\n      settings: {\n        react: { version: '16.1.0' },\n      },\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'allowTransparency',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div hasOwnProperty=\"should not be allowed property\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'hasOwnProperty',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div abc=\"should not be allowed property\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'abc',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div aria-fake=\"should not be allowed property\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'aria-fake',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div someProp=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'someProp',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div class=\"bar\"></div>;',\n      output: '<div className=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'class',\n            standardName: 'className',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div for=\"bar\"></div>;',\n      output: '<div htmlFor=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'for',\n            standardName: 'htmlFor',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div accept-charset=\"bar\"></div>;',\n      output: '<div acceptCharset=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'accept-charset',\n            standardName: 'acceptCharset',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div http-equiv=\"bar\"></div>;',\n      output: '<div httpEquiv=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'http-equiv',\n            standardName: 'httpEquiv',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div accesskey=\"bar\"></div>;',\n      output: '<div accessKey=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'accesskey',\n            standardName: 'accessKey',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div onclick=\"bar\"></div>;',\n      output: '<div onClick=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'onclick',\n            standardName: 'onClick',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div onmousedown=\"bar\"></div>;',\n      output: '<div onMouseDown=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'onmousedown',\n            standardName: 'onMouseDown',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div onMousedown=\"bar\"></div>;',\n      output: '<div onMouseDown=\"bar\"></div>;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'onMousedown',\n            standardName: 'onMouseDown',\n          },\n        },\n      ],\n    },\n    {\n      code: '<use xlink:href=\"bar\" />;',\n      output: '<use xlinkHref=\"bar\" />;',\n      features: ['jsx namespace'],\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'xlink:href',\n            standardName: 'xlinkHref',\n          },\n        },\n      ],\n    },\n    {\n      code: '<rect clip-path=\"bar\" transform-origin=\"center\" />;',\n      output: '<rect clipPath=\"bar\" transform-origin=\"center\" />;',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'clip-path',\n            standardName: 'clipPath',\n          },\n        },\n      ],\n    },\n    {\n      code: '<script crossorigin nomodule />',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'crossorigin',\n            standardName: 'crossOrigin',\n          },\n        },\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'nomodule',\n            standardName: 'noModule',\n          },\n        },\n      ],\n      output: '<script crossOrigin noModule />',\n    },\n    {\n      code: '<div crossorigin />',\n      errors: [\n        {\n          messageId: 'unknownPropWithStandardName',\n          data: {\n            name: 'crossorigin',\n            standardName: 'crossOrigin',\n          },\n        },\n      ],\n      output: '<div crossOrigin />',\n    },\n    {\n      code: '<div crossOrigin />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'crossOrigin',\n            tagName: 'div',\n            allowedTags: 'script, img, video, audio, link, image',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div as=\"audio\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'as',\n            tagName: 'div',\n            allowedTags: 'link',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onResize={this.resize} onError={this.error} />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onAbort',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onDurationChange',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onEmptied',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onEnded',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onResize',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onError',\n            tagName: 'div',\n            allowedTags: 'audio, video, img, link, source, script, picture, iframe',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div onLoad={this.load} />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'onLoad',\n            tagName: 'div',\n            allowedTags: 'script, img, link, picture, iframe, object, source, body',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div fill=\"pink\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'fill',\n            tagName: 'div',\n            allowedTags: 'altGlyph, circle, ellipse, g, line, marker, mask, path, polygon, polyline, rect, svg, symbol, text, textPath, tref, tspan, use, animate, animateColor, animateMotion, animateTransform, set',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true} allowFullScreen></div>',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'controls',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'loop',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'muted',\n            tagName: 'div',\n            allowedTags: 'audio, video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'playsInline',\n            tagName: 'div',\n            allowedTags: 'video',\n          },\n        },\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'allowFullScreen',\n            tagName: 'div',\n            allowedTags: 'iframe, video',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div download=\"foo\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'download',\n            tagName: 'div',\n            allowedTags: 'a, area',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div imageSrcSet=\"someImageSrcSet\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'imageSrcSet',\n            tagName: 'div',\n            allowedTags: 'link',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div imageSizes=\"someImageSizes\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'imageSizes',\n            tagName: 'div',\n            allowedTags: 'link',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div data-xml-anything=\"invalid\" />',\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'data-xml-anything',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div data-testID=\"bar\" data-under_sCoRe=\"bar\" dataNotAnDataAttribute=\"yes\" />;',\n      errors: [\n        {\n          messageId: 'dataLowercaseRequired',\n          data: {\n            name: 'data-testID',\n            lowerCaseName: 'data-testid',\n          },\n        },\n        {\n          messageId: 'dataLowercaseRequired',\n          data: {\n            name: 'data-under_sCoRe',\n            lowerCaseName: 'data-under_score',\n          },\n        },\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'dataNotAnDataAttribute',\n            lowerCaseName: 'datanotandataattribute',\n          },\n        },\n      ],\n      options: [{ requireDataLowercase: true }],\n    },\n    {\n      code: '<App data-testID=\"bar\" data-under_sCoRe=\"bar\" dataNotAnDataAttribute=\"yes\" />;',\n      errors: [\n        {\n          messageId: 'dataLowercaseRequired',\n          data: {\n            name: 'data-testID',\n            lowerCaseName: 'data-testid',\n          },\n        },\n        {\n          messageId: 'dataLowercaseRequired',\n          data: {\n            name: 'data-under_sCoRe',\n            lowerCaseName: 'data-under_score',\n          },\n        },\n      ],\n      options: [{ requireDataLowercase: true }],\n    },\n    {\n      code: '<div abbr=\"abbr\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'abbr',\n            tagName: 'div',\n            allowedTags: 'th, td',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div webkitDirectory=\"\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'webkitDirectory',\n            tagName: 'div',\n            allowedTags: 'input',\n          },\n        },\n      ],\n    },\n    {\n      code: '<div webkitdirectory=\"\" />',\n      errors: [\n        {\n          messageId: 'invalidPropOnTag',\n          data: {\n            name: 'webkitdirectory',\n            tagName: 'div',\n            allowedTags: 'input',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        <div className=\"App\" data-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash:c=\"customValue\">\n          Hello, world!\n        </div>\n      `,\n      features: ['no-ts'],\n      errors: [\n        {\n          messageId: 'unknownProp',\n          data: {\n            name: 'data-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash-crash:c',\n          },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unsafe.js",
    "content": "/**\n * @fileoverview Prevent usage of unsafe lifecycle methods\n * @author Sergei Startsev\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unsafe');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unsafe', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Foo extends React.Component {\n          componentDidUpdate() {}\n          render() {}\n        }\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        const Foo = createReactClass({\n          componentDidUpdate: function() {},\n          render: function() {}\n        });\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        class Foo extends Bar {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        class Foo extends Bar {\n          UNSAFE_componentWillMount() {}\n          UNSAFE_componentWillReceiveProps() {}\n          UNSAFE_componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        const Foo = bar({\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {},\n        });\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        const Foo = bar({\n          UNSAFE_componentWillMount: function() {},\n          UNSAFE_componentWillReceiveProps: function() {},\n          UNSAFE_componentWillUpdate: function() {},\n        });\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    // React.Component\n    {\n      code: `\n        class Foo extends React.Component {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          UNSAFE_componentWillMount() {}\n          UNSAFE_componentWillReceiveProps() {}\n          UNSAFE_componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n    },\n    // createReactClass\n    {\n      code: `\n        const Foo = createReactClass({\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {},\n        });\n      `,\n      settings: { react: { version: '16.4.0' } },\n    },\n    {\n      code: `\n        const Foo = createReactClass({\n          UNSAFE_componentWillMount: function() {},\n          UNSAFE_componentWillReceiveProps: function() {},\n          UNSAFE_componentWillUpdate: function() {},\n        });\n      `,\n      settings: { react: { version: '16.2.0' } },\n    },\n  ]),\n\n  invalid: parsers.all([\n    // React.Component\n    {\n      code: `\n        class Foo extends React.Component {\n          componentWillMount() {}\n          componentWillReceiveProps() {}\n          componentWillUpdate() {}\n        }\n      `,\n      options: [{ checkAliases: true }],\n      settings: { react: { version: '16.4.0' } },\n      errors: [\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillMount',\n            newMethod: 'componentDidMount',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 3,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillReceiveProps',\n            newMethod: 'getDerivedStateFromProps',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 4,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillUpdate',\n            newMethod: 'componentDidUpdate',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 5,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          UNSAFE_componentWillMount() {}\n          UNSAFE_componentWillReceiveProps() {}\n          UNSAFE_componentWillUpdate() {}\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillMount',\n            newMethod: 'componentDidMount',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 3,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillReceiveProps',\n            newMethod: 'getDerivedStateFromProps',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 4,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillUpdate',\n            newMethod: 'componentDidUpdate',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 5,\n          column: 11,\n          type: 'MethodDefinition',\n        },\n      ],\n    },\n    // createReactClass\n    {\n      code: `\n        const Foo = createReactClass({\n          componentWillMount: function() {},\n          componentWillReceiveProps: function() {},\n          componentWillUpdate: function() {},\n        });\n      `,\n      options: [{ checkAliases: true }],\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillMount',\n            newMethod: 'componentDidMount',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 3,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillReceiveProps',\n            newMethod: 'getDerivedStateFromProps',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 4,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'componentWillUpdate',\n            newMethod: 'componentDidUpdate',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 5,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = createReactClass({\n          UNSAFE_componentWillMount: function() {},\n          UNSAFE_componentWillReceiveProps: function() {},\n          UNSAFE_componentWillUpdate: function() {},\n        });\n      `,\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillMount',\n            newMethod: 'componentDidMount',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 3,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillReceiveProps',\n            newMethod: 'getDerivedStateFromProps',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 4,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'unsafeMethod',\n          data: {\n            method: 'UNSAFE_componentWillUpdate',\n            newMethod: 'componentDidUpdate',\n            details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',\n          },\n          line: 5,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unstable-nested-components.js",
    "content": "/**\n * @fileoverview Prevent creating unstable components inside components\n * @author Ari Perkkiö\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unstable-nested-components');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ERROR_MESSAGE = 'Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “ParentComponent” and pass data as props.';\nconst ERROR_MESSAGE_WITHOUT_NAME = 'Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component and pass data as props.';\nconst ERROR_MESSAGE_COMPONENT_AS_PROPS = `${ERROR_MESSAGE} If you want to allow component creation in props, set allowAsProps option to true.`;\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unstable-nested-components', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <div>\n              <OutsideDefinedFunctionComponent />\n            </div>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(OutsideDefinedFunctionComponent, null)\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <SomeComponent\n              footer={<OutsideDefinedComponent />}\n              header={<div />}\n              />\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return React.createElement(SomeComponent, {\n            footer: React.createElement(OutsideDefinedComponent, null),\n            header: React.createElement(\"div\", null)\n          });\n        }\n      `,\n    },\n    {\n      // false-negative.\n      code: `\n        function ParentComponent() {\n          const MemoizedNestedComponent = React.useCallback(() => <div />, []);\n\n          return (\n            <div>\n              <MemoizedNestedComponent />\n            </div>\n          );\n        }\n      `,\n    },\n    {\n      // false-negative.\n      code: `\n        function ParentComponent() {\n          const MemoizedNestedComponent = React.useCallback(\n            () => React.createElement(\"div\", null),\n            []\n          );\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(MemoizedNestedComponent, null)\n          );\n        }\n      `,\n    },\n    {\n      // false-negative.\n      code: `\n        function ParentComponent() {\n          const MemoizedNestedFunctionComponent = React.useCallback(\n            function () {\n              return <div />;\n            },\n            []\n          );\n\n          return (\n            <div>\n              <MemoizedNestedFunctionComponent />\n            </div>\n          );\n        }\n      `,\n    },\n    {\n      // false-negative.\n      code: `\n        function ParentComponent() {\n          const MemoizedNestedFunctionComponent = React.useCallback(\n            function () {\n              return React.createElement(\"div\", null);\n            },\n            []\n          );\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(MemoizedNestedFunctionComponent, null)\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          // Should not interfere handler declarations\n          function onClick(event) {\n            props.onClick(event.target.value);\n          }\n\n          const onKeyPress = () => null;\n\n          function getOnHover() {\n            return function onHover(event) {\n              props.onHover(event.target);\n            }\n          }\n\n          return (\n            <div>\n              <button\n                onClick={onClick}\n                onKeyPress={onKeyPress}\n                onHover={getOnHover()}\n\n                // These should not be considered as components\n                maybeComponentOrHandlerNull={() => null}\n                maybeComponentOrHandlerUndefined={() => undefined}\n                maybeComponentOrHandlerBlank={() => ''}\n                maybeComponentOrHandlerString={() => 'hello-world'}\n                maybeComponentOrHandlerNumber={() => 42}\n                maybeComponentOrHandlerArray={() => []}\n                maybeComponentOrHandlerObject={() => {}} />\n            </div>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          function getComponent() {\n            return <div />;\n          }\n\n          return (\n            <div>\n              {getComponent()}\n            </div>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          function getComponent() {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\"div\", null, getComponent());\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n            return (\n              <RenderPropComponent>\n                {() => <div />}\n              </RenderPropComponent>\n            );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n            return (\n              <RenderPropComponent children={() => <div />} />\n            );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <ComplexRenderPropComponent\n              listRenderer={data.map((items, index) => (\n                <ul>\n                  {items[index].map((item) =>\n                    <li>\n                      {item}\n                    </li>\n                  )}\n                </ul>\n              ))\n              }\n            />\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return React.createElement(\n              RenderPropComponent,\n              null,\n              () => React.createElement(\"div\", null)\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          return (\n            <ul>\n              {props.items.map(item => (\n                <li key={item.id}>\n                  {item.name}\n                </li>\n              ))}\n            </ul>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          return (\n            <List items={props.items.map(item => {\n              return (\n                <li key={item.id}>\n                  {item.name}\n                </li>\n              );\n            })}\n            />\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          return React.createElement(\n            \"ul\",\n            null,\n            props.items.map(() =>\n              React.createElement(\n                \"li\",\n                { key: item.id },\n                item.name\n              )\n            )\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          return (\n            <ul>\n              {props.items.map(function Item(item) {\n                return (\n                  <li key={item.id}>\n                    {item.name}\n                  </li>\n                );\n              })}\n            </ul>\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent(props) {\n          return React.createElement(\n            \"ul\",\n            null,\n            props.items.map(function Item() {\n              return React.createElement(\n                \"li\",\n                { key: item.id },\n                item.name\n              );\n            })\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function createTestComponent(props) {\n          return (\n            <div />\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function createTestComponent(props) {\n          return React.createElement(\"div\", null);\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <ComponentWithProps footer={() => <div />} />\n          );\n        }\n      `,\n      options: [{ allowAsProps: true }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return React.createElement(ComponentWithProps, {\n            footer: () => React.createElement(\"div\", null)\n          });\n        }\n      `,\n      options: [{ allowAsProps: true }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <SomeComponent item={{ children: () => <div /> }} />\n          )\n        }\n      `,\n      options: [{ allowAsProps: true }],\n    },\n    {\n      code: `\n      function ParentComponent() {\n        return (\n          <SomeComponent>\n            {\n              thing.match({\n                renderLoading: () => <div />,\n                renderSuccess: () => <div />,\n                renderFailure: () => <div />,\n              })\n            }\n          </SomeComponent>\n        )\n      }\n      `,\n    },\n    {\n      code: `\n      function ParentComponent() {\n        const thingElement = thing.match({\n          renderLoading: () => <div />,\n          renderSuccess: () => <div />,\n          renderFailure: () => <div />,\n        });\n        return (\n          <SomeComponent>\n            {thingElement}\n          </SomeComponent>\n        )\n      }\n      `,\n    },\n    {\n      code: `\n      function ParentComponent() {\n        return (\n          <SomeComponent>\n            {\n              thing.match({\n                loading: () => <div />,\n                success: () => <div />,\n                failure: () => <div />,\n              })\n            }\n          </SomeComponent>\n        )\n      }\n      `,\n      options: [{\n        allowAsProps: true,\n      }],\n    },\n    {\n      code: `\n      function ParentComponent() {\n        const thingElement = thing.match({\n          loading: () => <div />,\n          success: () => <div />,\n          failure: () => <div />,\n        });\n        return (\n          <SomeComponent>\n            {thingElement}\n          </SomeComponent>\n        )\n      }\n      `,\n      options: [{\n        allowAsProps: true,\n      }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <ComponentForProps renderFooter={() => <div />} />\n          );\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return React.createElement(ComponentForProps, {\n            renderFooter: () => React.createElement(\"div\", null)\n          });\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          useEffect(() => {\n            return () => null;\n          });\n\n          return <div />;\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <SomeComponent renderers={{ Header: () => <div /> }} />\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <SomeComponent renderMenu={() => (\n              <RenderPropComponent>\n                {items.map(item => (\n                  <li key={item}>{item}</li>\n                ))}\n              </RenderPropComponent>\n            )} />\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        const ParentComponent = () => (\n          <SomeComponent\n            components={[\n              <ul>\n                {list.map(item => (\n                  <li key={item}>{item}</li>\n                ))}\n              </ul>,\n            ]}\n          />\n        );\n     `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const rows = [\n            {\n              name: 'A',\n              render: (props) => <Row {...props} />\n            },\n          ];\n\n          return <Table rows={rows} />;\n        }\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return <SomeComponent renderers={{ notComponent: () => null }} />;\n        }\n      `,\n    },\n    {\n      code: `\n        const ParentComponent = createReactClass({\n          displayName: \"ParentComponent\",\n          statics: {\n            getSnapshotBeforeUpdate: function () {\n              return null;\n            },\n          },\n          render() {\n            return <div />;\n          },\n        });\n      `,\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const rows = [\n            {\n              name: 'A',\n              notPrefixedWithRender: (props) => <Row {...props} />\n            },\n          ];\n\n          return <Table rows={rows} />;\n        }\n      `,\n      options: [{\n        allowAsProps: true,\n      }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return <Table\n            rowRenderer={(rowData) => <Row data={data} />}\n          />\n        }\n      `,\n      options: [{\n        propNamePattern: '*Renderer',\n      }],\n    },\n    /* TODO These minor cases are currently falsely marked due to component detection\n    {\n      code: `\n        function ParentComponent() {\n          const _renderHeader = () => <div />;\n          return <div>{_renderHeader()}</div>;\n        }\n      `\n    },\n    {\n      // https://github.com/emotion-js/emotion/blob/a89d4257b0246a1640a99f77838e5edad4ec4386/packages/jest/test/react-enzyme.test.js#L26-L28\n      code: `\n        const testCases = {\n          basic: {\n            render() {\n              const Component = () => <div />;\n              return <div />;\n            }\n          }\n        }\n        `\n    },\n    */\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        function ParentComponent() {\n          function UnstableNestedFunctionComponent() {\n            return <div />;\n          }\n\n          return (\n            <div>\n              <UnstableNestedFunctionComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          function UnstableNestedFunctionComponent() {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedFunctionComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedVariableComponent = () => {\n            return <div />;\n          }\n\n          return (\n            <div>\n              <UnstableNestedVariableComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedVariableComponent = () => {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedVariableComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        const ParentComponent = () => {\n          function UnstableNestedFunctionComponent() {\n            return <div />;\n          }\n\n          return (\n            <div>\n              <UnstableNestedFunctionComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        const ParentComponent = () => {\n          function UnstableNestedFunctionComponent() {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedFunctionComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        export default () => {\n          function UnstableNestedFunctionComponent() {\n            return <div />;\n          }\n\n          return (\n            <div>\n              <UnstableNestedFunctionComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_WITHOUT_NAME }],\n    },\n    {\n      code: `\n        export default () => {\n          function UnstableNestedFunctionComponent() {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedFunctionComponent, null)\n          );\n        };\n      `,\n      errors: [{ message: ERROR_MESSAGE_WITHOUT_NAME }],\n    },\n    {\n      code: `\n        const ParentComponent = () => {\n          const UnstableNestedVariableComponent = () => {\n            return <div />;\n          }\n\n          return (\n            <div>\n              <UnstableNestedVariableComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        const ParentComponent = () => {\n          const UnstableNestedVariableComponent = () => {\n            return React.createElement(\"div\", null);\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedVariableComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          class UnstableNestedClassComponent extends React.Component {\n            render() {\n              return <div />;\n            }\n          };\n\n          return (\n            <div>\n              <UnstableNestedClassComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          class UnstableNestedClassComponent extends React.Component {\n            render() {\n              return React.createElement(\"div\", null);\n            }\n          }\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedClassComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            class UnstableNestedClassComponent extends React.Component {\n              render() {\n                return <div />;\n              }\n            };\n\n            return (\n              <div>\n                <UnstableNestedClassComponent />\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            class UnstableNestedClassComponent extends React.Component {\n              render() {\n                return React.createElement(\"div\", null);\n              }\n            }\n\n            return React.createElement(\n              \"div\",\n              null,\n              React.createElement(UnstableNestedClassComponent, null)\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            function UnstableNestedFunctionComponent() {\n              return <div />;\n            }\n\n            return (\n              <div>\n                <UnstableNestedFunctionComponent />\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            function UnstableNestedClassComponent() {\n              return React.createElement(\"div\", null);\n            }\n\n            return React.createElement(\n              \"div\",\n              null,\n              React.createElement(UnstableNestedClassComponent, null)\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            const UnstableNestedVariableComponent = () => {\n              return <div />;\n            }\n\n            return (\n              <div>\n                <UnstableNestedVariableComponent />\n              </div>\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            const UnstableNestedClassComponent = () => {\n              return React.createElement(\"div\", null);\n            }\n\n            return React.createElement(\n              \"div\",\n              null,\n              React.createElement(UnstableNestedClassComponent, null)\n            );\n          }\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          function getComponent() {\n            function NestedUnstableFunctionComponent() {\n              return <div />;\n            };\n\n            return <NestedUnstableFunctionComponent />;\n          }\n\n          return (\n            <div>\n              {getComponent()}\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          function getComponent() {\n            function NestedUnstableFunctionComponent() {\n              return React.createElement(\"div\", null);\n            }\n\n            return React.createElement(NestedUnstableFunctionComponent, null);\n          }\n\n          return React.createElement(\"div\", null, getComponent());\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ComponentWithProps(props) {\n          return <div />;\n        }\n\n        function ParentComponent() {\n          return (\n            <ComponentWithProps\n              footer={\n                function SomeFooter() {\n                  return <div />;\n                }\n              } />\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ComponentWithProps(props) {\n          return React.createElement(\"div\", null);\n        }\n\n        function ParentComponent() {\n          return React.createElement(ComponentWithProps, {\n            footer: function SomeFooter() {\n              return React.createElement(\"div\", null);\n            }\n          });\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ComponentWithProps(props) {\n          return <div />;\n        }\n\n        function ParentComponent() {\n            return (\n              <ComponentWithProps footer={() => <div />} />\n            );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ComponentWithProps(props) {\n          return React.createElement(\"div\", null);\n        }\n\n        function ParentComponent() {\n          return React.createElement(ComponentWithProps, {\n            footer: () => React.createElement(\"div\", null)\n          });\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n            return (\n              <RenderPropComponent>\n                {() => {\n                  function UnstableNestedComponent() {\n                    return <div />;\n                  }\n\n                  return (\n                    <div>\n                      <UnstableNestedComponent />\n                    </div>\n                  );\n                }}\n              </RenderPropComponent>\n            );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function RenderPropComponent(props) {\n          return props.render({});\n        }\n\n        function ParentComponent() {\n          return React.createElement(\n            RenderPropComponent,\n            null,\n            () => {\n              function UnstableNestedComponent() {\n                return React.createElement(\"div\", null);\n              }\n\n              return React.createElement(\n                \"div\",\n                null,\n                React.createElement(UnstableNestedComponent, null)\n              );\n            }\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ComponentForProps(props) {\n          return <div />;\n        }\n\n        function ParentComponent() {\n          return (\n            <ComponentForProps notPrefixedWithRender={() => <div />} />\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ComponentForProps(props) {\n          return React.createElement(\"div\", null);\n        }\n\n        function ParentComponent() {\n          return React.createElement(ComponentForProps, {\n            notPrefixedWithRender: () => React.createElement(\"div\", null)\n          });\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          return (\n            <ComponentForProps someMap={{ Header: () => <div /> }} />\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        class ParentComponent extends React.Component {\n          render() {\n            const List = (props) => {\n              const items = props.items\n                .map((item) => (\n                  <li key={item.key}>\n                    <span>{item.name}</span>\n                  </li>\n                ));\n\n              return <ul>{items}</ul>;\n            };\n\n            return <List {...this.props} />;\n          }\n        }\n      `,\n      // Only a single error should be shown. This can get easily marked twice.\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n      function ParentComponent() {\n        return (\n          <SomeComponent>\n            {\n              thing.match({\n                loading: () => <div />,\n                success: () => <div />,\n                failure: () => <div />,\n              })\n            }\n          </SomeComponent>\n        )\n      }\n      `,\n      errors: [\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n      ],\n    },\n    {\n      code: `\n      function ParentComponent() {\n        const thingElement = thing.match({\n          loading: () => <div />,\n          success: () => <div />,\n          failure: () => <div />,\n        });\n        return (\n          <SomeComponent>\n            {thingElement}\n          </SomeComponent>\n        )\n      }\n      `,\n      errors: [\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n        { message: ERROR_MESSAGE_COMPONENT_AS_PROPS },\n      ],\n    },\n    {\n      code: `\n      function ParentComponent() {\n        const rows = [\n          {\n            name: 'A',\n            notPrefixedWithRender: (props) => <Row {...props} />\n          },\n        ];\n\n        return <Table rows={rows} />;\n      }\n      `,\n      errors: [{ message: ERROR_MESSAGE_COMPONENT_AS_PROPS }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedComponent = React.memo(() => {\n            return <div />;\n          });\n\n          return (\n            <div>\n              <UnstableNestedComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedComponent = React.memo(\n            () => React.createElement(\"div\", null),\n          );\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedComponent = React.memo(\n            function () {\n              return <div />;\n            }\n          );\n\n          return (\n            <div>\n              <UnstableNestedComponent />\n            </div>\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n    {\n      code: `\n        function ParentComponent() {\n          const UnstableNestedComponent = React.memo(\n            function () {\n              return React.createElement(\"div\", null);\n            }\n          );\n\n          return React.createElement(\n            \"div\",\n            null,\n            React.createElement(UnstableNestedComponent, null)\n          );\n        }\n      `,\n      errors: [{ message: ERROR_MESSAGE }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unused-class-component-methods.js",
    "content": "/**\n * @fileoverview Prevent declaring unused methods and properties of component class\n * @author Paweł Nowak, Berton Zhu\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unused-class-component-methods');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unused-class-component-methods', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class SmockTestForTypeOfNullError extends React.Component {\n          handleClick() {}\n          foo;\n          render() {\n            let a;\n            return <button disabled onClick={this.handleClick} foo={this.foo}>Text</button>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          handleClick() {}\n          render() {\n            return <button onClick={this.handleClick}>Text</button>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          handleClick() {},\n          render() {\n            return <button onClick={this.handleClick}>Text</button>;\n          },\n        })\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action() {}\n          componentDidMount() {\n            this.action();\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          action() {},\n          componentDidMount() {\n            this.action();\n          },\n          render() {\n            return null;\n          },\n        })\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action() {}\n          componentDidMount() {\n            const action = this.action;\n            action();\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          getValue() {}\n          componentDidMount() {\n            const action = this.getValue();\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          handleClick = () => {}\n          render() {\n            return <button onClick={this.handleClick}>Button</button>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          renderContent() {}\n          render() {\n            return <div>{this.renderContent()}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          renderContent() {}\n          render() {\n            return (\n              <div>\n                <div>{this.renderContent()}</div>;\n              </div>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          property = {}\n          render() {\n            return <div property={this.property}>Example</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = () => {}\n          anotherAction = () => {\n            this.action();\n          }\n          render() {\n            return <button onClick={this.anotherAction}>Example</button>;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = () => {}\n          anotherAction = () => this.action()\n          render() {\n            return <button onClick={this.anotherAction}>Example</button>;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          getValue = () => {}\n          value = this.getValue()\n          render() {\n            return this.value;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class Foo {\n          action = () => {}\n          anotherAction = () => this.action()\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = async () => {}\n          render() {\n            return <button onClick={this.action}>Click</button>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          async action() {\n            console.log('error');\n          }\n          render() {\n            return <button onClick={() => this.action()}>Click</button>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          * action() {\n            console.log('error');\n          }\n          render() {\n            return <button onClick={() => this.action()}>Click</button>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          async * action() {\n            console.log('error');\n          }\n          render() {\n            return <button onClick={() => this.action()}>Click</button>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = function() {\n            console.log('error');\n          }\n          render() {\n            return <button onClick={() => this.action()}>Click</button>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class ClassAssignPropertyInMethodTest extends React.Component {\n          constructor() {\n            this.foo = 3;;\n          }\n          render() {\n            return <SomeComponent foo={this.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassPropertyTest extends React.Component {\n          foo;\n          render() {\n            return <SomeComponent foo={this.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class ClassPropertyTest extends React.Component {\n          foo = a;\n          render() {\n            return <SomeComponent foo={this.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          ['foo'] = a;\n          render() {\n            return <SomeComponent foo={this['foo']} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          ['foo'];\n          render() {\n            return <SomeComponent foo={this['foo']} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class ClassComputedTemplatePropertyTest extends React.Component {\n          [\\`foo\\`] = a;\n          render() {\n            return <SomeComponent foo={this[\\`foo\\`]} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class ClassComputedTemplatePropertyTest extends React.Component {\n          state = {}\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class ClassLiteralComputedMemberTest extends React.Component {\n          ['foo']() {}\n          render() {\n            return <SomeComponent foo={this.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassComputedTemplateMemberTest extends React.Component {\n          [\\`foo\\`]() {}\n          render() {\n            return <SomeComponent foo={this.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassUseAssignTest extends React.Component {\n          foo() {}\n          render() {\n            this.foo;\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassUseAssignTest extends React.Component {\n          foo() {}\n          render() {\n            const { foo } = this;\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassUseDestructuringTest extends React.Component {\n          foo() {}\n          render() {\n            const { foo } = this;\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassUseDestructuringTest extends React.Component {\n          ['foo']() {}\n          render() {\n            const { 'foo': bar } = this;\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassComputedMemberTest extends React.Component {\n          [foo]() {}\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassWithLifecyleTest extends React.Component {\n          constructor(props) {\n            super(props);\n          }\n          static getDerivedStateFromProps() {}\n          componentWillMount() {}\n          UNSAFE_componentWillMount() {}\n          componentDidMount() {}\n          componentWillReceiveProps() {}\n          UNSAFE_componentWillReceiveProps() {}\n          shouldComponentUpdate() {}\n          componentWillUpdate() {}\n          UNSAFE_componentWillUpdate() {}\n          static getSnapshotBeforeUpdate() {}\n          componentDidUpdate() {}\n          componentDidCatch() {}\n          componentWillUnmount() {}\n          getChildContext() {}\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var ClassWithLifecyleTest = createReactClass({\n          mixins: [],\n          constructor(props) {\n          },\n          getDefaultProps() {\n            return {}\n          },\n          getInitialState: function() {\n            return {x: 0};\n          },\n          componentWillMount() {},\n          UNSAFE_componentWillMount() {},\n          componentDidMount() {},\n          componentWillReceiveProps() {},\n          UNSAFE_componentWillReceiveProps() {},\n          shouldComponentUpdate() {},\n          componentWillUpdate() {},\n          UNSAFE_componentWillUpdate() {},\n          componentDidUpdate() {},\n          componentDidCatch() {},\n          componentWillUnmount() {},\n          getChildContext() {},\n          render() {\n            return <SomeComponent />;\n          },\n        })\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Foo extends React.Component {\n          getDerivedStateFromProps() {}\n          render() {\n            return <div>Example</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"getDerivedStateFromProps\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          property = {}\n          render() {\n            return <div>Example</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          message: 'Unused method or property \"property\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          handleClick() {}\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"handleClick\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          handleClick() {},\n          render() {\n            return null;\n          },\n        })\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"handleClick\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          a: 3,\n          render() {\n            return null;\n          },\n        })\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"a\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          handleScroll() {}\n          handleClick() {}\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"handleScroll\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n        {\n          message: 'Unused method or property \"handleClick\" of class \"Foo\"',\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          handleClick = () => {}\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          message: 'Unused method or property \"handleClick\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = async () => {}\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          message: 'Unused method or property \"action\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          async action() {\n            console.log('error');\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"action\" of class \"Foo\"',\n          line: 3,\n          column: 17,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          * action() {\n            console.log('error');\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"action\" of class \"Foo\"',\n          line: 3,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          async * action() {\n            console.log('error');\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"action\" of class \"Foo\"',\n          line: 3,\n          column: 19,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          getInitialState() {}\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          message: 'Unused method or property \"getInitialState\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          action = function() {\n            console.log('error');\n          }\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          message: 'Unused method or property \"action\" of class \"Foo\"',\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n         class ClassAssignPropertyInMethodTest extends React.Component {\n           constructor() {\n             this.foo = 3;\n           }\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"ClassAssignPropertyInMethodTest\"',\n          line: 4,\n          column: 19,\n        },\n      ],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           foo;\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 12,\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           foo = a;\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 12,\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           ['foo'];\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 13,\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           ['foo'] = a;\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 13,\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           foo = a;\n           render() {\n             return <SomeComponent foo={this[foo]} />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 12,\n        },\n      ],\n      features: ['class fields'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           private foo;\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 20,\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           private foo() {}\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 20,\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n         class Foo extends React.Component {\n           private foo = 3;\n           render() {\n             return <SomeComponent />;\n           }\n         }\n       `,\n      errors: [\n        {\n          message: 'Unused method or property \"foo\" of class \"Foo\"',\n          line: 3,\n          column: 20,\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unused-prop-types.js",
    "content": "/**\n * @fileoverview Warn about unused PropType definitions in React components\n * @author Evgueni Naverniouk\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst RuleTester = require('../../helpers/ruleTester');\n\nrequire('object.entries/auto'); // for node 6, eslint 5, new TS parser, `function Hello({firstname}: Props): React$Element {` cases\n\nconst rule = require('../../../lib/rules/no-unused-prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    pragma: 'Foo',\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-unused-prop-types', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello World</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var props = this.props;\n            return <div>Hello World</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var propName = \"foo\";\n            return <div>Hello World {this.props[propName]}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: externalPropTypes.mySharedPropTypes,\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello World</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string\n        };\n        Hello.propTypes.lastname = PropTypes.string;\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            var user = {\n              name: this.props.name\n            };\n            return <div>Hello {user.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello {\n          render() {\n            return 'Hello' + this.props.name;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello {\n          method;\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Props validation is ignored when spread is used\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var { firstname, ...props } = this.props;\n            var { category, icon } = props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string,\n          category: PropTypes.string,\n          icon: PropTypes.bool\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var {firstname, lastname} = this.state, something = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            name: PropTypes.string\n          };\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            name: PropTypes.string\n          };\n          render() {\n            return <div>Hello {this.props?.name}</div>;\n          }\n        }\n      `,\n      features: ['class fields', 'optional chaining'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          'firstname': PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            if (Object.prototype.hasOwnProperty.call(this.props, 'firstname')) {\n              return <div>Hello {this.props.firstname}</div>;\n            }\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          'firstname': PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {};\n        Hello.propTypes.a = PropTypes.shape({\n          b: PropTypes.string\n        });\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.shape({\n            })\n          })\n        };\n        Hello.propTypes.a.b.c = PropTypes.number;\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            this.props.a.__.d.length;\n            this.props.a.anything.e[2];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.objectOf(\n            PropTypes.shape({\n              c: PropTypes.number,\n              d: PropTypes.string,\n              e: PropTypes.array\n            })\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var i = 3;\n            this.props.a[2].c;\n            this.props.a[i].d.length;\n            this.props.a[i + 2].e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.arrayOf(\n            PropTypes.shape({\n              c: PropTypes.number,\n              d: PropTypes.string,\n              e: PropTypes.array\n            })\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.array,\n            PropTypes.string\n          ])\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.c;\n            this.props.a[2] === true;\n            this.props.a.e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.shape({\n              c: PropTypes.number,\n              e: PropTypes.array\n            }).isRequired,\n            PropTypes.arrayOf(\n              PropTypes.bool\n            )\n          ])\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.render;\n            this.props.a.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.instanceOf(Hello)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.arr;\n            this.props.arr[3];\n            this.props.arr.length;\n            this.props.arr.push(3);\n            this.props.bo;\n            this.props.bo.toString();\n            this.props.fu;\n            this.props.fu.bind(this);\n            this.props.numb;\n            this.props.numb.toFixed();\n            this.props.stri;\n            this.props.stri.length();\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          arr: PropTypes.array,\n          bo: PropTypes.bool.isRequired,\n          fu: PropTypes.func,\n          numb: PropTypes.number,\n          stri: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var {\n              propX,\n              \"aria-controls\": ariaControls,\n              ...props } = this.props;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"propX\": PropTypes.string,\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"some.value\": PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.array\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1][\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.arrayOf(\n            PropTypes.shape({\"some.value\": PropTypes.string})\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        var TestComp1 = createReactClass({\n          propTypes: {\n            size: PropTypes.string\n          },\n          render: function() {\n            var foo = {\n              baz: 'bar'\n            };\n            var icons = foo[this.props.size].salut;\n            return <div>{icons}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const {firstname, lastname} = this.props.name;\n            return <div>{firstname} {lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.shape({\n            firstname: PropTypes.string,\n            lastname: PropTypes.string\n          })\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            let {firstname} = this;\n            return <div>{firstname}</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        function Foo({ a }) {\n          return <>{ a.b }</>\n        }\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            b: PropType.string,\n          })\n        }\n      `,\n      options: [{ skipShapeProps: false }],\n      features: ['fragment'],\n    },\n    {\n      code: `\n        function Foo({ a }) {\n          const { b } = a\n          return <>{ b.c }</>\n        }\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            b: PropType.shape({\n              c: PropTypes.string,\n            }),\n          })\n        }\n      `,\n      options: [{ skipShapeProps: false }],\n      features: ['fragment'],\n    },\n    {\n      // Destructured assignment with Shape propTypes with skipShapeProps off issue #816\n      code: `\n        class Thing extends React.Component {\n          static propTypes = {\n            i18n: PropTypes.shape({\n              gettext: PropTypes.func,\n            }),\n          }\n\n          render() {\n            const { i18n } = this.props;\n            return (\n              <p>{i18n.gettext('Some Text')}</p>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        class Thing extends React.Component {\n          static propTypes = {\n            a: PropTypes.shape({\n              b: PropTypes.string,\n            }),\n          }\n\n          render() {\n            const { a } = this.props;\n            return (\n              <p>{ a.b }</p>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            router: PropTypes.func\n          },\n          render: function() {\n            var nextPath = this.props.router.getCurrentQuery().nextPath;\n            return <div>{nextPath}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            firstname: CustomValidator.string\n          },\n          render: function() {\n            return <div>{this.props.firstname}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: CustomValidator.shape({\n              inner: CustomValidator.map\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'], skipShapeProps: false }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: PropTypes.shape({\n              inner: CustomValidator.string\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'], skipShapeProps: false }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: CustomValidator.shape({\n              inner: PropTypes.string\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'], skipShapeProps: false }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string\n          },\n          render: function() {\n            return <div>{this.props.name.get(\"test\")}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        const SomeComponent = createReactClass({\n          propTypes: SomeOtherComponent.propTypes\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {}\n          render() {\n            return <div>Hello World</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {}\n          render() {\n            var users = this.props.users.find(user => user.name === 'John');\n            return <div>Hello you {users.length}</div>;\n          }\n        }\n        Hello.propTypes = {\n          users: PropTypes.arrayOf(PropTypes.object)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const {} = this.props;\n            return <div>Hello</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var foo = 'fullname';\n            var { [foo]: firstname } = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source.uri }\n          }\n          static propTypes = {\n            source: PropTypes.object\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props?.source?.uri }\n          }\n          static propTypes = {\n            source: PropTypes.object\n          };\n        }\n      `,\n      features: ['class fields', 'optional chaining'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: this.props.source.uri }\n          }\n          static propTypes = {\n            source: PropTypes.object\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Should not be detected as a component\n      code: `\n        HelloJohn.prototype.render = function() {\n          return React.createElement(Hello, {\n            name: this.props.firstname\n          });\n        };\n      `,\n    },\n    {\n      // Should not be detected as a component\n      code: `\n        HelloJohn.prototype.render = function() {\n          return React.createElement(Hello, {\n            name: this.props?.firstname\n          });\n        };\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          class Hello extends React.Component {\n            render() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n          Hello.propTypes = { name: PropTypes.string };\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n    },\n    {\n      code: `\n        function HelloComponent() {\n          class Hello extends React.Component {\n            render() {\n              return <div>Hello {this.props?.name}</div>;\n            }\n          }\n          Hello.propTypes = { name: PropTypes.string };\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          var Hello = createReactClass({\n            propTypes: { name: PropTypes.string },\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n    },\n    {\n      code: `\n        function HelloComponent() {\n          var Hello = createReactClass({\n            propTypes: { name: PropTypes.string },\n            render: function() {\n              return <div>Hello {this.props?.name}</div>;\n            }\n          });\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        class DynamicHello extends Component {\n          render() {\n            const {firstname} = this.props;\n            class Hello extends Component {\n              render() {\n                const {name} = this.props;\n                return <div>Hello {name}</div>;\n              }\n            }\n            Hello.propTypes = {\n              name: PropTypes.string\n            };\n            Hello = connectReduxForm({name: firstname})(Hello);\n            return <Hello />;\n          }\n        }\n        DynamicHello.propTypes = {\n          firstname: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          let team = props.names.map((name) => {\n              return <li>{name}, {props.company}</li>;\n            });\n          return <ul>{team}</ul>;\n        };\n        Hello.propTypes = {\n          names: PropTypes.array,\n          company: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          let team = props?.names.map((name) => {\n              return <li>{name}, {props?.company}</li>;\n            });\n          return <ul>{team}</ul>;\n        };\n        Hello.propTypes = {\n          names: PropTypes.array,\n          company: PropTypes.string\n        };\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        export default {\n          renderHello() {\n            let {name} = this.props;\n            return <div>{name}</div>;\n          }\n        };\n      `,\n    },\n    {\n      // Reassigned props are ignored\n      code: `\n        export class Hello extends Component {\n          render() {\n            const props = this.props;\n            return <div>Hello {props.name.firstname} {props['name'].lastname}</div>\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        export default function FooBar(props) {\n          const bar = props.bar;\n          return (<div bar={bar}><div {...props}/></div>);\n        }\n        if (process.env.NODE_ENV !== 'production') {\n          FooBar.propTypes = {\n            bar: PropTypes.string\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var {...other} = this.props;\n            return (\n              <div {...other} />\n            );\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        function notAComponent({ something }) {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      code: `\n        const notAComponent = function({ something }) {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      code: `\n        const notAComponent = ({ something }) => {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      // Validation is ignored on reassigned props object\n      code: `\n        const statelessComponent = (props) => {\n          let newProps = props;\n          return <span>{newProps.someProp}</span>;\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: string;\n          };\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: Object;\n          };\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {name: Object;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { a: string }\n        type PropsB = { b: string }\n        type Props = PropsA & PropsB;\n\n        class MyComponent extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>{this.props.a} - {this.props.b}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type { PropsA } from \"./myPropsA\";\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsB = { foo: string };\n        type PropsC = { bar: string };\n        type Props = PropsB & {\n          zap: string\n        };\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsB = { foo: string };\n        type PropsC = { bar: string };\n        type Props = {\n          zap: string\n        } & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: {\n              firstname: string;\n            }\n          };\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {name: {firstname: string;};};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        class Hello extends React.Component {\n          props: {people: Person[];};\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.firstname);\n            }\n            return <div>Hello {names.join(', ')}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        type Props = {people: Person[];};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.firstname);\n            }\n            return <div>Hello {names.join(', ')}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        type Props = {people: Person[]|Person;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            if (Array.isArray(this.props.people)) {\n              for (var i = 0; i < this.props.people.length; i++) {\n                names.push(this.props.people[i].name.firstname);\n              }\n            } else {\n              names.push(this.props.people.name.firstname);\n            }\n            return <div>Hello {names.join(', ')}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {ok: string | boolean;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.ok}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {result: {ok: string | boolean;}|{ok: number | Array}};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {result?: {ok?: ?string | boolean;}|{ok?: ?number | Array}};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {notTarget: string};\n        class Hello extends React.Component {\n          props: Props;\n          onEvent({ target }: { target: Object }) {};\n          render () {\n            return <div>Hello {this.props.notTarget}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {notTarget: string};\n        class Hello extends React.Component {\n          props: Props;\n          onEvent(infos: { target: Object }) {};\n          render () {\n            return <div>Hello {this.props.notTarget}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props = {a: 123};\n          render () {\n            return <div>Hello</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Ignore component validation if propTypes are composed using spread\n      code: `\n        class Hello extends React.Component {\n            render() {\n                return  <div>Hello {this.props.firstName} {this.props.lastName}</div>;\n            }\n        };\n        const otherPropTypes = {\n            lastName: PropTypes.string\n        };\n        Hello.propTypes = {\n            ...otherPropTypes,\n            firstName: PropTypes.string\n        };\n      `,\n    },\n    {\n      // Ignore destructured function arguments\n      code: `\n        class Hello extends React.Component {\n          render () {\n            return [\"string\"].map(({length}) => <div>{length}</div>);\n          }\n        }\n      `,\n    },\n    {\n      // Flow annotations on stateless components\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        function Hello(props: Props): React.Element {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        const Hello = function(props: Props): React.Element {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        const Hello = (props: Props): React.Element => {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsUnionA = {\n          a: string,\n          b?: void,\n        };\n        type PropsUnionB = {\n          a?: void,\n          b: string,\n        };\n        type Props = {\n          name: string,\n        } & (PropsUnionA | PropsUnionB);\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            const {name} = this.props;\n            return name;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type { FieldProps } from \"redux-form\"\n\n        type Props = {\n        label: string,\n          type: string,\n          options: Array<SelectOption>\n        } & FieldProps\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        Card.propTypes = {\n          title: PropTypes.string.isRequired,\n          children: PropTypes.element.isRequired,\n          footer: PropTypes.node\n        }\n        function Card ({ title, children, footer }) {\n          return (\n            <div/>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        function JobList(props) {\n          props\n          .jobs\n          .forEach(() => {});\n          return <div></div>;\n        }\n        JobList.propTypes = {\n          jobs: PropTypes.array\n        };\n      `,\n    },\n    {\n      code: `\n        type Props = {\n          firstname: ?string,\n        };\n        function Hello({firstname}: Props): React$Element {\n          return <div>Hello {firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        function Greetings() {\n          return <div>{({name}) => <Hello name={name} />}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        function Greetings() {\n          return <div>{function({name}) { return <Hello name={name} />; }}</div>\n        }\n      `,\n    },\n    {\n      // Should stop at the class when searching for a parent component\n      code: `\n        export default (ComposedComponent) => class Something extends SomeOtherComponent {\n          someMethod = ({width}) => {}\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Should stop at the decorator when searching for a parent component\n      code: `\n        @asyncConnect([{\n          promise: ({dispatch}) => {}\n        }])\n        class Something extends Component {}\n      `,\n      features: ['no-default'],\n    },\n    {\n      // Destructured shape props are skipped by default\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            params: PropTypes.shape({\n              id: PropTypes.string\n            })\n           }\n          render () {\n            const {params} = this.props\n            const id = (params || {}).id;\n            return <span>{id}</span>\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in componentWillReceiveProps shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentWillReceiveProps (nextProps) {\n            const {something} = nextProps;\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in componentWillReceiveProps shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentWillReceiveProps (nextProps) {\n            const {something} = nextProps;\n            doSomething(something);\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured props in componentWillReceiveProps shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentWillReceiveProps (nextProps) {\n            const {something} = nextProps;\n            doSomething(something);\n          }\n        })\n      `,\n    },\n    {\n      // Destructured function props in componentWillReceiveProps shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentWillReceiveProps ({something}) {\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured function props in componentWillReceiveProps shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentWillReceiveProps ({something}) {\n            doSomething(something);\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured function props in componentWillReceiveProps shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentWillReceiveProps ({something}) {\n            doSomething(something);\n          }\n        })\n      `,\n    },\n    {\n      // Destructured props in the constructor shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          constructor (props) {\n            super(props);\n            const {something} = props;\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in the constructor shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          constructor (props) {\n            super(props);\n            const {something} = props;\n            doSomething(something);\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured function props in the constructor shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          constructor ({something}) {\n            super({something});\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured function props in the constructor shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          constructor ({something}) {\n            super({something});\n            doSomething(something);\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      code: `\n        // Destructured props in the \\`shouldComponentUpdate\\` method shouldn’t throw errors\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          shouldComponentUpdate(nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        // Destructured props in the \\`shouldComponentUpdate\\` method shouldn’t throw errors\n        class Hello extends Component {\n          shouldComponentUpdate(nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      code: `\n        // Destructured props in \\`shouldComponentUpdate\\` shouldn’t throw errors when used with createReactClass\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          shouldComponentUpdate(nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured props in `shouldComponentUpdate` shouldn't throw errors when used createReactClass, with default parser\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          shouldComponentUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured function props in the `shouldComponentUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          shouldComponentUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured function props in the `shouldComponentUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          shouldComponentUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured function props in `shouldComponentUpdate` shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          shouldComponentUpdate ({something}, nextState) {\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured props in the `componentWillUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in the `componentWillUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured props in `componentWillUpdate` shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured function props in the `componentWillUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentWillUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured function props in the `componentWillUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentWillUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured function props in the `componentWillUpdate` method shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentWillUpdate ({something}, nextState) {\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured props in the `componentDidUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentDidUpdate (prevProps, prevState) {\n            const {something} = prevProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in the `componentDidUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentDidUpdate (prevProps, prevState) {\n            const {something} = prevProps;\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured props in `componentDidUpdate` shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentDidUpdate (prevProps, prevState) {\n            const {something} = prevProps;\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured function props in the `componentDidUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentDidUpdate ({something}, prevState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured function props in the `componentDidUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          componentDidUpdate ({something}, prevState) {\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured function props in the `componentDidUpdate` method shouldn't throw errors when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentDidUpdate ({something}, prevState) {\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured state props in `componentDidUpdate` [Issue #825]\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentDidUpdate ({something}, {state1, state2}) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured state props in `componentDidUpdate` [Issue #825]\n      code: `\n        class Hello extends Component {\n          componentDidUpdate ({something}, {state1, state2}) {\n            return something;\n          }\n        }\n        Hello.propTypes = {\n          something: PropTypes.bool,\n        };\n      `,\n    },\n    {\n      // Destructured state props in `componentDidUpdate` [Issue #825] when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentDidUpdate ({something}, {state1, state2}) {\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured state props in `componentDidUpdate` without custom parser [Issue #825]\n      code: `\n        var Hello = React.Component({\n          propTypes: {\n            something: PropTypes.bool\n          },\n          componentDidUpdate: function ({something}, {state1, state2}) {\n            return something;\n          }\n        });\n      `,\n    },\n    {\n      // Destructured state props in `componentDidUpdate` without custom parser [Issue #825] when used createReactClass\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool,\n          },\n          componentDidUpdate: function ({something}, {state1, state2}) {\n            return something;\n          }\n        })\n      `,\n    },\n    {\n      // Destructured props in a stateless function\n      code: `\n        const Hello = (props) => {\n          const {...rest} = props;\n          return <div />;\n        };\n      `,\n    },\n    {\n      // Nested destructuring; issue 2424\n      code: `\n        function SomeComponent(props) {\n          const {aaa: {bbb}} = props;\n          return <p>{bbb}</p>;\n        }\n\n        SomeComponent.propTypes = {\n          aaa: somePropType,\n        };\n      `,\n    },\n    {\n      // `no-unused-prop-types` in jsx expressions - [Issue #885]\n      code: `\n        const PagingBlock = function(props) {\n          return (\n            <span>\n              <a onClick={() => props.previousPage()}/>\n              <a onClick={() => props.nextPage()}/>\n            </span>\n         );\n        };\n\n        PagingBlock.propTypes = {\n          nextPage: PropTypes.func.isRequired,\n          previousPage: PropTypes.func.isRequired,\n        };\n      `,\n    },\n    {\n      // `no-unused-prop-types` rest param props in jsx expressions - [Issue #885]\n      code: `\n        const PagingBlock = function(props) {\n          return (\n            <SomeChild {...props} />\n         );\n        };\n\n        PagingBlock.propTypes = {\n          nextPage: PropTypes.func.isRequired,\n          previousPage: PropTypes.func.isRequired,\n        };\n      `,\n    },\n    {\n      // issue 2350\n      code: `\n        function Foo(props) {\n          useEffect(() => {\n            const { a } = props;\n            document.title = a;\n          });\n\n          return <p/>;\n        }\n\n        Foo.propTypes = {\n          a: PropTypes.string,\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillReceiveProps (nextProps) {\n            if (nextProps.foo) {\n              doSomething(this.props.bar);\n            }\n          }\n        }\n\n        Hello.propTypes = {\n          foo: PropTypes.bool,\n          bar: PropTypes.bool\n        };\n      `,\n    },\n    {\n      // The next two test cases are related to: https://github.com/jsx-eslint/eslint-plugin-react/issues/1183\n      code: `\n        export default function SomeComponent(props) {\n            const callback = () => {\n                props.a(props.b);\n            };\n\n            const anotherCallback = () => {};\n\n            return (\n                <SomeOtherComponent\n                    name={props.c}\n                    callback={callback}\n                />\n            );\n        }\n\n        SomeComponent.propTypes = {\n            a: React.PropTypes.func.isRequired,\n            b: React.PropTypes.string.isRequired,\n            c: React.PropTypes.string.isRequired,\n        };\n      `,\n    },\n    {\n      code: `\n        export default function SomeComponent(props) {\n            const callback = () => {\n                props.a(props.b);\n            };\n\n            return (\n                <SomeOtherComponent\n                    name={props.c}\n                    callback={callback}\n                />\n            );\n        }\n\n        SomeComponent.propTypes = {\n            a: React.PropTypes.func.isRequired,\n            b: React.PropTypes.string.isRequired,\n            c: React.PropTypes.string.isRequired,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          shouldComponentUpdate (props) {\n            if (props.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class HelloFooBar extends Component {\n          shouldComponentUpdate(props) {\n            if (props.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        HelloFooBar.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentWillUpdate (props) {\n            if (props.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillUpdate (props) {\n            if (props.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentWillReceiveProps (nextProps) {\n            const {foo} = nextProps;\n            if (foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Props used inside of an async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n          }\n          classProperty = async () => {\n            await this.props.foo();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // Multiple props used inside of an async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          classProperty = async () => {\n            await this.props.foo();\n            await this.props.bar();\n            await this.props.baz();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillReceiveProps (props) {\n            if (props.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          shouldComponentUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props inside of async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n          }\n          classProperty = async () => {\n            const { foo } = this.props;\n            await foo();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // Multiple destructured props inside of async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          classProperty = async () => {\n            const { foo, bar, baz } = this.props;\n            await foo();\n            await bar();\n            await baz();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class Hello extends Component {\n          shouldComponentUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentWillUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Props used inside of an async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n          }\n          async method() {\n            await this.props.foo();\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Multiple props used inside of an async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          async method() {\n            await this.props.foo();\n            await this.props.bar();\n            await this.props.baz();\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured props inside of async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n          }\n          async method() {\n            const { foo } = this.props;\n            await foo();\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentDidUpdate (prevProps) {\n            if (prevProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Multiple destructured props inside of async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          async method() {\n            const { foo, bar, baz } = this.props;\n            await foo();\n            await bar();\n            await baz();\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // factory functions that return async functions\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          factory() {\n            return async () => {\n              await this.props.foo();\n              await this.props.bar();\n              await this.props.baz();\n            };\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // factory functions that return async functions\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          factory() {\n            return async function onSubmit() {\n              await this.props.foo();\n              await this.props.bar();\n              await this.props.baz();\n            };\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentDidUpdate (prevProps) {\n            if (prevProps.foo) {\n              return true;\n            }\n          }\n\n          render() {\n            return (<div>{this.props.bar}</div>);\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      // Multiple props used inside of an async method\n      code: `\n        class Example extends Component {\n          async method() {\n            await this.props.foo();\n            await this.props.bar();\n          };\n        }\n        Example.propTypes = {\n          foo: PropTypes.func,\n          bar: PropTypes.func,\n        }\n      `,\n      parserOptions: Object.assign({}, parserOptions, { ecmaVersion: 2017 }),\n    },\n    {\n      // Multiple props used inside of an async function\n      code: `\n        class Example extends Component {\n          render() {\n            async function onSubmit() {\n              await this.props.foo();\n              await this.props.bar();\n            }\n            return <Form onSubmit={onSubmit} />\n          };\n        }\n        Example.propTypes = {\n          foo: PropTypes.func,\n          bar: PropTypes.func,\n        }\n      `,\n      parserOptions: Object.assign({}, parserOptions, { ecmaVersion: 2017 }),\n    },\n    {\n      // Multiple props used inside of an async arrow function\n      code: `\n        class Example extends Component {\n          render() {\n            const onSubmit = async () => {\n              await this.props.foo();\n              await this.props.bar();\n            }\n            return <Form onSubmit={onSubmit} />\n          };\n        }\n        Example.propTypes = {\n          foo: PropTypes.func,\n          bar: PropTypes.func,\n        }\n      `,\n      parserOptions: Object.assign({}, parserOptions, { ecmaVersion: 2017 }),\n    },\n    {\n      // Destructured assignment with Shape propTypes issue #816\n      code: `\n        export default class NavigationButton extends React.Component {\n         static propTypes = {\n           route: PropTypes.shape({\n            getBarTintColor: PropTypes.func.isRequired,\n          }).isRequired,\n         };\n\n         renderTitle() {\n          const { route } = this.props;\n           return <Title tintColor={route.getBarTintColor()}>TITLE</Title>;\n         }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Destructured assignment without Shape propTypes issue #816\n      code: `\n        const Component = ({ children: aNode }) => (\n         <div>{aNode}</div>\n        );\n\n        Component.defaultProps = {\n         children: null,\n        };\n\n        Component.propTypes = {\n         children: React.PropTypes.node,\n        };\n      `,\n    },\n    {\n      // issue 1309\n      code: `\n        const Thing = (props) => (\n            <div>\n              {(() => {\n                    if(props.enabled && props.test){\n                        return (\n                            <span>Enabled!</span>\n                        )\n                    }\n                    return (\n                        <span>Disabled..</span>\n                    )\n                })()}\n            </div>\n        );\n\n        Thing.propTypes = {\n            enabled: React.PropTypes.bool,\n            test: React.PropTypes.bool\n        };\n      `,\n    },\n    {\n      // issue 1107\n      code: `\n        const Test = props => <div>\n          {someArray.map(l => <div\n            key={l}>\n              {props.property + props.property2}\n            </div>)}\n        </div>\n\n        Test.propTypes = {\n          property: React.propTypes.string.isRequired,\n          property2: React.propTypes.string.isRequired\n        }\n      `,\n    },\n    {\n      // issue 811\n      code: `\n        const Button = React.createClass({\n        displayName: \"Button\",\n\n        propTypes: {\n            name: React.PropTypes.string.isRequired,\n            isEnabled: React.PropTypes.bool.isRequired\n        },\n\n        render() {\n            const item = this.props;\n            const disabled = !this.props.isEnabled;\n            return (\n                <div>\n                    <button type=\"button\" disabled={disabled}>{item.name}</button>\n                </div>\n            );\n        }\n        });\n      `,\n    },\n    {\n      // issue 811\n      code: `\n        class Foo extends React.Component {\n         static propTypes = {\n         foo: PropTypes.func.isRequired,\n        }\n\n        constructor(props) {\n          super(props);\n\n          const { foo } = props;\n          this.message = foo(\"blablabla\");\n        }\n\n        render() {\n          return <div>{this.message}</div>;\n        }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // issue #1097\n      code: `\n        class HelloGraphQL extends Component {\n          render() {\n              return <div>Hello</div>;\n          }\n        }\n\n        const HellowQueries = graphql(queryDetails, {\n          options: ownProps => ({\n          variables: ownProps.aProp\n          }),\n        })(HelloGraphQL)\n\n        HellowQueries.propTypes = {\n          aProp: PropTypes.string.isRequired\n        }\n\n        export default connect(mapStateToProps, mapDispatchToProps)(HellowQueries)\n      `,\n    },\n    {\n      // issue #1335\n      code: `\n        type Props = {\n         foo: {\n          bar: boolean\n         }\n        };\n\n        class DigitalServices extends React.Component {\n         props: Props\n         render() {\n           const { foo } = this.props;\n           return <div>{foo.bar}</div>;\n         }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const foo = {};\n        class Hello extends React.Component {\n          render() {\n            const {firstname, lastname} = this.props.name;\n            return <div>{firstname} {lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.shape(foo)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const {foo: {bar}} = this.props;\n            return <div>{bar}</div>;\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.shape({\n            bar: PropTypes.string,\n          })\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #933\n      code: `\n        type Props = {\n         onMouseOver: Function,\n         onClick: Function,\n        };\n\n        const MyComponent = (props: Props) => (\n        <div>\n          <button onMouseOver={() => props.onMouseOver()} />\n          <button onClick={() => props.onClick()} />\n        </div>\n        );\n      `,\n      features: ['types'],\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1506\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState((prevState, props) => {\n              props.doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n        var tempVar2;\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1506\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState((prevState, { doSomething }) => {\n              doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1506\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState((prevState, obj) => {\n              obj.doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n        var tempVar2;\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1506\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState(() => {\n              this.props.doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n        var tempVar;\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1542\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState((prevState) => {\n              this.props.doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #1542\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState(({ something }) => {\n              this.props.doSomething();\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n    },\n    {\n      // issue #106\n      code: `\n        import React from 'react';\n        import SharedPropTypes from './SharedPropTypes';\n\n        export default class A extends React.Component {\n          render() {\n            return (\n              <span\n                a={this.props.a}\n                b={this.props.b}\n                c={this.props.c}>\n                {this.props.children}\n              </span>\n            );\n          }\n        }\n\n        A.propTypes = {\n          a: React.PropTypes.string,\n          ...SharedPropTypes // eslint-disable-line object-shorthand\n        };\n      `,\n    },\n    {\n      code: `\n        type Props = $ReadOnly<{foo: number}>;\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      // issue #933\n      code: `\n        type Props = {\n          +foo: number\n        }\n        class MyComponent extends React.Component {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {\n          'completed?': boolean,\n        };\n        const Hello = (props: Props): React.Element => {\n          return <div>{props['completed?']}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        }\n        class MyComponent extends React.Component<void, Props, void> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        }\n        class MyComponent extends React.Component<void, Props, void> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        }\n        class MyComponent extends React.Component<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        }\n        class MyComponent extends React.Component<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.53' } },\n      features: ['flow'],\n    },\n    {\n      // Issue #1068\n      code: `\n      class MyComponent extends Component {\n        static propTypes = {\n          validate: PropTypes.bool,\n          options: PropTypes.array,\n          value: ({options, value, validate}) => {\n            if (!validate) return;\n            if (options.indexOf(value) < 0)\n              throw new Errow('oops');\n          }\n        }\n\n        render() {\n          return <ul>\n            {this.props.options.map(option =>\n              <li className={this.props.value == option && \"active\"}>{option}</li>\n            )}\n          </ul>\n        }\n      }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // Issue #1068\n      code: `\n      class MyComponent extends Component {\n        static propTypes = {\n          validate: PropTypes.bool,\n          options: PropTypes.array,\n          value: function ({options, value, validate}) {\n            if (!validate) return;\n            if (options.indexOf(value) < 0)\n              throw new Errow('oops');\n          }\n        }\n\n        render() {\n          return <ul>\n            {this.props.options.map(option =>\n              <li className={this.props.value == option && \"active\"}>{option}</li>\n            )}\n          </ul>\n        }\n      }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // Issue #1068\n      code: `\n      class MyComponent extends Component {\n        static propTypes = {\n          validate: PropTypes.bool,\n          options: PropTypes.array,\n          value({options, value, validate}) {\n            if (!validate) return;\n            if (options.indexOf(value) < 0)\n              throw new Errow('oops');\n          }\n        }\n\n        render() {\n          return <ul>\n            {this.props.options.map(option =>\n              <li className={this.props.value == option && \"active\"}>{option}</li>\n            )}\n          </ul>\n        }\n      }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return <div>{ this.props.other }</div>\n          }\n        }\n        MyComponent.propTypes = { other: () => {} };\n      `,\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return <div>{ this.props.other }</div>\n          }\n        }\n        MyComponent.propTypes = { other() {} };\n      `,\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return <div>{ this.props.other }</div>\n          }\n        }\n        MyComponent.propTypes = { other: function () {} };\n      `,\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return <div>{ this.props.other }</div>\n          }\n        }\n        MyComponent.propTypes = { * other() {} };\n      `,\n    },\n    {\n      // Sanity test coverage for new UNSAFE_componentWillReceiveProps lifecycles\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n          UNSAFE_componentWillReceiveProps (nextProps) {\n            const {something} = nextProps;\n            doSomething(something);\n          }\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      features: ['class fields'],\n    },\n    {\n      // Destructured props in the `UNSAFE_componentWillUpdate` method shouldn't throw errors\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n          UNSAFE_componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      features: ['class fields'],\n    },\n    {\n      // Simple test of new static getDerivedStateFromProps lifecycle\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            defaultValue: 'bar'\n          };\n          state = {\n            currentValue: null\n          };\n          static getDerivedStateFromProps(nextProps, prevState) {\n            if (prevState.currentValue === null) {\n              return {\n                currentValue: nextProps.defaultValue,\n              }\n            }\n            return null;\n          }\n          render() {\n            return <div>{ this.state.currentValue }</div>\n          }\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      features: ['class fields'],\n    },\n    {\n      // Simple test of new static getSnapshotBeforeUpdate lifecycle\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            defaultValue: PropTypes.string\n          };\n          getSnapshotBeforeUpdate(prevProps, prevState) {\n            if (prevProps.defaultValue === null) {\n              return 'snapshot';\n            }\n            return null;\n          }\n          render() {\n            return <div />\n          }\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      features: ['class fields'],\n    },\n    {\n      // Impossible intersection type\n      code: `\n        import React from 'react';\n        type Props = string & {\n          fullname: string\n        };\n        class Test extends React.PureComponent<Props> {\n          render() {\n            return <div>Hello {this.props.fullname}</div>\n          }\n        }\n      `,\n      features: ['class fields', 'types'],\n    },\n    {\n      code: `\n        import type {BasePerson} from './types'\n        type Props = {\n          person: {\n           ...$Exact<BasePerson>,\n           lastname: string\n          }\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import BasePerson from './types'\n        class Hello extends React.Component {\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          person: ProTypes.shape({\n            ...BasePerson,\n            lastname: PropTypes.string\n          })\n        };\n      `,\n    },\n    {\n      code: `\n        type Props = {\n          used: string,\n        }\n        class Hello extends React.Component<Props> {\n          renderHelper = ({notAProp}: {notAProp: string}) => {\n            return <div />;\n          }\n          render() {\n            return <div>{this.props.used}</div>;\n          }\n        }\n      `,\n      features: ['class fields', 'types'],\n    },\n    {\n      code: `\n        type Props = {\n          used: string,\n        }\n        class Hello extends React.Component<Props> {\n          componentDidMount() {\n            foo(\n              ({notAProp}: {notAProp: string}) => (<div />)\n            );\n          }\n          render() {\n            return <div>{this.props.used}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          used: string,\n        }\n        class Hello extends React.Component<Props> {\n          render() {\n            return <QueryRenderer\n              render={({notAProp}: {notAProp: string}) => <div>{this.props.used}</div>}\n            />;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>{this.props.used}</div>;\n          }\n        }\n        Hello.propTypes = {\n          used: PropTypes.string,\n          foo: PropTypes.string\n        };\n      `,\n      options: [{ ignore: ['foo'] }],\n    },\n    {\n      code: `\n        type Props = {\n          used: string,\n          foo: string,\n        }\n        class Hello extends React.Component<Props> {\n          render() {\n            return <div>{this.props.used}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      options: [{ ignore: ['foo'] }],\n    },\n    {\n      code: `\n        export default class Foo extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        Foo.defaultProps = Object.assign({});\n      `,\n    },\n    {\n      code: `\n        const Hello = ({a}) => (\n          <div>\n            {a.map(({b}) => (\n              <div>{b}</div>\n            ))}\n          </div>\n        );\n        Hello.propTypes = {\n          a: PropTypes.arrayOf(\n            PropTypes.exact({\n              b: PropTypes.string,\n            })\n          ),\n        };\n      `,\n    },\n    {\n      code: `\n        const Foo = (props) => {\n          const { foo } = props as unknown;\n          (props as unknown).bar as unknown;\n\n          return <></>;\n        };\n\n        Foo.propTypes = {\n          foo,\n          bar,\n        };\n      `,\n      features: ['ts', 'fragment', 'no-babel'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static propTypes = {\n            prevProp,\n            nextProp,\n            setStateProp,\n            thisPropsAliasDestructProp,\n            thisPropsAliasProp,\n            thisDestructPropsAliasDestructProp,\n            thisDestructPropsAliasProp,\n            thisDestructPropsDestructProp,\n            thisPropsDestructProp,\n            thisPropsProp,\n          };\n\n          componentDidUpdate(prevProps) {\n            (prevProps as unknown).prevProp as unknown;\n          }\n\n          shouldComponentUpdate(nextProps) {\n            (nextProps as unknown).nextProp as unknown;\n          }\n\n          stateProps() {\n            ((this as unknown).setState as unknown)((_, props) => (props as unknown).setStateProp as unknown);\n          }\n\n          thisPropsAlias() {\n            const props = (this as unknown).props as unknown;\n\n            const { thisPropsAliasDestructProp } = props as unknown;\n            (props as unknown).thisPropsAliasProp as unknown;\n          }\n\n          thisDestructPropsAlias() {\n            const { props } = this as unknown;\n\n            const { thisDestructPropsAliasDestructProp } = props as unknown;\n            (props as unknown).thisDestructPropsAliasProp as unknown;\n          }\n\n          render() {\n            const { props: { thisDestructPropsDestructProp } } = this as unknown;\n            const { thisPropsDestructProp } = (this as unknown).props as unknown;\n            ((this as unknown).props as unknown).thisPropsProp as unknown;\n\n            return null;\n          }\n        }\n      `,\n      features: ['ts', 'class fields', 'no-babel'],\n    },\n    {\n      code: `\n        declare class Thing {\n          constructor({ id }: { id: string });\n        }\n        export default Thing;\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    // this test checks that there is no crash if no declaration is found (TSTypeLiteral).\n    {\n      code: `\n        const Hello = (props: {firstname: string, lastname: string}) => {\n            return <div {...props}></div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // this test checks that there is no crash if no declaration is found (TSTypeReference).\n    {\n      code: `\n        const Hello = (props: UnfoundProps) => {\n            return <div {...props}></div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      // Omit, etc, cannot be handled, but must not trigger an error\n      code: `\n        const Hello = (props: Omit<{a: string, b: string, c: string}, \"a\">) => {\n            return <div>{props.b}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      // neither TSTypeReference or TSTypeLiteral, we do nothing. Weird case\n      code: `\n        const Hello = (props: () => any) => {\n            return <div>{props.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      // neither TSTypeReference or TSTypeLiteral, we do nothing. Weird case\n      code: `\n        const Hello = (props: () => any) => {\n            return <div>{props?.firstname}</div>;\n        }\n      `,\n      features: ['types', 'optional chaining'],\n    },\n    {\n      code: `\n        interface Props {\n          'aria-label': string;\n        }\n        export default function Component({\n          'aria-label': ariaLabel,\n        }: Props): JSX.Element {\n          return <div aria-label={ariaLabel} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          ['aria-label']: string;\n        }\n        export default function Component({\n          ['aria-label']: ariaLabel,\n        }: Props): JSX.Element {\n          return <div aria-label={ariaLabel} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          [1234]: string;\n        }\n        export default function Component(\n          props\n        : Props): JSX.Element {\n          return <div aria-label={props[1234]} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          ['1234']: string;\n        }\n        export default function Component(\n          props\n        : Props): JSX.Element {\n          return <div aria-label={props[1234]} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          [1234]: string;\n        }\n        export default function Component(\n          props\n        : Props): JSX.Element {\n          return <div aria-label={props['1234']} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          [1234]: string;\n        }\n        export default function Component(\n          props\n        : Props): JSX.Element {\n        const handleVerifySubmit = ({\n          otp,\n          }) => {\n          dispatch(\n            verifyOTPPhone({\n              otp,\n            }),\n          );\n        };\n        return <div aria-label={props['1234']} />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Props {\n          foo: string;\n        }\n        const Component = (props: Props) => (\n          <div>{(()=> {return props.foo})()}</div>\n        )\n        export default Component\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n\n        type Props = User;\n\n        export default (props: Props) => {\n          return <div><span>{props.user}</span></div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n\n        type Props = User & UserProps;\n\n        export default (props: Props) => {\n          return <div><span>{props.user}</span></div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        interface Person {\n          firstname: string\n          lastname?: never\n        };\n\n        const Hello = ({firstname}: Person) => {\n          return <div><span>{firstname}</span></div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        class App extends Component {\n          static propTypes = {\n            notifications: PropTypes.array.isRequired\n          };\n          customizeNotifications() {\n            const props = this.props;\n            return props.notifications.map((notification) => notification);\n          }\n          render() {\n            const notifications = this.customizeNotifications();\n            return (\n              <View>\n                {notifications.map((notification) => <Text>{notification}</Text>)}\n              </View>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const Home = () => {\n          const renderStaticList = ({\n              item,\n          }: {\n              item: IContent;\n          }) => (\n              <Section\n                  icon={<FlashImage />}\n                  title={item.title}\n                  titleFontSize={theme.typography.FONT_SIZE_24}\n              >\n                  <StaticFlatList\n                      data={item.pointsOfSale}\n                      renderItem={renderStaticItem}\n                      keyExtractor={staticItemKeyExtractor}\n                  />\n              </Section>\n          );\n\n          return (\n              <SafeAreaViewWrapper>\n                  <LightStatusBar />\n                  <HomeFlatList\n                      ListHeaderComponent={listHeaderComponent}\n                      data={home?.static}\n                      renderItem={renderStaticList}\n                      keyExtractor={staticListKeyExtractor}\n                  />\n              </SafeAreaViewWrapper>\n          );\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Home = () => {\n          const renderStaticList = function({\n              item,\n          }: {\n              item: IContent;\n          }) {\n            return (\n              <Section\n                  icon={<FlashImage />}\n                  title={item.title}\n                  titleFontSize={theme.typography.FONT_SIZE_24}\n              >\n                  <StaticFlatList\n                      data={item.pointsOfSale}\n                      renderItem={renderStaticItem}\n                      keyExtractor={staticItemKeyExtractor}\n                  />\n              </Section>\n            )\n          };\n\n          return (\n              <SafeAreaViewWrapper>\n                  <LightStatusBar />\n                  <HomeFlatList\n                      ListHeaderComponent={listHeaderComponent}\n                      data={home?.static}\n                      renderItem={renderStaticList}\n                      keyExtractor={staticListKeyExtractor}\n                  />\n              </SafeAreaViewWrapper>\n          );\n        };\n      `,\n      features: ['types'],\n    },\n    // Issue: #2795\n    {\n      code: `\n        type ConnectedProps = DispatchProps &\n          StateProps\n\n        const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n          // Do stuff\n          return (\n            <StyledComponent>...</StyledComponent>\n          )\n        }\n\n        const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({\n          ...bindActionCreators<ActionCreatorsMapObject<Types.RootAction>>(\n            { prop1: importedAction, prop2: anotherImportedAction },\n            dispatch,\n          ),\n        })\n\n        const mapStateToProps = (state: State) => ({\n          prop3: Selector.value(state),\n        })\n\n        type StateProps = ReturnType<typeof mapStateToProps>\n        type DispatchProps = ReturnType<typeof mapDispatchToProps>\n      `,\n      features: semver.satisfies(babelEslintVersion, '> 8') ? ['types'] : ['ts', 'no-babel'],\n    },\n    // Issue: #2795\n    {\n      code: `\n        type ConnectedProps = DispatchProps &\n          StateProps\n\n        const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n          // Do stuff\n          return (\n            <StyledComponent>...</StyledComponent>\n          )\n        }\n\n        const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({\n          ...bindActionCreators(\n            { prop1: importedAction, prop2: anotherImportedAction },\n            dispatch,\n          ),\n        })\n\n        const mapStateToProps = (state: State) => ({\n          prop3: Selector.value(state),\n        })\n\n        type StateProps = ReturnType<typeof mapStateToProps>\n        type DispatchProps = ReturnType<typeof mapDispatchToProps>\n      `,\n      features: [semver.satisfies(babelEslintVersion, '> 8') ? 'types' : 'flow'],\n    },\n    // Issue: #2795\n    {\n      code: `\n        type ConnectedProps = DispatchProps &\n          StateProps\n\n        const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n          // Do stuff\n          return (\n            <StyledComponent>...</StyledComponent>\n          )\n        }\n\n        const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) =>\n          bindActionCreators(\n            { prop1: importedAction, prop2: anotherImportedAction },\n            dispatch,\n          )\n\n        const mapStateToProps = (state: State) => ({\n          prop3: Selector.value(state),\n        })\n\n        type StateProps = ReturnType<typeof mapStateToProps>\n        type DispatchProps = ReturnType<typeof mapDispatchToProps>\n      `,\n      features: [semver.satisfies(babelEslintVersion, '> 8') ? 'types' : 'flow'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        interface Props {\n          name: string;\n        }\n\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n\n        export default MyComponent;\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          history: {\n            push: Function,\n          },\n          match?: {\n            params?: {\n              date?: string\n            },\n          },\n        };\n\n        export const Daily = ({ history, match: {\n          params: {\n            date = moment().toISOString(),\n          } = {},\n        } = {} }: Props) => (\n              <div>\n                <div style={{ textAlign: 'right', paddingRight: '25px' }}>\n                  Show <DatePicker\n                    selected={moment(date)}\n                    className=\"datetime\"\n                    onChange={d => history.push(\\`./\\${d.toISOString()}\\`)}\n                  />\n                </div>\n                <WithData url=\"/payments/daily\" body={{ date: moment(date).toISOString() }}>\n                  <Flashcards date={moment(date)} />\n                </WithData>\n              </div>\n        );\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        type Props = {\n          test: string,\n          callback: () => void,\n        };\n\n        export default function Foo(props: Props) {\n          return (\n            <div>\n              {[1, 2, 3].map(e => (\n                <div key={e} onClick={() => props.callback()}>\n                  {props.test}\n                </div>\n              ))}\n            </div>\n          );\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Component extends Component <{}, {updateQueue: Array<string>}> {\n          debouncedUpdate = debounce((cellsetId, options) => {\n            this.setState((prevState, props) => {\n              const {updateQueue} = prevState;\n              const {updateCells} = props;\n              updateCells(cellsetId, updateQueue, options);\n              return {\n                updateQueue: [],\n              };\n            });\n          }, 2000);\n\n          render() {\n            return <div />\n          }\n        }\n      `,\n      features: ['class fields', 'types'],\n    },\n    {\n      code: `\n        class Test extends Component<{}, {selectedId: string}> {\n          constructor(props: *) {\n            super(props);\n            this.state = {\n              selectedId: '',\n            };\n          }\n\n          onChange = ({id}: {id: string}) => { // This will say: 'id' PropType is defined but prop is never used (react/no-unused-prop-types)\n            this.setState({\n              selectedId: id,\n            });\n          };\n\n          render() {\n            const {selectedId} = this.state;\n            return (\n              <div>\n                {selectedId}\n                <select onChange={() => this.onChange({id: '1'})}>\n                  <option value='1'>1</option>\n                </select>\n              </div>\n            );\n          }\n        }\n      `,\n      features: ['class fields', 'types'],\n    },\n    {\n      code: `\n        function Foo (props) {\n          return <div>{ renderPhoto() }</div>;\n\n          function renderPhoto () {\n            return <div>{ props.renderPhotoTools() }</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        const Wrapper = featureToggle\n        ? ({ children }: { children: Node }) => (\n          <FeatureToggledComponent\n              featureToggle={featureToggle}\n              defaultValue\n          >\n              {children}\n          </FeatureToggledComponent>\n        )\n        : React.Fragment;\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          used: string;\n        };\n\n        const Demo = React.memo<Props>(\n          React.forwardRef<HTMLDivElement, Props>(\n            ({ used }, ref) => {\n              return <div>{used}</div>\n            }\n          )\n        );\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Demo = React.memo(\n          React.forwardRef(({ used }, ref) => {\n            return <div ref={ref}>{used}</div>\n          })\n        );\n        Demo.propTypes = {\n          used: PropTypes.string,\n        };\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            unused: PropTypes.string\n          },\n          render: function() {\n            return React.createElement(\"div\", {}, this.props.value);\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string\n          },\n          render: function() {\n            return <div>Hello {this.props.value}</div>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            name: PropTypes.string\n          }\n          render() {\n            return <div>Hello {this.props.value}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.propTypes = {\n          unused: PropTypes.string\n        };\n        class HelloBis extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            unused: PropTypes.string.isRequired,\n            anotherunused: PropTypes.string.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name} and {this.props.propWithoutTypeDefinition}</div>;\n          }\n        });\n        var Hello2 = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n        { message: '\\'anotherunused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var { firstname, lastname } = this.props;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.z\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.string\n          })\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [{ message: '\\'a.b\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.z;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.shape({\n              c: PropTypes.string\n            })\n          })\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [{ message: '\\'a.b.c\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            this.props.a.__.d.length;\n            this.props.a.anything.e[2];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.objectOf(\n            PropTypes.shape({\n              unused: PropTypes.string\n            })\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'a.*.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var i = 3;\n            this.props.a[2].c;\n            this.props.a[i].d.length;\n            this.props.a[i + 2].e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.arrayOf(\n            PropTypes.shape({\n              unused: PropTypes.string\n            })\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'a.*.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.length;\n            this.props.a.b;\n            this.props.a.e.length;\n            this.props.a.e.anyProp;\n            this.props.a.c.toString();\n            this.props.a.c.someThingElse();\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.shape({\n              unused: PropTypes.number,\n              anotherunused: PropTypes.array\n            })\n          ])\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'a.unused\\' PropType is defined but prop is never used' },\n        { message: '\\'a.anotherunused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"some.unused\": PropTypes.string\n        };\n      `,\n      errors: [\n        { message: '\\'some.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1][\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.arrayOf(\n            PropTypes.shape({\n              \"some.unused\": PropTypes.string\n        })\n          )\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'arr.*.some.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            unused: PropTypes.string\n          }\n          render() {\n            var text;\n            text = 'Hello ';\n            let {props: {firstname}} = this;\n            return <div>{text} {firstname}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            if (true) {\n              return <span>{this.props.firstname}</span>\n            } else {\n              return <span>{this.props.lastname}</span>\n            }\n          }\n        }\n        Hello.propTypes = {\n          unused: PropTypes.string\n        }\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        var Hello = function(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div>Hello {props.name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          const {name} = props;\n          return <div>Hello {name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        function Hello({ name }) {\n          return <div>Hello {name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const Hello = function({ name }) {\n          return <div>Hello {name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const Hello = ({ name }) => {\n          return <div>Hello {name}</div>;\n        }\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {unused: PropTypes.string}\n          render() {\n            var props = {firstname: 'John'};\n            return <div>Hello {props.firstname} {this.props.lastname}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {unused: PropTypes.string}\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source }\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {unused: PropTypes.string}\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source.uri }\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          var Hello = createReactClass({\n            propTypes: {unused: PropTypes.string},\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          let team = props.names.map((name) => {\n              return <li>{name}, {props.company}</li>;\n            });\n          return <ul>{team}</ul>;\n        };\n        Hello.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const Annotation = props => (\n          <div>\n            {props.text}\n          </div>\n        )\n        Annotation.prototype.propTypes = {unused: PropTypes.string};\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        for (var key in foo) {\n          var Hello = createReactClass({\n            propTypes: {unused: PropTypes.string},\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n        }\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        var propTypes = {\n          unused: PropTypes.string\n        };\n        class Test extends React.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = propTypes;\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      settings,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        /** @jsx Foo */\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        /** @jsx Foo */\n        /** @jsx React */\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        /**\n         * Copyright ....\n         * @jsx Foo\n         */\n        /** @jsx React */\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          unused: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            unused: string\n          };\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? [\n      {\n        code: `\n          class Hello extends React.Component {\n            props: {\n              unused: Object;\n            };\n            render () {\n              return <div>Hello {this.props.firstname}</div>;\n            }\n          }\n        `,\n        features: ['flow'],\n        errors: [\n          { message: '\\'unused\\' PropType is defined but prop is never used' },\n        ],\n      },\n    ] : [],\n    {\n      code: `\n        type Props = {unused: Object;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = $ReadOnly<{unused: Object;}>;\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type PropsA = { a: string }\n        type PropsB = { b: string }\n        type Props = PropsA & PropsB;\n\n        class MyComponent extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>{this.props.a}</div>\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        { message: '\\'b\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        { message: '\\'zap\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type PropsB = { foo: string };\n        type PropsC = { bar: string };\n        type Props = PropsB & {\n          zap: string\n        };\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      errors: [\n        { message: '\\'zap\\' PropType is defined but prop is never used' },\n      ],\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsB = { foo: string };\n        type PropsC = { bar: string };\n        type Props = {\n          zap: string\n        } & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      errors: [\n        { message: '\\'zap\\' PropType is defined but prop is never used' },\n      ],\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: {\n              unused: string;\n            }\n          };\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = {name: {unused: string;};};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {person: {name: {unused: string;};};};\n          render () {\n            return <div>Hello {this.props.person.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'person.name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = {person: {name: {unused: string;};};};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.person.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'person.name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {name: {unused: string;}};\n        class Hello extends React.Component {\n          props: {people: Person[];};\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.lastname);\n            }\n            return <div>Hello {names.join(', ')}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'people.*.name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {name: {unused: string;}};\n        type Props = {people: Person[];};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.lastname);\n            }\n            return <div>Hello {names.join(', ')}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'people.*.name.unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.notok}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'result.ok\\' PropType is defined but prop is never used' },\n        { message: '\\'result.ok\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        function Greetings({names}) {\n          names = names.map(({firstname, lastname}) => <div>{firstname} {lastname}</div>);\n          return <Hello>{names}</Hello>;\n        }\n        Greetings.propTypes = {unused: Object};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const MyComponent = props => (\n          <div onClick={() => props.toggle()}></div>\n        )\n        MyComponent.propTypes = {unused: Object};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const MyComponent = props => props.test ? <div /> : <span />\n        MyComponent.propTypes = {unused: Object};\n      `,\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {\n          unused: ?string,\n        };\n        function Hello({firstname, lastname}: Props): React$Element {\n          return <div>Hello {firstname} {lastname}</div>;\n        }\n      `,\n      features: ['types'],\n      errors: [{ message: '\\'unused\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          constructor (props) {\n            super(props);\n            const {something} = props;\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          constructor ({something}) {\n            super({something});\n            doSomething(something);\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentWillReceiveProps (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentWillReceiveProps ({something}, nextState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          shouldComponentUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          shouldComponentUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentWillUpdate ({something}, nextState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentDidUpdate (prevProps, prevState) {\n            const {something} = prevProps;\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            unused: PropTypes.bool\n          }\n          componentDidUpdate ({something}, prevState) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'unused' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          }\n          componentDidUpdate (prevProps, {state1, state2}) {\n            return something;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'something' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            something: PropTypes.bool\n          },\n          componentDidUpdate: function (prevProps, {state1, state2}) {\n            return something;\n          }\n        })\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'something' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentWillUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      // Multiple props used inside of an async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          classProperty = async () => {\n            await this.props.foo();\n            await this.props.bar();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'baz' },\n          line: 6,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          shouldComponentUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      // Multiple destructured props inside of async class property\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          classProperty = async () => {\n            const { bar, baz } = this.props;\n            await bar();\n            await baz();\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [{ message: '\\'foo\\' PropType is defined but prop is never used' }],\n    },\n    {\n      // Multiple props used inside of an async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          async method() {\n            await this.props.foo();\n            await this.props.baz();\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          shouldComponentUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string,\n          };\n\n          componentDidUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      // Multiple destructured props inside of async class method\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          async method() {\n            const { foo, bar } = this.props;\n            await foo();\n            await bar();\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'baz' },\n          line: 6,\n          column: 13,\n        },\n      ],\n    },\n    {\n      // factory functions that return async functions\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          factory() {\n            return async () => {\n              await this.props.foo();\n              await this.props.bar();\n            };\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'baz' },\n          line: 6,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentDidUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentDidUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        }\n        Hello.propTypes = forbidExtraProps({\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        class Hello extends Component {\n          propTypes = forbidExtraProps({\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          });\n          componentDidUpdate (nextProps) {\n            if (nextProps.foo) {\n              return true;\n            }\n          }\n        };\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      // factory functions that return async functions\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            foo: PropTypes.func,\n            bar: PropTypes.func,\n            baz: PropTypes.func,\n          }\n          factory() {\n            return async function onSubmit() {\n              await this.props.bar();\n              await this.props.baz();\n            };\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'foo' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      // Multiple props used inside of an async function\n      code: `\n        class Example extends Component {\n          render() {\n            async function onSubmit() {\n              await this.props.foo();\n              await this.props.bar();\n            }\n            return <Form onSubmit={onSubmit} />\n          };\n        }\n        Example.propTypes = {\n          foo: PropTypes.func,\n          bar: PropTypes.func,\n          baz: PropTypes.func,\n        }\n      `,\n      parserOptions: Object.assign({}, parserOptions, { ecmaVersion: 2017 }),\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'baz' },\n          line: 14,\n          column: 11,\n        },\n      ],\n    },\n    {\n      // Multiple props used inside of an async arrow function\n      code: `\n        class Example extends Component {\n          render() {\n            const onSubmit = async () => {\n              await this.props.bar();\n              await this.props.baz();\n            }\n            return <Form onSubmit={onSubmit} />\n          };\n        }\n        Example.propTypes = {\n          foo: PropTypes.func,\n          bar: PropTypes.func,\n          baz: PropTypes.func,\n        }\n      `,\n      parserOptions: Object.assign({}, parserOptions, { ecmaVersion: 2017 }),\n      errors: [\n        {\n          messageId: 'unusedPropType',\n          data: { name: 'foo' },\n          line: 12,\n          column: 11,\n        },\n      ],\n    },\n    {\n      // None of the props are used issue #1162\n      code: `\n        import React from \"react\";\n        var Hello = React.createReactClass({\n         propTypes: {\n           name: React.PropTypes.string\n         },\n         render: function() {\n           return <div>Hello Bob</div>;\n          }\n        });\n      `,\n      errors: [{ message: '\\'name\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        class Comp2 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp2.propTypes = {\n          prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n        };\n      `,\n      errors: [\n        { message: '\\'prop1\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2.*\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        class Comp2 extends Component {\n          static propTypes = {\n            prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n          }\n          render() {\n            return <span />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        { message: '\\'prop1\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2.*\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        var Comp2 = createReactClass({\n          propTypes: {\n            prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n          },\n          render() {\n            return <span />;\n          }\n        });\n      `,\n      errors: [\n        { message: '\\'prop1\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2\\' PropType is defined but prop is never used' },\n        { message: '\\'prop2.*\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      // issue #1097\n      code: `\n        class HelloGraphQL extends Component {\n          render() {\n              return <div>Hello</div>;\n          }\n        }\n        HelloGraphQL.propTypes = {\n          aProp: PropTypes.string.isRequired\n        }\n\n        const HellowQueries = graphql(queryDetails, {\n          options: ownProps => ({\n          variables: ownProps.aProp\n          }),\n        })(HelloGraphQL)\n\n        export default connect(mapStateToProps, mapDispatchToProps)(HellowQueries)\n      `,\n      errors: [{ message: '\\'aProp\\' PropType is defined but prop is never used' }],\n    },\n    {\n      // issue #2138\n      code: `\n        type UsedProps = {|\n          usedProp: number,\n        |};\n\n        type UnusedProps = {|\n          unusedProp: number,\n        |};\n\n        type Props = {| ...UsedProps, ...UnusedProps |};\n\n        function MyComponent({ usedProp, notOne }: Props) {\n          return <div>{usedProp}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          message: \"'unusedProp' PropType is defined but prop is never used\",\n          line: 7,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string,\n          lastname: string,\n        }\n        class MyComponent extends React.Component<void, Props, void> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string,\n          lastname: string,\n        }\n        class MyComponent extends React.Component<void, Props, void> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string,\n          lastname: string,\n        }\n        class MyComponent extends React.Component<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n        MyComponent.propTypes = {\n          firstname: PropTypes.string,\n          lastname: PropTypes.string,\n          foo: PropTypes.string,\n        };\n      `,\n      options: [{ ignore: ['foo'] }],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string,\n          lastname: string,\n          foo: string,\n        }\n        class MyComponent extends React.Component<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ ignore: ['foo'] }],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Person = string;\n        class Hello extends React.Component<{ person: Person }> {\n          render () {\n            return <div />;\n          }\n        }\n      `,\n      features: ['flow'],\n      settings: { react: { flowVersion: '0.53' } },\n      errors: [{ message: '\\'person\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Person = string;\n        class Hello extends React.Component<void, { person: Person }, void> {\n          render () {\n            return <div />;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [{ message: '\\'person\\' PropType is defined but prop is never used' }],\n      features: ['flow'],\n    },\n    (semver.satisfies(eslintPkg.version, '> 3') ? [\n      {\n        code: `\n          function higherOrderComponent<P: { foo: string }>() {\n            return class extends React.Component<P> {\n              render() {\n                return <div />;\n              }\n            }\n          }\n        `,\n        errors: [{ message: '\\'foo\\' PropType is defined but prop is never used' }],\n        features: ['flow'],\n      },\n    ] : []),\n    {\n      // issue #1506\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState(({ doSomething }, props) => {\n              return { doSomething: doSomething + 1 };\n            });\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n      `,\n      errors: [{ message: '\\'doSomething\\' PropType is defined but prop is never used' }],\n    },\n    {\n      // issue #1685\n      code: `\n        class MyComponent extends React.Component {\n          onFoo() {\n            this.setState(prevState => ({\n              doSomething: prevState.doSomething + 1,\n            }));\n          }\n          render() {\n            return (\n               <div onClick={this.onFoo}>Test</div>\n            );\n          }\n        }\n        MyComponent.propTypes = {\n          doSomething: PropTypes.func\n        };\n      `,\n      errors: [{ message: '\\'doSomething\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string,\n          lastname: string,\n        }\n        class MyComponent extends React.Component<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.53' } },\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n          UNSAFE_componentWillReceiveProps (nextProps) {\n            const {something} = nextProps;\n            doSomething(something);\n          }\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n      features: ['class fields'],\n      errors: [{ message: '\\'something\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n          UNSAFE_componentWillUpdate (nextProps, nextState) {\n            const {something} = nextProps;\n            return something;\n          }\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n      features: ['class fields'],\n      errors: [{ message: '\\'something\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            defaultValue: 'bar'\n          };\n          state = {\n            currentValue: null\n          };\n          static getDerivedStateFromProps(nextProps, prevState) {\n            if (prevState.currentValue === null) {\n              return {\n                currentValue: nextProps.defaultValue,\n              }\n            }\n            return null;\n          }\n          render() {\n            return <div>{ this.state.currentValue }</div>\n          }\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n      features: ['class fields'],\n      errors: [{ message: '\\'defaultValue\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            defaultValue: PropTypes.string\n          };\n          getSnapshotBeforeUpdate(prevProps, prevState) {\n            if (prevProps.defaultValue === null) {\n              return 'snapshot';\n            }\n            return null;\n          }\n          render() {\n            return <div />\n          }\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n      features: ['class fields'],\n      errors: [{ message: '\\'defaultValue\\' PropType is defined but prop is never used' }],\n    },\n    {\n      // Mixed union and intersection types\n      code: `\n        import React from 'react';\n        type OtherProps = {\n          firstname: string,\n          lastname: string,\n        } | {\n          fullname: string\n        };\n        type Props = OtherProps & {\n          age: number\n        };\n        class Test extends React.PureComponent<Props> {\n          render() {\n            return <div>Hello {this.props.firstname}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'age\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.shape({\n            })\n          })\n        };\n        Hello.propTypes.a.b.c = PropTypes.number;\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [\n        { message: '\\'a\\' PropType is defined but prop is never used' },\n        { message: '\\'a.b\\' PropType is defined but prop is never used' },\n        { message: '\\'a.b.c\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = { foo: string }\n        function higherOrderComponent<Props>() {\n          return class extends React.Component<Props> {\n            render() {\n              return <div />;\n            }\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'foo\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Person = {\n          ...data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Person = {|\n          ...data,\n          lastname: string\n        |};\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Person = {\n          ...$Exact<data>,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        import type {Data} from './Data'\n        type Person = {\n          ...Data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        import type {Data} from 'some-libdef-like-flow-typed-provides'\n        type Person = {\n          ...Data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          ...BasePerson,\n          lastname: PropTypes.string\n        };\n      `,\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        import type {BasePerson} from './types'\n        type Props = {\n          person: {\n           ...$Exact<BasePerson>,\n           lastname: string\n          }\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ skipShapeProps: false }],\n      errors: [{ message: '\\'person.lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        import BasePerson from './types'\n        class Hello extends React.Component {\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          person: ProTypes.shape({\n            ...BasePerson,\n            lastname: PropTypes.string\n          })\n        };\n      `,\n      options: [{ skipShapeProps: false }],\n      errors: [{ message: '\\'person.lastname\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        type Props = {notTarget: string, unused: string};\n        class Hello extends React.Component {\n          props: Props;\n          onEvent = ({ target }: { target: Object }) => {};\n          render () {\n            return <div>Hello {this.props.notTarget}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        const MyComponent= (props) => {\n          switch (props.usedProp) {\n            case 1:\n              return (<div />);\n            default:\n              return <div />;\n          }\n        };\n\n        MyComponent.propTypes = {\n          usedProp: PropTypes.string,\n          unUsedProp: PropTypes.string,\n        };\n\n        export default MyComponent;\n      `,\n      errors: [{ message: '\\'unUsedProp\\' PropType is defined but prop is never used' }],\n    },\n    {\n      code: `\n        const Foo = (props) => {\n          const { foo } = props as unknown;\n          (props as unknown).bar as unknown;\n\n          return <></>;\n        };\n\n        Foo.propTypes = {\n          fooUnused,\n          barUnused,\n        };\n      `,\n      features: ['ts', 'fragment', 'no-babel'],\n      errors: [\n        { message: '\\'fooUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'barUnused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static propTypes = {\n            prevPropUnused,\n            nextPropUnused,\n            setStatePropUnused,\n            thisPropsAliasDestructPropUnused,\n            thisPropsAliasPropUnused,\n            thisDestructPropsAliasDestructPropUnused,\n            thisDestructPropsAliasPropUnused,\n            thisDestructPropsDestructPropUnused,\n            thisPropsDestructPropUnused,\n            thisPropsPropUnused,\n          };\n\n          componentDidUpdate(prevProps) {\n            (prevProps as unknown).prevProp as unknown;\n          }\n\n          shouldComponentUpdate(nextProps) {\n            (nextProps as unknown).nextProp as unknown;\n          }\n\n          stateProps() {\n            ((this as unknown).setState as unknown)((_, props) => (props as unknown).setStateProp as unknown);\n          }\n\n          thisPropsAlias() {\n            const props = (this as unknown).props as unknown;\n\n            const { thisPropsAliasDestructProp } = props as unknown;\n            (props as unknown).thisPropsAliasProp as unknown;\n          }\n\n          thisDestructPropsAlias() {\n            const { props } = this as unknown;\n\n            const { thisDestructPropsAliasDestructProp } = props as unknown;\n            (props as unknown).thisDestructPropsAliasProp as unknown;\n          }\n\n          render() {\n            const { props: { thisDestructPropsDestructProp } } = this as unknown;\n            const { thisPropsDestructProp } = (this as unknown).props as unknown;\n            ((this as unknown).props as unknown).thisPropsProp as unknown;\n\n            return null;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'prevPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'nextPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'setStatePropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisPropsAliasDestructPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisPropsAliasPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisDestructPropsAliasDestructPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisDestructPropsAliasPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisDestructPropsDestructPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisPropsDestructPropUnused\\' PropType is defined but prop is never used' },\n        { message: '\\'thisPropsPropUnused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          lastname: string\n        };\n        const Hello = (props: Person) => {\n            return <div>Hello {props.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          lastname: string\n        };\n        const Hello = (props: Person) => {\n            return <div>Hello {props?.firstname}</div>;\n        }\n      `,\n      features: ['types', 'optional chaining'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          lastname: string\n        };\n        const Hello = (props: Person) => {\n            return <div>Hello {props?.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          lastname?: string\n        };\n        const Hello = (props: Person) => {\n            return <div>Hello {props.firstname}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          lastname?: string\n        };\n        const Hello = (props: Person) => {\n            return <div>Hello {props?.firstname}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n          lastname: string\n        };\n        const Hello = ({firstname}: Person) => {\n            return <div>Hello {firstname}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        interface Person {\n          firstname: string\n          lastname: string\n        };\n        const Hello = ({firstname}: Person) => {\n            return <div>Hello {firstname}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        interface Foo {\n          foo: string;\n          [blah: string]: number;\n        }\n        const Hello = ({bar}: Foo) => {\n            return <div>Hello {bar}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'foo\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        interface Props {\n          'aria-label': string;\n        }\n        export default function Component(props: Props): JSX.Element {\n          return <div />;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'aria-label\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        interface Props {\n        [1234]: string;\n        }\n        export default function Component(props: Props): JSX.Element {\n          return <div />;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'1234\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        const Hello = ({firstname}: {firstname: string, lastname: string}) => {\n            return <div>Hello {firstname}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'lastname\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n    // test same name of interface should be merge\n      code: `\n        interface Foo {\n          x: number;\n        }\n\n        interface Foo {\n          z: string;\n        }\n\n        interface Bar extends Foo {\n          y: string;\n        }\n\n        const Baz = ({ x, y }: Bar) => (\n          <span>\n              {x}\n              {y}\n          </span>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'z\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n    // test extends\n      code: `\n        interface Foo {\n          x: number;\n        }\n\n        interface Bar extends Foo {\n          y: string;\n        }\n\n        const Baz = ({ x }: Bar) => (\n          <span>\n              {x}\n          </span>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'y\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n    // test extends\n      code: `\n        interface Foo {\n          x: number;\n        }\n\n        interface Bar {\n          y: string;\n        }\n\n        interface Baz {\n          z:string;\n        }\n\n        const Baz = ({ x }: Bar & Foo & Baz) => (\n          <span>\n              {x}\n          </span>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'y\\' PropType is defined but prop is never used' },\n        { message: '\\'z\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n    // test same name merge and extends\n      code: `\n        interface Foo {\n          x: number;\n        }\n\n        interface Foo {\n          z: string;\n        }\n\n        interface Bar extends Foo {\n          y: string;\n        }\n\n        const Baz = ({ x }: Bar) => (\n          <span>\n              {x}\n          </span>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'z\\' PropType is defined but prop is never used' },\n        { message: '\\'y\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n    // test same name merge and extends\n      code: `\n        interface Foo {\n          x: number;\n        }\n\n        interface Foo {\n          z: string;\n        }\n\n        interface Foo {\n          y: string;\n        }\n\n        const Baz = ({ x }: Foo) => (\n          <span>\n              {x}\n          </span>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'z\\' PropType is defined but prop is never used' },\n        { message: '\\'y\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n\n        type UserProps = {\n          userId: string;\n        }\n\n        type AgeProps = {\n          age: number;\n        }\n\n        type BirthdayProps = {\n          birthday: string;\n        }\n\n        type intersectionUserProps = AgeProps & BirthdayProps;\n\n        type Props = User & UserProps & intersectionUserProps;\n\n        export default (props: Props) => {\n          const { userId, user } = props;\n\n          if (userId === 0) {\n            return <p>userId is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'age\\' PropType is defined but prop is never used' },\n        { message: '\\'birthday\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n          books: state.books\n        });\n\n        interface InfoLibTableProps extends ReturnType<typeof mapStateToProps> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'books\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n          books: state.books,\n        });\n\n        interface BooksTable extends ReturnType<typeof mapStateToProps> {\n          username: string;\n        }\n\n        const App = (props: BooksTable) => {\n          return <div />;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'books\\' PropType is defined but prop is never used' },\n        { message: '\\'username\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        interface BooksTable extends ReturnType<() => {books:Array<string>}> {\n          username: string;\n        }\n\n        const App = (props: BooksTable) => {\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'books\\' PropType is defined but prop is never used' },\n        { message: '\\'username\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type BooksTable = ReturnType<() => {books:Array<string>}> & {\n          username: string;\n        }\n\n        const App = (props: BooksTable) => {\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'books\\' PropType is defined but prop is never used' },\n        { message: '\\'username\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type mapStateToProps = ReturnType<() => {books:Array<string>}>;\n\n        type Props = {\n          username: string;\n        }\n\n        type BooksTable = mapStateToProps & Props;\n\n        const App = (props: BooksTable) => {\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'books\\' PropType is defined but prop is never used' },\n        { message: '\\'username\\' PropType is defined but prop is never used' },\n      ],\n    },\n    // Issue: #2795\n    {\n      code: `\n        type ConnectedProps = DispatchProps &\n          StateProps\n\n        const Component = ({ prop2, prop3 }: ConnectedProps) => {\n          // Do stuff\n          return (\n            <StyledComponent>...</StyledComponent>\n          )\n        }\n\n        const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({\n          ...bindActionCreators<{prop1: ()=>void,prop2: ()=>string}>(\n            { prop1: importedAction, prop2: anotherImportedAction },\n            dispatch,\n          ),\n        })\n\n        const mapStateToProps = (state: State) => ({\n          prop3: Selector.value(state),\n        })\n\n        type StateProps = ReturnType<typeof mapStateToProps>\n        type DispatchProps = ReturnType<typeof mapDispatchToProps>\n      `,\n      features: ['ts', 'no-ts-old', 'no-babel'], // TODO: FIXME: remove no-ts-old and no-babel and fix\n      errors: [{ message: '\\'prop1\\' PropType is defined but prop is never used' }],\n    },\n    // Issue: #296\n    {\n      code: `\n        function Foo(props) {\n          const { bar: { nope } } = props;\n          return <div test={nope} />;\n        }\n        Foo.propTypes = {\n          foo: PropTypes.number,\n          bar: PropTypes.shape({\n            faz: PropTypes.number,\n            qaz: PropTypes.object,\n          }),\n        };\n      `,\n      errors: [{ message: '\\'foo\\' PropType is defined but prop is never used' }],\n    },\n\n    {\n      code: `\n        interface Props {\n          readonly firstname: string;\n          readonly lastname: string;\n        }\n\n        class TestComponent extends React.Component<Props> {\n          public render() {\n            return <div>{this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [{ message: '\\'lastname\\' PropType is defined but prop is never used' }],\n    },\n\n    {\n      code: `\n        import React from \"react\";\n\n        var Hello = React.createClass({\n          propTypes: {\n            name: React.PropTypes.string,\n            foo: React.PropTypes.string,\n            propTypes: React.PropTypes.string\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      settings: {\n        react: {\n          createClass: 'createClass',\n        },\n      },\n      errors: [\n        { message: '\\'foo\\' PropType is defined but prop is never used' },\n        { message: '\\'propTypes\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        type props = {\n          foo: string;\n          bar: string;\n        };\n\n        const Demo: React.FC<props> = ({ foo }) => {\n          return <div {...{}}>{foo}</div>;\n        };\n\n        export default Demo;\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'bar\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          used: string;\n          unused: string;\n        };\n\n        const Demo = React.memo<Props>(\n          React.forwardRef<HTMLDivElement, Props>(\n            ({ used }, ref) => {\n              return <div>{used}</div>\n            }\n          )\n        );\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    },\n    {\n      code: `\n        const Demo = React.memo(\n          React.forwardRef(({ used }, ref) => {\n            return <div ref={ref}>{used}</div>\n          })\n        );\n        Demo.propTypes = {\n          used: PropTypes.string,\n          unused: PropTypes.string,\n        };\n      `,\n      errors: [\n        { message: '\\'unused\\' PropType is defined but prop is never used' },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-unused-state.js",
    "content": "/**\n * @fileoverview Tests for no-unused-state\n */\n\n'use strict';\n\nconst semver = require('semver');\nconst tsEslintVersion = require('@typescript-eslint/parser/package.json').version;\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-unused-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst eslintTester = new RuleTester({ parserOptions });\n\nfunction getErrorMessages(unusedFields) {\n  return unusedFields.map((field) => ({\n    messageId: 'unusedStateField',\n    data: { name: field },\n  }));\n}\n\neslintTester.run('no-unused-state', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        function StatelessFnUnaffectedTest(props) {\n          return <SomeComponent foo={props.foo} />;\n        };\n      `,\n    },\n    {\n      code: `\n        var NoStateTest = createReactClass({\n          render: function() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var NoStateMethodTest = createReactClass({\n          render() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var GetInitialStateTest = createReactClass({\n          getInitialState: function() {\n            return { foo: 0 };\n          },\n          render: function() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromVariableTest = createReactClass({\n          getInitialState: function() {\n            return { [foo]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromBooleanLiteralTest = createReactClass({\n          getInitialState: function() {\n            return { [true]: 0 };\n          },\n          render: function() {\n            return <SomeComponent foo={this.state[true]} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromNumberLiteralTest = createReactClass({\n          getInitialState: function() {\n            return { [123]: 0 };\n          },\n          render: function() {\n            return <SomeComponent foo={this.state[123]} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromExpressionTest = createReactClass({\n          getInitialState: function() {\n            return { [foo + bar]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromBinaryExpressionTest = createReactClass({\n          getInitialState: function() {\n            return { ['foo' + 'bar' * 8]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromStringLiteralTest = createReactClass({\n          getInitialState: function() {\n            return { ['foo']: 0 };\n          },\n          render: function() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromTemplateLiteralTest = createReactClass({\n          getInitialState: function() {\n            return { [\\`foo\\${bar}\\`]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var ComputedKeyFromTemplateLiteralTest = createReactClass({\n          getInitialState: function() {\n            return { [\\`foo\\`]: 0 };\n          },\n          render: function() {\n            return <SomeComponent foo={this.state['foo']} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var GetInitialStateMethodTest = createReactClass({\n          getInitialState() {\n            return { foo: 0 };\n          },\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var SetStateTest = createReactClass({\n          onFooChange(newFoo) {\n            this.setState({ foo: newFoo });\n          },\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var MultipleSetState = createReactClass({\n          getInitialState() {\n            return { foo: 0 };\n          },\n          update() {\n            this.setState({foo: 1});\n          },\n          render() {\n            return <SomeComponent onClick={this.update} foo={this.state.foo} />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class NoStateTest extends React.Component {\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class CtorStateTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromVariableTest extends React.Component {\n          constructor() {\n            this.state = { [foo]: 0 };\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromBooleanLiteralTest extends React.Component {\n          constructor() {\n            this.state = { [false]: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state['false']} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromNumberLiteralTest extends React.Component {\n          constructor() {\n            this.state = { [345]: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state[345]} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromExpressionTest extends React.Component {\n          constructor() {\n            this.state = { [foo + bar]: 0 };\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromBinaryExpressionTest extends React.Component {\n          constructor() {\n            this.state = { [1 + 2 * 8]: 0 };\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromStringLiteralTest extends React.Component {\n          constructor() {\n            this.state = { ['foo']: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromTemplateLiteralTest extends React.Component {\n          constructor() {\n            this.state = { [\\`foo\\${bar}\\`]: 0 };\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComputedKeyFromTemplateLiteralTest extends React.Component {\n          constructor() {\n            this.state = { [\\`foo\\`]: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class SetStateTest extends React.Component {\n          onFooChange(newFoo) {\n            this.setState({ foo: newFoo });\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ClassPropertyStateTest extends React.Component {\n          state = { foo: 0 };\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class OptionalChaining extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            return <SomeComponent foo={this.state?.foo} />;\n          }\n        }\n      `,\n      features: ['optional chaining'],\n    },\n    {\n      code: `\n        class VariableDeclarationTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            const foo = this.state.foo;\n            return <SomeComponent foo={foo} />;\n          }\n        }\n      `,\n    },\n    `\n      class DestructuringTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const {foo: myFoo} = this.state;\n          return <SomeComponent foo={myFoo} />;\n        }\n      }\n    `,\n    `\n      class ShorthandDestructuringTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const {foo} = this.state;\n          return <SomeComponent foo={foo} />;\n        }\n      }\n    `,\n    `\n      class AliasDeclarationTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const state = this.state;\n          return <SomeComponent foo={state.foo} />;\n        }\n      }\n    `,\n    `\n      class AliasAssignmentTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          let state;\n          state = this.state;\n          return <SomeComponent foo={state.foo} />;\n        }\n      }\n    `,\n    `\n      class DestructuringAliasTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const {state: myState} = this;\n          return <SomeComponent foo={myState.foo} />;\n        }\n      }\n    `,\n    `\n      class ShorthandDestructuringAliasTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const {state} = this;\n          return <SomeComponent foo={state.foo} />;\n        }\n      }\n    `,\n    `\n      class RestPropertyTest extends React.Component {\n        constructor() {\n          this.state = {\n            foo: 0,\n            bar: 1,\n          };\n        }\n        render() {\n          const {foo, ...others} = this.state;\n          return <SomeComponent foo={foo} bar={others.bar} />;\n        }\n      }\n    `,\n    {\n      code: `\n        class DeepDestructuringTest extends React.Component {\n          state = { foo: 0, bar: 0 };\n          render() {\n            const {state: {foo, ...others}} = this;\n            return <SomeComponent foo={foo} bar={others.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    // A cleverer analysis might recognize that the following should be errors,\n    // but they're out of scope for this lint rule.\n    `\n      class MethodArgFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        consumeFoo(foo) {}\n        render() {\n          this.consumeFoo(this.state.foo);\n          return <SomeComponent />;\n        }\n      }\n    `,\n    `\n      class AssignedToObjectFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const obj = { foo: this.state.foo, bar: 0 };\n          return <SomeComponent bar={obj.bar} />;\n        }\n      }\n    `,\n    `\n      class ComputedAccessFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0, bar: 1 };\n        }\n        render() {\n          const bar = 'bar';\n          return <SomeComponent bar={this.state[bar]} />;\n        }\n      }\n    `,\n    `\n      class JsxSpreadFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          return <SomeComponent {...this.state} />;\n        }\n      }\n    `,\n    `\n      class AliasedJsxSpreadFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const state = this.state;\n          return <SomeComponent {...state} />;\n        }\n      }\n    `,\n    `\n      class ObjectSpreadFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const attrs = { ...this.state, foo: 1 };\n          return <SomeComponent foo={attrs.foo} />;\n        }\n      }\n    `,\n    `\n      class ShadowingFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0 };\n        }\n        render() {\n          const state = this.state;\n          let foo;\n          {\n            const state = { foo: 5 };\n            foo = state.foo;\n          }\n          return <SomeComponent foo={foo} />;\n        }\n      }\n    `,\n    `\n      class NonRenderClassMethodFalseNegativeTest extends React.Component {\n        constructor() {\n          this.state = { foo: 0, bar: 0 };\n        }\n        doSomething() {\n          const { foo } = this.state;\n          return this.state.foo;\n        }\n        doSomethingElse() {\n          const { state: { bar }} = this;\n          return bar;\n        }\n        render() {\n          return <SomeComponent />;\n        }\n      }\n    `,\n    {\n      code: `\n        class TypeCastExpressionSpreadFalseNegativeTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            return <SomeComponent {...(this.state: any)} />;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        class ArrowFunctionClassMethodDestructuringFalseNegativeTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n\n          doSomething = () => {\n            const { state: { foo } } = this;\n\n            return foo;\n          }\n\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class ArrowFunctionClassMethodWithClassPropertyTransformFalseNegativeTest extends React.Component {\n          state = { foo: 0 };\n\n          doSomething = () => {\n            const { state:{ foo } } = this;\n\n            return foo;\n          }\n\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class ArrowFunctionClassMethodDeepDestructuringFalseNegativeTest extends React.Component {\n          state = { foo: { bar: 0 } };\n\n          doSomething = () => {\n            const { state: { foo: { bar }}} = this;\n\n            return bar;\n          }\n\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class ArrowFunctionClassMethodDestructuringAssignmentFalseNegativeTest extends React.Component {\n          state = { foo: 0 };\n\n          doSomething = () => {\n            const { state: { foo: bar }} = this;\n\n            return bar;\n          }\n\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class ThisStateAsAnObject extends React.Component {\n          state = {\n            active: true\n          };\n\n          render() {\n            return <div className={classNames('overflowEdgeIndicator', className, this.state)} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class GetDerivedStateFromPropsTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123,\n            };\n          }\n          static getDerivedStateFromProps(nextProps, otherState) {\n            if (otherState.id === nextProps.id) {\n              return {\n                selected: true,\n              };\n            }\n            return null;\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ComponentDidUpdateTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123,\n            };\n          }\n\n          componentDidUpdate(someProps, someState) {\n            if (someState.id === someProps.id) {\n              doStuff();\n            }\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class ShouldComponentUpdateTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123,\n            };\n          }\n          shouldComponentUpdate(nextProps, nextState) {\n            return nextState.id === nextProps.id;\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class NestedScopesTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123,\n            };\n          }\n          shouldComponentUpdate(nextProps, nextState) {\n            return (function() {\n              return nextState.id === nextProps.id;\n            })();\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends Component {\n          state = {\n            initial: 'foo',\n          }\n          handleChange = () => {\n            this.setState(state => ({\n              current: state.initial\n            }));\n          }\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Foo extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              initial: 'foo',\n            }\n          }\n          handleChange = () => {\n            this.setState(state => ({\n              current: state.initial\n            }));\n          }\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class Foo extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              initial: 'foo',\n            }\n          }\n          handleChange = () => {\n            this.setState((state, props) => ({\n              current: state.initial\n            }));\n          }\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          getInitialState: function() {\n            return { initial: 'foo' };\n          },\n          handleChange: function() {\n            this.setState(state => ({\n              current: state.initial\n            }));\n          },\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          getInitialState: function() {\n            return { initial: 'foo' };\n          },\n          handleChange: function() {\n            this.setState((state, props) => ({\n              current: state.initial\n            }));\n          },\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        });\n      `,\n      features: ['no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class SetStateDestructuringCallback extends Component {\n          state = {\n              used: 1, unused: 2\n          }\n          handleChange = () => {\n            this.setState(({unused}) => ({\n              used: unused * unused,\n            }));\n          }\n          render() {\n            return <div>{this.state.used}</div>\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      code: `\n        class SetStateCallbackStateCondition extends Component {\n          state = {\n              isUsed: true,\n              foo: 'foo'\n          }\n          handleChange = () => {\n            this.setState((prevState) => (prevState.isUsed ? {foo: 'bar', isUsed: false} : {}));\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove \"no-ts-old\"\n    },\n    {\n      // Don't error out\n      code: `\n        class Foo extends Component {\n          handleChange = function() {\n            this.setState(() => ({ foo: value }));\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Don't error out\n      code: `\n        class Foo extends Component {\n          handleChange = function() {\n            this.setState(state => ({ foo: value }));\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Don't error out\n      code: `\n        class Foo extends Component {\n          static handleChange = () => {\n            this.setState(state => ({ foo: value }));\n          }\n          render() {\n            return <SomeComponent foo={this.state.foo} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          state = {\n            thisStateAliasProp,\n            thisStateAliasRestProp,\n            thisDestructStateAliasProp,\n            thisDestructStateAliasRestProp,\n            thisDestructStateDestructRestProp,\n            thisSetStateProp,\n            thisSetStateRestProp,\n          } as unknown\n\n          constructor() {\n            // other methods of defining state props\n            ((this as unknown).state as unknown) = { thisStateProp } as unknown;\n            ((this as unknown).setState as unknown)({ thisStateDestructProp } as unknown);\n            ((this as unknown).setState as unknown)(state => ({ thisDestructStateDestructProp } as unknown));\n          }\n\n          thisStateAlias() {\n            const state = (this as unknown).state as unknown;\n\n            (state as unknown).thisStateAliasProp as unknown;\n            const { ...thisStateAliasRest } = state as unknown;\n            (thisStateAliasRest as unknown).thisStateAliasRestProp as unknown;\n          }\n\n          thisDestructStateAlias() {\n            const { state } = this as unknown;\n\n            (state as unknown).thisDestructStateAliasProp as unknown;\n            const { ...thisDestructStateAliasRest } = state as unknown;\n            (thisDestructStateAliasRest as unknown).thisDestructStateAliasRestProp as unknown;\n          }\n\n          thisSetState() {\n            ((this as unknown).setState as unknown)(state => (state as unknown).thisSetStateProp as unknown);\n            ((this as unknown).setState as unknown)(({ ...thisSetStateRest }) => (thisSetStateRest as unknown).thisSetStateRestProp as unknown);\n          }\n\n          render() {\n            ((this as unknown).state as unknown).thisStateProp as unknown;\n            const { thisStateDestructProp } = (this as unknown).state as unknown;\n            const { state: { thisDestructStateDestructProp, ...thisDestructStateDestructRest } } = this as unknown;\n            (thisDestructStateDestructRest as unknown).thisDestructStateDestructRestProp as unknown;\n\n            return null;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    semver.satisfies(tsEslintVersion, '>= 5') ? {\n      code: `\n        interface Props {}\n\n        interface State {\n          flag: boolean;\n        }\n\n        export default class RuleTest extends React.Component<Props, State> {\n          readonly state: State = {\n            flag: false,\n          };\n\n          static getDerivedStateFromProps = (props: Props, state: State) => {\n            const newState: Partial<State> = {};\n            if (!state.flag) {\n              newState.flag = true;\n            }\n            return newState;\n          };\n        }\n      `,\n      features: ['ts', 'no-babel-old', 'no-ts-old'],\n    } : [],\n    {\n      code: `\n        class Foo extends React.Component {\n          onCancel = (data) => {\n            console.log('Cancelled', data)\n            this.setState({ status: 'Cancelled. Try again?' })\n          }\n          render() {\n            const { status } = this.state;\n            return <div>{status}</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class KarmaRefundPillComponent extends GenericPillComponent {\n          renderContent = () => {\n            const { action } = this.props\n\n            return (\n              <Box fontSize={[1]} mx={[2]} minWidth=\"10px\" minHeight=\"26px\" alignItems=\"center\">\n                <FormattedText\n                  fields={getKarmaClaimLevel1Fields(action)}\n                  i18nKey=\"pillTemplates.karmarefund.summary\"\n                  fontSize={[1]}\n                />\n              </Box>\n            )\n          }\n        }\n      `,\n      features: ['ts'],\n    },\n    {\n      code: `\n        class AutoControlledComponent<P = {}, S = {}> extends UIComponent<P, S> {\n          static getDerivedStateFromProps: React.GetDerivedStateFromProps<any, any>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        export const commonMixinWrapper = ComposeComponent => class extends ComposeComponent {\n          static getDerivedStateFromProps = ComposeComponent.getDerivedStateFromProps;\n          render() { return <div />; }\n        }\n      `,\n      features: ['class fields'],\n      parserOptions: {\n        sourceType: 'module',\n      },\n    },\n    {\n      code: `\n        import React, { PureComponent } from 'react';\n\n        class TestNoUnusedState extends React.Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: null,\n            };\n          }\n\n          static getDerivedStateFromProps = (props, state) => {\n            if (state.id !== props.id) {\n              return {\n                id: props.id,\n              };\n            }\n\n            return null;\n          };\n\n          render() {\n            return <h1>{this.state.id}</h1>;\n          }\n        }\n\n        export default TestNoUnusedState;\n      `,\n      features: ['class fields'],\n      parserOptions: {\n        sourceType: 'module',\n      },\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static getDerivedStateFromProps = ({value, disableAnimation}: ToggleProps, {isControlled, isOn}: ToggleState) => {\n            return { isControlled, isOn };\n          };\n\n          render() {\n            const { isControlled, isOn } = this.state;\n            return <div>{isControlled ? 'controlled' : ''}{isOn ? 'on' : ''}</div>;\n          }\n        }\n      `,\n      features: ['types', 'class fields'],\n    }\n  )),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var UnusedGetInitialStateTest = createReactClass({\n          getInitialState: function() {\n            return { foo: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        var UnusedComputedStringLiteralKeyStateTest = createReactClass({\n          getInitialState: function() {\n            return { ['foo']: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        var UnusedComputedTemplateLiteralKeyStateTest = createReactClass({\n          getInitialState: function() {\n            return { [\\`foo\\`]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        var UnusedComputedNumberLiteralKeyStateTest = createReactClass({\n          getInitialState: function() {\n            return { [123]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['123']),\n    },\n    {\n      code: `\n        var UnusedComputedBooleanLiteralKeyStateTest = createReactClass({\n          getInitialState: function() {\n            return { [true]: 0 };\n          },\n          render: function() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['true']),\n    },\n    {\n      code: `\n        var UnusedGetInitialStateMethodTest = createReactClass({\n          getInitialState() {\n            return { foo: 0 };\n          },\n          render() {\n            return <SomeComponent />;\n          }\n        })\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        var UnusedSetStateTest = createReactClass({\n          onFooChange(newFoo) {\n            this.setState({ foo: newFoo });\n          },\n          render() {\n            return <SomeComponent />;\n          }\n        });\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class UnusedCtorStateTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class UnusedSetStateTest extends React.Component {\n          onFooChange(newFoo) {\n            this.setState({ foo: newFoo });\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class UnusedClassPropertyStateTest extends React.Component {\n          state = { foo: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedStringLiteralKeyStateTest extends React.Component {\n          state = { ['foo']: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {\n          state = { [\\`foo\\`]: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedTemplateLiteralKeyStateTest extends React.Component {\n          state = { [\\`foo \\\\n bar\\`]: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo \\\\n bar']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedBooleanLiteralKeyStateTest extends React.Component {\n          state = { [true]: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['true']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedNumberLiteralKeyStateTest extends React.Component {\n          state = { [123]: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['123']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedComputedFloatLiteralKeyStateTest extends React.Component {\n          state = { [123.12]: 0 };\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['123.12']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class UnusedStateWhenPropsAreSpreadTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            return <SomeComponent {...this.props} />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class AliasOutOfScopeTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          render() {\n            const state = this.state;\n            return <SomeComponent />;\n          }\n          someMethod() {\n            const outOfScope = state.foo;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class MultipleErrorsTest extends React.Component {\n          constructor() {\n            this.state = {\n              foo: 0,\n              bar: 1,\n              baz: 2,\n              qux: 3,\n            };\n          }\n          render() {\n            let {state} = this;\n            return <SomeComponent baz={state.baz} qux={state.qux} />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo', 'bar']),\n    },\n    {\n      code: `\n        class MultipleErrorsForSameKeyTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          onFooChange(newFoo) {\n            this.setState({ foo: newFoo });\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo', 'foo']),\n    },\n    {\n      code: `\n        class UnusedRestPropertyFieldTest extends React.Component {\n          constructor() {\n            this.state = {\n              foo: 0,\n              bar: 1,\n            };\n          }\n          render() {\n            const {bar, ...others} = this.state;\n            return <SomeComponent bar={bar} />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class UnusedStateArrowFunctionMethodTest extends React.Component {\n          constructor() {\n            this.state = { foo: 0 };\n          }\n          doSomething = () => {\n            return null;\n          }\n          render() {\n            return <SomeComponent />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class TypeCastExpressionTest extends React.Component {\n          constructor() {\n            this.state = {\n              foo: 0,\n              bar: 1,\n              baz: 2,\n              qux: 3,\n            };\n          }\n          render() {\n            const foo = ((this: any).state: any).foo;\n            const {bar, ...others} = (this.state: any);\n            let baz;\n            baz = (others: any)['baz'];\n            return <SomeComponent foo={foo} bar={bar} baz={baz} />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['qux']),\n      features: ['flow'],\n    },\n    {\n      code: `\n        class UnusedDeepDestructuringTest extends React.Component {\n          state = { foo: 0, bar: 0 };\n          render() {\n            const {state: {foo}} = this;\n            return <SomeComponent foo={foo} />;\n          }\n        }\n      `,\n      errors: getErrorMessages(['bar']),\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class FakePrevStateVariableTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123,\n              foo: 456\n            };\n          }\n\n          componentDidUpdate(someProps, someState) {\n            if (someState.id === someProps.id) {\n              const prevState = { foo: 789 };\n              console.log(prevState.foo);\n            }\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class UseStateParameterOfNonLifecycleTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              foo: 123,\n            };\n          }\n          nonLifecycle(someProps, someState) {\n            doStuff(someState.foo)\n          }\n          render() {\n            return (\n              <SomeComponent />\n            );\n          }\n        }\n      `,\n      errors: getErrorMessages(['foo']),\n    },\n    {\n      code: `\n        class MissingStateParameterTest extends Component {\n          constructor(props) {\n            super(props);\n            this.state = {\n              id: 123\n            };\n          }\n\n          componentDidUpdate(someProps) {\n            const prevState = { id: 456 };\n            console.log(prevState.id);\n          }\n          render() {\n            return (\n              <h1>{this.state.selected ? 'Selected' : 'Not selected'}</h1>\n            );\n          }\n        }\n      `,\n      errors: getErrorMessages(['id']),\n    },\n    {\n      code: `\n        class Foo extends Component {\n          state = {\n            initial: 'foo',\n          }\n          handleChange = () => {\n            this.setState(() => ({\n              current: 'hi'\n            }));\n          }\n          render() {\n            const { current } = this.state;\n            return <div>{current}</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: getErrorMessages(['initial']),\n    },\n    {\n      code: `\n        wrap(class NotWorking extends React.Component {\n            state = {\n                dummy: null\n            };\n        });\n      `,\n      features: ['class fields'],\n      errors: getErrorMessages(['dummy']),\n    },\n    {\n      code: `\n        class Foo extends Component {\n          state = {\n            thisStateAliasPropUnused,\n            thisStateAliasRestPropUnused,\n            thisDestructStateAliasPropUnused,\n            thisDestructStateAliasRestPropUnused,\n            thisDestructStateDestructRestPropUnused,\n            thisSetStatePropUnused,\n            thisSetStateRestPropUnused,\n          } as unknown\n\n          constructor() {\n            // other methods of defining state props\n            ((this as unknown).state as unknown) = { thisStatePropUnused } as unknown;\n            ((this as unknown).setState as unknown)({ thisStateDestructPropUnused } as unknown);\n            ((this as unknown).setState as unknown)(state => ({ thisDestructStateDestructPropUnused } as unknown));\n          }\n\n          thisStateAlias() {\n            const state = (this as unknown).state as unknown;\n\n            (state as unknown).thisStateAliasProp as unknown;\n            const { ...thisStateAliasRest } = state as unknown;\n            (thisStateAliasRest as unknown).thisStateAliasRestProp as unknown;\n          }\n\n          thisDestructStateAlias() {\n            const { state } = this as unknown;\n\n            (state as unknown).thisDestructStateAliasProp as unknown;\n            const { ...thisDestructStateAliasRest } = state as unknown;\n            (thisDestructStateAliasRest as unknown).thisDestructStateAliasRestProp as unknown;\n          }\n\n          thisSetState() {\n            ((this as unknown).setState as unknown)(state => (state as unknown).thisSetStateProp as unknown);\n            ((this as unknown).setState as unknown)(({ ...thisSetStateRest }) => (thisSetStateRest as unknown).thisSetStateRestProp as unknown);\n          }\n\n          render() {\n            ((this as unknown).state as unknown).thisStateProp as unknown;\n            const { thisStateDestructProp } = (this as unknown).state as unknown;\n            const { state: { thisDestructStateDestructProp, ...thisDestructStateDestructRest } } = this as unknown;\n            (thisDestructStateDestructRest as unknown).thisDestructStateDestructRestProp as unknown;\n\n            return null;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: getErrorMessages([\n        'thisStateAliasPropUnused',\n        'thisStateAliasRestPropUnused',\n        'thisDestructStateAliasPropUnused',\n        'thisDestructStateAliasRestPropUnused',\n        'thisDestructStateDestructRestPropUnused',\n        'thisSetStatePropUnused',\n        'thisSetStateRestPropUnused',\n        'thisStatePropUnused',\n        'thisStateDestructPropUnused',\n        'thisDestructStateDestructPropUnused',\n      ]),\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/no-will-update-set-state.js",
    "content": "/**\n * @fileoverview Prevent usage of setState in componentWillUpdate\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/no-will-update-set-state');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('no-will-update-set-state', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {}\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            someNonMemberFunction(arg);\n            this.someHandler = this.setState;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            someClass.onSomeEvent(function(data) {\n              this.setState({\n                data: data\n              });\n            })\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            function handleEvent(data) {\n              this.setState({\n                data: data\n              });\n            }\n            someClass.onSomeEvent(handleEvent)\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          UNSAFE_componentWillUpdate() {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      `,\n      settings: { react: { version: '16.2.0' } },\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            this.setState({\n              data: data\n            });\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            this.setState({\n              data: data\n            });\n          }\n        });\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            someClass.onSomeEvent(function(data) {\n              this.setState({\n                data: data\n              });\n            })\n          }\n        });\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            someClass.onSomeEvent(function(data) {\n              this.setState({\n                data: data\n              });\n            })\n          }\n        }\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            if (true) {\n              this.setState({\n                data: data\n              });\n            }\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            if (true) {\n              this.setState({\n                data: data\n              });\n            }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          componentWillUpdate: function() {\n            someClass.onSomeEvent((data) => this.setState({data: data}));\n          }\n        });\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          componentWillUpdate() {\n            someClass.onSomeEvent((data) => this.setState({data: data}));\n          }\n        }\n      `,\n      options: ['disallow-in-func'],\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          UNSAFE_componentWillUpdate() {\n            this.setState({\n              data: data\n            });\n          }\n        }\n      `,\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'UNSAFE_componentWillUpdate' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          UNSAFE_componentWillUpdate: function() {\n            this.setState({\n              data: data\n            });\n          }\n        });\n      `,\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'noSetState',\n          data: { name: 'UNSAFE_componentWillUpdate' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/prefer-es6-class.js",
    "content": "/**\n * @fileoverview Prefer es6 class instead of createClass for React Component\n * @author Dan Hamilton\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/prefer-es6-class');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('prefer-es6-class', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.displayName = 'Hello'\n      `,\n    },\n    {\n      code: `\n        export default class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.displayName = 'Hello'\n      `,\n    },\n    {\n      code: `\n        var Hello = \"foo\";\n        module.exports = {};\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: ['always'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'shouldUseES6Class' }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      options: ['always'],\n      errors: [{ messageId: 'shouldUseES6Class' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: ['never'],\n      errors: [{ messageId: 'shouldUseCreateClass' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/prefer-exact-props.js",
    "content": "/**\n * @fileoverview Prefer exact proptype definitions\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/prefer-exact-props');\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 8,\n  sourceType: 'module',\n  ecmaFeatures: {\n    experimentalObjectRestSpread: true,\n    jsx: true,\n  },\n};\n\nconst settings = {\n  propWrapperFunctions: [\n    { property: 'exact', exact: true },\n  ],\n};\n\nconst PROP_TYPES_MESSAGE = 'Component propTypes should be exact by using \\'exact\\'.';\nconst FLOW_MESSAGE = 'Component flow props should be set with exact objects.';\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('prefer-exact-props', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {};\n      `,\n      settings,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {};\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      settings,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          props: {};\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['types'],\n      settings,\n    },\n    {\n      code: `\n        function Component(props) {\n          return <div />;\n        }\n        Component.propTypes = {};\n      `,\n      settings,\n    },\n    {\n      code: `\n        function Component(props: {}) {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {|\n          foo: string\n        |}\n        function Component(props: Props) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {|\n          foo: string\n        |}\n        function Component(props: Props) {\n          let someVar: { foo: string };\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        function Component(props: {| foo : string |}) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {}\n        function Component(props: Props) {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type Props from 'foo';\n        function Component(props: Props) {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const props = {};\n        function Component(props) {\n          return <div />;\n        }\n        Component.propTypes = props;\n      `,\n      settings,\n    },\n    {\n      code: `\n        const props = {};\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = props;\n      `,\n      settings,\n    },\n    {\n      code: `\n        import props from 'foo';\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = props;\n      `,\n      settings,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          state = {hi: 'hi'}\n          render() {\n            return <div>{this.state.hi}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        import exact from \"prop-types-exact\";\n        function Component({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        Component.propTypes = exact({\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        });\n      `,\n      settings,\n    },\n    {\n      code: `\n        function Component({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        Component.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            const { foo, bar } = this.props;\n            return <div>{foo}{bar}</div>;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        import somethingElse from \"something-else\";\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.shape({\n            baz: PropTypes.string\n          })\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = somethingElse(props);\n      `,\n    },\n    {\n      code: `\n        import somethingElse from \"something-else\";\n        const props =\n        class Component extends React.Component {\n          static propTypes = somethingElse({\n            foo: PropTypes.string,\n            bar: PropTypes.shape({\n              baz: PropTypes.string\n            })\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.string\n        };\n      `,\n      settings,\n      errors: [{ message: PROP_TYPES_MESSAGE }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            foo: PropTypes.string\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      settings,\n      features: ['class fields'],\n      errors: [{ message: PROP_TYPES_MESSAGE }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          props: {\n            foo: string\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: FLOW_MESSAGE }],\n    },\n    {\n      code: `\n        function Component(props: { foo: string }) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: FLOW_MESSAGE }],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string\n        }\n        function Component(props: Props) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n      errors: [{ message: FLOW_MESSAGE }],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string\n        };\n        function Component(props) {\n          return <div />;\n        }\n        Component.propTypes = props;\n      `,\n      settings,\n      errors: [{ message: PROP_TYPES_MESSAGE }],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = props;\n      `,\n      settings,\n      errors: [{ message: PROP_TYPES_MESSAGE }],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = props;\n      `,\n      settings: {\n        propWrapperFunctions: [\n          { property: 'exact', exact: true },\n          { property: 'forbidExtraProps', exact: true },\n        ],\n      },\n      errors: [{ message: 'Component propTypes should be exact by using one of \\'exact\\', \\'forbidExtraProps\\'.' }],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.shape({\n            baz: PropTypes.string\n          })\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = props;\n      `,\n      settings: {\n        propWrapperFunctions: [\n          { property: 'exact', exact: true },\n          { property: 'forbidExtraProps', exact: true },\n        ],\n      },\n      errors: [{ message: 'Component propTypes should be exact by using one of \\'exact\\', \\'forbidExtraProps\\'.' }],\n    },\n    {\n      code: `\n        import somethingElse from \"something-else\";\n        function Component({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        Component.propTypes = somethingElse({\n          foo: PropTypes.string,\n          bar: PropTypes.string,\n        });\n      `,\n      settings,\n      errors: [{ message: 'Component propTypes should be exact by using \\'exact\\'.' }],\n    },\n    {\n      code: `\n        import somethingElse from \"something-else\";\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.shape({\n            baz: PropTypes.string\n          })\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = somethingElse(props);\n      `,\n      settings,\n      errors: [{ message: 'Component propTypes should be exact by using \\'exact\\'.' }],\n    },\n    {\n      code: `\n        import somethingElse from \"something-else\";\n        const props =\n        class Component extends React.Component {\n          static propTypes = somethingElse({\n            foo: PropTypes.string,\n            bar: PropTypes.shape({\n              baz: PropTypes.string\n            })\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      settings,\n      features: ['class fields'],\n      errors: [{ message: 'Component propTypes should be exact by using \\'exact\\'.' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/prefer-read-only-props.js",
    "content": "/**\n * @fileoverview Require component props to be typed as read-only.\n * @author Luke Zapart\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/prefer-read-only-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('prefer-read-only-props', rule, {\n  valid: parsers.all([\n    {\n      // Class component with type parameter\n      code: `\n        type Props = {\n          +name: string,\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      // Class component with typed props property\n      code: `\n        class Hello extends React.Component {\n          props: {\n            +name: string,\n          }\n\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      // Functional component with typed props argument\n      code: `\n        function Hello(props: {+name: string}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      // Functional component with type intersection\n      code: `\n        type PropsA = {+firstName: string};\n        type PropsB = {+lastName: string};\n        type Props = PropsA & PropsB;\n\n        function Hello({firstName, lastName}: Props) {\n          return <div>Hello {firstName} {lastName}</div>;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      // Arrow function\n      code: `\n        const Hello = (props: {+name: string}) => (\n          <div>Hello {props.name}</div>\n        );\n      `,\n      features: ['flow'],\n    },\n    {\n      // Destructured props\n      code: `\n        const Hello = ({name}: {+name: string}) => (\n          <div>Hello {props.name}</div>\n        );\n      `,\n      features: ['flow'],\n    },\n    {\n      // No error, because this is not a component\n      code: `\n        const notAComponent = (props: {n: number}) => {\n          return props.n + 1;\n        };\n      `,\n      features: ['flow'],\n    },\n    {\n      // No error, because there is no Props flow type\n      code: `\n        class Hello extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // No error, because PropTypes do not support variance\n      code: `\n        class Hello extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.string,\n        };\n      `,\n    },\n    {\n      // Class component with typed props argument\n      code: `\n        type Props = $ReadOnly<{\n          name: string,\n        }>\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      // Class component with typed props argument\n      code: `\n        type Props = $ReadOnly<{\n          +firstName: string,\n          lastName: string\n        }>\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.firstName} {this.props.lastName}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        interface Props {\n          readonly name: string;\n        }\n\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          readonly firstName: string;\n          readonly lastName: string;\n        }\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          readonly name: string;\n        }\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          readonly name: string[];\n        }\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          readonly name: string[];\n        }\n        const MyComponent: React.FC<Props> = async ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          readonly person: {\n            name: string;\n          }\n        }\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      // Props.name is not read-only\n      code: `\n        type Props = {\n          name: string,\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        type Props = {\n          +name: string,\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      // Props.name is contravariant\n      code: `\n        type Props = {\n          -name: string,\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        type Props = {\n          +name: string,\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: string,\n          }\n\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        class Hello extends React.Component {\n          props: {\n            +name: string,\n          }\n\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: {name: string}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      output: `\n        function Hello(props: {+name: string}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: {|name: string|}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      output: `\n        function Hello(props: {|+name: string|}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello({name}: {name: string}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      output: `\n        function Hello({name}: {+name: string}) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        type PropsA = {firstName: string};\n        type PropsB = {lastName: string};\n        type Props = PropsA & PropsB;\n\n        function Hello({firstName, lastName}: Props) {\n          return <div>Hello {firstName} {lastName}</div>;\n        }\n      `,\n      output: `\n        type PropsA = {+firstName: string};\n        type PropsB = {+lastName: string};\n        type Props = PropsA & PropsB;\n\n        function Hello({firstName, lastName}: Props) {\n          return <div>Hello {firstName} {lastName}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'firstName' },\n        },\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'lastName' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props: {-name: string}) => (\n          <div>Hello {props.name}</div>\n        );\n      `,\n      output: `\n        const Hello = (props: {+name: string}) => (\n          <div>Hello {props.name}</div>\n        );\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          name: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        type Props = {\n          readonly name: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel-old'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        interface Props {\n          name: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        interface Props {\n          readonly name: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel-old'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React from \"react\";\n        type Props = {\n          name: string[];\n        }\n        const MyComponent: React.FC<Props> = async ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      output: `\n        import React from \"react\";\n        type Props = {\n          readonly name: string[];\n        }\n        const MyComponent: React.FC<Props> = async ({ name }) => {\n          return <div>{name}</div>;\n        };\n        export default MyComponent;\n      `,\n      features: ['ts', 'no-babel-old'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          readonly firstName: string;\n          lastName: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      output: `\n        type Props = {\n          readonly firstName: string;\n          readonly lastName: string;\n        }\n\n        class Hello extends React.Component<Props> {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['ts', 'no-babel-old'],\n      errors: [\n        {\n          messageId: 'readOnlyProp',\n          data: { name: 'lastName' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/prefer-stateless-function.js",
    "content": "/**\n * @fileoverview Enforce stateless components to be written as a pure function\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/prefer-stateless-function');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('prefer-stateless-function', rule, {\n  valid: parsers.all([\n    {\n      // Already a stateless function\n      code: `\n        const Foo = function(props) {\n          return <div>{props.foo}</div>;\n        };\n      `,\n    },\n    {\n      // Already a stateless (arrow) function\n      code: 'const Foo = ({foo}) => <div>{foo}</div>;',\n    },\n    {\n      // Extends from PureComponent and uses props\n      code: `\n        class Foo extends React.PureComponent {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      // Extends from PureComponent and uses context\n      code: `\n        class Foo extends React.PureComponent {\n          render() {\n            return <div>{this.context.foo}</div>;\n          }\n        }\n      `,\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      // Extends from PureComponent in an expression context.\n      code: `\n        const Foo = class extends React.PureComponent {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        };\n      `,\n      parserOptions,\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      // Has a lifecycle method\n      code: `\n        class Foo extends React.Component {\n          shouldComponentUpdate() {\n            return false;\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Has a state\n      code: `\n        class Foo extends React.Component {\n          changeState() {\n            this.setState({foo: \"clicked\"});\n          }\n          render() {\n            return <div onClick={this.changeState.bind(this)}>{this.state.foo || \"bar\"}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Use refs\n      code: `\n        class Foo extends React.Component {\n          doStuff() {\n            this.refs.foo.style.backgroundColor = \"red\";\n          }\n          render() {\n            return <div ref=\"foo\" onClick={this.doStuff}>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Has an additional method\n      code: `\n        class Foo extends React.Component {\n          doStuff() {}\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Has an empty (no super) constructor\n      code: `\n        class Foo extends React.Component {\n          constructor() {}\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Has a constructor\n      code: `\n        class Foo extends React.Component {\n          constructor() {\n            doSpecialStuffs();\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Has a constructor (2)\n      code: `\n        class Foo extends React.Component {\n          constructor() {\n            foo;\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Issue 2187\n      code: `\n        class Foo extends React.Component {\n          constructor(props)\n\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['no-default', 'no-babel'],\n    },\n    {\n      // Use this.bar\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.bar}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Use this.bar (destructuring)\n      code: `\n        class Foo extends React.Component {\n          render() {\n            let {props:{foo}, bar} = this;\n            return <div>{foo}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Use this[bar]\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this[bar]}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Use this['bar']\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this['bar']}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // Can return null (ES6, React 0.14.0)\n      code: `\n        class Foo extends React.Component {\n          render() {\n            if (!this.props.foo) {\n              return null;\n            }\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      settings: { react: { version: '0.14.0' } },\n    },\n    {\n      // Can return null (ES5, React 0.14.0)\n      code: `\n        var Foo = createReactClass({\n          render: function() {\n            if (!this.props.foo) {\n              return null;\n            }\n            return <div>{this.props.foo}</div>;\n          }\n        });\n      `,\n      settings: { react: { version: '0.14.0' } },\n    },\n    {\n      // Can return null (shorthand if in return, React 0.14.0)\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return true ? <div /> : null;\n          }\n        }\n      `,\n      settings: { react: { version: '0.14.0' } },\n    },\n    {\n      code: `\n        export default (Component) => (\n          class Test extends React.Component {\n            componentDidMount() {}\n            render() {\n              return <Component />;\n            }\n          }\n        );\n      `,\n    },\n    {\n      // Has childContextTypes\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.props.children}</div>;\n          }\n        }\n        Foo.childContextTypes = {\n          color: PropTypes.string\n        };\n      `,\n    },\n    {\n      // Uses a decorator\n      code: `\n        @foo\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['decorators'],\n    },\n    {\n      // Uses a called decorator\n      code: `\n        @foo(\"bar\")\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['decorators'],\n    },\n    {\n      // Uses multiple decorators\n      code: `\n        @foo\n        @bar()\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['decorators'],\n    },\n    {\n      code: `\n        class Child extends PureComponent {\n          render() {\n            return <h1>I don't</h1>;\n          }\n        }\n      `,\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      code: `\n        import React, {PureComponent, PropTypes} from 'react'\n\n        export default function errorDecorator (options) {\n          return WrappedComponent => {\n            class Wrapper extends PureComponent {\n              static propTypes = {\n                error: PropTypes.string\n              }\n              render () {\n                const {error, ...props} = this.props\n                if (error) {\n                  return <div>Error! {error}</div>\n                } else {\n                  return <WrappedComponent {...props} />\n                }\n              }\n            }\n            return Wrapper\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      code: `\n        import React, {PureComponent, PropTypes} from 'react'\n\n        export default function errorDecorator (options) {\n          return WrappedComponent =>\n            class Wrapper extends PureComponent {\n              static propTypes = {\n                error: PropTypes.string\n              }\n              render () {\n                const {error, ...props} = this.props\n                if (error) {\n                  return <div>Error! {error}</div>\n                } else {\n                  return <WrappedComponent {...props} />\n                }\n              }\n            }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      code: `\n        export default function errorDecorator (options) {\n          return WrappedComponent =>\n            class Wrapper extends React.PureComponent {\n              static propTypes = {\n                error: PropTypes.string\n              }\n              render () {\n                const {error, ...props} = this.props\n                if (error) {\n                  return <div>Error! {error}</div>\n                } else {\n                  return <WrappedComponent {...props} />\n                }\n              }\n            }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ ignorePureComponents: true }],\n    },\n    {\n      code: `\n        /**\n         * @param a.\n         */\n        function Comp() {\n          return <a></a>\n        }\n      `,\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      // Only use this.props\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>{this['props'].foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.PureComponent {\n          render() {\n            return <div>foo</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.PureComponent {\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static get displayName() {\n            return 'Foo';\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static displayName = 'Foo';\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static propTypes = {\n            name: PropTypes.string\n          };\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          props: {\n            name: string;\n          };\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor() {\n            super();\n          }\n          render() {\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            let {props:{foo}, context:{bar}} = this;\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            if (!this.props.foo) {\n              return null;\n            }\n            return <div>{this.props.foo}</div>;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        var Foo = createReactClass({\n          render: function() {\n            if (!this.props.foo) {\n              return null;\n            }\n            return <div>{this.props.foo}</div>;\n          }\n        });\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return true ? <div /> : null;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static defaultProps = {\n            foo: true\n          }\n          render() {\n            const { foo } = this.props;\n            return foo ? <div /> : null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static get defaultProps() {\n            return {\n              foo: true\n            };\n          }\n          render() {\n            const { foo } = this.props;\n            return foo ? <div /> : null;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            const { foo } = this.props;\n            return foo ? <div /> : null;\n          }\n        }\n        Foo.defaultProps = {\n          foo: true\n        };\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static contextTypes = {\n            foo: PropTypes.boolean\n          }\n          render() {\n            const { foo } = this.context;\n            return foo ? <div /> : null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static get contextTypes() {\n            return {\n              foo: PropTypes.boolean\n            };\n          }\n          render() {\n            const { foo } = this.context;\n            return foo ? <div /> : null;\n          }\n        }\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            const { foo } = this.context;\n            return foo ? <div /> : null;\n          }\n        }\n        Foo.contextTypes = {\n          foo: PropTypes.boolean\n        };\n      `,\n      errors: [{ messageId: 'componentShouldBePure' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/prop-types.js",
    "content": "/**\n * @fileoverview Prevent missing props validation in a React component definition\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json').version;\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    pragma: 'Foo',\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('prop-types', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello World</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello World {this.props.children}</div>;\n          }\n        });\n      `,\n      options: [{ ignore: ['children'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var props = this.props;\n            return <div>Hello World</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var propName = \"foo\";\n            return <div>Hello World {this.props[propName]}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: externalPropTypes.mySharedPropTypes,\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello World</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string\n        };\n        Hello.propTypes.lastname = PropTypes.string;\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            var user = {\n              name: this.props.name\n            };\n            return <div>Hello {user.name}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello {\n          render() {\n            return 'Hello' + this.props.name;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello {\n          method;\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var { firstname, ...other } = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var {firstname, lastname} = this.state, something = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            name: PropTypes.string\n          };\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          'firstname': PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            if (Object.prototype.hasOwnProperty.call(this.props, 'firstname')) {\n              return <div>Hello {this.props.firstname}</div>;\n            }\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          'firstname': PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {};\n        Hello.propTypes.a = PropTypes.shape({\n          b: PropTypes.string\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.shape({\n            })\n          })\n        };\n        Hello.propTypes.a.b.c = PropTypes.number;\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            this.props.a.__.d.length;\n            this.props.a.anything.e[2];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.objectOf(\n            PropTypes.shape({\n              c: PropTypes.number,\n              d: PropTypes.string,\n              e: PropTypes.array\n            })\n          )\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var i = 3;\n            this.props.a[2].c;\n            this.props.a[i].d.length;\n            this.props.a[i + 2].e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.arrayOf(\n            PropTypes.shape({\n              c: PropTypes.number,\n              d: PropTypes.string,\n              e: PropTypes.array\n            })\n          )\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.array,\n            PropTypes.string\n          ])\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.c;\n            this.props.a[2] === true;\n            this.props.a.e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.shape({\n              c: PropTypes.number,\n              e: PropTypes.array\n            }).isRequired,\n            PropTypes.arrayOf(\n              PropTypes.bool\n            )\n          ])\n        };\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div>{this.props.foo.baz}</div>;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.oneOfType([\n            PropTypes.shape({\n              bar: PropTypes.string\n            }),\n            PropTypes.shape({\n              baz: PropTypes.string\n            })\n          ])\n        };\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div>{this.props.foo.baz}</div>;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.oneOfType([\n            PropTypes.shape({\n              bar: PropTypes.string\n            }),\n            PropTypes.instanceOf(Baz)\n          ])\n        };\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div>{this.props.foo.baz}</div>;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.oneOf(['bar', 'baz'])\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.render;\n            this.props.a.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.instanceOf(Hello)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.arr;\n            this.props.arr[3];\n            this.props.arr.length;\n            this.props.arr.push(3);\n            this.props.bo;\n            this.props.bo.toString();\n            this.props.fu;\n            this.props.fu.bind(this);\n            this.props.numb;\n            this.props.numb.toFixed();\n            this.props.stri;\n            this.props.stri.length();\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          arr: PropTypes.array,\n          bo: PropTypes.bool.isRequired,\n          fu: PropTypes.func,\n          numb: PropTypes.number,\n          stri: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var {\n              propX,\n              \"aria-controls\": ariaControls,\n              ...props } = this.props;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"propX\": PropTypes.string,\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"some.value\": PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.array\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1][\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.arrayOf(\n            PropTypes.shape({\"some.value\": PropTypes.string})\n          )\n        };\n      `,\n    },\n    {\n      code: `\n        class ArrayLengthTest extends React.Component {\n          render() {\n            use(this.props.arr.length)\n            use(this.props.arr2.length)\n            return <div />\n          }\n        }\n\n        ArrayLengthTest.propTypes = {\n          arr: PropTypes.array,\n          arr2: PropTypes.arrayOf(PropTypes.number),\n        }`,\n    },\n    {\n      code: `\n        var TestComp1 = createReactClass({\n          propTypes: {\n            size: PropTypes.string\n          },\n          render: function() {\n            var foo = {\n              baz: 'bar'\n            };\n            var icons = foo[this.props.size].salut;\n            return <div>{icons}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>{this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      options: [{ ignore: ['name'] }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const {firstname, lastname} = this.props.name;\n            return <div>{firstname} {lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.shape({\n            firstname: PropTypes.string,\n            lastname: PropTypes.string\n          })\n        };\n      `,\n    },\n    {\n      code: `\n        const foo = {};\n        class Hello extends React.Component {\n          render() {\n            const {firstname, lastname} = this.props.name;\n            return <div>{firstname} {lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.shape(foo)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            let {firstname} = this;\n            return <div>{firstname}</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            router: PropTypes.func\n          },\n          render: function() {\n            var nextPath = this.props.router.getCurrentQuery().nextPath;\n            return <div>{nextPath}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            firstname: CustomValidator.string\n          },\n          render: function() {\n            return <div>{this.props.firstname}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: CustomValidator.shape({\n              inner: CustomValidator.map\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: PropTypes.shape({\n              inner: CustomValidator.string\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            outer: CustomValidator.shape({\n              inner: PropTypes.string\n            })\n          },\n          render: function() {\n            return <div>{this.props.outer.inner}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string\n          },\n          render: function() {\n            return <div>{this.props.name.get(\"test\")}</div>;\n          }\n        });\n      `,\n      options: [{ customValidators: ['CustomValidator'] }],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        class Comp2 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp2.propTypes = {\n          prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n        };\n      `,\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        class Comp2 extends Component {\n          static propTypes = {\n            prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n          }\n          render() {\n            return <span />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Comp1 extends Component {\n          render() {\n            return <span />;\n          }\n        }\n        Comp1.propTypes = {\n          prop1: PropTypes.number\n        };\n        var Comp2 = createReactClass({\n          propTypes: {\n            prop2: PropTypes.arrayOf(Comp1.propTypes.prop1)\n          },\n          render() {\n            return <span />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        const SomeComponent = createReactClass({\n          propTypes: SomeOtherComponent.propTypes\n        });\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {}\n          render() {\n            return <div>Hello World</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {}\n          render() {\n            var users = this.props.users.find(user => user.name === 'John');\n            return <div>Hello you {users.length}</div>;\n          }\n        }\n        Hello.propTypes = {\n          users: PropTypes.arrayOf(PropTypes.object)\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const {} = this.props;\n            return <div>Hello</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var foo = 'fullname';\n            var { [foo]: firstname } = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source.uri }\n          }\n          static propTypes = {\n            source: PropTypes.object\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: this.props.source.uri }\n          }\n          static propTypes = {\n            source: PropTypes.object\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Should not be detected as a component\n      code: `\n        HelloJohn.prototype.render = function() {\n          return React.createElement(Hello, {\n            name: this.props.firstname\n          });\n        };\n      `,\n    },\n    {\n      code: `\n        function HelloComponent() {\n          class Hello extends React.Component {\n            render() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n          Hello.propTypes = { name: PropTypes.string };\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n    },\n    {\n      code: `\n        function HelloComponent() {\n          var Hello = createReactClass({\n            propTypes: { name: PropTypes.string },\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n    },\n    {\n      code: `\n        class DynamicHello extends Component {\n          render() {\n            const {firstname} = this.props;\n            class Hello extends Component {\n              render() {\n                const {name} = this.props;\n                return <div>Hello {name}</div>;\n              }\n            }\n            Hello.propTypes = {\n              name: PropTypes.string\n            };\n            Hello = connectReduxForm({name: firstname})(Hello);\n            return <Hello />;\n          }\n        }\n        DynamicHello.propTypes = {\n          firstname: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          let team = props.names.map((name) => {\n              return <li>{name}, {props.company}</li>;\n            });\n          return <ul>{team}</ul>;\n        };\n        Hello.propTypes = {\n          names: PropTypes.array,\n          company: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        export default {\n          renderHello() {\n            let {name} = this.props;\n            return <div>{name}</div>;\n          }\n        };\n      `,\n    },\n    {\n      code: `\n        export default function FooBar(props) {\n          const bar = props.bar;\n          return (<div bar={bar}><div {...props}/></div>);\n        }\n        if (process.env.NODE_ENV !== 'production') {\n          FooBar.propTypes = {\n            bar: PropTypes.string\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            var {...other} = this.props;\n            return (\n              <div {...other} />\n            );\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        const statelessComponent = (props) => {\n          const subRender = () => {\n            return <span>{props.someProp}</span>;\n          };\n          return <div>{subRender()}</div>;\n        };\n        statelessComponent.propTypes = {\n          someProp: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        const statelessComponent = ({ someProp }) => {\n          const subRender = () => {\n            return <span>{someProp}</span>;\n          };\n          return <div>{subRender()}</div>;\n        };\n        statelessComponent.propTypes = {\n          someProp: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        const statelessComponent = function({ someProp }) {\n          const subRender = () => {\n            return <span>{someProp}</span>;\n          };\n          return <div>{subRender()}</div>;\n        };\n        statelessComponent.propTypes = {\n          someProp: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        function statelessComponent({ someProp }) {\n          const subRender = () => {\n            return <span>{someProp}</span>;\n          };\n          return <div>{subRender()}</div>;\n        };\n        statelessComponent.propTypes = {\n          someProp: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        function notAComponent({ something }) {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      code: `\n        const notAComponent = function({ something }) {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      code: `\n        const notAComponent = ({ something }) => {\n          return something + 1;\n        };\n      `,\n    },\n    {\n      // Validation is ignored on reassigned props object\n      code: `\n        const statelessComponent = (props) => {\n          let newProps = props;\n          return <span>{newProps.someProp}</span>;\n        }\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: string;\n          };\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: Object;\n          };\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {name: Object;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {'data-action': string};\n        function Button({ 'data-action': dataAction }: Props) {\n          return <div data-action={dataAction} />;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: {\n              firstname: string;\n            }\n          };\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {name: {firstname: string;};};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {name: {firstname: string; lastname: string;};};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        class Hello extends React.Component {\n          props: {people: Person[];};\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.firstname);\n            }\n            return <div>Hello {names.join(\n        )}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        type Props = {people: Person[];};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.firstname);\n            }\n            return <div>Hello {names.join(\n        )}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {name: {firstname: string;}};\n        type Props = {people: Person[]|Person;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            if (Array.isArray(this.props.people)) {\n              for (var i = 0; i < this.props.people.length; i++) {\n                names.push(this.props.people[i].name.firstname);\n              }\n            } else {\n              names.push(this.props.people.name.firstname);\n            }\n            return <div>Hello {names.join(\n        )}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {ok: string | boolean;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.ok}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {result: {ok: string | boolean;}|{ok: number | Array}};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {result?: {ok?: ?string | boolean;}|{ok?: ?number | Array}};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props = {a: 123};\n          render () {\n            return <div>Hello</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Ignore component validation if propTypes are composed using spread\n      code: `\n        class Hello extends React.Component {\n            render() {\n                return  <div>Hello {this.props.firstName} {this.props.lastName}</div>;\n            }\n        };\n        const otherPropTypes = {\n            lastName: PropTypes.string\n        };\n        Hello.propTypes = {\n            ...otherPropTypes,\n            firstName: PropTypes.string\n        };\n      `,\n    },\n    {\n      // Ignore destructured function arguments\n      code: `\n        class Hello extends React.Component {\n          render () {\n            return [\"string\"].map(({length}) => <div>{length}</div>);\n          }\n        }\n      `,\n    },\n    {\n      // Flow annotations on stateless components\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        function Hello(props: Props): React.Element {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        const Hello = function(props: Props): React.Element {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: string;\n          lastname: string;\n        };\n        const Hello = (props: Props): React.Element => {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          'completed?': boolean,\n        };\n        const Hello = (props: Props): React.Element => {\n          return <div>{props['completed?']}</div>;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {\n          name: string,\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            const {name} = this.props;\n            return name;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type PropsUnionA = {\n          a: string,\n          b?: void,\n        };\n        type PropsUnionB = {\n          a?: void,\n          b: string,\n        };\n        type Props = {\n          name: string,\n        } & (PropsUnionA | PropsUnionB);\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            const {name} = this.props;\n            return name;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type { FieldProps } from \"redux-form\"\n\n        type Props = {\n        label: string,\n          type: string,\n          options: Array<SelectOption>\n        } & FieldProps\n      `,\n      features: ['types'],\n    },\n    {\n      // Impossible intersection type\n      code: `\n        import React from 'react';\n        type Props = string & {\n          fullname: string\n        };\n        class Test extends React.PureComponent<Props> {\n          render() {\n            return <div>Hello {this.props.fullname}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        Card.propTypes = {\n          title: PropTypes.string.isRequired,\n          children: PropTypes.element.isRequired,\n          footer: PropTypes.node\n        }\n        function Card ({ title, children, footer }) {\n          return (\n            <div/>\n          )\n        }\n      `,\n    },\n    {\n      code: `\n        function JobList(props) {\n          props\n          .jobs\n          .forEach(() => {});\n          return <div></div>;\n        }\n        JobList.propTypes = {\n          jobs: PropTypes.array\n        };\n      `,\n    },\n    {\n      code: `\n        type Props = {\n          firstname: ?string,\n        };\n        function Hello({firstname}: Props): React$Element {\n          return <div>Hello {firstname}</div>;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        function Greetings() {\n          return <div>{({name}) => <Hello name={name} />}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        function Greetings() {\n          return <div>{function({name}) { return <Hello name={name} />; }}</div>\n        }\n      `,\n    },\n    {\n      // Should stop at the class when searching for a parent component\n      code: `\n        export default (ComposedComponent) => class Something extends SomeOtherComponent {\n          someMethod = ({width}) => {}\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Should stop at the decorator when searching for a parent component\n      code: `\n        @asyncConnect([{\n          promise: ({dispatch}) => {}\n        }])\n        class Something extends Component {}\n      `,\n      features: ['decorators'],\n    },\n    {\n      // Should not find any used props\n      code: `\n        function Hello(props) {\n          const {...rest} = props;\n          return <div>Hello</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        let Greetings = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        };\n        Greetings.propTypes = {\n          name: PropTypes.string\n        }\n      `,\n    },\n    {\n      code: `\n        let Greetings = {\n          Hello: class extends React.Component {\n            render () {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n        }\n        Greetings.Hello.propTypes = {\n          name: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        let Greetings = {};\n        Greetings.Hello = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        };\n        Greetings.Hello.propTypes = {\n          name: PropTypes.string\n        }\n      `,\n    },\n    {\n      code: `\n        function Hello({names}) {\n          return names.map((name) => {\n            return <div>{name}</div>;\n          });\n        }\n      `,\n    },\n    {\n      code: `\n        type Target = { target: EventTarget }\n        class MyComponent extends Component {\n          static propTypes = {\n            children: PropTypes.any,\n          }\n          handler({ target }: Target) {}\n          render() {\n            return <div>{this.props.children}</div>;\n          }\n        }\n      `,\n      features: ['class fields', 'types'],\n    },\n    {\n      code: `\n        class Hello extends Component {}\n        Hello.Foo = ({foo}) => (\n          <div>Hello {foo}</div>\n        )\n        Hello.Foo.propTypes = {\n          foo: PropTypes.node\n        }\n      `,\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>{this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ skipUndeclared: true }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>{this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ skipUndeclared: true }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            return <div>{this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ skipUndeclared: true }],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.object.isRequired\n          },\n          render: function() {\n            return <div>{this.props.name}</div>;\n          }\n        });\n      `,\n      options: [{ skipUndeclared: false }],\n    },\n    {\n      // Async generator functions can't be components.\n      code: `\n        var Hello = async function* (props) {\n          yield null;\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n    },\n    {\n      // Async generator functions can't be components.\n      code: `\n        async function* Hello(props) {\n          yield null;\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n    },\n    {\n      // Flow annotations with variance\n      code: `\n        type Props = {\n          +firstname: string;\n          -lastname: string;\n        };\n        function Hello(props: Props): React.Element {\n          const {firstname, lastname} = props;\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          async onSelect({ name }) {\n            return null;\n          }\n          render() {\n            return <Greeting onSelect={this.onSelect} />;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        export class Example extends Component {\n          static propTypes = {\n            onDelete: PropTypes.func.isRequired\n          }\n          handleDeleteConfirm = () => {\n            this.props.onDelete();\n          };\n          handleSubmit = async ({ certificate, key }) => {};\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        type Person = {\n          ...data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {|\n          ...data,\n          lastname: string\n        |};\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          ...$Exact<data>,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type { Data } from './Data'\n        type Person = {\n          ...Data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type { Data } from 'some-libdef-like-flow-typed-provides'\n        type Person = {\n          ...Data,\n          lastname: string\n        };\n        class Hello extends React.Component {\n          props: Person;\n          render () {\n            return <div>Hello {this.props.bar}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type { BasePerson } from './types'\n        type Props = {\n          person: {\n           ...$Exact<BasePerson>,\n           lastname: string\n          }\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type OtherProps = {\n          firstname: string,\n        };\n        type Props = {\n           ...OtherProps,\n           lastname: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type FooProps = {\n          ...any,\n          ...42,\n        }\n        function Foo(props: FooProps) {\n          return <p />;\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            const { firstname } = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            const { firstname } = this.props;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { name: { firstname: string; }; };\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { name: { firstname: string; }; };\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Note = { text: string, children?: Note[] };\n        type Props = {\n          notes: Note[];\n        };\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.notes[0].text}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, { person: Person }, void> {\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, { person: Person }, void> {\n          render () {\n            return <div>Hello {this.props.person.firstname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { result?: { ok?: ?string | boolean; } | { ok?: ?number | Array } };\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { result?: { ok?: ?string | boolean;} | { ok?: ?number | Array } };\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.result.ok}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<Props> {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<Props> {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<Props> {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.53' } },\n      features: ['flow'],\n    },\n    {\n      code: `\n        type FancyProps = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<FancyProps> {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type FancyProps = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<FancyProps> {\n          render() {\n            return <div>{this.props.foo}</div>\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.53' } },\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type { PropsA } from \"./myPropsA\";\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap}</div>\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type PropsA = { bar: string };\n        type PropsB = { zap: string };\n        type Props = PropsA & {\n          baz: string\n        };\n\n        class Bar extends React.Component {\n          props: Props & PropsB;\n\n          render() {\n            return <div>{this.props.bar} - {this.props.zap} - {this.props.baz}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type PropsA = { bar: string };\n        type PropsB = { zap: string };\n        type Props =  {\n          baz: string\n        } & PropsA;\n\n        class Bar extends React.Component {\n          props: Props & PropsB;\n\n          render() {\n            return <div>{this.props.bar} - {this.props.zap} - {this.props.baz}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { foo: string }\n        function higherOrderComponent<Props>() {\n          return class extends React.Component<Props> {\n            render() {\n              return <div>{this.props.foo}</div>\n            }\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        function higherOrderComponent<P: { foo: string }>() {\n          return class extends React.Component<P> {\n            render() {\n              return <div>{this.props.foo}</div>\n            }\n          }\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        const withOverlayState = <P: { foo: string }>(WrappedComponent: ComponentType<P>): ComponentType<P> => (\n          class extends React.Component<P> {\n            constructor(props) {\n              super(props);\n              this.state = { foo: props.foo };\n            }\n            render() {\n              return <div>Hello World</div>;\n            }\n          }\n        )\n      `,\n      features: ['flow'],\n    },\n\n    // issue #1288\n    `function Foo() {\n      const props = {};\n      props.bar = 'bar';\n      return <div {...props} />;\n    }`,\n    // issue #1288\n    `function Foo(props) {\n      props.bar = 'bar';\n      return <div {...props} />;\n    }`,\n    {\n      // issue #106\n      code: `\n      import React from 'react';\n      import SharedPropTypes from './SharedPropTypes';\n\n      export default class A extends React.Component {\n        render() {\n          return (\n            <span\n              a={this.props.a}\n              b={this.props.b}\n              c={this.props.c}>\n              {this.props.children}\n            </span>\n          );\n        }\n      }\n\n      A.propTypes = {\n        a: React.PropTypes.string,\n        ...SharedPropTypes // eslint-disable-line object-shorthand\n      };\n    `,\n      features: ['flow'],\n    },\n    {\n      code: `\n      // @flow\n      import * as React from 'react';\n\n      type Props = {};\n\n      const func = <OP: *>(arg) => arg;\n\n      const hoc = <OP>() => () => {\n        class Inner extends React.Component<Props & OP> {\n          render() {\n            return <div />;\n          }\n        }\n      };\n    `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        const Slider = props => (\n          <RcSlider {...props} />\n        );\n\n        Slider.propTypes = RcSlider.propTypes;\n      `,\n    },\n    {\n      code: `\n        const Slider = props => (\n          <RcSlider foo={props.bar} />\n        );\n\n        Slider.propTypes = RcSlider.propTypes;\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          bar() {\n            this.setState((state, props) => ({ current: props.current }));\n          }\n          render() {\n            return <div />;\n          }\n        }\n\n        Foo.propTypes = {\n          current: PropTypes.number.isRequired,\n        };\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          bar() {\n            this.setState((state, props) => {\n              function f(_, { aaaaaaa }) {}\n            });\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static getDerivedStateFromProps(props) {\n            const { foo } = props;\n            return {\n              foobar: foo\n            };\n          }\n\n          render() {\n            const { foobar } = this.state;\n            return <div>{foobar}</div>;\n          }\n        }\n\n        Foo.propTypes = {\n          foo: PropTypes.func.isRequired,\n        };\n      `,\n      settings: { react: { version: '16.3.0' } },\n    },\n    {\n      code: `\n        const HeaderBalance = React.memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n        HeaderBalance.propTypes = {\n          cryptoCurrency: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        import React, { memo } from 'react';\n        const HeaderBalance = memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n        HeaderBalance.propTypes = {\n          cryptoCurrency: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        import Foo, { memo } from 'foo';\n        const HeaderBalance = memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n        HeaderBalance.propTypes = {\n          cryptoCurrency: PropTypes.string\n        };\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: `\n        const Label = React.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n        Label.propTypes = {\n          text: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        const Label = Foo.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n        Label.propTypes = {\n          text: PropTypes.string,\n        };\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react';\n        const Label = forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n        Label.propTypes = {\n          text: PropTypes.string,\n        };\n      `,\n    },\n    {\n      code: `\n        import Foo, { forwardRef } from 'foo';\n        const Label = forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n        Label.propTypes = {\n          text: PropTypes.string,\n        };\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: `\n      class Foo extends React.Component {\n        propTypes = {\n          actions: PropTypes.object.isRequired,\n        };\n        componentWillReceiveProps (nextProps) {\n          this.props.actions.doSomething();\n        }\n\n        componentWillUnmount () {\n          this.props.actions.doSomething();\n        }\n\n        render() {\n          return <div>foo</div>;\n        }\n      }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          componentDidUpdate() { this.inputRef.focus(); }\n          render() {\n            return (\n              <div>\n                <input ref={(node) => { this.inputRef = node; }} />\n              </div>\n            )\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          componentDidUpdate(nextProps, nextState) {\n            const {\n                first_organization,\n                second_organization,\n            } = this.state;\n            return true;\n          }\n          render() {\n            return <div>hi</div>;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n      class Foo extends React.Component {\n        shouldComponentUpdate(nextProps) {\n          if (this.props.search !== nextProps.search) {\n            let query = nextProps.query;\n            let result = nextProps.list.filter(item => {\n              return (item.name.toLowerCase().includes(query.trim().toLowerCase()));\n            });\n\n            this.setState({ result });\n\n            return true;\n          }\n        }\n        render() {\n          return <div>foo</div>;\n        }\n      }\n      Foo.propTypes = {\n        search: PropTypes.object,\n        list: PropTypes.array,\n        query: PropTypes.string,\n      };\n      `,\n    },\n    {\n      code: `\n        export default class LazyLoader extends Component {\n          static propTypes = {\n            children: PropTypes.node,\n            load: PropTypes.any,\n          };\n          state = { mod: null };\n          shouldComponentUpdate(prevProps) {\n            assert(prevProps.load === this.props.load);\n            return true;\n          }\n          load() {\n            this.props.load(mod => {\n              this.setState({\n                mod: mod.default ? mod.default : mod\n              });\n            });\n          }\n          render() {\n            if (this.state.mod !== null) {\n              return this.props.children(this.state.mod);\n            }\n            this.load();\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        import React from 'react';\n        import PropTypes from 'prop-types';\n        import { connect } from 'react-redux';\n\n        class Foo extends React.Component {\n          render() {\n            return this.props.children;\n          }\n        }\n\n        Foo.propTypes = {\n          children: PropTypes.element.isRequired\n        };\n\n        export const Unconnected = Foo;\n        export default connect(Foo);\n      `,\n    },\n    {\n      code: `\n        const a = {};\n        function fn1() {}\n        const b = a::fn1();\n      `,\n      features: ['bind operator'],\n    },\n    {\n      // issue #2138\n      code: `\n        type UsedProps = {|\n          usedProp: number,\n        |};\n\n        type UnusedProps = {|\n          unusedProp: number,\n        |};\n\n        type Props = {| ...UsedProps, ...UnusedProps |};\n\n        function MyComponent({ usedProp }: Props) {\n          return <div>{usedProp}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          message: \"'notOne' is missing in props validation\",\n          line: 8,\n          column: 34,\n        },\n      ],\n    },\n    {\n      // issue #1259\n      code: `\n        const Hello = props => {\n          const { notInProp } = dict[props.foo];\n          return <div />\n        }\n\n        Hello.propTypes = {\n          foo: PropTypes.number,\n        }\n      `,\n    },\n    {\n      // issue #2298\n      code: `\n      type Props = {|\n        firstname?: string\n      |};\n\n      function Hello({ firstname = 'John' }: Props = {}) {\n        return <div>Hello {firstname}</div>\n      }\n      `,\n      features: ['flow'],\n    },\n    {\n      // issue #2326\n      code: `\n        for (const { result } of results) {}\n      `,\n    },\n    {\n      // issue #2330\n      code: `\n        type Props = {\n          user: {\n            [string]: string\n          }\n        };\n\n        export function Bar(props: Props) {\n          return (\n            <div>\n              {props.user}\n              {props.user.name}\n            </div>\n          );\n        }\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        const Label = React.memo(React.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n        Label.propTypes = {\n          text: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react';\n        const Label = memo(forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n        Label.propTypes = {\n          text: PropTypes.string\n        };\n      `,\n    },\n    {\n      code: `\n        import Foo, { memo, forwardRef } from 'foo';\n        const Label = memo(forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n        Label.propTypes = {\n          text: PropTypes.string\n        };\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n    },\n    {\n      code: `\n        const Foo = ({ length, ordering }) => (\n          length > 0 && (\n            <Paginator items={ordering} pageSize={10} />\n          )\n        );\n        Foo.propTypes = {\n          length: PropTypes.number,\n          ordering: PropTypes.array\n        };\n      `,\n    },\n    // shouldn't trigger this rule since functions stating with a lowercase\n    // letter are not considered components\n    `\n      function noAComponent(props) {\n        return <div>{props.text}</div>\n      }\n    `,\n    {\n      code: `\n      export default function() {}\n      `,\n    },\n    {\n      code: `\n        function Component(props) {\n          return 0,\n          <div>\n            Hello, { props.name }!\n          </div>\n        }\n\n        Component.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n    },\n    {\n      code: `\n      const SideMenu = styled(\n        ({ componentId }) => (\n          <S.Container>\n            <S.Head />\n            <UserInfo />\n            <Separator />\n            <MenuList componentId={componentId} />\n          </S.Container>\n        ),\n      );\n      SideMenu.propTypes = {\n        componentId: PropTypes.string.isRequired\n      }\n      `,\n      settings: {\n        componentWrapperFunctions: [{ property: 'styled' }],\n      },\n    },\n    {\n      code: `\n        interface Props {\n          'aria-label': string // 'undefined' PropType is defined but prop is never used eslint(react/no-unused-prop-types)\n          // 'undefined' PropType is defined but prop is never used eslint(react-redux/no-unused-prop-types)\n        }\n\n        export default function Component({\n          'aria-label': ariaLabel, // 'aria-label' is missing in props validation eslint(react/prop-types)\n        }: Props): JSX.Element {\n          return <div aria-label={ariaLabel} />\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface Props {\n          value?: string;\n        }\n\n        // without the | null, all ok, with it, it is broken\n        function Test ({ value }: Props): React.ReactElement<Props> | null {\n          if (!value) {\n            return null;\n          }\n\n          return <div>{value}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface Props {\n          value?: string;\n        }\n\n        // without the | null, all ok, with it, it is broken\n        function Test ({ value }: Props): React.ReactElement<Props> | null {\n          if (!value) {\n            return <div>{value}</div>;;\n          }\n\n          return null;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface Props {\n          value?: string;\n        }\n        const Hello = (props: Props) => {\n          if (props.value) {\n            return <div></div>;\n          }\n          return null;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    // shouldn't trigger this rule for 'render' since functions stating with a lowercase\n    // letter are not considered components\n    {\n      code: `\n      const MyComponent = (props) => {\n        const render = () => {\n          return <test>{props.hello}</test>;\n        }\n        return render();\n      };\n      MyComponent.propTypes = {\n        hello: PropTypes.string.isRequired,\n      };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface Props {\n          value?: string;\n        }\n\n        // without the | null, all ok, with it, it is broken\n        function Test ({ value }: Props): React.ReactElement<Props> | null {\n          if (!value) {\n            return null;\n          }\n          return <div>{value}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from 'react';\n\n        interface Props {\n          text: string;\n        }\n\n        export const Test: React.FC<Props> = (props: Props) => {\n          const createElement = (text: string) => {\n            return (\n              <div>\n                {text}\n              </div>\n            );\n          };\n\n          return <>{createElement(props.text)}</>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n          books: state.books\n        });\n\n        interface InfoLibTableProps extends ReturnType<typeof mapStateToProps> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          props.books();\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n          books: state.books\n        });\n\n        interface BooksTable extends ReturnType<typeof mapStateToProps> {\n          username: string;\n        }\n\n        const App = (props: BooksTable) => {\n          props.books();\n          return <div><span>{props.username}</span></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface infoLibTable {\n          removeCollection(): Array<string>;\n        }\n\n        interface InfoLibTableProps extends ReturnType<(dispatch: storeDispatch) => infoLibTable> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          props.removeCollection();\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface addTable {\n          createCollection: () => Array<string>\n        }\n\n        type infoLibTable = addTable & {\n          removeCollection: () => Array<string>\n        }\n\n        interface InfoLibTableProps extends ReturnType<(dispatch: storeDispatch) => infoLibTable> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          props.createCollection();\n          props.removeCollection();\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface InfoLibTableProps extends ReturnType<(dispatch: storeDispatch) => {\n          removeCollection:  () => Array<string>,\n        }> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          props.removeCollection();\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface addTable {\n          createCollection: () => Array<string>;\n        }\n\n        type infoLibTable = {\n          removeCollection: () => Array<string>,\n        };\n\n        interface InfoLibTableProps extends  ReturnType<\n        (dispatch: storeDispatch) => infoLibTable & addTable,\n        >{}\n\n        const App = (props: InfoLibTableProps) => {\n          props.createCollection();\n          props.removeCollection();\n          return <div></div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface addTable {\n          createCollection: () => Array<string>;\n        }\n\n        type infoLibTable = ReturnType<(dispatch: storeDispatch) => infoLibTable & addTable> & {\n          removeCollection: () => Array<string>,\n        };\n\n        interface InfoLibTableProps {}\n\n        const App = (props: infoLibTable) => {\n          props.createCollection();\n          props.removeCollection();\n          return <div></div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface InfoLibTableProps extends ReturnType<(dispatch: storeDispatch) => ({\n          removeCollection:  () => Array<string>,\n        })> {\n        }\n\n        const App = (props: InfoLibTableProps) => {\n          props.removeCollection();\n          return <div></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface ThingProps extends React.HTMLAttributes<HTMLDivElement> {\n          thing?: number\n        }\n\n        export const Thing = ({ thing = 1, style, ...props }: ThingProps) => {\n          return <div />;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface ThingProps {\n          thing?: number\n        }\n\n        export const Thing = ({ thing = 1, style, ...props }: ThingProps & React.HTMLAttributes<HTMLDivElement>) => {\n          return <div />;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n\n        type Props = User & UserProps;\n\n        export default (props: Props) => {\n          const { userId, user } = props;\n\n          if (userId === 0) {\n            return <p>userId is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        type User = {\n        }\n\n        type Props = User & UserProps;\n\n        export default (props: Props) => {\n          const { user } = props;\n\n          if (user === 0) {\n            return <p>user is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface GenericProps {\n          onClose: () => void\n        }\n\n        interface ImplementationProps extends GenericProps {\n          onClick: () => void\n        }\n\n        export const Implementation: FC<ImplementationProps> = (\n          {\n            onClick,\n            onClose,\n          }: ImplementationProps\n        ) => (<div />)\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface Props extends V2SocialLoginProps {\n          autoLoad: boolean;\n        }\n\n        export const DKFacebookButton = ({\n          autoLoad,\n          authAction,\n          errorHandler,\n          redirectUrl,\n          isSignup,\n        }: Props): JSX.Element | null => {\n          if (!APP_ID) {\n            rollbar.error('Missing Facebook OAuth App Id');\n            return null;\n          }\n\n          const fbButtonText = isSignup ? 'Sign up with Facebook' : 'Log in with Facebook';\n\n          const responseCallback = async ({\n            accessToken,\n            email = '',\n            name = '',\n          }: ReactFacebookLoginInfo) => {\n            const [firstName, lastName] = name.split(' ');\n\n            const requestData: DK.SocialLogin = {\n              accessToken,\n              email,\n              firstName,\n              lastName,\n              intercomUserId: intercomService.getVisitorId(),\n            };\n\n            try {\n              await authAction(requestData, redirectUrl);\n            } catch (err) {\n              errorHandler(err.message);\n            }\n          };\n\n          const FacebookIcon = () => (\n            <img\n              style={{ marginRight: '8px' }}\n              src={facebookIcon}\n              alt='Facebook Login'\n            />\n          );\n\n          return (\n            <FacebookLogin\n              cssClass='ant-btn dk-button dk-facebook-button dk-button--secondary ant-btn-primary ant-btn-lg'\n              autoLoad={autoLoad}\n              textButton={fbButtonText}\n              size='small'\n              icon={<FacebookIcon />}\n              appId={APP_ID}\n              fields='name,email'\n              callback={responseCallback}\n              data-testId='dk-facebook-button'\n            />\n          );\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        function Foo({ bar = \"\" }: { bar: string }): JSX.Element {\n          return <div>{bar}</div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    // Issue: #2795\n    {\n      code: `\n      type ConnectedProps = DispatchProps &\n        StateProps\n\n      const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n        // Do stuff\n        return (\n          <StyledComponent>...</StyledComponent>\n        )\n      }\n\n      const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({\n        ...bindActionCreators<{ prop1: ()=>void, prop2: ()=>string }>(\n          { prop1: importedAction, prop2: anotherImportedAction },\n          dispatch,\n        ),\n      })\n\n      const mapStateToProps = (state: State) => ({\n        prop3: Selector.value(state),\n      })\n\n      type StateProps = ReturnType<typeof mapStateToProps>\n      type DispatchProps = ReturnType<typeof mapDispatchToProps>`,\n      features: ['ts', 'no-babel'],\n    },\n    // Issue: #2795\n    {\n      code: `\n      type ConnectedProps = DispatchProps &\n        StateProps\n\n      const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n        // Do stuff\n        return (\n          <StyledComponent>...</StyledComponent>\n        )\n      }\n\n      const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) => ({\n        ...bindActionCreators<ActionCreatorsMapObject<Types.RootAction>>(\n          { prop1: importedAction, prop2: anotherImportedAction },\n          dispatch,\n        ),\n      })\n\n      const mapStateToProps = (state: State) => ({\n        prop3: Selector.value(state),\n      })\n\n      type StateProps = ReturnType<typeof mapStateToProps>\n      type DispatchProps = ReturnType<typeof mapDispatchToProps>`,\n      features: ['ts', 'no-babel'],\n    },\n    // Issue: #2795\n    {\n      code: `\n      type ConnectedProps = DispatchProps &\n        StateProps\n\n      const Component = ({ prop1, prop2, prop3 }: ConnectedProps) => {\n        // Do stuff\n        return (\n          <StyledComponent>...</StyledComponent>\n        )\n      }\n\n      const mapDispatchToProps = (dispatch: ThunkDispatch<State, null, Action>) =>\n        bindActionCreators<{ prop1: () => void, prop2: () => string }>(\n          { prop1: importedAction, prop2: anotherImportedAction },\n          dispatch,\n        )\n\n      const mapStateToProps = (state: State) => ({\n        prop3: Selector.value(state),\n      })\n\n      type StateProps = ReturnType<typeof mapStateToProps>\n      type DispatchProps = ReturnType<typeof mapDispatchToProps>`,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n      import React from 'react'\n\n      interface Meta {\n        touched: boolean,\n        error: string;\n      }\n\n      interface Props {\n        input: string,\n        meta: Meta,\n        cssClasses: object\n      }\n      const InputField = ({ input, meta: { touched, error }, cssClasses = {}, ...restProps }: Props) => {\n        restProps.className = cssClasses.base\n\n        if (cssClasses.custom) {\n          restProps.className += 'cssClasses.custom'\n        }\n        if (touched && error) {\n          restProps.className += 'cssClasses.error'\n        }\n\n        return(\n          <input\n            {...input}\n            {...restProps}\n          />\n        )\n      }\n      export default InputField`,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        type ComponentProps = {\n          name: string\n        }\n\n        class Factory {\n          getComponent() {\n            return function Component({ name }: ComponentProps) {\n              return <div>Hello {name}</div>\n            }\n          }\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        interface PersonProps {\n            username: string;\n        }\n        const Person: React.FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const Person: React.FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        interface PersonProps {\n            username: string;\n        }\n        const Person: React.FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: React.FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        const Person: React.FunctionComponent<{ username: string }> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        type PersonProps = {\n            username: string;\n        }\n        const Person: React.FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { FunctionComponent } from 'react';\n\n        type PersonProps = {\n            username: string;\n        }\n        const Person: FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { FC } from 'react';\n        type PersonProps = {\n            username: string;\n        }\n        const Person: FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import type { FC } from 'react';\n        type PersonProps = {\n            username: string;\n        }\n        const Person: FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { FC as X } from 'react';\n        interface PersonProps {\n            username: string;\n        }\n        const Person: X<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as X from 'react';\n        interface PersonProps {\n            username: string;\n        }\n        const Person: X.FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      // issue: https://github.com/jsx-eslint/eslint-plugin-react/issues/2786\n      code: `\n        import React from 'react';\n\n        interface Props {\n          item: any;\n        }\n\n        const SomeComponent: React.FC<Props> = ({ item }: Props) => {\n          return item ? <></> : <></>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const returnTypeProp = (someProp: any) => ({ someProp });\n\n        const SomeComponent: React.FunctionComponent<\n          ReturnType<typeof returnTypeProp>\n        > = ({ someProp }) => {\n          return <div>{someProp}</div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        export const EuiSuperSelectControl: <T extends string>(\n          props: EuiSuperSelectControlProps<T>\n        ) => ReturnType<FunctionComponent<EuiSuperSelectControlProps<T>>> = ({\n          ...rest\n        }) => {\n          return null;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        const MyComponent = (props: React.PropsWithChildren<{ username: string }>): React.ReactElement => {\n          return <>{props.children}{props.username}</>;\n        };\n\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        type Props<ValueType> = {\n          value: ValueType;\n          onClick: (value: ValueType) => void;\n        };\n\n        const Button = <T,>({ onClick, value }: Props<T>) => {\n          return <button type=\"button\" onClick={() => onClick(value)}>BUTTON</button>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React, { VoidFunctionComponent } from 'react'\n\n          interface Props {\n          age: number\n          }\n          const Hello: VoidFunctionComponent<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React from 'react'\n\n          interface Props {\n          age: number\n          }\n          const Hello: React.VoidFunctionComponent<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React from 'react'\n\n          export interface Props {\n          age: number\n          }\n          const Hello: React.VoidFunctionComponent<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React, { VFC } from 'react'\n\n          interface Props {\n          age: number\n          }\n          const Hello: VFC<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React from 'react'\n\n          interface Props {\n          age: number\n          }\n          const Hello: React.VFC<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n          import React from 'react'\n\n          export interface Props {\n          age: number\n          }\n          const Hello: React.VFC<Props> = function Hello(props) {\n          const { age } = props;\n\n          return <div>Hello {age}</div>;\n          }\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ForwardRefRenderFunction  as X } from 'react'\n\n        type IfooProps = { e: string };\n          const Foo: X<HTMLDivElement, IfooProps> = function Foo (props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ForwardRefRenderFunction  as X } from 'react'\n\n        export type IfooProps = { e: string };\n          const Foo: X<HTMLDivElement, IfooProps> = function Foo (props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ForwardRefRenderFunction } from 'react'\n\n        type IfooProps = { e: string };\n          const Foo: ForwardRefRenderFunction<HTMLDivElement, IfooProps> = function Foo (props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ForwardRefRenderFunction } from 'react'\n\n        type IfooProps = { e: string };\n          const Foo: ForwardRefRenderFunction<HTMLDivElement, IfooProps> = (props, ref) => {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        type IfooProps = { e: string };\n        const Foo= React.forwardRef<HTMLDivElement, IfooProps>((props, ref) => {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react'\n\n        type IfooProps = { e: string };\n        const Foo= forwardRef<HTMLDivElement, IfooProps>((props, ref) => {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n        type IfooProps = { e: string };\n        const Foo= React.forwardRef<HTMLDivElement, IfooProps>(function Foo(props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n        interface IfooProps { e: string }\n        const Foo= React.forwardRef<HTMLDivElement, IfooProps>(function Foo(props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react'\n        interface IfooProps { e: string }\n        const Foo= forwardRef<HTMLDivElement, IfooProps>(function Foo(props, ref) {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef as X } from 'react'\n\n        type IfooProps = { e: string };\n        const Foo= X<HTMLDivElement, IfooProps>((props, ref) => {\n          const { e } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        class Factory {\n          getRenderFunction() {\n            return function renderFunction({ name }) {\n              return <div>Hello {name}</div>\n            }\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Test extends React.Component {\n          static propTypes = {\n            value: PropTypes.string\n          };\n\n          render() {\n            return <span>{this.props.value}</span>;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n\n    // #2944\n    {\n      code: `\n        const styles = { width: 0 };\n\n        function Foo(props) {\n          const { styles: x } = props;\n          return (\n            <p>\n              {styles.width} {x._}\n            </p>\n          );\n        }\n\n        Foo.propTypes = {\n          styles: PropTypes.shape({\n            _: PropTypes.number,\n          }),\n        };\n      `,\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export type Props = { children: React.ReactNode; type: \"submit\" | \"button\" };\n\n        export const FancyButton = forwardRef<HTMLButtonElement, Props>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.type}>\n            {props.children}\n          </button>\n        ));\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export type X = { num: number };\n        export type Props = { children: React.ReactNode; type: \"submit\" | \"button\" } & X;\n\n        export const FancyButton = forwardRef<HTMLButtonElement, Props>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.type} num={props.num}>\n            {props.children}\n          </button>\n        ));\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export interface IProps {\n          children: React.ReactNode;\n          type: \"submit\" | \"button\"\n        }\n\n        export const FancyButton = forwardRef<HTMLButtonElement, IProps>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.type}>\n            {props.children}\n          </button>\n        ));\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export interface X {\n          num: number\n        }\n        export interface IProps extends X {\n          children: React.ReactNode;\n          type: \"submit\" | \"button\"\n        }\n\n        export const FancyButton = forwardRef<HTMLButtonElement, IProps>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.type} num={props.num}>\n            {props.children}\n          </button>\n        ));\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        type ButtonProps = ({\n            children: React.Node,\n        } | {\n            icon: React.Element,\n        }) & {\n            label: string,\n            disabled?: boolean\n        } & {};\n\n        const Button: React.FC<ButtonProps> = ({ children, icon, label, disabled }: ButtonProps) => {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React, { PropTypes } from 'react'\n\n        function Foo({ bar }) {\n          const { baz } = Foo;\n          return <div>{baz} {bar}</div>\n        }\n\n        Foo.propTypes = {\n          bar: PropTypes.string.isRequired,\n        };\n\n        Foo.baz = 'hi';\n      `,\n    },\n\n    {\n      code: `\n        type Props = {\n          'data-hover': string\n        }\n\n        function MyComponent({\n          'data-hover': dataHover\n        }: Props) {\n          return <span data-hover={dataHover} />\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React, { PropTypes } from 'react';\n\n        function MyComponent({ name }) {\n          const someParams = {\n            userName: name,\n            greeting: 'Hi there',\n          };\n\n          function getMessage({ userName, greeting }) {\n            return <span>\\`\\${greeting} \\${userName}\\`</span>;\n          }\n\n          return (\n            <div>\n              { getMessage(someParams) }\n            </div>\n          );\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired,\n        };\n\n        export default MyComponent;\n      `,\n    },\n    {\n      code: `\n        type Field = {\n            value: string,\n            error: string,\n        }\n\n        type Form = {\n            fields: {\n                [string]: Field,\n            },\n            formError: string,\n        }\n\n        type Props = {\n            bankDetails: Form,\n            onBankDetailsUpdate: any => void,\n        }\n\n        const Provider = (props:Props) =>\n                    <Input\n                        label={'Account Name'}\n                        value={props.bankDetails.fields.accountName.value}\n                        error={props.bankDetails.fields.accountName.error}\n                        onChange={newVal => props.onBankDetailsUpdate({ accountName: newVal })}\n                    />\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        class App extends React.Component {\n          render() {\n            return (\n                <h1>Open the console</h1>\n            )\n          }\n        }\n\n        // does not work\n        App.propTypes = PropTypes.exact({\n          foo: PropTypes.object,\n        });\n      `,\n      settings: {\n        propWrapperFunctions: [\n          { object: 'PropTypes', property: 'exact', exact: true },\n        ],\n      },\n    },\n    {\n      code: `\n        class Test extends React.Component {\n          componentDidUpdate() {\n              const { bar } = this.state;\n              console.log(bar);\n          }\n\n          render() {\n              return null;\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        const DisplayName = (props) => {\n            const getNameDiv = () => {\n                return <div>{props.name}</div>;\n            };\n\n            return getNameDiv();\n        };\n\n        DisplayName.propTypes = {\n            name: PropTypes.string.isRequired,\n        };\n      `,\n    },\n    {\n      code: `\n        const SomeComponent = (props) => {\n          function renderComponent() {\n            return <div>{props.name}</div>\n          }\n\n          return renderComponent();\n        }\n\n        SomeComponent.propTypes = {\n          name: PropTypes.string\n        }\n      `,\n    },\n    {\n      code: `\n        import React from 'react';\n        import { MyType } from './types';\n\n        function Component(props: Props): JSX.Element | null {\n          const { array } = props;\n\n          function renderFound(): JSX.Element | null {\n            const found = array.find(x => x.id === id); // issue here\n\n            if (!found) {\n              return null;\n            }\n\n            return (\n              <div>{found.id}</div>\n            );\n          }\n\n          return renderFound();\n        }\n\n        interface Props {\n          array: MyType[];\n        }\n\n        export default Component;\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        export default React.memo(function AppIcon({\n          icon,\n          className,\n          title,\n          spinning,\n        }: {\n          icon: string | IconDefinition;\n          className?: string;\n          title?: string;\n          spinning?: boolean;\n        }) {\n          if (typeof icon === 'string') {\n            return (\n              <span\n                className={clsx(\n                  icon,\n                  'app-icon',\n                  'no-pointer-events',\n                  className,\n                  spinning ? 'fa-spin' : false\n                )}\n                title={title}\n              />\n            );\n          } else {\n            return (\n              <FontAwesomeIcon\n                className={className ? 'app-icon ' + className : 'app-icon'}\n                icon={icon}\n                title={title}\n                spin={spinning}\n              />\n            );\n          }\n        });\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        import { Link } from '..';\n\n        const LinkWrapper = ({ primaryLinks }) => (\n          <>\n            {primaryLinks.map((x, index) => (\n              <Link key={index} href={x.link}>\n                {x.text}\n              </Link>\n            ))}\n          </>\n        );\n\n        LinkWrapper.propTypes = {\n          primaryLinks: PropTypes.arrayOf(\n            PropTypes.shape({\n              text: PropTypes.string,\n            })\n          ),\n        };\n\n        export default LinkWrapper;\n      `,\n      features: ['fragment'],\n    },\n    {\n      code: `\n        const projectType = PropTypes.shape({\n          id: PropTypes.string.isRequired,\n          name: PropTypes.string.isRequired,\n        });\n\n        const nodesType = PropTypes.arrayOf(\n          PropTypes.shape({ project: projectType, children: nodesType }),\n        );\n\n        class ProjectNode extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n\n        ProjectNode.propTypes = {\n          project: projectType.isRequired,\n          nodes: nodesType,\n          depth: PropTypes.number.isRequired,\n          setActiveProject: PropTypes.func.isRequired,\n          activeProject: projectType,\n        };\n      `,\n    },\n    {\n      code: `\n        import React from 'react';\n\n        interface SomeType<ContextType = any> {\n          renderValue: (context: ContextType) => React.ReactNode;\n        }\n\n        interface DataObject {\n          id: string,\n          title: string,\n          value: string,\n        }\n\n        const someType: SomeType<DataObject> = {\n          renderValue: ({ title }) => <div>{title}</div>,\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        <MyComponent\n          options={{\n            tabBarIcon: ({ color, size }) => (\n              <Icon name=\"dumbbell\" size={size} color={color} />\n            )\n          }}\n        />\n      `,\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react';\n        import { ControlProps, NamedProps } from './ext';\n\n        type ButtonProps = ControlProps & NamedProps & {\n          onClick?: (() => void) | undefined;\n          onMouseDown?: (() => void) | undefined;\n          onMouseUp?: (() => void) | undefined;\n          disabled?: boolean | undefined;\n          width?: number;\n          type?: 'submit' | 'reset' | 'button' | undefined;\n        };\n\n        const BaseButton = forwardRef<HTMLButtonElement, ButtonProps>((\n          {\n            name,\n            className,\n            onClick,\n            onMouseDown,\n            onMouseUp,\n            children,\n            disabled,\n            width,\n            type,\n          },\n          ref,\n        ): JSX.Element => {\n          return <span>{width}</span>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react';\n        import { ControlProps, NamedProps } from './ext';\n\n        interface ButtonProps extends NamedProps {\n          onClick?: (() => void) | undefined;\n          onMouseDown?: (() => void) | undefined;\n          onMouseUp?: (() => void) | undefined;\n          disabled?: boolean | undefined;\n          width?: number;\n          type?: 'submit' | 'reset' | 'button' | undefined;\n        };\n\n        const BaseButton = forwardRef<HTMLButtonElement, ButtonProps>((\n          {\n            name,\n            className,\n            onClick,\n            onMouseDown,\n            onMouseUp,\n            children,\n            disabled,\n            width,\n            type,\n          },\n          ref,\n        ): JSX.Element => {\n          return <span>{width}</span>;\n        });\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentPropsWithoutRef, forwardRef } from 'react';\n\n        export const FancyButton = forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentPropsWithRef, forwardRef } from \"react\";\n\n        export const FancyButton = forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, forwardRef } from \"react\";\n\n        export const FancyButton = forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentPropsWithoutRef, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentPropsWithRef, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, ComponentPropsWithoutRef, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, ComponentPropsWithoutRef, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, ComponentPropsWithRef, ElementRef, forwardRef } from \"react\";\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import { ComponentProps, ComponentPropsWithRef, ElementRef, forwardRef } from 'react';\n\n        const BaseButton = forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import * as React from \"react\";\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<React.ElementRef<typeof BaseButton>, React.ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, {ComponentPropsWithoutRef } from 'react';\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentPropsWithRef } from 'react';\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps } from 'react';\n\n        export const FancyButton = React.forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ className, children, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n              {children}\n            </button>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentPropsWithoutRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentPropsWithRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps, ComponentPropsWithoutRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithoutRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps, ComponentPropsWithoutRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithoutRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps, ComponentPropsWithRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentPropsWithRef<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentProps<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ComponentProps, ComponentPropsWithRef, ElementRef } from 'react';\n\n        const BaseButton = React.forwardRef<HTMLButtonElement, ComponentProps<\"button\">>(\n          ({ children, className, ...props }, ref) => (\n            <button type=\"button\" ref={ref} className={className} {...props}>\n                {children}\n            </button>\n          ),\n        );\n\n        export const FancyButton = React.forwardRef<ElementRef<typeof BaseButton>, ComponentPropsWithRef<typeof BaseButton>>(\n          ({ children, className, ...props }, ref) => (\n            <BaseButton ref={ref} className={className} {...props}>\n              {children}\n            </BaseButton>\n          ),\n        );\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react';\n        import { IExt1 } from './ext';\n\n        interface IProps extends IExt1 {\n          onClick?: (() => void) | undefined;\n          onMouseDown?: (() => void) | undefined;\n          onMouseUp?: (() => void) | undefined;\n          disabled?: boolean | undefined;\n          width?: number;\n          type?: 'submit' | 'reset' | 'button' | undefined;\n        };\n\n        const Button: React.FC<IProps> = ({\n          name,\n          className,\n          onClick,\n          onMouseDown,\n          onMouseUp,\n          children,\n          disabled,\n          width,\n          type,\n        }): JSX.Element => {\n          return <span>{width}</span>;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { memo } from 'react';\n        interface Props1 {\n            age: number;\n        }\n        const HelloTemp = memo(({ age }: Props1) => {\n            return <div>Hello {age}</div>;\n        });\n        export const Hello = HelloTemp\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React, { forwardRef, memo } from 'react';\n        interface Props1 {\n            age: number;\n        }\n        const HelloTemp = forwardRef(({ age }: Props1) => {\n            return <div>Hello {age}</div>;\n        });\n        export const Hello = memo(HelloTemp);\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React, { forwardRef, memo } from 'react';\n        interface Props1 {\n            age: number;\n        }\n        export const Hello = memo(\n            forwardRef(({ age }: Props1) => {\n                return <div>Hello {age}</div>;\n            }),\n        );\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React from \"react\"\n\n        export function Heading({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n          return <div className={cn(\"font-semibold text-lg\", className)} {...props} />\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import React from 'react';\n        type TDelIconProps = React.HTMLProps<HTMLDivElement>;\n\n        const DelIcon: React.FC<TDelIconProps> = ({ className, ...rest }) => (\n            <div className={classNames('del flex-center', className)} {...rest}>\n                <i className=\"iconfont icon-del f12\" />\n            </div>\n        );\n      `,\n      features: ['types'],\n    }\n  )),\n\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        type Props = {\n          name: string,\n        };\n        class Hello extends React.Component {\n          foo(props: Props) {}\n          render() {\n            return this.props.name;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 8,\n          column: 31,\n          type: 'Identifier',\n        },\n      ],\n      features: ['types'],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return React.createElement(\"div\", {}, this.props.name);\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 62,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const { foo: { bar } } = this.props;\n            return <p>{bar}</p>\n          }\n        }\n      `,\n      errors: [\n        { message: \"'foo' is missing in props validation\" },\n        { message: \"'foo.bar' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const { foo: { bar } } = this.props;\n            return <p>{bar}</p>\n          }\n        }\n\n        Hello.propTypes = {\n          foo: PropTypes.shape({\n            _: PropTypes.string,\n          })\n        }\n      `,\n      errors: [\n        { message: \"'foo.bar' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        function Foo({ foo: { bar } }) {\n          return <p>{bar}</p>\n        }\n      `,\n      errors: [\n        { message: \"'foo' is missing in props validation\" },\n        { message: \"'foo.bar' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        function Foo({ a }) {\n          return <p>{ a.nope }</p>\n        }\n\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            _: PropType.string,\n          })\n        }\n      `,\n      errors: [\n        { message: \"'a.nope' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        function Foo({ a }) {\n          const { b } = a\n          return <p>{ b.nope }</p>\n        }\n\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            b: PropType.shape({\n              _: PropType.string,\n            }),\n          })\n        }\n      `,\n      errors: [\n        { message: \"'a.b.nope' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        function Foo(props) {\n          const { a } = props\n          return <p>{ a.nope }</p>\n        }\n\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            _: PropType.string,\n          })\n        }\n      `,\n      errors: [\n        { message: \"'a.nope' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        function Foo(props) {\n          const a = props.a\n          return <p>{ a.nope }</p>\n        }\n\n        Foo.propTypes = {\n          a: PropTypes.shape({\n            _: PropType.string,\n          })\n        }\n      `,\n      errors: [\n        { message: \"'a.nope' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          render() {\n            const props = this.props\n            return <div>{props.cat}</div>\n          }\n        }\n      `,\n      errors: [\n        { message: \"'cat' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        class Foo extends Component {\n          render() {\n            const { props } = this;\n            return <div>{props.cat}</div>;\n          }\n        }\n      `,\n      errors: [\n        { message: \"'cat' is missing in props validation\" },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const { name, ...rest } = this.props\n            return <div>Hello</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 21,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const { name, title, ...rest } = this.props\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.string\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'title' },\n          line: 4,\n          column: 27,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n           renderStuff() {\n            const { name, ...rest } = this.props\n            return (<div {...rest}>{name}</div>);\n          }\n          render() {\n            this.renderStuff()\n          }\n        }\n        Hello.propTypes = {};\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 21,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        /** @extends React.Component */\n        class Hello extends ChildComponent {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 5,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.firstname} {this.props.lastname}</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Hello.propTypes = {\n          name: PropTypes.string\n        };\n        class HelloBis extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {\n            name: PropTypes.string.isRequired\n          },\n          render: function() {\n            return <div>Hello {this.props.name} and {this.props.propWithoutTypeDefinition}</div>;\n          }\n        });\n        var Hello2 = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'propWithoutTypeDefinition' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var { firstname, lastname } = this.props;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          firstname: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n      code: `\n        class Hello extends React.Component {\n          static propTypes: {\n            firstname: PropTypes.string\n          };\n          render() {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    } : [],\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n          })\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({\n            b: PropTypes.shape({\n            })\n          })\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b.c' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.shape({})\n        };\n        Hello.propTypes.a.b = PropTypes.shape({});\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b.c' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.b.c;\n            this.props.a.__.d.length;\n            this.props.a.anything.e[2];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.objectOf(\n            PropTypes.shape({\n            })\n          )\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b.c' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.__.d' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.__.d.length' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.anything.e' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var i = 3;\n            this.props.a[2].c;\n            this.props.a[i].d.length;\n            this.props.a[i + 2].e[2];\n            this.props.a.length;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.arrayOf(\n            PropTypes.shape({\n            })\n          )\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a[].c' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a[].d' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a[].d.length' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a[].e' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props.a.length;\n            this.props.a.b;\n            this.props.a.e.length;\n            this.props.a.e.anyProp;\n            this.props.a.c.toString();\n            this.props.a.c.someThingElse();\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          a: PropTypes.oneOfType([\n            PropTypes.shape({\n              c: PropTypes.number,\n              e: PropTypes.array\n            })\n          ])\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.length' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var {\n              \"aria-controls\": ariaControls,\n              propX,\n              ...props } = this.props;\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'propX' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'some.value' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'arr' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            this.props[\"arr\"][1][\"some.value\"];\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"arr\": PropTypes.arrayOf(\n            PropTypes.shape({})\n          )\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'arr[].some.value' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var text;\n            text = 'Hello ';\n            let { props: { firstname } } = this;\n            return <div>{text} {firstname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var { 'props': { firstname } } = this;\n            return <div>Hello {firstname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            if (true) {\n              return <span>{this.props.firstname}</span>\n            } else {\n              return <span>{this.props.lastname}</span>\n            }\n          }\n        }\n        Hello.propTypes = {\n          lastname: PropTypes.string\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = function(props) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = (props) => {\n          const { name } = props;\n          return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello({ name }) {\n          return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = function({ name }) {\n          return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = ({ name }) => {\n          return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      features: ['no-default', 'no-ts', 'no-babel'], // TODO: remove this entire line, and fix the failures\n      code: `\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        };\n        const propTypes = forbidExtraProps({\n          firstname: PropTypes.string\n        });\n        Test.propTypes = propTypes;\n      `,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          firstname: PropTypes.string\n        };\n      `,\n      settings,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 5,\n        },\n      ],\n    },\n    {\n      code: `\n        type MyComponentProps = {\n          a: number,\n        };\n        function MyComponent({ a, b }: MyComponentProps) {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'b' },\n          line: 5,\n          column: 35,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            var props = { firstname: 'John' };\n            return <div>Hello {props.firstname} {this.props.lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: props.source.uri }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source.uri' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: this.props.source }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            this.state = { status: this.props.source.uri }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'source.uri' },\n        },\n      ],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          class Hello extends React.Component {\n            render() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function HelloComponent() {\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n          return Hello;\n        }\n        module.exports = HelloComponent();\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class DynamicHello extends Component {\n          render() {\n            const { firstname } = this.props;\n            class Hello extends Component {\n              render() {\n                const { name } = this.props;\n                return <div>Hello {name}</div>;\n              }\n            }\n            Hello = connectReduxForm({ name: firstname })(Hello);\n            return <Hello />;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          let team = props.names.map((name) => {\n              return <li>{name}, {props.company}</li>;\n            });\n          return <ul>{team}</ul>;\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'names' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'names.map' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'company' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Annotation = props => (\n          <div>\n            {props.text}\n          </div>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        for (var key in foo) {\n          var Hello = createReactClass({\n            render: function() {\n              return <div>Hello {this.props.name}</div>;\n            }\n          });\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        var propTypes = {\n          firstname: PropTypes.string\n        };\n        class Test extends React.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = propTypes;\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        var thePropsTypes = {a: PropTypes.string.isRequired};\n        var Foo = function (props) { return <div>{props.a}{props.b}</div>; };\n        Foo.propTypes = thePropsTypes;\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'b' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = forbidExtraProps({\n          firstname: PropTypes.string\n        });\n      `,\n      settings: Object.assign({}, settings, {\n        propWrapperFunctions: ['forbidExtraProps'],\n      }),\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = Object.freeze({\n          firstname: PropTypes.string\n        });\n      `,\n      settings: Object.assign({}, settings, {\n        propWrapperFunctions: ['Object.freeze'],\n      }),\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        /** @jsx Foo */\n        class Test extends Foo.Component {\n          render() {\n            return (\n              <div>{this.props.firstname} {this.props.lastname}</div>\n            );\n          }\n        }\n        Test.propTypes = {\n          firstname: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {};\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: Object;\n          };\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = { name: Object; };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            name: {\n              firstname: string;\n            }\n          };\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = { name: { firstname: string; }; };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: { person: { name: { firstname: string; }; }; };\n          render () {\n            return <div>Hello {this.props.person.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = { person: { name: { firstname: string; }; }; };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.person.name.lastname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Person = { name: { firstname: string; } };\n        class Hello extends React.Component {\n          props: { people: Person[]; };\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.lastname);\n            }\n            return <div>Hello {names.join(\n        )}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'people[].name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Person = { name: { firstname: string } };\n        type Props = { people: Person[] };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            var names = [];\n            for (var i = 0; i < this.props.people.length; i++) {\n              names.push(this.props.people[i].name.lastname);\n            }\n            return <div>Hello {names.join(\n        )}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'people[].name.lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = { result?: { ok: string | boolean; } | { ok: number | Array } };\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.result.notok}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'result.notok' },\n        },\n      ],\n    },\n    {\n      code: `\n        let Greetings = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Greetings.propTypes = {};\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        let Greetings = {\n          Hello: class extends React.Component {\n            render () {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n        }\n        Greetings.Hello.propTypes = {};\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        let Greetings = {};\n        Greetings.Hello = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n        Greetings.Hello.propTypes = {};\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Greetings({ names }) {\n          names = names.map(({ firstname, lastname }) => <div>{firstname} {lastname}</div>);\n          return <Hello>{names}</Hello>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'names' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'names.map' },\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = props => (\n          <div onClick={() => props.toggle()}></div>\n        )\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'toggle' },\n        },\n      ],\n    },\n    {\n      code: `\n        const MyComponent = props => props.test ? <div /> : <span />\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        const TestComponent = props =>\n          <div onClick={() => props.test()} />\n        const mapStateToProps = (_, props) => ({\n          otherProp: props.otherProp,\n        })\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          firstname: ?string,\n        };\n        function Hello({ firstname, lastname }: Props): React$Element {\n          return <div>Hello {firstname} {lastname}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          constructor(props, context) {\n            super(props, context)\n            const firstname = props.firstname;\n            const { lastname } = props;\n            this.state = {\n              firstname,\n              lastname\n            }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>{props.name.constructor.firstname}</div>\n        }\n        Hello.propTypes = {\n          name: PropTypes.shape({\n            firstname: PropTypes.object\n          })\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name.constructor.firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n      function Hello({ foo = '' }) {\n        return <p>{foo}</p>\n      }\n    `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        function SomeComponent({bar}) {\n          function f({foo}) {}\n          return <div className={f()}>{bar}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        function SomeComponent({bar} = baz) {\n          function f({foo}) {}\n          return <div className={f()}>{bar}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.PureComponent {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends PureComponent {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n          line: 4,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        type MyComponentProps = {\n          a: number,\n        };\n        function MyComponent({ a, b }: MyComponentProps) {\n          return <div />;\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'b' },\n          line: 5,\n          column: 35,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          propTypes: {},\n          render: function() {\n            return <div>{this.props.firstname}</div>;\n          }\n        });\n      `,\n      options: [{ skipUndeclared: true }],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n          line: 5,\n          column: 37,\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = function(props) {\n          return <div>{props.firstname}</div>;\n        };\n        Hello.propTypes = {}\n      `,\n      options: [{ skipUndeclared: true }],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n          line: 3,\n          column: 30,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {};\n          }\n          render() {\n            return <div>{this.props.firstname}</div>;\n          }\n        }\n      `,\n      options: [{ skipUndeclared: true }],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n          line: 7,\n          column: 37,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>{this.props.firstname}</div>;\n          }\n        }\n        Hello.propTypes = {};\n      `,\n      options: [{ skipUndeclared: true }],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n          line: 4,\n          column: 37,\n        },\n      ],\n    },\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            return <div>{this.props.firstname}</div>;\n          }\n        });\n      `,\n      options: [{ skipUndeclared: false }],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n          line: 4,\n          column: 37,\n        },\n      ],\n    },\n    {\n      code: `\n        type MyComponentProps = {\n          +a: number,\n        };\n        function MyComponent({ a, b }: MyComponentProps) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'b' },\n          line: 5,\n          column: 35,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        type MyComponentProps = {\n          -a: number,\n        };\n        function MyComponent({ a, b }: MyComponentProps) {\n          return <div />;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'b' },\n          line: 5,\n          column: 35,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {+name: Object;};\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.firstname}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'firstname' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          onSelect = async ({ name }) => {\n            return this.props.foo;\n          }\n          render() {\n            return <Greeting onSelect={this.onSelect} />;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = forbidExtraProps({\n            bar: PropTypes.func\n          })\n          componentWillReceiveProps(nextProps) {\n            if (nextProps.foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      settings: Object.assign({}, settings, {\n        propWrapperFunctions: ['forbidExtraProps'],\n      }),\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            bar: PropTypes.func\n          }\n          componentWillReceiveProps(nextProps) {\n            if (nextProps.foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            bar: PropTypes.func\n          }\n          componentWillReceiveProps(nextProps) {\n            const {foo} = nextProps;\n            if (foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = {\n            bar: PropTypes.func\n          }\n          componentWillReceiveProps({foo}) {\n            if (foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          componentWillReceiveProps({foo}) {\n            if (foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n        Hello.propTypes = {\n            bar: PropTypes.func\n          }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          static propTypes = forbidExtraProps({\n            bar: PropTypes.func\n          })\n          shouldComponentUpdate(nextProps) {\n            if (nextProps.foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      settings: Object.assign({}, settings, {\n        propWrapperFunctions: ['forbidExtraProps'],\n      }),\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends Component {\n          shouldComponentUpdate({foo}) {\n            if (foo) {\n              return;\n            }\n          }\n          render() {\n            return <div bar={this.props.bar} />;\n          }\n        }\n        Hello.propTypes = {\n            bar: PropTypes.func\n          }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            return <div>Hello {this.props.lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 7,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            return <div>Hello {this.props.lastname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 7,\n          column: 43,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            const {\n              lastname,\n            } = this.props;\n            return <div>Hello {lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 8,\n          column: 15,\n          type: 'Property',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, Person, void> {\n          render () {\n            const {\n              lastname,\n            } = this.props;\n            return <div>Hello {lastname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n          line: 8,\n          column: 15,\n          type: 'Property',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {name: {firstname: string;};};\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name.lastname' },\n          line: 5,\n          column: 48,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {name: {firstname: string;};};\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.name.lastname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name.lastname' },\n          line: 5,\n          column: 48,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.result.notok}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'result.notok' },\n          line: 5,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {result?: {ok: string | boolean;}|{ok: number | Array}};\n        class Hello extends React.Component<void, Props, void> {\n          render () {\n            return <div>Hello {this.props.result.notok}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'result.notok' },\n          line: 5,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, { person: Person }, void> {\n          render () {\n            return <div>Hello {this.props.person.lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.lastname' },\n          line: 7,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<void, { person: Person }, void> {\n          render () {\n            return <div>Hello {this.props.person.lastname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.52' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.lastname' },\n          line: 7,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<Props> {\n          render() {\n            return <div>{this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n          line: 8,\n          column: 37,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<Props> {\n          render() {\n            return <div>{this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      settings: { react: { flowVersion: '0.53' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n          line: 8,\n          column: 37,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        type FancyProps = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<FancyProps> {\n          render() {\n            return <div>{this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n          line: 8,\n          column: 37,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        type FancyProps = {\n          foo: string,\n        };\n\n        class Bar extends React.Component<FancyProps> {\n          render() {\n            return <div>{this.props.bar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      settings: { react: { flowVersion: '0.53' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n          line: 8,\n          column: 37,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<{ person: Person }> {\n          render () {\n            return <div>Hello {this.props.person.lastname}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.lastname' },\n          line: 7,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Person = {\n          firstname: string\n        };\n        class Hello extends React.Component<{ person: Person }> {\n          render () {\n            return <div>Hello {this.props.person.lastname}</div>;\n          }\n        }\n      `,\n      settings: { react: { flowVersion: '0.53' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'person.lastname' },\n          line: 7,\n          column: 50,\n          type: 'Identifier',\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type Props = { foo: string }\n        function higherOrderComponent<Props>() {\n          return class extends React.Component<Props> {\n            render() {\n              return <div>{this.props.foo} - {this.props.bar}</div>\n            }\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n      features: ['flow'],\n    },\n    (semver.satisfies(eslintPkg.version, '> 3') ? [\n      {\n        code: `\n          function higherOrderComponent<P: { foo: string }>() {\n            return class extends React.Component<P> {\n              render() {\n                return <div>{this.props.foo} - {this.props.bar}</div>\n              }\n            }\n          }\n        `,\n        errors: [\n          {\n            messageId: 'missingPropType',\n            data: { name: 'bar' },\n          },\n        ],\n        features: ['flow'],\n      },\n      {\n        code: `\n          const withOverlayState = <P: {foo: string}>(WrappedComponent: ComponentType<P>): ComponentType<P> => (\n            class extends React.Component<P> {\n              constructor(props) {\n                super(props);\n                this.state = {foo: props.foo, bar: props.bar}\n              }\n              render() {\n                return <div>Hello World</div>\n              }\n            }\n          )\n        `,\n        errors: [\n          {\n            messageId: 'missingPropType',\n            data: { name: 'bar' },\n          },\n        ],\n        features: ['flow'],\n      },\n    ] : []),\n    {\n      code: `\n        type PropsA = {foo: string };\n        type PropsB = { bar: string };\n        type Props = PropsA & PropsB;\n\n        class MyComponent extends React.Component {\n          props: Props;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.fooBar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'fooBar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type PropsA = { foo: string };\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsA & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.foo} - {this.props.bar} - {this.props.zap} - {this.props.fooBar}</div>\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'fooBar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = PropsB & {\n          baz: string\n        };\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.bar} - {this.props.baz} - {this.props.fooBar}</div>\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'fooBar' },\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        type PropsB = { bar: string };\n        type PropsC = { zap: string };\n        type Props = {\n          baz: string\n        } & PropsB;\n\n        class Bar extends React.Component {\n          props: Props & PropsC;\n\n          render() {\n            return <div>{this.props.bar} - {this.props.baz} - {this.props.fooBar}</div>\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'fooBar' },\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n      type ReduxState = {bar: number};\n\n      const mapStateToProps = (state: ReduxState) => ({\n          foo: state.bar,\n      });\n      // utility to extract the return type from a function\n      type ExtractReturn_<R, Fn: (...args: any[]) => R> = R;\n      type ExtractReturn<T> = ExtractReturn_<*, T>;\n\n      type PropsFromRedux = ExtractReturn<typeof mapStateToProps>;\n\n      type OwnProps = {\n          baz: string,\n      }\n\n      // I want my Props to be {baz: string, foo: number}\n      type Props = PropsFromRedux & OwnProps;\n\n      const Component = (props: Props) => (\n        <div>\n            {props.baz}\n            {props.bad}\n        </div>\n      );\n    `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bad' },\n        },\n      ],\n      features: ['flow'],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div>{this.props.foo.baz}</div>;\n          }\n        }\n        Component.propTypes = {\n          foo: PropTypes.oneOfType([\n            PropTypes.shape({\n              bar: PropTypes.string\n            })\n          ])\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo.baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          bar() {\n            this.setState((state, props) => ({ current: props.current, bar: props.bar }));\n          }\n          render() {\n            return <div />;\n          }\n        }\n\n        Foo.propTypes = {\n          current: PropTypes.number.isRequired,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          setZoo() {\n            this.setState((state, {zoo}) => ({ zoo }));\n          }\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'zoo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          static getDerivedStateFromProps(props) {\n            const { foo, bar } = props;\n            return {\n              foobar: foo + bar\n            };\n          }\n\n          render() {\n            const { foobar } = this.state;\n            return <div>{foobar}</div>;\n          }\n        }\n\n        Foo.propTypes = {\n          foo: PropTypes.func.isRequired,\n        };\n      `,\n      settings: { react: { version: '16.3.0' } },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        const ForAttendees = ({ page }) => (\n          <>\n            <section>{page}</section>\n          </>\n        );\n\n        export default ForAttendees;\n      `,\n      features: ['fragment'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'page' },\n        },\n      ],\n    },\n    {\n      code: `\n        const HeaderBalance = React.memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'cryptoCurrency' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, { memo } from 'react';\n        const HeaderBalance = memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'cryptoCurrency' },\n        },\n      ],\n    },\n    {\n      code: `\n        const HeaderBalance = Foo.memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'cryptoCurrency' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Foo, { memo } from 'foo';\n        const HeaderBalance = memo(({ cryptoCurrency }) => (\n          <div className=\"header-balance\">\n            <div className=\"header-balance__balance\">\n              BTC\n              {cryptoCurrency}\n            </div>\n          </div>\n        ));\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'cryptoCurrency' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Label = React.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react';\n        const Label = forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Label = Foo.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Foo, { forwardRef } from 'foo';\n        const Label = forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        });\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        const MyComponent = (props) => {\n          switch (props.usedProp) {\n            case 1:\n              return (<div />);\n            default:\n              return <div />;\n          }\n        };\n\n        export default MyComponent;\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'usedProp' },\n        },\n      ],\n    },\n    {\n      code: `\n        export default class Controller extends React.Component {\n          handleAdd = id => {\n            this.setState((state, { name }) => {\n                const item = this.buildItem(id);\n            });\n          };\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        export default class extends React.Component {\n          onSubmit = () => {\n            this.setState((state, { a }) => {\n              a.b.c();\n              return null;\n            });\n          };\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'a.b.c' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props);\n            this.initialValues = {\n              test: '',\n            };\n          }\n\n          render = () => {\n            return (\n              <Component\n                initialValues={this.props.initialValues || this.initialValues}\n              >\n                {formikProps => (\n                  <Input {...formikProps} />\n                )}\n              </Component>\n            );\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'initialValues' },\n        },\n      ],\n    },\n    {\n      // issue #2138\n      code: `\n        type UsedProps = {|\n          usedProp: number,\n        |};\n\n        type UnusedProps = {|\n          unusedProp: number,\n        |};\n\n        type Props = {| ...UsedProps, ...UnusedProps |};\n\n        function MyComponent({ usedProp, notOne }: Props) {\n          return <div>{usedProp}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          message: \"'notOne' is missing in props validation\",\n          line: 12,\n          column: 42,\n        },\n      ],\n    },\n    {\n      // issue #2298\n      code: `\n        type Props = {|\n          firstname?: string\n        |};\n\n        function Hello({ firstname = 'John', lastname = 'Doe' }: Props = {}) {\n          return <div>Hello {firstname} {lastname}</div>\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'lastname' },\n        },\n      ],\n    },\n    {\n      // issue #2330\n      code: `\n        type Props = {\n          user: {\n            name: {\n              firstname: string,\n              [string]: string\n            }\n          }\n        };\n\n        export function Bar(props: Props) {\n          return (\n            <div>\n              {props.user}\n              {props.user.name.firstname}\n              {props.user.name.lastname}\n              {props.user.age}\n            </div>\n          );\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'user.age' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Label = React.memo(React.forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, { memo, forwardRef } from 'react';\n        const Label = memo(forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        import Foo, { memo, forwardRef } from 'foo';\n        const Label = memo(forwardRef(({ text }, ref) => {\n          return <div ref={ref}>{text}</div>;\n        }));\n      `,\n      settings: {\n        react: {\n          pragma: 'Foo',\n        },\n      },\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'text' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo({\n          foo: {\n            bar: foo,\n            baz\n          },\n        }) {\n          return <p>{foo.reduce(() => 5)}</p>;\n        }\n\n        Foo.propTypes = {\n          foo: PropTypes.shape({\n            bar: PropTypes.arrayOf(PropTypes.string).isRequired,\n          }).isRequired,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo.baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = ({length, ordering}) => (\n          length > 0 && (\n            <Paginator items={ordering} pageSize={10} />\n          )\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'length' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'ordering' },\n        },\n      ],\n    },\n    {\n      code: `\n        const firstType = PropTypes.shape({\n          id: PropTypes.number,\n        });\n        class ComponentX extends React.Component {\n          static propTypes = {\n            first: firstType.isRequired,\n          };\n          render() {\n            return (\n              <div>\n                <div>Counter = {this.props.first.name}</div>\n              </div>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: \"'first.name' is missing in props validation\" }],\n    },\n    {\n      code: `\n        const firstType = PropTypes.shape({\n          id: PropTypes.number,\n        }).isRequired;\n        class ComponentX extends React.Component {\n          static propTypes = {\n            first: firstType,\n          };\n          render() {\n            return (\n              <div>\n                <div>Counter = {this.props.first.name}</div>\n              </div>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: \"'first.name' is missing in props validation\" }],\n    },\n    {\n      code: `\n        const firstType = PropTypes.shape({\n          id: PropTypes.number,\n        });\n        class ComponentX extends React.Component {\n          static propTypes = {\n            first: firstType,\n          };\n          render() {\n            return (\n              <div>\n                <div>Counter = {this.props.first.name}</div>\n              </div>\n            );\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ message: \"'first.name' is missing in props validation\" }],\n    },\n    {\n      code: `\n        function Foo({\n          foo: {\n            bar: foo,\n            baz\n          },\n        }) {\n          return <p>{foo.reduce(() => 5)}</p>;\n        }\n        const fooType = PropTypes.shape({\n          bar: PropTypes.arrayOf(PropTypes.string).isRequired,\n        }).isRequired\n        Foo.propTypes = {\n          foo: fooType,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo.baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo({\n          foo: {\n            bar: foo,\n            baz\n          },\n        }) {\n          return <p>{foo.reduce(() => 5)}</p>;\n        }\n        const fooType = PropTypes.shape({\n          bar: PropTypes.arrayOf(PropTypes.string).isRequired,\n        })\n        Foo.propTypes = {\n          foo: fooType.isRequired,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo.baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Foo({\n          foo: {\n            bar: foo,\n            baz\n          },\n        }) {\n          return <p>{foo.reduce(() => 5)}</p>;\n        }\n        const fooType = PropTypes.shape({\n          bar: PropTypes.arrayOf(PropTypes.string).isRequired,\n        })\n        Foo.propTypes = {\n          foo: fooType,\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo.baz' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Component(props) {\n          return 0,\n          <div>\n            Hello, { props.name }!\n          </div>\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n      const SideMenu = observer(\n        ({ componentId }) => (\n          <S.Container>\n            <S.Head />\n            <UserInfo />\n            <Separator />\n            <MenuList componentId={componentId} />\n          </S.Container>\n        ),\n      );`,\n      settings: {\n        componentWrapperFunctions: ['observer'],\n      },\n      errors: [{ message: '\\'componentId\\' is missing in props validation' }],\n    },\n    {\n      code: `\n      const SideMenu = Mobx.observer(\n        ({ id }) => (\n          <S.Container>\n            <S.Head />\n            <UserInfo />\n            <Separator />\n            <MenuList componentId={id} />\n          </S.Container>\n        ),\n      );\n      `,\n      settings: {\n        componentWrapperFunctions: [{ property: 'observer', object: 'Mobx' }],\n      },\n      errors: [{ message: '\\'id\\' is missing in props validation' }],\n    },\n    {\n      code: `\n        interface Props {\n        }\n        const Hello = (props: Props) => {\n          if (props.value) {\n            return <div></div>;\n          }\n          return null;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'value' },\n        },\n      ],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n\n        type Props = User & {\n        };\n\n        export default (props: Props) => {\n          const { userId, user } = props;\n\n          if (userId === 0) {\n            return <p>userId is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'userId' },\n        },\n      ],\n    },\n    {\n      code: `\n        type User = {\n        }\n\n        type Props = User & {\n          userId\n        };\n\n        export default (props: Props) => {\n          const { userId, user } = props;\n\n          if (userId === 0) {\n            return <p>userId is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'user' },\n        },\n      ],\n    },\n    {\n      code: `\n        type User = {\n          user: string;\n        }\n        type UserProps = {\n        }\n\n        type Props = User & UserProps;\n\n        export default (props: Props) => {\n          const { userId, user } = props;\n\n          if (userId === 0) {\n            return <p>userId is 0</p>;\n          }\n\n          return null;\n        };\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'userId' },\n        },\n      ],\n    },\n    {\n      code: `\n        interface GenericProps {\n          onClose: () => void\n        }\n\n        interface ImplementationProps extends GenericProps {\n        }\n\n        export const Implementation: FC<ImplementationProps> = (\n          {\n            onClick,\n            onClose,\n          }: ImplementationProps\n        ) => (<div />)\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'onClick' },\n        },\n      ],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n        });\n\n        interface BooksTable extends ReturnType<typeof mapStateToProps> {\n          username: string;\n        }\n\n        const App = (props: BooksTable) => {\n          props.books();\n          return <div><span>{props.username}</span></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'books' },\n        },\n      ],\n    },\n    {\n      code: `\n        const mapStateToProps = state => ({\n          books: state.books,\n        });\n\n        interface BooksTable extends ReturnType<typeof mapStateToProps> {\n        }\n\n        const App = (props: BooksTable) => {\n          props.books();\n          return <div><span>{props.username}</span></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'username' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Event = {\n            name: string;\n            type: string;\n        }\n\n        interface UserEvent extends Event {\n            UserId: string;\n        }\n        const App = (props: UserEvent) => {\n          props.name();\n          props.type;\n          props.UserId;\n          return <div><span>{props.dateCreated}</span></div>;\n        }\n      `,\n      features: ['ts', 'no-babel'],\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'dateCreated' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Zoo(props) {\n          return (\n            <>\n              {props.foo.c}\n            </>\n          );\n        }\n\n        Zoo.propTypes = {\n          foo: PropTypes.exact({\n            a: PropTypes.number,\n            b: PropTypes.number,\n          }),\n        };\n      `,\n      features: ['fragment'],\n      errors: [{ message: \"'foo.c' is missing in props validation\" }],\n    },\n    {\n      code: `\n        function Zoo(props) {\n          return (\n            <>\n              {props.foo.c}\n            </>\n          );\n        }\n\n        Zoo.propTypes = {\n          foo: React.PropTypes.exact({\n            a: PropTypes.number,\n            b: PropTypes.number,\n          }),\n        };\n      `,\n      features: ['fragment'],\n      errors: [{ message: \"'foo.c' is missing in props validation\" }],\n    },\n    {\n      code: `\n        function Zoo(props) {\n          return (\n            <>\n              {props.foo.c}\n            </>\n          );\n        }\n\n        Zoo.propTypes = {\n          foo: Foo.PropTypes.exact({\n            a: PropTypes.number,\n            b: PropTypes.number,\n          }),\n        };\n      `,\n      settings,\n      features: ['fragment'],\n      errors: [{ message: \"'foo.c' is missing in props validation\" }],\n    },\n    {\n      code: `\n        const Foo: JSX.Element = ({ bar }) => {\n          return <div>{bar}</div>;\n        }\n      `,\n      settings,\n      features: ['ts', 'no-babel'],\n      errors: [{ message: \"'bar' is missing in props validation\" }],\n    },\n    {\n      code: `\n        const Foo: JSX.Element = function foo ({ bar }) {\n          return <div>{bar}</div>;\n        }\n      `,\n      settings,\n      features: ['ts', 'no-babel'],\n      errors: [{ message: \"'bar' is missing in props validation\" }],\n    },\n    // fix #2804\n    {\n      code: `\n        import React from 'react'\n\n        const InputField = ({ type, ...restProps }) => {\n\n          return(\n            <input\n              type={type}\n              {...restProps}\n            />\n          )\n        }\n\n        export default InputField;\n      `,\n      errors: [{ message: \"'type' is missing in props validation\" }],\n    },\n    {\n      code: `\n        const Foo: JSX.Element = ({ bar = \"\" }) => {\n          return <div>{bar}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        function Foo({ foo = \"\" }): JSX.Element {\n          return <div>{foo}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n      const Foo: JSX.Element = function foo ({ bar = \"\" }) {\n        return <div>{bar}</div>;\n      }\n    `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n      function Foo({ bar = \"\" as string }): JSX.Element {\n        return <div>{bar}</div>;\n      }\n    `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'bar' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        interface PersonProps {\n            test: string;\n        }\n        const Person: React.FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'username' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        interface PersonProps {\n            username: string;\n        }\n        const Person: React.FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.test}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        const returnTypeProp = (someProp: any) => ({ someProp });\n\n        const SomeComponent: React.FunctionComponent<\n          ReturnType<typeof returnTypeProp>\n        > = ({ someIncorrectProp }) => {\n          return <div>{someProp}</div>;\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'someIncorrectProp' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n        interface PersonProps {\n            username: string;\n        }\n        const Person: FunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.test}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface PersonProps {\n            username: string;\n        }\n        const Person: X.FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'username' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        interface PersonProps {\n            username: string;\n        }\n        const Person: FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'username' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        type PersonProps<T> = {\n            x: T;\n        }\n        const Person = (props: PersonProps<string>): React.ReactElement => (\n            <div>{props.username}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'username' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { VoidFunctionComponent } from 'react'\n\n        interface Props {\n        age: number\n        }\n        const Hello: VoidFunctionComponent<Props> = function Hello(props) {\n        const { test } = props;\n\n        return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { VFC } from 'react'\n\n        interface Props {\n        age: number\n        }\n        const Hello: VFC<Props> = function Hello(props) {\n        const { test } = props;\n\n        return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        interface Props {\n        age: number\n        }\n        const Hello: React.VoidFunctionComponent<Props> = function Hello(props) {\n        const { test } = props;\n\n        return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        interface Props {\n        age: number\n        }\n        const Hello: React.VFC<Props> = function Hello(props) {\n        const { test } = props;\n\n        return <div>Hello {name}</div>;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'test' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        type IfooProps = { e: string };\n          const Foo: React.ForwardRefRenderFunction<HTMLDivElement, IfooProps> = function Foo (props, ref) {\n          const { name } = props;\n          return  <div ref={ref}>{name}</div>;\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'name' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n        type IfooProps = { k: string, a: number }\n        const Foo= React.forwardRef<HTMLDivElement, IfooProps>((props, ref) => {\n          return  <div ref={ref}>{props.l}</div>;\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'l' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react'\n\n        type IfooProps = { e: string };\n        const Foo= React.forwardRef<HTMLDivElement, IfooProps>(function Foo(props, ref) {\n          const { l } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'l' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from 'react'\n\n        type IfooProps = { e: string };\n        const Foo= forwardRef<HTMLDivElement, IfooProps>(function Foo(props, ref) {\n          const { l } = props;\n          return  <div ref={ref}>hello</div>;\n        });\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'l' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export type Props = { children: React.ReactNode; type: \"submit\" | \"button\" };\n\n        export const FancyButton = forwardRef<HTMLButtonElement, Props>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.nonExistent}>\n            {props.children}\n          </button>\n        ));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { forwardRef } from \"react\";\n\n        export interface IProps { children: React.ReactNode; type: \"submit\" | \"button\" };\n\n        export const FancyButton = forwardRef<HTMLButtonElement, IProps>((props, ref) => (\n          <button type=\"button\" ref={ref} className=\"MyClassName\" type={props.nonExistent}>\n            {props.children}\n          </button>\n        ));\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: React.FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.nonExistent}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { FC } from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: FC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.nonExistent}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { FC as X } from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: X<PersonProps> = (props): React.ReactElement => (\n            <div>{props.nonExistent}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React, { ForwardRefRenderFunction  as X } from 'react'\n\n        export type IfooProps = { e: string };\n        const Foo: X<HTMLDivElement, IfooProps> = function Foo (props, ref) {\n          const { nonExistent } = props;\n          return  <div ref={ref}>hello</div>;\n        };\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: React.VoidFunctionComponent<PersonProps> = (props): React.ReactElement => (\n            <div>{props.nonExistent}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        import React from 'react';\n\n        export interface PersonProps {\n            username: string;\n        }\n        const Person: React.VFC<PersonProps> = (props): React.ReactElement => (\n            <div>{props.nonExistent}</div>\n        );\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'nonExistent' },\n        },\n      ],\n      features: ['ts', 'no-babel'],\n    },\n    {\n      code: `\n        const Foo = ({ foo }) => {\n          return <SomeJSX />;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = ({ foo }) => {\n          const returnValue = <SomeJSX />;\n          return returnValue;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        function _EventsList({ prop_ }) {\n            return (\n                <div>\n                    {prop_.events.map((event) => (\n                        <Event key={event.id} eventId={event.id} />\n                    ))}\n                </div>\n            );\n        }\n\n        function $EventsList({ prop$ }) {\n          return (\n              <div>\n                  {prop$.events.map((event) => (\n                      <Event key={event.id} eventId={event.id} />\n                  ))}\n              </div>\n          );\n      }\n      `,\n      errors: [\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop_' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop_.events' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop_.events.map' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop$' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop$.events' },\n        },\n        {\n          messageId: 'missingPropType',\n          data: { name: 'prop$.events.map' },\n        },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/react-in-jsx-scope.js",
    "content": "/**\n * @fileoverview Tests for react-in-jsx-scope\n * @author Glen Mailer\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/react-in-jsx-scope');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst settings = {\n  react: {\n    pragma: 'Foo',\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('react-in-jsx-scope', rule, {\n  valid: parsers.all([\n    { code: 'var React, App; <App />;' },\n    { code: 'var React; <img />;' },\n    {\n      code: 'var React; <>fragment</>;',\n      features: ['fragment'],\n    },\n    { code: 'var React; <x-gif />;' },\n    { code: 'var React, App, a=1; <App attr={a} />;' },\n    { code: 'var React, App, a=1; function elem() { return <App attr={a} />; }' },\n    { code: '/** @jsx Foo */ var Foo, App; <App />;' },\n    { code: '/** @jsx Foo.Bar */ var Foo, App; <App />;' },\n    {\n      code: `\n        import React from 'react/addons';\n        const Button = createReactClass({\n          render() {\n            return (\n              <button {...this.props}>{this.props.children}</button>\n            )\n          }\n        });\n        export default Button;\n      `,\n    },\n    {\n      code: 'var Foo, App; <App />;',\n      settings,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: 'var App, a = <App />;',\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'React' },\n        },\n      ],\n    },\n    {\n      code: 'var a = <App />;',\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'React' },\n        },\n      ],\n    },\n    {\n      code: 'var a = <img />;',\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'React' },\n        },\n      ],\n    },\n    {\n      code: 'var a = <>fragment</>;',\n      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'React' },\n        },\n      ],\n    },\n    {\n      code: '/** @jsx React.DOM */ var a = <img />;',\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'React' },\n        },\n      ],\n    },\n    {\n      code: '/** @jsx Foo.bar */ var React, a = <img />;',\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'Foo' },\n        },\n      ],\n    },\n    {\n      code: 'var React, a = <img />;',\n      settings,\n      errors: [\n        {\n          messageId: 'notInScope',\n          data: { name: 'Foo' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/require-default-props.js",
    "content": "/**\n * @fileoverview Enforce a defaultProps definition for every prop that is not a required prop.\n * @author Vitor Balocco\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/require-default-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nruleTester.run('require-default-props', rule, {\n  valid: parsers.all([\n    // stateless components as function declarations\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes.foo = PropTypes.string;\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes.foo = PropTypes.string;\n        MyStatelessComponent.defaultProps = {};\n        MyStatelessComponent.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo }) {\n          return <div>{foo}</div>;\n        }\n        MyStatelessComponent.propTypes = {};\n        MyStatelessComponent.propTypes.foo = PropTypes.string;\n        MyStatelessComponent.defaultProps = {};\n        MyStatelessComponent.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo = \"test\", bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo = \"test\", bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n        };\n      `,\n      options: [\n        {\n          forbidDefaultForRequired: true,\n          ignoreFunctionalComponents: true,\n        },\n      ],\n    },\n    {\n      code: `\n        export function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        export default function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string\n        };\n        Hello.defaultProps = {\n          foo: 'bar;'\n        }\n      `,\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    {\n      code: `\n        function Hello({ foo = 'asdf', bar }) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        function Hello({ foo = 'asdf', bar = 'qwer' }) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string.isRequired,\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar = 'asdf', ...props }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string,\n          hello: PropTypes.string.isRequired,\n          world: PropTypes.string.isRequired\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar, ...props }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string.isRequired,\n          hello: PropTypes.string.isRequired,\n          world: PropTypes.string.isRequired\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n\n    // stateless components as function expressions\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        const MyComponent = function({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        };\n\n        MyComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n\n        export default MyComponent;\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        export const MyComponent = function({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        };\n\n        MyComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        const Hello = function({ foo = 'asdf', bar = 'qwer' }) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        const NoPropsComponent = function () {\n          return <div>Hello, world!</div>;\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        function NoPropsComponent() {\n          return <div>Hello, world!</div>;\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        const NoPropsComponent = () => {\n          return <div>Hello, world!</div>;\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        const NoPropsComponent = function () {\n          return <div>Hello, world!</div>;\n        }\n        NoPropsComponent.propTypes = {};\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n\n    // stateless components as arrow function expressions\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        const MyComponent = ({ foo, bar }) => {\n          return <div>{foo}{bar}</div>;\n        };\n\n        MyComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n\n        export default MyComponent;\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        export const MyComponent = ({ foo, bar }) => {\n          return <div>{foo}{bar}</div>;\n        };\n\n        MyComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n\n        export default MyComponent;\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        const Hello = ({ foo = 'asdf', bar = 'qwer' }) => {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n\n    // createReactClass components\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string.isRequired,\n            bar: PropTypes.string.isRequired\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string.isRequired\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\"\n            };\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\",\n              bar: \"bar\"\n            };\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\",\n              bar: \"bar\"\n            };\n          }\n        });\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\",\n              bar: \"bar\"\n            };\n          }\n        });\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n\n    // ES6 class component\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = PropTypes.string;\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {};\n        Greeting.propTypes.foo = PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ classes: 'ignore' }],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      options: [{ classes: 'ignore' }],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ classes: 'ignore' }],\n    },\n\n    // edge cases\n\n    // not a react component\n    {\n      code: `\n        function NotAComponent({ foo, bar }) {}\n        NotAComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        let Greetings = {};\n        Greetings.Hello = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Greetings.Hello.propTypes = {\n          foo: PropTypes.string\n        };\n      `,\n      options: [{ classes: 'ignore' }],\n    },\n    // external references\n    {\n      code: `\n        const defaults = require(\"./defaults\");\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = require(\"./propTypes\");\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = require(\"./defaults\").foo;\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = require(\"./defaults\").foo;\n        MyStatelessComponent.defaultProps.bar = \"bar\";\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        import defaults from \"./defaults\";\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = defaults;\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    {\n      code: `\n        import { foo } from \"./defaults\";\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = foo;\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    // using spread operator\n    {\n      code: `\n        const component = rowsOfType(GuestlistEntry, (rowData, ownProps) => ({\n            ...rowData,\n            onPress: () => ownProps.onPress(rowData.id),\n        }));\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          ...stuff,\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = {\n        foo: \"foo\"\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = {\n        ...defaults,\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n    },\n    {\n      code: `\n        MyStatelessComponent.propTypes = {\n          ...stuff,\n          foo: PropTypes.string\n        };\n        function MyStatelessComponent({ foo = \"foo\", bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          ...someProps,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.defaultProps = {\n          ...defaults,\n          bar: \"bar\"\n        };\n      `,\n    },\n\n    // with Flow annotations\n    {\n      code: `\n        type Props = {\n          foo: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string,\n            bar?: string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        function Hello(props: { foo: string }) {\n          return <div>Hello {foo}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = (props: { foo?: string }) => {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = (props: { foo: string }) => {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo: string }) {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n        type Props2 = {\n          foo: string,\n          baz?: string\n        }\n        function Hello(props: Props | Props2) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = {\n          bar: \"bar\",\n          baz: \"baz\"\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type Props from \"fake\";\n        class Hello extends React.Component {\n          props: Props;\n          render () {\n            return <div>Hello {this.props.name.firstname}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        type Props = any;\n        const Hello = function({ foo }: Props) {\n          return <div>Hello {foo}</div>;\n        };\n      `,\n      features: ['types'],\n    },\n    {\n      code: `\n        import type ImportedProps from \"fake\";\n        type Props = ImportedProps;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // don't error when variable is not in scope\n    {\n      code: `\n        import type { ImportedType } from \"fake\";\n        type Props = ImportedType;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // make sure error is not thrown with multiple assignments\n    {\n      code: `\n        import type ImportedProps from \"fake\";\n        type NestedProps = ImportedProps;\n        type Props = NestedProps;\n        function Hello(props: Props) {\n          return <div>Hello {props.name.firstname}</div>;\n        }\n      `,\n      features: ['types'],\n    },\n    // make sure defaultProps are correctly detected with quoted properties\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.bar}</div>;\n        }\n        Hello.propTypes = {\n          bar: PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"bar\": \"bar\"\n        };\n      `,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            foo: PropTypes.string.isRequired\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    // test support for React PropTypes as Component's class generic\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends React.Component<HelloProps> {\n          static defaultProps = {\n            bar: \"bar\"\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends Component<HelloProps> {\n          static defaultProps = {\n            bar: \"bar\"\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        type HelloState = {\n          dummyState: string\n        };\n        class Hello extends Component<HelloProps, HelloState> {\n          static defaultProps = {\n            bar: \"bar\"\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo?: string,\n          bar?: string\n        };\n        class Hello extends Component<HelloProps> {\n          static defaultProps = {\n            foo: \"foo\",\n            bar: \"bar\"\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      options: [{ forbidDefaultForRequired: true }],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string,\n          bar?: string\n        }\n        function Hello({ foo = 'asdf', bar = 'qwer' }: Props) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n      `,\n      features: ['types'],\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string,\n          bar: string\n        }\n        function Hello({ foo = 'asdf', bar }: Props) {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n      `,\n      features: ['types'],\n      options: [{ functions: 'defaultArguments' }],\n    },\n    {\n      code: `\n        type Props = {\n          +name?: string,\n        };\n        function Hello(props: Props) {\n          return <div>Hello {props.name}</div>;\n        }\n        Hello.defaultProps = {\n          name: 'foo'\n        };\n      `,\n      features: ['flow'],\n    },\n    {\n      code: `\n        import React from \"react\";\n\n        interface Props {\n          name: string;\n        }\n\n        const MyComponent: React.FC<Props> = ({ name }) => {\n          return <div>{name}</div>;\n        };\n\n        export default MyComponent;\n      `,\n      features: ['ts'],\n    },\n    {\n      code: `\n        interface Props {\n          foo?: string,\n          bar?: string\n        }\n        const Hello: React.FC<Props> = ({ foo = 'asdf', bar = 'qwer' }) => {\n          return <div>Hello {foo} and {bar}</div>;\n        }\n      `,\n      features: ['ts'],\n      options: [{ functions: 'defaultArguments' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    // stateless components\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = forbidExtraProps({\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        });\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        const propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes = forbidExtraProps(propTypes);\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        MyStatelessComponent.propTypes.baz = React.propTypes.string;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'baz' },\n          line: 9,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          foo: \"foo\"\n        };\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n        MyStatelessComponent.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 7,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const types = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        function MyStatelessComponent({ foo, bar = \"asdf\" }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'shouldAssignObjectDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 41,\n        },\n      ],\n    },\n    {\n      code: `\n        const types = {\n          foo: PropTypes.string,\n        };\n        function MyStatelessComponent(props) {\n          return <div>{props.foo}</div>;\n        }\n        MyStatelessComponent.propTypes = types;\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'destructureInSignature',\n          line: 5,\n          column: 39,\n        },\n      ],\n    },\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar, ...props }) {\n          return <div>{foo}{bar}</div>;\n        }\n        MyStatelessComponent.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired,\n          hello: PropTypes.string.isRequired,\n          world: PropTypes.string.isRequired\n        }\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'shouldAssignObjectDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 41,\n        },\n      ],\n    },\n\n    // createReactClass components\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string.isRequired\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 7,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string.isRequired\n          }\n        });\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 7,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        var Greeting = createReactClass({\n          render: function() {\n            return <div>Hello {this.props.foo} {this.props.bar}</div>;\n          },\n          propTypes: {\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              foo: \"foo\"\n            };\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 8,\n          column: 13,\n        },\n      ],\n    },\n\n    // ES6 class component\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        Greeting.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.propTypes.foo = PropTypes.string;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 12,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {\n          bar: PropTypes.string\n        };\n        Greeting.propTypes.foo = PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.foo = \"foo\";\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        Greeting.propTypes = {};\n        Greeting.propTypes.foo = PropTypes.string;\n        Greeting.defaultProps = {};\n        Greeting.defaultProps.bar = \"bar\";\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 10,\n          column: 9,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        Greeting.propTypes = props;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 10,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n        }\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        const defaults = {\n          foo: \"foo\"\n        };\n        Greeting.propTypes = props;\n        Greeting.defaultProps = defaults;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 11,\n          column: 11,\n        },\n      ],\n    },\n\n    // ES6 classes with static getter methods\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'name' },\n          line: 5,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      options: [{ ignoreFunctionalComponents: true }],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'name' },\n          line: 5,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              foo: PropTypes.string,\n              bar: PropTypes.string\n            };\n          }\n          static get defaultProps() {\n            return {\n              bar: \"world\"\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 5,\n          column: 15,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string\n        };\n        class Hello extends React.Component {\n          static get propTypes() {\n            return props;\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const defaults = {\n          bar: \"world\"\n        };\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              foo: PropTypes.string,\n              bar: PropTypes.string\n            };\n          }\n          static get defaultProps() {\n            return defaults;\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 8,\n          column: 15,\n        },\n      ],\n    },\n\n    // ES6 classes with property initializers\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string.isRequired\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 9,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string.isRequired\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [{ ignoreFunctionalComponents: true }],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 9,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = {\n            foo: PropTypes.string,\n            bar: PropTypes.string\n          };\n          static defaultProps = {\n            foo: \"foo\"\n          };\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 10,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        };\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = props;\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const props = {\n          foo: PropTypes.string,\n          bar: PropTypes.string\n        };\n        const defaults = {\n          foo: \"foo\"\n        };\n        class Greeting extends React.Component {\n          render() {\n            return (\n              <h1>Hello, {this.props.foo} {this.props.bar}</h1>\n            );\n          }\n          static propTypes = props;\n          static defaultProps = defaults;\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n\n    // edge cases\n    {\n      code: `\n        let Greetings = {};\n        Greetings.Hello = class extends React.Component {\n          render () {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Greetings.Hello.propTypes = {\n          foo: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 9,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        var Greetings = ({ foo = \"foo\" }) => {\n          return <div>Hello {this.props.foo}</div>;\n        }\n        Greetings.propTypes = {\n          foo: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n          column: 11,\n        },\n      ],\n    },\n\n    // component with no declared props followed by a failing component\n    {\n      code: `\n        var ComponentWithNoProps = ({ bar = \"bar\" }) => {\n          return <div>Hello {this.props.foo}</div>;\n        }\n        var Greetings = ({ foo = \"foo\" }) => {\n          return <div>Hello {this.props.foo}</div>;\n        }\n        Greetings.propTypes = {\n          foo: PropTypes.string\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 9,\n          column: 11,\n        },\n      ],\n    },\n\n    // with Flow annotations\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo?: string,\n            bar?: string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          static defaultProps: { foo: string };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo: string,\n            bar?: string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo?: string,\n            bar?: string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 4,\n          column: 13,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo?: string\n          };\n          static defaultProps: { foo: string };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string,\n          bar?: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string,\n          bar?: string\n        };\n        class Hello extends React.Component {\n          props: Props;\n          static defaultProps: { foo: string, bar: string };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          props: {\n            foo?: string,\n            bar?: string\n          };\n          static defaultProps: { foo: string, bar: string };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.defaultProps = {\n          foo: \"foo\"\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 5,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 33,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello({ foo = \"foo\" }: { foo?: string }) {\n          return <div>Hello {foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 43,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: { foo?: string, bar?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 2,\n          column: 47,\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props: { foo?: string, bar?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 33,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 2,\n          column: 47,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string\n        };\n        function Hello(props: Props) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props: { foo?: string }) => {\n          return <div>Hello {props.foo}</div>;\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 33,\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props: { foo?: string, bar?: string }) => {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 2,\n          column: 47,\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo?: string }) {\n          return <div>Hello {props.foo}</div>;\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 2,\n          column: 41,\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = function(props: { foo?: string, bar?: string }) {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 2,\n          column: 55,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo?: string,\n          bar?: string\n        };\n        function Hello(props: Props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = { foo: \"foo\" };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n\n    // UnionType\n    {\n      code: `\n        function Hello(props: { one?: string } | { two?: string }) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'one' },\n          line: 2,\n          column: 33,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'two' },\n          line: 2,\n          column: 52,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n        type Props2 = {\n          foo: string,\n          baz?: string\n        }\n        function Hello(props: Props | Props2) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n          line: 4,\n          column: 11,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'baz' },\n          line: 8,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          foo: string,\n          bar?: string\n        };\n        type Props2 = {\n          foo: string,\n          baz?: string\n        }\n        function Hello(props: Props | Props2) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.defaultProps = {\n          bar: \"bar\"\n        };\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'baz' },\n          line: 8,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type HelloProps = {\n          two?: string,\n          three: string\n        };\n        function Hello(props: { one?: string } | HelloProps) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'two' },\n          line: 3,\n          column: 11,\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'one' },\n          line: 6,\n          column: 33,\n        },\n      ],\n    },\n    {\n      code: `\n        type HelloProps = {\n          two?: string,\n          three: string\n        };\n        function Hello(props: ExternalProps | HelloProps) {\n          return <div>Hello {props.foo}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'two' },\n          line: 3,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            foo: PropTypes.string\n          };\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 4,\n          column: 13,\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              name: PropTypes.string\n            };\n          }\n          static defaultProps() {\n            return {\n              name: 'John'\n            };\n          }\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes() {\n            return {\n              'first-name': PropTypes.string\n            };\n          }\n          render() {\n            return <div>Hello {this.props['first-name']}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'first-name' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired\n        };\n        Hello.defaultProps = {\n          foo: 'bar'\n        };\n      `,\n      options: [{ forbidDefaultForRequired: true }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired\n        };\n        Hello.defaultProps = {\n          foo: 'bar'\n        };\n      `,\n      options: [{ forbidDefaultForRequired: true }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        const Hello = (props) => {\n          return <div>Hello {props.foo}</div>;\n        };\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired\n        };\n        Hello.defaultProps = {\n          foo: 'bar'\n        };\n      `,\n      options: [{ forbidDefaultForRequired: true }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static propTypes = {\n            foo: PropTypes.string.isRequired\n          }\n          static defaultProps = {\n            foo: 'bar'\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [{ forbidDefaultForRequired: true }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          static get propTypes () {\n            return {\n              foo: PropTypes.string.isRequired\n            };\n          }\n          static get defaultProps() {\n            return {\n              foo: 'bar'\n            };\n          }\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      options: [{ forbidDefaultForRequired: true }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.foo}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired\n        };\n        Hello.defaultProps = {\n          foo: 'bar'\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'noDefaultPropsWithFunction',\n        },\n      ],\n    },\n    {\n      code: `\n        function Hello(props) {\n          return <div>Hello {props.foo} and {props.bar}</div>;\n        }\n        Hello.propTypes = {\n          foo: PropTypes.string.isRequired,\n          bar: PropTypes.string\n        };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'destructureInSignature',\n        },\n      ],\n    },\n\n    // test support for React PropTypes as Component's class generic\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends React.Component<HelloProps> {\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        class Hello extends Component<HelloProps> {\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo: string,\n          bar?: string\n        };\n        type HelloState = {\n          dummyState: string\n        };\n        class Hello extends Component<HelloProps, HelloState> {\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type HelloProps = {\n          foo?: string,\n          bar?: string\n        };\n        class Hello extends Component<HelloProps> {\n          render() {\n            return <div>Hello {this.props.foo}</div>;\n          }\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n        },\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'bar' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          +name?: string,\n        };\n        function Hello(props: Props) {\n          return <div>Hello {props.name}</div>;\n        }\n      `,\n      features: ['flow'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'name' },\n        },\n      ],\n    },\n    {\n      code: `\n        import PropTypes from 'prop-types';\n        import React from 'react';\n\n        const MyComponent= (props) => {\n          switch (props.usedProp) {\n            case 1:\n              return (<div />);\n            default:\n              return <div />;\n          }\n        };\n\n        MyComponent.propTypes = {\n          usedProp: PropTypes.string,\n        };\n\n        export default MyComponent;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'usedProp' },\n        },\n      ],\n    },\n    {\n      code: `\n        Foo.propTypes = {\n          a: PropTypes.string,\n        }\n\n        export default function Foo(props) {\n          return <p>{props.a}</p>\n        };\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'a' },\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          history: {\n            push: Function,\n          },\n          match?: {\n            params?: {\n              date?: string\n            },\n          },\n        };\n\n        export const Daily = ({ history, match: {\n          params: {\n            date = moment().toISOString(),\n          } = {},\n        } = {} }: Props) => (\n              <div>\n                <div style={{ textAlign: 'right', paddingRight: '25px' }}>\n                  Show <DatePicker\n                    selected={moment(date)}\n                    className=\"datetime\"\n                    onChange={d => history.push(\\`./\\${d.toISOString()}\\`)}\n                  />\n                </div>\n                <WithData url=\"/payments/daily\" body={{ date: moment(date).toISOString() }}>\n                  <Flashcards date={moment(date)} />\n                </WithData>\n              </div>\n        );\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: {\n            name: 'match',\n          },\n        },\n      ],\n    },\n\n    {\n      code: `\n        function MyStatelessComponent({ foo, bar }) {\n          return <div>{foo}{bar}</div>;\n        }\n        const propTypes = forbidExtraProps({\n          foo: PropTypes.string,\n          bar: PropTypes.string.isRequired\n        });\n        MyStatelessComponent.propTypes = propTypes;\n      `,\n      errors: [\n        {\n          messageId: 'shouldHaveDefault',\n          data: { name: 'foo' },\n          line: 6,\n        },\n      ],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n    },\n    {\n      code: `\n      function MyStatelessComponent({ foo = 'foo' }) {\n        return <div>{foo}{bar}</div>;\n      }\n      MyStatelessComponent.propTypes = {\n        foo: PropTypes.string.isRequired,\n      };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n          line: 2,\n        },\n      ],\n    },\n    {\n      code: `\n      function MyStatelessComponent({ foo = 'foo', bar }) {\n        return <div>{foo}{bar}</div>;\n      }\n      MyStatelessComponent.propTypes = {\n        foo: PropTypes.string.isRequired,\n        bar: PropTypes.string\n      };\n      `,\n      options: [{ functions: 'defaultArguments' }],\n      errors: [\n        {\n          messageId: 'noDefaultWithRequired',\n          data: { name: 'foo' },\n          line: 2,\n        },\n        {\n          messageId: 'shouldAssignObjectDefault',\n          data: { name: 'bar' },\n          line: 2,\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/require-optimization.js",
    "content": "/**\n * @fileoverview Enforce React components to have a shouldComponentUpdate method\n * @author Evgueni Naverniouk\n */\n\n'use strict';\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/require-optimization');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('react-require-optimization', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class A {}\n      `,\n    },\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.Component {\n          shouldComponentUpdate () {}\n        }\n      `,\n    },\n    {\n      code: `\n        import React, {Component} from \"react\";\n        class YourComponent extends Component {\n          shouldComponentUpdate () {}\n        }\n      `,\n    },\n    {\n      code: `\n        import React, {Component} from \"react\";\n        @reactMixin.decorate(PureRenderMixin)\n        class YourComponent extends Component {\n          componentDidMount () {}\n          render() {}\n        }\n      `,\n      features: ['decorators'],\n    },\n    {\n      code: `\n        import React from \"react\";\n        createReactClass({\n          shouldComponentUpdate: function () {}\n        })\n      `,\n    },\n    {\n      code: `\n        import React from \"react\";\n        createReactClass({\n          mixins: [PureRenderMixin]\n        })\n      `,\n    },\n    {\n      code: `\n        @reactMixin.decorate(PureRenderMixin)\n        class DecoratedComponent extends Component {}\n      `,\n      features: ['decorators'],\n    },\n    {\n      code: `\n        const FunctionalComponent = function (props) {\n          return <div />;\n        }\n      `,\n    },\n    {\n      code: `\n        function FunctionalComponent(props) {\n          return <div />;\n        }\n      `,\n    },\n    {\n      code: `\n        const FunctionalComponent = (props) => {\n          return <div />;\n        }\n      `,\n    },\n    {\n      code: `\n        @bar\n        @pureRender\n        @foo\n        class DecoratedComponent extends Component {}\n      `,\n      features: ['decorators'],\n      options: [{ allowDecorators: ['renderPure', 'pureRender'] }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.PureComponent {}\n      `,\n      options: [{ allowDecorators: ['renderPure', 'pureRender'] }],\n    },\n    {\n      code: `\n        import React, {PureComponent} from \"react\";\n        class YourComponent extends PureComponent {}\n      `,\n      options: [{ allowDecorators: ['renderPure', 'pureRender'] }],\n    },\n    {\n      code: `\n        const obj = { prop: [,,,,,] }\n      `,\n    },\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.Component {\n          handleClick = () => {}\n          shouldComponentUpdate(){\n            return true;\n          }\n          render() {\n            return <div onClick={this.handleClick}>123</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.Component {}\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.Component {\n          handleClick() {}\n          render() {\n            return <div onClick={this.handleClick}>123</div>\n          }\n        }\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        class YourComponent extends React.Component {\n          handleClick = () => {}\n          render() {\n            return <div onClick={this.handleClick}>123</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        import React, {Component} from \"react\";\n        class YourComponent extends Component {}\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        createReactClass({})\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        import React from \"react\";\n        createReactClass({\n          mixins: [RandomMixin]\n        })\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n    },\n    {\n      code: `\n        @reactMixin.decorate(SomeOtherMixin)\n        class DecoratedComponent extends Component {}\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n      features: ['decorators'],\n    },\n    {\n      code: `\n        @bar\n        @pure\n        @foo\n        class DecoratedComponent extends Component {}\n      `,\n      errors: [{ messageId: 'noShouldComponentUpdate' }],\n      features: ['decorators'],\n      options: [{ allowDecorators: ['renderPure', 'pureRender'] }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/require-render-return.js",
    "content": "/**\n * @fileoverview Enforce ES5 or ES6 class for returning value in render function.\n * @author Mark Orel\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/require-render-return');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('require-render-return', rule, {\n  valid: parsers.all([\n    {\n      // ES6 class\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n    },\n    {\n      // ES6 class with render property\n      code: `\n        class Hello extends React.Component {\n          render = () => {\n            return <div>Hello {this.props.name}</div>;\n          }\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // ES6 class with render property (implicit return)\n      code: `\n        class Hello extends React.Component {\n          render = () => (\n            <div>Hello {this.props.name}</div>\n          )\n        }\n      `,\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n    },\n    {\n      // ES5 class\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {\n            return <div></div>\n          }\n        });\n      `,\n    },\n    {\n      // Stateless function\n      code: `\n        function Hello() {\n          return <div></div>;\n        }\n      `,\n    },\n    {\n      // Stateless arrow function\n      code: `\n        var Hello = () => (\n          <div></div>\n        );\n      `,\n    },\n    {\n      // Return in a switch...case\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            switch (this.props.name) {\n              case 'Foo':\n                return <div>Hello Foo</div>;\n              default:\n                return <div>Hello {this.props.name}</div>;\n            }\n          }\n        });\n      `,\n    },\n    {\n      // Return in a if...else\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            if (this.props.name === 'Foo') {\n              return <div>Hello Foo</div>;\n            } else {\n              return <div>Hello {this.props.name}</div>;\n            }\n          }\n        });\n      `,\n    },\n    {\n      // Not a React component\n      code: `\n        class Hello {\n          render() {}\n        }\n      `,\n    },\n    {\n      // ES6 class without a render method\n      code: 'class Hello extends React.Component {}',\n    },\n    {\n      // ES5 class without a render method\n      code: 'var Hello = createReactClass({});',\n    },\n    {\n      // ES5 class with an imported render method\n      code: `\n        var render = require('./render');\n        var Hello = createReactClass({\n          render\n        });\n      `,\n    },\n    {\n      // Invalid render method (but accepted by Babel)\n      code: `\n        class Foo extends Component {\n          render\n        }\n      `,\n      features: ['class fields'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      // Missing return in ES5 class\n      code: `\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          render: function() {}\n        });\n      `,\n      errors: [\n        {\n          messageId: 'noRenderReturn',\n          line: 4,\n        },\n      ],\n    },\n    {\n      // Missing return in ES6 class\n      code: `\n        class Hello extends React.Component {\n          render() {}\n        }\n      `,\n      errors: [{ messageId: 'noRenderReturn' }],\n    },\n    {\n      // Missing return (but one is present in a sub-function)\n      code: `\n        class Hello extends React.Component {\n          render() {\n            const names = this.props.names.map(function(name) {\n              return <div>{name}</div>\n            });\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'noRenderReturn',\n          line: 3,\n        },\n      ],\n    },\n    {\n      // Missing return ES6 class render property\n      code: `\n        class Hello extends React.Component {\n          render = () => {\n            <div>Hello {this.props.name}</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'noRenderReturn',\n          line: 3,\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/self-closing-comp.js",
    "content": "/**\n * @fileoverview Prevent extra closing tags for components without children\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/self-closing-comp');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('self-closing-comp', rule, {\n  valid: parsers.all([\n    {\n      code: 'var HelloJohn = <Hello name=\"John\" />;',\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\" />;',\n    },\n    {\n      code: 'var Profile = <Hello name=\"John\"><img src=\"picture.png\" /></Hello>;',\n    },\n    {\n      code: 'var Profile = <Hello.Compound name=\"John\"><img src=\"picture.png\" /></Hello.Compound>;',\n    },\n    {\n      code: `\n        <Hello>\n          <Hello name=\"John\" />\n        </Hello>\n      `,\n    },\n    {\n      code: `\n        <Hello.Compound>\n          <Hello.Compound name=\"John\" />\n        </Hello.Compound>\n      `,\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\"> </Hello>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\"> </Hello.Compound>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">        </Hello>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">        </Hello.Compound>;',\n    },\n    {\n      code: 'var HelloJohn = <div>&nbsp;</div>;',\n    },\n    {\n      code: 'var HelloJohn = <div>{\\' \\'}</div>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">&nbsp;</Hello>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">&nbsp;</Hello.Compound>;',\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\" />;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\" />;',\n      options: [],\n    },\n    {\n      code: 'var Profile = <Hello name=\"John\"><img src=\"picture.png\" /></Hello>;',\n      options: [],\n    },\n    {\n      code: 'var Profile = <Hello.Compound name=\"John\"><img src=\"picture.png\" /></Hello.Compound>;',\n      options: [],\n    },\n    {\n      code: `\n        <Hello>\n          <Hello name=\"John\" />\n        </Hello>\n      `,\n      options: [],\n    },\n    {\n      code: `\n        <Hello.Compound>\n          <Hello.Compound name=\"John\" />\n        </Hello.Compound>\n      `,\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <div> </div>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <div>        </div>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <div>&nbsp;</div>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <div>{\\' \\'}</div>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">&nbsp;</Hello>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">&nbsp;</Hello.Compound>;',\n      options: [],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\"></Hello>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\"></Hello.Compound>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">\\n</Hello>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">\\n</Hello.Compound>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\"> </Hello>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\"> </Hello.Compound>;',\n      options: [{ component: false }],\n    },\n    {\n      code: 'var contentContainer = <div className=\"content\" />;',\n      options: [{ html: true }],\n    },\n    {\n      code: 'var contentContainer = <div className=\"content\"><img src=\"picture.png\" /></div>;',\n      options: [{ html: true }],\n    },\n    {\n      code: `\n        <div>\n          <div className=\"content\" />\n        </div>\n      `,\n      options: [{ html: true }],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: 'var contentContainer = <div className=\"content\"></div>;',\n      output: 'var contentContainer = <div className=\"content\" />;',\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var contentContainer = <div className=\"content\"></div>;',\n      output: 'var contentContainer = <div className=\"content\" />;',\n      options: [],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\"></Hello>;',\n      output: 'var HelloJohn = <Hello name=\"John\" />;',\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var CompoundHelloJohn = <Hello.Compound name=\"John\"></Hello.Compound>;',\n      output: 'var CompoundHelloJohn = <Hello.Compound name=\"John\" />;',\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">\\n</Hello>;',\n      output: 'var HelloJohn = <Hello name=\"John\" />;',\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">\\n</Hello.Compound>;',\n      output: 'var HelloJohn = <Hello.Compound name=\"John\" />;',\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\"></Hello>;',\n      output: 'var HelloJohn = <Hello name=\"John\" />;',\n      options: [],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\"></Hello.Compound>;',\n      output: 'var HelloJohn = <Hello.Compound name=\"John\" />;',\n      options: [],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello name=\"John\">\\n</Hello>;',\n      output: 'var HelloJohn = <Hello name=\"John\" />;',\n      options: [],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var HelloJohn = <Hello.Compound name=\"John\">\\n</Hello.Compound>;',\n      output: 'var HelloJohn = <Hello.Compound name=\"John\" />;',\n      options: [],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var contentContainer = <div className=\"content\"></div>;',\n      output: 'var contentContainer = <div className=\"content\" />;',\n      options: [{ html: true }],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n    {\n      code: 'var contentContainer = <div className=\"content\">\\n</div>;',\n      output: 'var contentContainer = <div className=\"content\" />;',\n      options: [{ html: true }],\n      errors: [{ messageId: 'notSelfClosing' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/sort-comp.js",
    "content": "/**\n * @fileoverview Enforce component methods order\n * @author Yannick Croissant\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/sort-comp');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('sort-comp', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        // Must validate a full class\n        var Hello = createReactClass({\n          displayName : '',\n          propTypes: {},\n          contextTypes: {},\n          childContextTypes: {},\n          mixins: [],\n          statics: {},\n          getDefaultProps: function() {},\n          getInitialState: function() {},\n          getChildContext: function() {},\n          componentWillMount: function() {},\n          componentDidMount: function() {},\n          componentWillReceiveProps: function() {},\n          shouldComponentUpdate: function() {},\n          componentWillUpdate: function() {},\n          componentDidUpdate: function() {},\n          componentWillUnmount: function() {},\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        // Must validate a class with missing groups\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        // Must put a custom method in 'everything-else'\n        var Hello = createReactClass({\n          onClick: function() {},\n          render: function() {\n            return <button onClick={this.onClick}>Hello</button>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        // Must allow us to re-order the groups\n        var Hello = createReactClass({\n          displayName : 'Hello',\n          render: function() {\n            return <button onClick={this.onClick}>Hello</button>;\n          },\n          onClick: function() {}\n        });\n      `,\n      options: [\n        {\n          order: [\n            'lifecycle',\n            'render',\n            'everything-else',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Must validate a full React 16.3 createReactClass class\n        var Hello = createReactClass({\n          displayName : '',\n          propTypes: {},\n          contextTypes: {},\n          childContextTypes: {},\n          mixins: [],\n          statics: {},\n          getDefaultProps: function() {},\n          getInitialState: function() {},\n          getChildContext: function() {},\n          UNSAFE_componentWillMount: function() {},\n          componentDidMount: function() {},\n          UNSAFE_componentWillReceiveProps: function() {},\n          shouldComponentUpdate: function() {},\n          UNSAFE_componentWillUpdate: function() {},\n          getSnapshotBeforeUpdate: function() {},\n          componentDidUpdate: function() {},\n          componentDidCatch: function() {},\n          componentWillUnmount: function() {},\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        // Must validate React 16.3 lifecycle methods with the default parser\n        class Hello extends React.Component {\n          constructor() {}\n          static getDerivedStateFromProps() {}\n          UNSAFE_componentWillMount() {}\n          componentDidMount() {}\n          UNSAFE_componentWillReceiveProps() {}\n          shouldComponentUpdate() {}\n          UNSAFE_componentWillUpdate() {}\n          getSnapshotBeforeUpdate() {}\n          componentDidUpdate() {}\n          componentDidCatch() {}\n          componentWillUnmount() {}\n          testInstanceMethod() {}\n          render() { return (<div>Hello</div>); }\n        }\n      `,\n    },\n    {\n      code: `\n        // Must validate a full React 16.3 ES6 class\n        class Hello extends React.Component {\n          static displayName = ''\n          static propTypes = {}\n          static defaultProps = {}\n          constructor() {}\n          state = {}\n          static getDerivedStateFromProps = () => {}\n          UNSAFE_componentWillMount = () => {}\n          componentDidMount = () => {}\n          UNSAFE_componentWillReceiveProps = () => {}\n          shouldComponentUpdate = () => {}\n          UNSAFE_componentWillUpdate = () => {}\n          getSnapshotBeforeUpdate = () => {}\n          componentDidUpdate = () => {}\n          componentDidCatch = () => {}\n          componentWillUnmount = () => {}\n          testArrowMethod = () => {}\n          testInstanceMethod() {}\n          render = () => (<div>Hello</div>)\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        // Must allow us to create a RegExp-based group\n        class Hello extends React.Component {\n          customHandler() {}\n          render() {\n            return <div>Hello</div>;\n          }\n          onClick() {}\n        }\n      `,\n      options: [\n        {\n          order: [\n            'lifecycle',\n            'everything-else',\n            'render',\n            '/on.*/',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Must allow us to create a named group\n        class Hello extends React.Component {\n          customHandler() {}\n          render() {\n            return <div>Hello</div>;\n          }\n          onClick() {}\n        }\n      `,\n      options: [\n        {\n          order: [\n            'lifecycle',\n            'everything-else',\n            'render',\n            'customGroup',\n          ],\n          groups: {\n            customGroup: [\n              '/on.*/',\n            ],\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must allow a method to be in different places if it's matches multiple patterns\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n          onClick() {}\n        }\n      `,\n      options: [\n        {\n          order: [\n            '/on.*/',\n            'render',\n            '/.*Click/',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Must allow us to use 'constructor' as a method name\n        class Hello extends React.Component {\n          constructor() {}\n          displayName() {}\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n      `,\n      options: [\n        {\n          order: [\n            'constructor',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Must ignore stateless components\n        function Hello(props) {\n          return <div>Hello {props.name}</div>\n        }\n      `,\n    },\n    {\n      code: `\n        // Must ignore stateless components (arrow function with explicit return)\n        var Hello = props => (\n          <div>Hello {props.name}</div>\n        )\n      `,\n    },\n    {\n      code: `\n        // Must ignore spread operator\n        var Hello = createReactClass({\n          ...proto,\n          render: function() {\n            return <div>Hello</div>;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        // Type Annotations should be first\n        class Hello extends React.Component {\n          props: { text: string };\n          constructor() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      options: [\n        {\n          order: [\n            'type-annotations',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Properties with Type Annotations should not be at the top\n        class Hello extends React.Component {\n          props: { text: string };\n          constructor() {}\n          state: Object = {};\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      options: [\n        {\n          order: [\n            'type-annotations',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Non-react classes should be ignored, even in expressions\n        return class Hello {\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n          props: { text: string };\n          constructor() {}\n          state: Object = {};\n        }\n      `,\n      features: ['types'],\n      parserOptions,\n    },\n    {\n      code: `\n        // Non-react classes should be ignored, even in expressions\n        return class {\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n          props: { text: string };\n          constructor() {}\n          state: Object = {};\n        }\n      `,\n      features: ['types'],\n      parserOptions,\n    },\n    {\n      code: `\n        // Getters should be at the top\n        class Hello extends React.Component {\n          get foo() {}\n          constructor() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      options: [\n        {\n          order: [\n            'getters',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Setters should be at the top\n        class Hello extends React.Component {\n          set foo(bar) {}\n          constructor() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      options: [\n        {\n          order: [\n            'setters',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Instance methods should be at the top\n        class Hello extends React.Component {\n          foo = () => {}\n          constructor() {}\n          classMethod() {}\n          static bar = () => {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'instance-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Instance variables should be at the top\n        class Hello extends React.Component {\n          foo = 'bar'\n          constructor() {}\n          state = {}\n          static bar = 'foo'\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'instance-variables',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Methods can be grouped with any matching group (with statics)\n        class Hello extends React.Component {\n          static onFoo() {}\n          static renderFoo() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n          getFoo() {}\n        }\n      `,\n      options: [\n        {\n          order: [\n            'static-methods',\n            'render',\n            '/^get.+$/',\n            '/^on.+$/',\n            '/^render.+$/',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Methods can be grouped with any matching group (with RegExp)\n        class Hello extends React.Component {\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n          getFoo() {}\n          static onFoo() {}\n          static renderFoo() {}\n        }\n      `,\n      options: [\n        {\n          order: [\n            'static-methods',\n            'render',\n            '/^get.+$/',\n            '/^on.+$/',\n            '/^render.+$/',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // static lifecycle methods can be grouped (with statics)\n        class Hello extends React.Component {\n          static getDerivedStateFromProps() {}\n          constructor() {}\n        }\n      `,\n    },\n    {\n      code: `\n        // static lifecycle methods can be grouped (with lifecycle)\n        class Hello extends React.Component {\n          constructor() {}\n          static getDerivedStateFromProps() {}\n        }\n      `,\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          state = {};\n          foo;\n          static propTypes;\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'state',\n            'instance-variables',\n            'static-methods',\n            'lifecycle',\n            'render',\n            'everything-else',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static foo;\n          static getDerivedStateFromProps() {}\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-variables',\n            'static-methods',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static getDerivedStateFromProps() {}\n          static foo = 'some-str';\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-methods',\n            'static-variables',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          foo = {};\n          static bar = 0;\n          static getDerivedStateFromProps() {}\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'instance-variables',\n            'static-variables',\n            'static-methods',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static bar = 1;\n          foo = {};\n          static getDerivedStateFromProps() {}\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-variables',\n            'instance-variables',\n            'static-methods',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static getDerivedStateFromProps() {}\n          render() {\n            return null;\n          }\n          static bar;\n          foo = {};\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-methods',\n            'render',\n            'static-variables',\n            'instance-variables',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static foo = 1;\n          bar;\n\n          constructor() {\n            super(props);\n\n            this.state = {};\n          }\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-variables',\n            'instance-variables',\n            'constructor',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class ClassName extends React.Component {\n          static defaultProps = {};\n          static parseDateString(date?: Date) {}\n          state = {};\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['types'],\n      options: [\n        {\n          order: [\n            'static-variables',\n            'static-methods',\n            'type-annotations',\n            'instance-variables',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        // Must force a lifecycle method to be placed before render\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello</div>;\n          },\n          displayName : 'Hello',\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'displayName',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must run rule when render uses createElement instead of JSX\n        var Hello = createReactClass({\n          render: function() {\n            return React.createElement(\"div\", null, \"Hello\");\n          },\n          displayName : 'Hello',\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'displayName',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must force a custom method to be placed before render\n        var Hello = createReactClass({\n          render: function() {\n            return <div>Hello</div>;\n          },\n          onClick: function() {},\n        });\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'onClick',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must force a custom method to be placed before render, even in function\n        var Hello = () => {\n          return class Test extends React.Component {\n            render () {\n              return <div>Hello</div>;\n            }\n            onClick () {}\n          }\n        };\n      `,\n      parserOptions,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'onClick',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must force a custom method to be placed after render if no 'everything-else' group is specified\n        var Hello = createReactClass({\n          displayName: 'Hello',\n          onClick: function() {},\n          render: function() {\n            return <button onClick={this.onClick}>Hello</button>;\n          }\n        });\n      `,\n      options: [\n        {\n          order: [\n            'lifecycle',\n            'render',\n          ],\n        },\n      ],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'onClick',\n            position: 'after',\n            propB: 'render',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Must validate static properties\n        class Hello extends React.Component {\n          render() {\n            return <div></div>\n          }\n          static displayName = 'Hello';\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'displayName',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Type Annotations should not be at the top by default\n        class Hello extends React.Component {\n          props: { text: string };\n          constructor() {}\n          state: Object = {};\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'props',\n            position: 'after',\n            propB: 'state',\n          },\n        },\n      ],\n    },\n    {\n      code: `\n        // Type Annotations should be first\n        class Hello extends React.Component {\n          constructor() {}\n          props: { text: string };\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'constructor',\n            position: 'after',\n            propB: 'props',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'type-annotations',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Properties with Type Annotations should not be at the top\n        class Hello extends React.Component {\n          props: { text: string };\n          state: Object = {};\n          constructor() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['types'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'state',\n            position: 'after',\n            propB: 'constructor',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'type-annotations',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // componentDidMountOk should be placed after getA\n        export default class View extends React.Component {\n          componentDidMountOk() {}\n          getB() {}\n          componentWillMount() {}\n          getA() {}\n          render() {}\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'componentDidMountOk',\n            position: 'after',\n            propB: 'getA',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'static-methods',\n            'lifecycle',\n            '/^on.+$/',\n            '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',\n            'everything-else',\n            '/^render.+$/',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Getters should at the top\n        class Hello extends React.Component {\n          constructor() {}\n          get foo() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'constructor',\n            position: 'after getter',\n            propB: 'functions',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'getters',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Setters should at the top\n        class Hello extends React.Component {\n          constructor() {}\n          set foo(bar) {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'constructor',\n            position: 'after setter',\n            propB: 'functions',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'setters',\n            'static-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Instance methods should not be at the top\n        class Hello extends React.Component {\n          constructor() {}\n          static bar = () => {}\n          classMethod() {}\n          foo = function() {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'foo',\n            position: 'before',\n            propB: 'constructor',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'instance-methods',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Instance variables should not be at the top\n        class Hello extends React.Component {\n          constructor() {}\n          state = {}\n          static bar = {}\n          foo = {}\n          render() {\n            return <div>{this.props.text}</div>;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'foo',\n            position: 'before',\n            propB: 'constructor',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'instance-variables',\n            'lifecycle',\n            'everything-else',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Should not confuse method names with group names\n        class Hello extends React.Component {\n          setters() {}\n          constructor() {}\n          render() {}\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'setters',\n            position: 'after',\n            propB: 'render',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'setters',\n            'lifecycle',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        // Explicitly named methods should appear in the correct order\n        class Hello extends React.Component {\n          render() {}\n          foo() {}\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'render',\n            position: 'after',\n            propB: 'foo',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'foo',\n            'render',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static getDerivedStateFromProps() {}\n          static foo;\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'getDerivedStateFromProps',\n            position: 'after',\n            propB: 'foo',\n          },\n        },\n      ],\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'static-variables',\n            'static-methods',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static foo;\n          bar = 'some-str'\n          static getDerivedStateFromProps() {}\n\n          render() {\n            return null;\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'foo',\n            position: 'after',\n            propB: 'bar',\n          },\n        },\n      ],\n      features: ['class fields'],\n      options: [\n        {\n          order: [\n            'instance-variables',\n            'static-variables',\n            'static-methods',\n          ],\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          static getDerivedStateFromProps() {}\n          static bar;\n          render() {\n            return null;\n          }\n          foo = {};\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'unsortedProps',\n          data: {\n            propA: 'bar',\n            position: 'after',\n            propB: 'render',\n          },\n        },\n      ],\n      options: [\n        {\n          order: [\n            'static-methods',\n            'render',\n            'static-variables',\n            'instance-variables',\n          ],\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/sort-default-props.js",
    "content": "/**\n * @fileoverview Tests for sort-default-props\n * @author Vladimir Kattsov\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst semver = require('semver');\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/sort-default-props');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('sort-default-props', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            A: PropTypes.any,\n            Z: PropTypes.string,\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              A: \"A\",\n              Z: \"Z\",\n              a: \"a\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            A: PropTypes.any,\n            z: PropTypes.string,\n            Z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              a: \"a\",\n              A: \"A\",\n              z: \"z\",\n              Z: \"Z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              a: \"a\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            AA: PropTypes.any,\n            ZZ: PropTypes.string\n          },\n          getDefaultProps: function() {\n            return {\n              AA: \"AA\",\n              ZZ: \"ZZ\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.string,\n          z: PropTypes.string\n        };\n        First.propTypes.justforcheck = PropTypes.string;\n        First.defaultProps = {\n          a: a,\n          z: z\n        };\n        First.defaultProps.justforcheck = \"justforcheck\";\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.any,\n          A: PropTypes.any,\n          z: PropTypes.string,\n          Z: PropTypes.string\n        };\n        First.defaultProps = {\n          a: \"a\",\n          A: \"A\",\n          z: \"z\",\n          Z: \"Z\"\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"aria-controls\": \"aria-controls\"\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n    // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          propTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          defaultProps: {\n            a: \"a\",\n            c: \"c\",\n            b: \"b\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            barRequired: PropTypes.func.isRequired,\n            onBar: PropTypes.func,\n            z: PropTypes.any\n          },\n          getDefaultProps: function() {\n            return {\n              barRequired: \"barRequired\",\n              onBar: \"onBar\",\n              z: \"z\"\n            };\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            ...c.defaultProps,\n            a: \"a\"\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps,\n            e: \"e\",\n            f: \"f\",\n            ...d.defaultProps\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          c: \"c\",\n          ...defaults,\n          a: \"a\"\n        };\n      `,\n    },\n    {\n      code: `\n        const propTypes = require('./externalPropTypes')\n        const defaultProps = require('./externalDefaultProps')\n        const TextFieldLabel = (props) => {\n          return <div />;\n        };\n        TextFieldLabel.propTypes = propTypes;\n        TextFieldLabel.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        export const propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n        };\n        export const defaultProps = {\n            a: \"a\",\n            z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const First = (props) => <div />;\n        export const propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            z: PropTypes.string,\n        };\n        export const defaultProps = {\n            ...defaults,\n            a: \"a\",\n            z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n\n        First.defaultProps = {\n            a: PropTypes.any,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func,\n            z: PropTypes.string,\n        };\n      `,\n    }\n  )),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            c: \"c\",\n            b: \"b\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 11,\n          column: 13,\n          type: 'Property',\n        },\n      ], /* ,\n      output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      ` */\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            c: \"c\",\n            b: \"b\",\n            a: \"a\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            c: \"c\"\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any\n          };\n          static defaultProps = {\n            Z: \"Z\",\n            a: \"a\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            Z: \"Z\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.any\n          };\n          static defaultProps = {\n            a: \"a\",\n            Z: \"Z\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      /* output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.any\n          };\n          static defaultProps = {\n            Z: \"Z\",\n            a: \"a\",\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"b\": \"b\",\n          \"a\": \"a\"\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"b\": \"b\"\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string,\n          \"c\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"c\": \"c\",\n          \"b\": \"b\",\n          \"a\": \"a\"\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"b\": PropTypes.string,\n          \"c\": PropTypes.string\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"b\": \"b\",\n          \"c\": \"c\"\n        };\n      `, */\n      errors: 2,\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"B\": \"B\",\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"B\": \"B\",\n          \"a\": \"a\",\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    // {\n    // Disabled test for comments -- fails\n    //   code: `\n    //     class Hello extends React.Component {\n    //       render() {\n    //         return <div>Hello</div>;\n    //       }\n    //     }\n    //     Hello.propTypes = {\n    //       \"a\": PropTypes.string,\n    //       \"B\": PropTypes.string,\n    //     };\n    //     Hello.defaultProps = {\n    //       /* a */\n    //       \"a\": \"a\",\n    //       /* B */\n    //       \"B\": \"B\",\n    //     };\n    //   `,\n    //   errors: [\n    //     {\n    //       messageId: 'propsNotSorted',\n    //       line: 14,\n    //       column: 3,\n    //       type: 'Property'\n    //     }\n    //   ],\n    //   output: `\n    //     class Hello extends React.Component {\n    //       render() {\n    //         return <div>Hello</div>;\n    //       }\n    //     }\n    //     Hello.propTypes = {\n    //       \"a\": PropTypes.string,\n    //       \"B\": PropTypes.string,\n    //     };\n    //     Hello.defaultProps = {\n    //       /* B */\n    //       \"B\": \"B\",\n    //       /* a */\n    //       \"a\": \"a\",\n    //     };\n    //   `\n    // },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"B\": \"B\",\n          \"a\": \"a\",\n        };\n      `,\n      /* output: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"a\": PropTypes.string,\n          \"B\": PropTypes.string,\n        };\n        Hello.defaultProps = {\n          \"a\": \"a\",\n          \"B\": \"B\",\n        };\n      `, */\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        const propTypes = {\n          z: PropTypes.string,\n          a: PropTypes.any,\n        };\n        const defaultProps = {\n          z: \"z\",\n          a: \"a\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `,\n      /* output: `\n        const First = (props) => <div />;\n        const propTypes = {\n          z: PropTypes.string,\n          a: PropTypes.any,\n        };\n        const defaultProps = {\n          a: \"a\",\n          z: \"z\",\n        };\n        First.propTypes = propTypes;\n        First.defaultProps = defaultProps;\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            a: \"a\",\n            ...c.defaultProps\n          }\n        }\n      `,\n      /* output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 10,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            b: \"b\",\n            a: \"a\",\n            ...c.defaultProps,\n            f: \"f\",\n            e: \"e\",\n            ...d.defaultProps\n          }\n        }\n      `,\n      /* output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            a: PropTypes.string,\n            b: PropTypes.string,\n            c: PropTypes.string,\n            d: PropTypes.string,\n            e: PropTypes.string,\n            f: PropTypes.string\n          }\n          static defaultProps = {\n            a: \"a\",\n            b: \"b\",\n            ...c.defaultProps,\n            e: \"e\",\n            f: \"f\",\n            ...d.defaultProps\n          }\n        }\n      `, */\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          c: \"c\",\n          a: \"a\",\n          ...defaults,\n        };\n      `,\n      /* output: `\n        const defaults = {\n          b: \"b\"\n        };\n        const types = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n          c: PropTypes.string\n        };\n        function StatelessComponentWithSpreadInPropTypes({ a, b, c }) {\n          return <div>{a}{b}{c}</div>;\n        }\n        StatelessComponentWithSpreadInPropTypes.propTypes = types;\n        StatelessComponentWithSpreadInPropTypes.defaultProps = {\n          a: \"a\",\n          c: \"c\",\n          ...defaults,\n        };\n      `, */\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 16,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n\n        First.defaultProps = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func,\n        };\n      `,\n      errors: [\n        { messageId: 'propsNotSorted', line: 11 },\n        { messageId: 'propsNotSorted', line: 12 },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/sort-prop-types.js",
    "content": "/**\n * @fileoverview Tests for sort-prop-types\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst babelEslintVersion = require('babel-eslint/package.json').version;\nconst semver = require('semver');\nconst eslintPkg = require('eslint/package.json');\nconst RuleTester = require('../../helpers/ruleTester');\n\nconst rule = require('../../../lib/rules/sort-prop-types');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('sort-prop-types', rule, {\n  valid: parsers.all([].concat(\n    {\n      code: `\n        var First = createReactClass({\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: externalPropTypes,\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            A: PropTypes.any,\n            Z: PropTypes.string,\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            A: PropTypes.any,\n            z: PropTypes.string,\n            Z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            AA: PropTypes.any,\n            ZZ: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.string,\n          z: PropTypes.string\n        };\n        First.propTypes.justforcheck = PropTypes.string;\n      `,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n          a: PropTypes.any,\n          A: PropTypes.any,\n          z: PropTypes.string,\n          Z: PropTypes.string\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            b: PropTypes.any,\n            c: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Hello extends React.Component {\n          render() {\n            return <div>Hello</div>;\n          }\n        }\n        Hello.propTypes = {\n          \"aria-controls\": PropTypes.string\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    semver.satisfies(babelEslintVersion, '< 9') ? {\n      // Invalid code, should not be validated\n      code: `\n        class Component extends React.Component {\n          propTypes: {\n            a: PropTypes.any,\n            c: PropTypes.any,\n            b: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      parser: parsers.BABEL_ESLINT,\n    } : [],\n    {\n      code: `\n        var Hello = createReactClass({\n          render: function() {\n            let { a, ...b } = obj;\n            let c = { ...d };\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            barRequired: PropTypes.func.isRequired,\n            onBar: PropTypes.func,\n            z: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ callbacksLast: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ callbacksLast: true }],\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n        };\n      `,\n      options: [{ callbacksLast: true }],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            barRequired: PropTypes.string.isRequired,\n            a: PropTypes.any\n        };\n      `,\n      options: [{ requiredFirst: true }],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            fooRequired: MyPropType,\n        };\n      `,\n      options: [{ requiredFirst: true }],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            barRequired: PropTypes.string.isRequired,\n            fooRequired: PropTypes.any.isRequired,\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n        };\n      `,\n      options: [\n        {\n          requiredFirst: true,\n          callbacksLast: true,\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...c.propTypes,\n            a: PropTypes.string\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const propTypes = require('./externalPropTypes')\n        const TextFieldLabel = (props) => {\n          return <div />;\n        };\n        TextFieldLabel.propTypes = propTypes;\n      `,\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        export const propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n        };\n        First.propTypes = propTypes;\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            c: PropTypes.any,\n            C: PropTypes.string,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n          }),\n        };\n      `,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          a: PropTypes.any,\n          b: PropTypes.any,\n          c: PropTypes.shape({\n            c: PropTypes.any,\n            ...otherPropTypes,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n          }),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          a: PropTypes.any,\n          b: PropTypes.any,\n          c: PropTypes.shape(\n            importedPropType,\n          ),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          a: PropTypes.any,\n          z: PropTypes.any,\n        };\n      `,\n      options: [{ noSortAlphabetically: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          z: PropTypes.any,\n          a: PropTypes.any,\n        };\n      `,\n      options: [{ noSortAlphabetically: true }],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          0: PropTypes.any,\n          1: PropTypes.any,\n        };\n      `,\n      options: [{ ignoreCase: true }],\n    },\n    {\n      code: `\n        const shape = {\n          a: PropTypes.any,\n          b: PropTypes.bool,\n          c: PropTypes.any,\n        };\n        class Component extends React.Component {\n          static propTypes = {\n            x: PropTypes.shape(shape),\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ sortShapeProp: true }],\n      features: ['class fields'],\n    },\n    {\n      code: `\n        const shape = {\n          a: PropTypes.any,\n          b: PropTypes.bool,\n          c: PropTypes.any,\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.shape(shape)\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n    },\n    {\n      code: `\n        var Component = createReactClass({\n          propTypes: {\n            a: React.PropTypes.string,\n            c: React.PropTypes.string,\n            b: React.PropTypes.string,\n            onChange: React.PropTypes.func,\n          }\n        });\n      `,\n      options: [{ callbacksLast: true, noSortAlphabetically: true }],\n    },\n    {\n      code: `\n        type Props = {\n          zzz: string;\n          aaa: string;\n        }\n        function Foo(props: Props) {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: false }],\n    },\n    {\n      code: `\n        function Foo() {\n          return <div />;\n        }\n      `,\n      options: [{ checkTypes: true }],\n    },\n    {\n      code: `\n        const Foo = (props: {\n          aaa: string,\n          zzz: string\n        }) => {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n    }\n  )),\n  invalid: parsers.all([].concat(\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            z: PropTypes.string,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            /* z */\n            z: PropTypes.string,\n            /* a */\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            /* a */\n            a: PropTypes.any,\n            /* z */\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 7,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            z: PropTypes.any,\n            Z: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            Z: PropTypes.any,\n            z: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            Z: PropTypes.any,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            Z: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            A: PropTypes.any,\n            z: PropTypes.string,\n            Z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            A: PropTypes.any,\n            Z: PropTypes.string,\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            Zz: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            aAA: PropTypes.any,\n            ZZ: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            Zz: PropTypes.string,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n        var Second = createReactClass({\n          propTypes: {\n            ZZ: PropTypes.string,\n            aAA: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            yy: PropTypes.any,\n            bb: PropTypes.string\n        };\n        class Second extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Second.propTypes = {\n            aAA: PropTypes.any,\n            ZZ: PropTypes.string\n        };\n      `,\n      output: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            bb: PropTypes.string,\n            yy: PropTypes.any\n        };\n        class Second extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Second.propTypes = {\n            ZZ: PropTypes.string,\n            aAA: PropTypes.any\n        };\n      `,\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            z: PropTypes.any,\n            y: PropTypes.any,\n            a: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            y: PropTypes.any,\n            z: PropTypes.any\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: 2,\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = forbidExtraProps({\n            z: PropTypes.any,\n            y: PropTypes.any,\n            a: PropTypes.any\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      output: `\n        class Component extends React.Component {\n          static propTypes = forbidExtraProps({\n            a: PropTypes.any,\n            y: PropTypes.any,\n            z: PropTypes.any\n          });\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      features: ['class fields'],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: 2,\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ callbacksLast: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 7,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ callbacksLast: true }],\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 7,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func\n        };\n      `,\n      output: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n        };\n      `,\n      options: [{ callbacksLast: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 11,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = forbidExtraProps({\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onFoo: PropTypes.func,\n            onBar: PropTypes.func\n        });\n      `,\n      output: `\n        class First extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        First.propTypes = forbidExtraProps({\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n        });\n      `,\n      options: [{ callbacksLast: true }],\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 11,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        const propTypes = {\n            z: PropTypes.string,\n            a: PropTypes.any,\n        };\n        First.propTypes = forbidExtraProps(propTypes);\n      `,\n      output: `\n        const First = (props) => <div />;\n        const propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n        };\n        First.propTypes = forbidExtraProps(propTypes);\n      `,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const First = (props) => <div />;\n        const propTypes = {\n            z: PropTypes.string,\n            a: PropTypes.any,\n        };\n        First.propTypes = propTypes;\n      `,\n      output: `\n        const First = (props) => <div />;\n        const propTypes = {\n            a: PropTypes.any,\n            z: PropTypes.string,\n        };\n        First.propTypes = propTypes;\n      `,\n      settings: {\n        propWrapperFunctions: ['forbidExtraProps'],\n      },\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string,\n            onBar: PropTypes.func,\n            onFoo: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ callbacksLast: true }],\n      errors: [\n        {\n          messageId: 'callbackPropsLast',\n          line: 6,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            fooRequired: PropTypes.string.isRequired,\n            barRequired: PropTypes.string.isRequired,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            barRequired: PropTypes.string.isRequired,\n            fooRequired: PropTypes.string.isRequired,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ requiredFirst: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            barRequired: PropTypes.string.isRequired,\n            onFoo: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            barRequired: PropTypes.string.isRequired,\n            a: PropTypes.any,\n            onFoo: PropTypes.func\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ requiredFirst: true }],\n      errors: [\n        {\n          messageId: 'requiredPropsFirst',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...a.propTypes,\n            d: PropTypes.string,\n            c: PropTypes.string\n          }\n        }\n      `,\n      output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...a.propTypes,\n            c: PropTypes.string,\n            d: PropTypes.string\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 7,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...a.propTypes,\n            f: PropTypes.string,\n            d: PropTypes.string,\n            ...e.propTypes,\n            c: PropTypes.string\n          }\n        }\n      `,\n      output: `\n        export default class ClassWithSpreadInPropTypes extends BaseClass {\n          static propTypes = {\n            b: PropTypes.string,\n            ...a.propTypes,\n            d: PropTypes.string,\n            f: PropTypes.string,\n            ...e.propTypes,\n            c: PropTypes.string\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 7,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const propTypes = {\n          b: PropTypes.string,\n          a: PropTypes.string,\n        };\n        const TextFieldLabel = (props) => {\n          return <div />;\n        };\n        TextFieldLabel.propTypes = propTypes;\n      `,\n      output: `\n        const propTypes = {\n          a: PropTypes.string,\n          b: PropTypes.string,\n        };\n        const TextFieldLabel = (props) => {\n          return <div />;\n        };\n        TextFieldLabel.propTypes = propTypes;\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            c: PropTypes.any,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.any,\n            b: PropTypes.bool,\n            c: PropTypes.any,\n          }),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 12,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          z: PropTypes.shape(),\n          y: PropTypes.any,\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape(),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 10,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          z: PropTypes.shape(someType),\n          y: PropTypes.any,\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape(someType),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 10,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          z: PropTypes.any,\n          y: PropTypes.any,\n          a: PropTypes.shape({\n            c: PropTypes.any,\n            C: PropTypes.string,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          a: PropTypes.shape({\n            C: PropTypes.string,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n            c: PropTypes.any,\n          }),\n          y: PropTypes.any,\n          z: PropTypes.any,\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 10,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 12,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 14,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            c: PropTypes.any,\n            C: PropTypes.string,\n            a: PropTypes.any,\n            b: PropTypes.bool,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.any,\n            b: PropTypes.bool,\n            c: PropTypes.any,\n            C: PropTypes.string,\n          }),\n        };\n      `,\n      options: [\n        {\n          sortShapeProp: true,\n          ignoreCase: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 14,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            c: PropTypes.number.isRequired,\n            b: PropTypes.any,\n            d: PropTypes.bool,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            c: PropTypes.number.isRequired,\n            a: PropTypes.string,\n            b: PropTypes.any,\n            d: PropTypes.bool,\n          }),\n        };\n      `,\n      options: [\n        {\n          sortShapeProp: true,\n          requiredFirst: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'requiredPropsFirst',\n          line: 12,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            c: PropTypes.number.isRequired,\n            b: PropTypes.any,\n            onFoo: PropTypes.func,\n            d: PropTypes.bool,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            b: PropTypes.any,\n            c: PropTypes.number.isRequired,\n            d: PropTypes.bool,\n            onFoo: PropTypes.func,\n          }),\n        };\n      `,\n      options: [\n        {\n          sortShapeProp: true,\n          callbacksLast: true,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'callbackPropsLast',\n          line: 14,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            c: PropTypes.number.isRequired,\n            b: PropTypes.any,\n            ...otherPropTypes,\n            f: PropTypes.bool,\n            d: PropTypes.string,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            b: PropTypes.any,\n            c: PropTypes.number.isRequired,\n            ...otherPropTypes,\n            d: PropTypes.string,\n            f: PropTypes.bool,\n          }),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 16,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          static propTypes = {\n            z: PropTypes.any,\n            y: PropTypes.any,\n            a: PropTypes.shape({\n              c: PropTypes.any,\n              a: PropTypes.any,\n              b: PropTypes.bool,\n            }),\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      output: `\n        class Component extends React.Component {\n          static propTypes = {\n            a: PropTypes.shape({\n              a: PropTypes.any,\n              b: PropTypes.bool,\n              c: PropTypes.any,\n            }),\n            y: PropTypes.any,\n            z: PropTypes.any,\n          };\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ sortShapeProp: true }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 6,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 8,\n          column: 15,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 15,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            z: PropTypes.string,\n            a: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ noSortAlphabetically: false }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            'data-letter': PropTypes.string,\n            a: PropTypes.any,\n            e: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any,\n            'data-letter': PropTypes.string,\n            e: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      options: [{ noSortAlphabetically: false }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          1: PropTypes.any,\n          0: PropTypes.any,\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          0: PropTypes.any,\n          1: PropTypes.any,\n        };\n      `,\n      options: [{ ignoreCase: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 9,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const shape = {\n          c: PropTypes.any,\n          a: PropTypes.any,\n          b: PropTypes.bool,\n        };\n        class Component extends React.Component {\n          static propTypes = {\n            x: PropTypes.shape(shape),\n          };\n\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      output: `\n        const shape = {\n          a: PropTypes.any,\n          b: PropTypes.bool,\n          c: PropTypes.any,\n        };\n        class Component extends React.Component {\n          static propTypes = {\n            x: PropTypes.shape(shape),\n          };\n\n          render() {\n            return <div />;\n          }\n        }\n      `,\n      options: [{ sortShapeProp: true }],\n      features: ['class fields', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        const shape = {\n          c: PropTypes.any,\n          a: PropTypes.any,\n          b: PropTypes.bool,\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.shape(shape)\n        };\n      `,\n      output: `\n        const shape = {\n          a: PropTypes.any,\n          b: PropTypes.bool,\n          c: PropTypes.any,\n        };\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.shape(shape)\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 11,\n          type: 'Property',\n        },\n      ],\n    },\n    {\n      code: `\n        var Component = React.createClass({\n          propTypes: {\n            onChange: React.PropTypes.func,\n            a: React.PropTypes.string,\n            c: React.PropTypes.string,\n            b: React.PropTypes.string,\n          }\n        });\n      `,\n      output: `\n        var Component = React.createClass({\n          propTypes: {\n            a: React.PropTypes.string,\n            b: React.PropTypes.string,\n            c: React.PropTypes.string,\n            onChange: React.PropTypes.func,\n          }\n        });\n      `,\n      options: [{ callbacksLast: true }],\n      errors: [\n        {\n          messageId: 'callbackPropsLast',\n          line: 4,\n        },\n      ],\n    },\n    {\n      code: `\n        var Component = createReactClass({\n          propTypes: {\n            onChange: React.PropTypes.func,\n            a: React.PropTypes.string,\n            c: React.PropTypes.string,\n            b: React.PropTypes.string,\n          }\n        });\n      `,\n      output: `\n        var Component = createReactClass({\n          propTypes: {\n            a: React.PropTypes.string,\n            c: React.PropTypes.string,\n            b: React.PropTypes.string,\n            onChange: React.PropTypes.func,\n          }\n        });\n      `,\n      options: [{ callbacksLast: true, noSortAlphabetically: true }],\n      errors: [\n        {\n          messageId: 'callbackPropsLast',\n          line: 4,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    },\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            z: PropTypes.string /* z */,\n            a: PropTypes.any /* a */,\n            b: PropTypes.any /* b */\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            a: PropTypes.any /* a */,\n            b: PropTypes.any /* b */,\n            z: PropTypes.string /* z */\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 6,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            /* z */ z: PropTypes.string,\n            /* a */ a: PropTypes.any,\n            /* b */ b: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            /* a */ a: PropTypes.any,\n            /* b */ b: PropTypes.any,\n            /* z */ z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 21,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 6,\n          column: 21,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            /* z */ z: PropTypes.string /* z */,\n            /* a */ a: PropTypes.any /* a */,\n            /* b */ b: PropTypes.any /* b */\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            /* a */ a: PropTypes.any /* a */,\n            /* b */ b: PropTypes.any /* b */,\n            /* z */ z: PropTypes.string /* z */\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 5,\n          column: 21,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 6,\n          column: 21,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            /* z */ z: PropTypes.string, /* a */ a: PropTypes.any, /* b */ b: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            /* a */ a: PropTypes.any, /* b */ b: PropTypes.any, /* z */ z: PropTypes.string\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 50,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 76,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            c: PropTypes.number.isRequired /* c */,\n            b: PropTypes.any,\n            ...otherPropTypes,\n            f: PropTypes.bool,\n            /* d */\n            d: PropTypes.string,\n          }),\n        };\n      `,\n      output: `\n        class Component extends React.Component {\n          render() {\n            return <div />;\n          }\n        }\n        Component.propTypes = {\n          x: PropTypes.any,\n          y: PropTypes.any,\n          z: PropTypes.shape({\n            a: PropTypes.string,\n            b: PropTypes.any,\n            c: PropTypes.number.isRequired /* c */,\n            ...otherPropTypes,\n            /* d */\n            d: PropTypes.string,\n            f: PropTypes.bool,\n          }),\n        };\n      `,\n      options: [{ sortShapeProp: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 13,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 17,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var First = createReactClass({\n          propTypes: {\n            /* z */\n            /* z */\n            z: PropTypes.string /* z */,\n            /* a */\n            a: PropTypes.any /* a */\n            /* a */\n            /* a */,\n            b: PropTypes.any\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      output: `\n        var First = createReactClass({\n          propTypes: {\n            /* a */\n            a: PropTypes.any /* a */\n            /* a */\n            /* a */,\n            b: PropTypes.any,\n            /* z */\n            /* z */\n            z: PropTypes.string /* z */\n          },\n          render: function() {\n            return <div />;\n          }\n        });\n      `,\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 8,\n          column: 13,\n          type: 'Property',\n        },\n        {\n          messageId: 'propsNotSorted',\n          line: 11,\n          column: 13,\n          type: 'Property',\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var Component = createReactClass({\n          propTypes: {\n            /* onChange */ onChange: React.PropTypes.func,\n            /* a */ a: React.PropTypes.string,\n            /* c */ c: React.PropTypes.string,\n            /* b */ b: React.PropTypes.string,\n          }\n        });\n      `,\n      output: `\n        var Component = createReactClass({\n          propTypes: {\n            /* a */ a: React.PropTypes.string,\n            /* c */ c: React.PropTypes.string,\n            /* b */ b: React.PropTypes.string,\n            /* onChange */ onChange: React.PropTypes.func,\n          }\n        });\n      `,\n      options: [{ callbacksLast: true, noSortAlphabetically: true }],\n      errors: [\n        {\n          messageId: 'callbackPropsLast',\n          line: 4,\n        },\n      ],\n    } : [],\n    semver.satisfies(eslintPkg.version, '> 3') ? {\n      code: `\n        var Component = createReactClass({\n          propTypes: {\n            /* onChange */ onChange: React.PropTypes.func /* onChange */,\n            /* a */ a: React.PropTypes.string /* a */,\n            /* c */ c: React.PropTypes.string /* c */,\n            /* b */ b: React.PropTypes.string /* b */,\n          }\n        });\n      `,\n      output: `\n        var Component = createReactClass({\n          propTypes: {\n            /* a */ a: React.PropTypes.string /* a */,\n            /* c */ c: React.PropTypes.string /* c */,\n            /* b */ b: React.PropTypes.string /* b */,\n            /* onChange */ onChange: React.PropTypes.func /* onChange */,\n          }\n        });\n      `,\n      options: [{ callbacksLast: true, noSortAlphabetically: true }],\n      errors: [\n        {\n          messageId: 'callbackPropsLast',\n          line: 4,\n        },\n      ],\n    } : [],\n    {\n      code: `\n        type Props = {\n          zzz: string;\n          aaa: string;\n        }\n        function Foo(props: Props) {\n          return null;\n        }\n      `,\n      output: `\n        type Props = {\n          aaa: string;\n          zzz: string;\n        }\n        function Foo(props: Props) {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type Props = {\n          zzz: string;\n          aaa: string;\n        }\n        const Foo = (props: Props) => {\n          return null;\n        }\n      `,\n      output: `\n        type Props = {\n          aaa: string;\n          zzz: string;\n        }\n        const Foo = (props: Props) => {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        const Foo = (props: {\n          zzz: string,\n          aaa: string,\n        }) => {\n          return null;\n        }\n      `,\n      output: `\n        const Foo = (props: {\n          aaa: string,\n          zzz: string,\n        }) => {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 4,\n          column: 11,\n        },\n      ],\n    },\n    {\n      code: `\n        type CustomProps = { onChange: () => void; name: string };\n        const Foo = (props: CustomProps) => {\n          return null;\n        }\n      `,\n      output: `\n        type CustomProps = { name: string; onChange: () => void };\n        const Foo = (props: CustomProps) => {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 2,\n          column: 52,\n        },\n      ],\n    },\n    {\n      code: `\n        type CustomProps = { onChange: (event: { target: { name: string; value: string } }) => void; name: string };\n        const Foo = (props: CustomProps) => {\n          return null;\n        }\n      `,\n      output: `\n        type CustomProps = { name: string; onChange: (event: { target: { name: string; value: string } }) => void };\n        const Foo = (props: CustomProps) => {\n          return null;\n        }\n      `,\n      features: ['types'],\n      options: [{ checkTypes: true }],\n      errors: [\n        {\n          messageId: 'propsNotSorted',\n          line: 2,\n          column: 102,\n        },\n      ],\n    }\n  )),\n});\n"
  },
  {
    "path": "tests/lib/rules/state-in-constructor.js",
    "content": "/**\n * @fileoverview Enforce the state initialization style to be either in a constructor or with a class property\n * @author Kanitkorn Sujautra\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/state-in-constructor');\n\nconst parsers = require('../../helpers/parsers');\n\nconst ruleTesterConfig = {\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester(ruleTesterConfig);\nruleTester.run('state-in-constructor', rule, {\n  valid: parsers.all([\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['always'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.baz = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.baz = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n    },\n    {\n      code: `\n        const Foo = () => <div>Foo</div>\n      `,\n    },\n    {\n      code: `\n        const Foo = () => <div>Foo</div>\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        function Foo () {\n          return <div>Foo</div>\n        }\n      `,\n    },\n    {\n      code: `\n        function Foo () {\n          return <div>Foo</div>\n        }\n      `,\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          state = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          state = { bar: 0 }\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.baz = { bar: 0 }\n          }\n          state = { baz: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            if (foobar) {\n              this.state = { bar: 0 }\n            }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            foobar = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            foobar = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      options: ['never'],\n    },\n  ]),\n\n  invalid: parsers.all([\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      options: ['never'],\n      errors: [{ messageId: 'stateInitClassProp' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n      errors: [{ messageId: 'stateInitClassProp' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          state = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'stateInitConstructor' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          state = { bar: 0 }\n          baz = { bar: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'stateInitConstructor' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.baz = { bar: 0 }\n          }\n          state = { baz: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'stateInitConstructor' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          state = { baz: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      errors: [{ messageId: 'stateInitConstructor' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            this.state = { bar: 0 }\n          }\n          state = { baz: 0 }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n      errors: [{ messageId: 'stateInitClassProp' }],\n    },\n    {\n      code: `\n        class Foo extends React.Component {\n          constructor(props) {\n            super(props)\n            if (foobar) {\n              this.state = { bar: 0 }\n            }\n          }\n          render() {\n            return <div>Foo</div>\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: ['never'],\n      errors: [{ messageId: 'stateInitClassProp' }],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/static-property-placement.js",
    "content": "/**\n * @fileoverview Defines where React component static properties should be positioned.\n * @author Daniel Mason\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Positioning Options\n// ------------------------------------------------------------------------------\nconst STATIC_PUBLIC_FIELD = 'static public field';\nconst STATIC_GETTER = 'static getter';\nconst PROPERTY_ASSIGNMENT = 'property assignment';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/static-property-placement');\n\nconst parsers = require('../../helpers/parsers');\n\nconst ruleTesterConfig = {\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n  settings: {\n    react: {\n      version: '15',\n    },\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester(ruleTesterConfig);\nruleTester.run('static-property-placement', rule, {\n  valid: parsers.all([\n    // ------------------------------------------------------------------------------\n    // Ignore createClass/createReactClass and Static Functional Components\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error on createReactClass pragma\n      code: `\n        var MyComponent = createReactClass({\n          childContextTypes: {\n            something: PropTypes.bool\n          },\n\n          contextTypes: {\n            something: PropTypes.bool\n          },\n\n          getDefaultProps: function() {\n            name: 'Bob'\n          },\n\n          displayName: 'Hello',\n\n          propTypes: {\n            something: PropTypes.bool\n          },\n\n          render: function() {\n            return null;\n          },\n        });\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error on createClass pragma\n      code: `\n        var MyComponent = React.createClass({\n          childContextTypes: {\n            something: PropTypes.bool\n          },\n\n          contextTypes: {\n            something: PropTypes.bool\n          },\n\n          getDefaultProps: function() {\n            name: 'Bob'\n          },\n\n          displayName: 'Hello',\n\n          propTypes: {\n            something: PropTypes.bool\n          },\n\n          render: function() {\n            return null;\n          },\n        });\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error on SFC arrow function with return\n      code: `\n        const MyComponent = () => {\n            return <div>Hello</div>;\n        };\n\n        MyComponent.childContextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.contextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.defaultProps = {\n          something: 'Bob'\n        };\n\n        MyComponent.displayName = 'Hello';\n\n        MyComponent.propTypes = {\n          something: PropTypes.bool\n        };\n      `,\n    },\n    {\n      // Do not error on SFC arrow function with direct return\n      code: `\n        const MyComponent = () => (<div>Hello</div>);\n\n        MyComponent.childContextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.contextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.defaultProps = {\n          something: 'Bob'\n        };\n\n        MyComponent.displayName = 'Hello';\n\n        MyComponent.propTypes = {\n          something: PropTypes.bool\n        };\n      `,\n    },\n    {\n      // Do not error on SFC as unnamed function\n      code: `\n        export function MyComponent () {\n            return <div>Hello</div>;\n        };\n\n        MyComponent.childContextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.contextTypes = {\n          something: PropTypes.bool\n        };\n\n        MyComponent.defaultProps = {\n          something: 'Bob'\n        };\n\n        MyComponent.displayName = 'Hello';\n\n        MyComponent.propTypes = {\n          something: PropTypes.bool\n        };\n      `,\n    },\n\n    {\n      // Do not error on non-component classes #2884\n      code: `\n        class Foo {\n          static get propTypes() {}\n        }\n      `,\n    },\n\n    {\n      // Do not error on non-component classes #2884\n      code: `\n        class Foo {\n          static propTypes = {}\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT],\n    },\n\n    // ------------------------------------------------------------------------------\n    // no properties\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if no properties defined\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n      `,\n    },\n    {\n      // Do not error if unchecked properties defined\n      code: `\n        class MyComponent extends React.Component {\n          static randomlyNamed = {\n            name: 'random'\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if unchecked static properties defined and assignment rule enabled\n      code: `\n        class MyComponent extends React.Component {\n          static randomlyNamed = {\n            name: 'random'\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if unchecked assignment properties defined and assignment rule enabled\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.randomlyNamed = {\n          name: 'random'\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if unchecked assignment properties defined and static rule enabled\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.randomlyNamed = {\n          name: 'random'\n        }\n      `,\n    },\n    // ------------------------------------------------------------------------------\n    // childContextTypes - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if childContextTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if childContextTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, { childContextTypes: STATIC_PUBLIC_FIELD }],\n    },\n    // ------------------------------------------------------------------------------\n    // childContextTypes - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if childContextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { childContextTypes: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // childContextTypes - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if childContextTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if childContextTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [STATIC_PUBLIC_FIELD, { childContextTypes: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // contextTypes - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, { contextTypes: STATIC_PUBLIC_FIELD }],\n    },\n    // ------------------------------------------------------------------------------\n    // contextTypes - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { contextTypes: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // contextTypes - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if contextTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [STATIC_PUBLIC_FIELD, { contextTypes: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // contextType - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextType correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static contextType = MyContext;\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if contextType correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static contextType = MyContext;\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { contextType: STATIC_PUBLIC_FIELD }],\n      features: ['class fields'],\n    },\n    // ------------------------------------------------------------------------------\n    // contextType - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextType correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static get contextType() {\n             return MyContext;\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextType correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static get contextType() {\n             return MyContext;\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { contextType: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // contextType - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if contextType correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.contextType = MyContext;\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if contextType correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.contextType = MyContext;\n      `,\n      options: [STATIC_PUBLIC_FIELD, { contextType: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // displayName - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if displayName correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static displayName = \"Hello\";\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if displayName correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static displayName = \"Hello\";\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, { displayName: STATIC_PUBLIC_FIELD }],\n    },\n    // ------------------------------------------------------------------------------\n    // displayName - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if displayName correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { displayName: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // displayName - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if displayName correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.displayName = \"Hello\";\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if displayName correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.displayName = \"Hello\";\n      `,\n      options: [STATIC_PUBLIC_FIELD, { displayName: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // defaultProps - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if defaultProps correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static defaultProps = {\n            something: 'Bob'\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if defaultProps correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static defaultProps = {\n            something: 'Bob'\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, { defaultProps: STATIC_PUBLIC_FIELD }],\n    },\n    // ------------------------------------------------------------------------------\n    // defaultProps - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if defaultProps correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get defaultProps() {\n            return {\n              something: 'Bob'\n            };\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get defaultProps() {\n            return {\n              something: 'Bob'\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { defaultProps: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // defaultProps - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if defaultProps correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if defaultProps correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n      `,\n      options: [STATIC_PUBLIC_FIELD, { defaultProps: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // propTypes - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if propTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if propTypes correctly defined - static field\n      code: `\n        class MyComponent extends React.Component {\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, { propTypes: STATIC_PUBLIC_FIELD }],\n    },\n    // ------------------------------------------------------------------------------\n    // propTypes - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if propTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, { propTypes: STATIC_GETTER }],\n    },\n    // ------------------------------------------------------------------------------\n    // propTypes - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if propTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if propTypes correctly defined - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [STATIC_PUBLIC_FIELD, { propTypes: PROPERTY_ASSIGNMENT }],\n    },\n    // ------------------------------------------------------------------------------\n    // multiple - static field\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if multiple properties and match config - static field\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Do not error if multiple properties and match config - static field\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, {\n        childContextTypes: STATIC_PUBLIC_FIELD,\n        contextTypes: STATIC_PUBLIC_FIELD,\n        contextType: STATIC_PUBLIC_FIELD,\n        displayName: STATIC_PUBLIC_FIELD,\n        defaultProps: STATIC_PUBLIC_FIELD,\n        propTypes: STATIC_PUBLIC_FIELD,\n      }],\n    },\n    // ------------------------------------------------------------------------------\n    // multiple - static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if childContextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [STATIC_GETTER],\n    },\n    {\n      // Do not error if contextTypes correctly defined - static getter\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, {\n        childContextTypes: STATIC_GETTER,\n        contextTypes: STATIC_GETTER,\n        contextType: STATIC_GETTER,\n        displayName: STATIC_GETTER,\n        defaultProps: STATIC_GETTER,\n        propTypes: STATIC_GETTER,\n      }],\n    },\n    // ------------------------------------------------------------------------------\n    // multiple - assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if multiple properties and match config - assignment\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n    },\n    {\n      // Do not error if multiple properties and match config - static field\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [STATIC_PUBLIC_FIELD, {\n        childContextTypes: PROPERTY_ASSIGNMENT,\n        contextTypes: PROPERTY_ASSIGNMENT,\n        displayName: PROPERTY_ASSIGNMENT,\n        defaultProps: PROPERTY_ASSIGNMENT,\n        propTypes: PROPERTY_ASSIGNMENT,\n      }],\n    },\n    // ------------------------------------------------------------------------------\n    // combined - mixed\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if mixed property positions and match config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static get displayName() {\n            return \"Hello\"\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n      options: [STATIC_PUBLIC_FIELD, {\n        displayName: STATIC_GETTER,\n        defaultProps: PROPERTY_ASSIGNMENT,\n        propTypes: PROPERTY_ASSIGNMENT,\n      }],\n    },\n    {\n      // Do not error if mixed property positions and match config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static get displayName() {\n            return \"Hello\"\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT, {\n        childContextTypes: STATIC_PUBLIC_FIELD,\n        contextTypes: STATIC_PUBLIC_FIELD,\n        displayName: STATIC_GETTER,\n      }],\n    },\n    // ------------------------------------------------------------------------------\n    // mixed component types\n    // ------------------------------------------------------------------------------\n    {\n      // SFC ignored and component is valid\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static displayName = \"Hello\";\n        }\n\n        const OtherComponent = () => (<div>Hello</div>);\n\n        OtherComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        OtherComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n    },\n    {\n      // Multiple components validated\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static displayName = \"Hello\";\n        }\n\n        class OtherComponent extends React.Component {\n          static defaultProps = {\n            name: 'Bob'\n          }\n\n          static propTypes = {\n            name: PropTypes.string.isRequired\n          }\n        }\n      `,\n      features: ['class fields'],\n    },\n    // ------------------------------------------------------------------------------\n    // edge cases\n    // ------------------------------------------------------------------------------\n    {\n      // Do not error if property assignment is inside a class function\n      code: `\n        class MyComponent extends React.Component {\n          static displayName = \"Hello\";\n\n          myMethod() {\n            console.log(MyComponent.displayName);\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [STATIC_PUBLIC_FIELD],\n    },\n    {\n      // Do not error if display name value changed\n      code: `\n        class MyComponent extends React.Component {\n          static displayName = \"Hello\";\n\n          myMethod() {\n            MyComponent.displayName = \"Bonjour\";\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [STATIC_PUBLIC_FIELD],\n    },\n  ]),\n\n  invalid: parsers.all([\n    // ------------------------------------------------------------------------------\n    // expected static field when got property assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextType = MyContext;\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      errors: [\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextType = MyContext;\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT, {\n        childContextTypes: STATIC_PUBLIC_FIELD,\n        contextTypes: STATIC_PUBLIC_FIELD,\n        contextType: STATIC_PUBLIC_FIELD,\n        displayName: STATIC_PUBLIC_FIELD,\n        defaultProps: STATIC_PUBLIC_FIELD,\n        propTypes: STATIC_PUBLIC_FIELD,\n      }],\n      errors: [\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // expected static field when got static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      errors: [\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [\n        PROPERTY_ASSIGNMENT,\n        {\n          childContextTypes: STATIC_PUBLIC_FIELD,\n          contextTypes: STATIC_PUBLIC_FIELD,\n          contextType: STATIC_PUBLIC_FIELD,\n          displayName: STATIC_PUBLIC_FIELD,\n          defaultProps: STATIC_PUBLIC_FIELD,\n          propTypes: STATIC_PUBLIC_FIELD,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // expected property assignment when got static field\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        STATIC_PUBLIC_FIELD,\n        {\n          childContextTypes: PROPERTY_ASSIGNMENT,\n          contextTypes: PROPERTY_ASSIGNMENT,\n          contextType: PROPERTY_ASSIGNMENT,\n          displayName: PROPERTY_ASSIGNMENT,\n          defaultProps: PROPERTY_ASSIGNMENT,\n          propTypes: PROPERTY_ASSIGNMENT,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // expected property assignment when got static getter\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [PROPERTY_ASSIGNMENT],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static get childContextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get contextType() {\n            return MyContext;\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n\n          static get defaultProps() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n\n          static get propTypes() {\n            return {\n              something: PropTypes.bool\n            };\n          }\n        }\n      `,\n      options: [\n        STATIC_GETTER,\n        {\n          childContextTypes: PROPERTY_ASSIGNMENT,\n          contextTypes: PROPERTY_ASSIGNMENT,\n          contextType: PROPERTY_ASSIGNMENT,\n          displayName: PROPERTY_ASSIGNMENT,\n          defaultProps: PROPERTY_ASSIGNMENT,\n          propTypes: PROPERTY_ASSIGNMENT,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // expected static getter when got static field\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [STATIC_GETTER],\n      errors: [\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextTypes = {\n            something: PropTypes.bool\n          };\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n\n          static defaultProps = {\n            something: 'Bob'\n          };\n\n          static propTypes = {\n            something: PropTypes.bool\n          };\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        STATIC_PUBLIC_FIELD,\n        {\n          childContextTypes: STATIC_GETTER,\n          contextTypes: STATIC_GETTER,\n          contextType: STATIC_GETTER,\n          displayName: STATIC_GETTER,\n          defaultProps: STATIC_GETTER,\n          propTypes: STATIC_GETTER,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // expected static getter when got property assignment\n    // ------------------------------------------------------------------------------\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextType = MyContext;\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [STATIC_GETTER],\n      errors: [\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if multiple properties are incorrectly positioned according to config\n      code: `\n        class MyComponent extends React.Component {\n          render() {\n            return null;\n          }\n        }\n\n        MyComponent.childContextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextTypes = {\n          name: PropTypes.string.isRequired\n        }\n\n        MyComponent.contextType = MyContext;\n\n        MyComponent.displayName = \"Hello\";\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      options: [\n        PROPERTY_ASSIGNMENT,\n        {\n          childContextTypes: STATIC_GETTER,\n          contextTypes: STATIC_GETTER,\n          contextType: STATIC_GETTER,\n          displayName: STATIC_GETTER,\n          defaultProps: STATIC_GETTER,\n          propTypes: STATIC_GETTER,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // combined - mixed\n    // ------------------------------------------------------------------------------\n    {\n      // Error if mixed property positions but don't match config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextType = MyContext;\n\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        PROPERTY_ASSIGNMENT,\n        {\n          defaultProps: STATIC_GETTER,\n          propTypes: STATIC_PUBLIC_FIELD,\n          displayName: STATIC_PUBLIC_FIELD,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    {\n      // Error if mixed property positions but don't match config\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextType = MyContext;\n\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n\n        MyComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        MyComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        STATIC_GETTER,\n        {\n          childContextTypes: PROPERTY_ASSIGNMENT,\n          contextTypes: PROPERTY_ASSIGNMENT,\n          contextType: PROPERTY_ASSIGNMENT,\n          displayName: PROPERTY_ASSIGNMENT,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'notGetterClassFunc',\n          data: { name: 'propTypes' },\n        },\n      ],\n    },\n    // ------------------------------------------------------------------------------\n    // mixed component types\n    // ------------------------------------------------------------------------------\n    {\n      // SFC ignored and component is invalid\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextType = MyContext;\n\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n\n        const OtherComponent = () => (<div>Hello</div>);\n\n        OtherComponent.defaultProps = {\n          name: 'Bob'\n        }\n\n        OtherComponent.propTypes = {\n          name: PropTypes.string.isRequired\n        }\n      `,\n      features: ['class fields'],\n      options: [\n        PROPERTY_ASSIGNMENT,\n        {\n          defaultProps: STATIC_PUBLIC_FIELD,\n          propTypes: STATIC_GETTER,\n        },\n      ],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n      ],\n    },\n    {\n      // Multiple components validated\n      code: `\n        class MyComponent extends React.Component {\n          static childContextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static contextType = MyContext;\n\n          static displayName = \"Hello\";\n        }\n\n        class OtherComponent extends React.Component {\n          static contextTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static defaultProps = {\n            name: 'Bob'\n          }\n\n          static propTypes = {\n            name: PropTypes.string.isRequired\n          }\n\n          static get displayName() {\n            return \"Hello\";\n          }\n        }\n      `,\n      features: ['class fields'],\n      options: [PROPERTY_ASSIGNMENT],\n      errors: [\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'childContextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextType' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'contextTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'defaultProps' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'propTypes' },\n        },\n        {\n          messageId: 'declareOutsideClass',\n          data: { name: 'displayName' },\n        },\n      ],\n    },\n    {\n      code: `\n        class MyComponent extends React.Component {\n          displayName = 'Foo';\n        }\n      `,\n      features: ['class fields'],\n      options: [STATIC_PUBLIC_FIELD],\n      errors: [\n        {\n          messageId: 'notStaticClassProp',\n          data: { name: 'displayName' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/style-prop-object.js",
    "content": "/**\n * @fileoverview Enforce style prop value is an object\n * @author David Petersen\n */\n\n'use strict';\n\n// ------------------------------------------------------------------------------\n// Requirements\n// ------------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/style-prop-object');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// ------------------------------------------------------------------------------\n// Tests\n// ------------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('style-prop-object', rule, {\n  valid: parsers.all([\n    {\n      code: '<div style={{ color: \"red\" }} />',\n    },\n    {\n      code: '<Hello style={{ color: \"red\" }} />',\n    },\n    {\n      code: `\n        function redDiv() {\n          const styles = { color: \"red\" };\n          return <div style={styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        function redDiv() {\n          const styles = { color: \"red\" };\n          return <Hello style={styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        const styles = { color: \"red\" };\n        function redDiv() {\n          return <div style={styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        function redDiv(props) {\n          return <div style={props.styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        import styles from './styles';\n        function redDiv() {\n          return <div style={styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        import mystyles from './styles';\n        const styles = Object.assign({ color: 'red' }, mystyles);\n        function redDiv() {\n          return <div style={styles} />;\n        }\n      `,\n    },\n    {\n      code: `\n        const otherProps = { style: { color: \"red\" } };\n        const { a, b, ...props } = otherProps;\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        const styles = Object.assign({ color: 'red' }, mystyles);\n        React.createElement(\"div\", { style: styles });\n      `,\n      parserOptions: Object.assign({ sourceType: 'module' }, parserOptions),\n    },\n    {\n      code: '<div style></div>',\n    },\n    {\n      code: `\n        React.createElement(MyCustomElem, {\n          [style]: true\n        }, 'My custom Elem')\n      `,\n    },\n    {\n      code: `\n        let style;\n        <div style={style}></div>\n      `,\n    },\n    {\n      code: `\n        let style = null;\n        <div style={style}></div>\n      `,\n    },\n    {\n      code: `\n        let style = undefined;\n        <div style={style}></div>\n      `,\n    },\n    {\n      code: '<div style={undefined}></div>',\n    },\n    {\n      code: `\n        const props = { style: undefined };\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        const otherProps = { style: undefined };\n        const { a, b, ...props } = otherProps;\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        React.createElement(\"div\", {\n          style: undefined\n        })\n      `,\n    },\n    {\n      code: `\n        let style;\n        React.createElement(\"div\", {\n          style\n        })\n      `,\n    },\n    {\n      code: '<div style={null}></div>',\n    },\n    {\n      code: `\n        const props = { style: null };\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        const otherProps = { style: null };\n        const { a, b, ...props } = otherProps;\n        <div {...props} />\n      `,\n    },\n    {\n      code: `\n        React.createElement(\"div\", {\n          style: null\n        })\n      `,\n    },\n    {\n      code: `\n        const MyComponent = (props) => {\n          React.createElement(MyCustomElem, {\n            ...props\n          });\n        };\n      `,\n    },\n    {\n      code: '<MyComponent style=\"myStyle\" />',\n      options: [{ allow: ['MyComponent'] }],\n    },\n    {\n      code: 'React.createElement(MyComponent, { style: \"mySpecialStyle\" })',\n      options: [{ allow: ['MyComponent'] }],\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<div style=\"color: \\'red\\'\" />',\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 1,\n          column: 6,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: '<Hello style=\"color: \\'red\\'\" />',\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 1,\n          column: 8,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: '<div style={true} />',\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 1,\n          column: 6,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: `\n        const styles = 'color: \"red\"';\n        function redDiv2() {\n          return <div style={styles} />;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 4,\n          column: 30,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        const styles = 'color: \"red\"';\n        function redDiv2() {\n          return <Hello style={styles} />;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 4,\n          column: 32,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: `\n        const styles = true;\n        function redDiv() {\n          return <div style={styles} />;\n        }\n      `,\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 4,\n          column: 30,\n          type: 'Identifier',\n        },\n      ],\n    },\n    {\n      code: '<MyComponent style=\"myStyle\" />',\n      options: [{ allow: ['MyOtherComponent'] }],\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 1,\n          column: 14,\n          type: 'JSXAttribute',\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(MyComponent, { style: \"mySpecialStyle\" })',\n      options: [{ allow: ['MyOtherComponent'] }],\n      errors: [\n        {\n          messageId: 'stylePropNotObject',\n          line: 1,\n          column: 43,\n          type: 'Literal',\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/lib/rules/void-dom-elements-no-children.js",
    "content": "/**\n * @fileoverview Tests for void-dom-elements-no-children\n * @author Joe Lencioni\n */\n\n'use strict';\n\n// -----------------------------------------------------------------------------\n// Requirements\n// -----------------------------------------------------------------------------\n\nconst RuleTester = require('../../helpers/ruleTester');\nconst rule = require('../../../lib/rules/void-dom-elements-no-children');\n\nconst parsers = require('../../helpers/parsers');\n\nconst parserOptions = {\n  ecmaVersion: 2018,\n  sourceType: 'module',\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\n// -----------------------------------------------------------------------------\n// Tests\n// -----------------------------------------------------------------------------\n\nconst ruleTester = new RuleTester({ parserOptions });\nruleTester.run('void-dom-elements-no-children', rule, {\n  valid: parsers.all([\n    {\n      code: '<div>Foo</div>;',\n    },\n    {\n      code: '<div children=\"Foo\" />;',\n    },\n    {\n      code: '<div dangerouslySetInnerHTML={{ __html: \"Foo\" }} />;',\n    },\n    {\n      code: 'React.createElement(\"div\", {}, \"Foo\");',\n    },\n    {\n      code: 'React.createElement(\"div\", { children: \"Foo\" });',\n    },\n    {\n      code: 'React.createElement(\"div\", { dangerouslySetInnerHTML: { __html: \"Foo\" } });',\n    },\n    {\n      code: 'document.createElement(\"img\");',\n    },\n    {\n      code: 'React.createElement(\"img\");',\n    },\n    {\n      code: 'React.createElement();',\n    },\n    {\n      code: 'document.createElement();',\n    },\n    {\n      code: `\n        const props = {};\n        React.createElement(\"img\", props);\n      `,\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        createElement(\"div\");\n      `,\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        createElement(\"img\");\n      `,\n    },\n    {\n      code: `\n        import React, {createElement, PureComponent} from \"react\";\n        class Button extends PureComponent {\n          handleClick(ev) {\n            ev.preventDefault();\n          }\n          render() {\n            return <div onClick={this.handleClick}>Hello</div>;\n          }\n        }\n      `,\n    },\n  ]),\n  invalid: parsers.all([\n    {\n      code: '<br>Foo</br>;',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: '<br children=\"Foo\" />;',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: '<img {...props} children=\"Foo\" />;',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'img' },\n        },\n      ],\n    },\n    {\n      code: '<br dangerouslySetInnerHTML={{ __html: \"Foo\" }} />;',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"br\", {}, \"Foo\");',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"br\", { children: \"Foo\" });',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: 'React.createElement(\"br\", { dangerouslySetInnerHTML: { __html: \"Foo\" } });',\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'br' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        createElement(\"img\", {}, \"Foo\");\n      `,\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'img' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        createElement(\"img\", { children: \"Foo\" });\n      `,\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'img' },\n        },\n      ],\n    },\n    {\n      code: `\n        import React, {createElement} from \"react\";\n        createElement(\"img\", { dangerouslySetInnerHTML: { __html: \"Foo\" } });\n      `,\n      errors: [\n        {\n          messageId: 'noChildrenInVoidEl',\n          data: { element: 'img' },\n        },\n      ],\n    },\n  ]),\n});\n"
  },
  {
    "path": "tests/util/.eslintrc",
    "content": "{\n  \"env\": {\n     \"mocha\": true\n  }\n}\n"
  },
  {
    "path": "tests/util/Components.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst entries = require('object.entries');\nconst fromEntries = require('object.fromentries');\nconst values = require('object.values');\n\nconst RuleTester = require('../helpers/ruleTester');\nconst Components = require('../../lib/util/Components');\nconst parsers = require('../helpers/parsers');\n\nconst ruleTester = new RuleTester({\n  parserOptions: {\n    ecmaVersion: 2018,\n    sourceType: 'module',\n    ecmaFeatures: {\n      jsx: true,\n    },\n  },\n});\n\ndescribe('Components', () => {\n  describe('static detect', () => {\n    function testComponentsDetect(test, instructionsOrDone, orDone) {\n      const done = orDone || instructionsOrDone;\n      const instructions = orDone ? instructionsOrDone : instructionsOrDone;\n\n      const rule = {\n        create: Components.detect((_context, components, util) => {\n          const instructionResults = [];\n\n          const augmentedInstructions = fromEntries(\n            entries(instructions || {}).map((nodeTypeAndHandler) => {\n              const nodeType = nodeTypeAndHandler[0];\n              const handler = nodeTypeAndHandler[1];\n              return [nodeType, (node) => {\n                instructionResults.push({ type: nodeType, result: handler(node, context, components, util) });\n              }];\n            })\n          );\n\n          return Object.assign({}, augmentedInstructions, {\n            'Program:exit'(node) {\n              if (augmentedInstructions['Program:exit']) {\n                augmentedInstructions['Program:exit'](node, context, components, util);\n              }\n              done(components, instructionResults);\n            },\n          });\n        }),\n      };\n\n      const tests = {\n        valid: parsers.all([Object.assign({}, test, {\n          settings: {\n            react: {\n              version: 'detect',\n            },\n          },\n        })]),\n        invalid: [],\n      };\n\n      ruleTester.run(test.code, rule, tests);\n    }\n\n    it('should detect Stateless Function Component', () => {\n      testComponentsDetect({\n        code: `import React from 'react'\n          function MyStatelessComponent() {\n            return <React.Fragment />;\n          }`,\n      }, (components) => {\n        assert.equal(components.length(), 1, 'MyStatelessComponent should be detected component');\n        values(components.list()).forEach((component) => {\n          assert.equal(\n            component.node.id.name,\n            'MyStatelessComponent',\n            'MyStatelessComponent should be detected component'\n          );\n        });\n      });\n    });\n\n    it('should detect Class Components', () => {\n      testComponentsDetect({\n        code: `import React from 'react'\n        class MyClassComponent extends React.Component {\n          render() {\n            return <React.Fragment />;\n          }\n        }`,\n      }, (components) => {\n        assert(components.length() === 1, 'MyClassComponent should be detected component');\n        values(components.list()).forEach((component) => {\n          assert.equal(\n            component.node.id.name,\n            'MyClassComponent',\n            'MyClassComponent should be detected component'\n          );\n        });\n      });\n    });\n\n    it('should detect React Imports', () => {\n      testComponentsDetect({\n        code: 'import React, { useCallback, useState } from \\'react\\'',\n      }, (components) => {\n        assert.deepEqual(\n          components.getDefaultReactImports().map((specifier) => specifier.local.name),\n          ['React'],\n          'default React import identifier should be \"React\"'\n        );\n\n        assert.deepEqual(\n          components.getNamedReactImports().map((specifier) => specifier.local.name),\n          ['useCallback', 'useState'],\n          'named React import identifiers should be \"useCallback\" and \"useState\"'\n        );\n      });\n    });\n\n    describe('utils', () => {\n      describe('isReactHookCall', () => {\n        it('should not identify hook-like call', () => {\n          testComponentsDetect({\n            code: `\n              import { useRef } from 'react'\n              function useColor() {\n                return useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: false }]);\n          });\n        });\n\n        it('should identify hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState } from 'react'\n              function useColor() {\n                return useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should identify aliased hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState as useStateAlternative } from 'react'\n              function useColor() {\n                return useStateAlternative()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should identify aliased present named hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState as useStateAlternative } from 'react'\n              function useColor() {\n                return useStateAlternative()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node, ['useState']),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should not identify shadowed hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState } from 'react'\n              function useColor() {\n                function useState() {\n                  return null\n                }\n                return useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: false }]);\n          });\n        });\n\n        it('should not identify shadowed aliased present named hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState as useStateAlternative } from 'react'\n              function useColor() {\n                function useStateAlternative() {\n                  return null\n                }\n                return useStateAlternative()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node, ['useState']),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: false }]);\n          });\n        });\n\n        it('should identify React hook call', () => {\n          testComponentsDetect({\n            code: `\n              import React from 'react'\n              function useColor() {\n                return React.useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should identify aliased React hook call', () => {\n          testComponentsDetect({\n            code: `\n              import ReactAlternative from 'react'\n              function useColor() {\n                return ReactAlternative.useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should not identify shadowed React hook call', () => {\n          testComponentsDetect({\n            code: `\n              import React from 'react'\n              function useColor() {\n                const React = {\n                  useState: () => null\n                }\n                return React.useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: false }]);\n          });\n        });\n\n        it('should identify present named hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState } from 'react'\n              function useColor() {\n                return useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node, ['useState']),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should identify present named React hook call', () => {\n          testComponentsDetect({\n            code: `\n              import React from 'react'\n              function useColor() {\n                return React.useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node, ['useState']),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: true }]);\n          });\n        });\n\n        it('should not identify missing named hook call', () => {\n          testComponentsDetect({\n            code: `\n              import { useState } from 'react'\n              function useColor() {\n                return useState()\n              }\n            `,\n          }, {\n            CallExpression: (node, _context, _components, util) => util.isReactHookCall(node, ['useRef']),\n          }, (_components, instructionResults) => {\n            assert.deepEqual(instructionResults, [{ type: 'CallExpression', result: false }]);\n          });\n        });\n      });\n    });\n\n    describe('testComponentsDetect', () => {\n      it('should log Program:exit instruction', () => {\n        testComponentsDetect({\n          code: '',\n        }, {\n          'Program:exit': () => true,\n        }, (_components, instructionResults) => {\n          assert.deepEqual(instructionResults, [{ type: 'Program:exit', result: true }]);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/ast.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst sinon = require('sinon');\nconst espree = require('espree');\n\nconst ast = require('../../lib/util/ast');\n\nconst traverseReturns = ast.traverseReturns;\nconst isFunctionLike = ast.isFunctionLike;\n\nconst DEFAULT_CONFIG = {\n  ecmaVersion: 6,\n};\n\nconst parseCode = (code) => {\n  const ASTnode = espree.parse(code, DEFAULT_CONFIG);\n  // Return only first statement\n  return ASTnode.body[0];\n};\n\nconst mockContext = {};\n\ndescribe('ast', () => {\n  describe('traverseReturnStatements', () => {\n    it('Correctly traverses function declarations', () => {\n      const spy = sinon.spy();\n      traverseReturns(parseCode(`\n        function foo({prop}) {\n          return;\n        }\n      `), mockContext, spy);\n\n      assert(spy.calledOnce);\n    });\n\n    it('Correctly traverses function expressions', () => {\n      const spy = sinon.spy();\n      traverseReturns(parseCode(`\n        const foo = function({prop}) {\n          return;\n        }\n      `).declarations[0].init, mockContext, spy);\n\n      assert(spy.calledOnce);\n    });\n\n    it('Correctly traverses arrow functions', () => {\n      const spy = sinon.spy();\n      traverseReturns(parseCode(`\n        ({prop}) => {\n          return;\n        }\n      `).expression, mockContext, spy);\n\n      assert(spy.calledOnce);\n\n      spy.resetHistory();\n\n      traverseReturns(parseCode(`\n        ({prop}) => 'something'\n      `).expression, mockContext, spy);\n\n      assert(spy.calledOnce);\n    });\n\n    it('Correctly traverses inside control flow expressions', () => {\n      const spy = sinon.spy();\n      traverseReturns(parseCode(`\n        function foo({prop}) {\n          if (prop) {\n            return 0;\n          } else {\n            return 1;\n          }\n\n          while(prop) {\n            return 2;\n          }\n\n          for (;;) {\n            return 3;\n          }\n\n          switch (prop) {\n            case 'a':\n              return 4;\n            default:\n              return 5;\n          }\n\n          const foo = () => 'not valid';\n        }\n      `), mockContext, spy);\n\n      const enterCalls = spy.getCalls();\n\n      assert.strictEqual(enterCalls.length, 6);\n\n      enterCalls.forEach((call, idx) => {\n        assert.strictEqual(call.args[0].value, idx);\n      });\n    });\n  });\n\n  describe('isFunctionLike()', () => {\n    it('FunctionDeclaration should return true', () => {\n      const node1 = parseCode(`\n        function foo(bar) {\n          const asdf = () => 'zxcv';\n          return asdf;\n        }\n      `);\n      assert.strictEqual(isFunctionLike(node1), true);\n\n      const node2 = parseCode(`\n        function foo({bar}) {\n          const asdf = () => 'zxcv';\n          console.log(bar);\n          return '5'\n        }\n      `);\n      assert.strictEqual(isFunctionLike(node2), true);\n    });\n\n    it('FunctionExpression should return true', () => {\n      const node1 = parseCode(`\n        const foo = function(bar) {\n          return () => 'zxcv';\n        }\n      `).declarations[0].init;\n      assert.strictEqual(isFunctionLike(node1), true);\n\n      const node2 = parseCode(`\n        const foo = function ({bar}) {\n          return '5';\n        }\n      `).declarations[0].init;\n      assert.strictEqual(isFunctionLike(node2), true);\n    });\n\n    it('ArrowFunctionExpression should return true', () => {\n      const node1 = parseCode(`\n        (bar) => {\n          return () => 'zxcv';\n        }\n      `).expression;\n      assert.strictEqual(isFunctionLike(node1), true);\n\n      const node2 = parseCode(`\n        ({bar}) => '5';\n      `).expression;\n      assert.strictEqual(isFunctionLike(node2), true);\n\n      const node3 = parseCode(`\n        bar => '5';\n      `).expression;\n      assert.strictEqual(isFunctionLike(node3), true);\n    });\n\n    it('Non-functions should return false', () => {\n      const node1 = parseCode(`\n        class bar {\n          a() {\n            return 'a';\n          }\n        }\n      `);\n      assert.strictEqual(isFunctionLike(node1), false);\n\n      const node2 = parseCode(`\n        const a = 5;\n      `);\n      assert.strictEqual(isFunctionLike(node2), false);\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/isFirstLetterCapitalized.js",
    "content": "'use strict';\n\nconst assert = require('assert');\n\nconst isFirstLetterCapitalized = require('../../lib/util/isFirstLetterCapitalized');\n\ndescribe('isFirstLetterCapitalized', () => {\n  it('should return false for invalid input', () => {\n    assert.equal(isFirstLetterCapitalized(), false);\n    assert.equal(isFirstLetterCapitalized(null), false);\n    assert.equal(isFirstLetterCapitalized(''), false);\n  });\n\n  it('should return false for uncapitalized string', () => {\n    assert.equal(isFirstLetterCapitalized('isCapitalized'), false);\n    assert.equal(isFirstLetterCapitalized('lowercase'), false);\n    assert.equal(isFirstLetterCapitalized('_startsWithUnderscore'), false);\n    assert.equal(isFirstLetterCapitalized('__startsWithUnderscore'), false);\n  });\n\n  it('should return true for capitalized string, with or without leading underscores', () => {\n    assert.equal(isFirstLetterCapitalized('IsCapitalized'), true);\n    assert.equal(isFirstLetterCapitalized('_IsCapitalized'), true);\n    assert.equal(isFirstLetterCapitalized('__IsCapitalized'), true);\n    assert.equal(isFirstLetterCapitalized('UPPERCASE'), true);\n    assert.equal(isFirstLetterCapitalized('_UPPERCASE'), true);\n    assert.equal(isFirstLetterCapitalized('__UPPERCASE'), true);\n  });\n});\n"
  },
  {
    "path": "tests/util/jsx.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst espree = require('espree');\n\nconst jsxUtil = require('../../lib/util/jsx');\n\nconst isReturningJSX = jsxUtil.isReturningJSX;\n\nconst DEFAULT_CONFIG = {\n  ecmaVersion: 6,\n  ecmaFeatures: {\n    jsx: true,\n  },\n};\n\nconst parseCode = (code) => {\n  const ASTnode = espree.parse(code, DEFAULT_CONFIG);\n  // Return only first statement\n  return ASTnode.body[0];\n};\n\nconst mockContext = {\n  getSourceCode() { return { getScope: mockContext.getScope }; },\n  getScope() {\n    return {\n      type: 'global',\n      upper: null,\n      childScopes: [],\n      variables: [],\n    };\n  },\n};\n\ndescribe('jsxUtil', () => {\n  describe('isReturningJSX', () => {\n    const assertValid = (codeStr) => assert(\n      isReturningJSX(mockContext, parseCode(codeStr))\n    );\n\n    it('Works when returning JSX', () => {\n      assertValid(`\n        function Test() {\n          return (\n            <a>something</a>\n          )\n        }\n      `);\n\n      assertValid(`\n        function Test() {\n          return <a>something</a>;\n        }\n      `);\n    });\n\n    it('Works when returning null', () => {\n      assertValid(`\n        function Test() {\n          return null;\n        }\n      `);\n\n      assertValid(`\n        function Test({prop}) {\n          return prop || null;\n        }\n      `);\n    });\n\n    it('Works with nested return', () => {\n      assertValid(`\n        function Test({prop}) {\n          if (prop) {\n            return <a>something</a>\n          }\n        }\n      `);\n    });\n\n    it('Can ignore null', () => {\n      assertValid(`\n        function Test() {\n          return null;\n        }\n      `);\n    });\n\n    it('Ignores JSX arguments to function calls used as return value of arrow functions', () => {\n      let astNode = parseCode(`const obj = {\n        prop: () => test(<a>something</a>)\n      }`);\n      let arrowFunctionExpression = astNode.declarations[0].init.properties[0].value;\n\n      assert(!isReturningJSX(() => false, arrowFunctionExpression, mockContext));\n\n      astNode = parseCode(`const obj = {\n        prop: () => { return test(<a>something</a>); }\n      }`);\n      arrowFunctionExpression = astNode.declarations[0].init.properties[0].value;\n\n      assert(!isReturningJSX(() => false, arrowFunctionExpression, mockContext));\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/linkComponents.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst linkComponentsUtil = require('../../lib/util/linkComponents');\n\ndescribe('linkComponentsFunctions', () => {\n  describe('getLinkComponents', () => {\n    it('returns a default map of components', () => {\n      const context = {};\n      assert.deepStrictEqual(linkComponentsUtil.getLinkComponents(context), new Map([\n        ['a', ['href']],\n      ]));\n    });\n\n    it('returns a map of components', () => {\n      const linkComponents = [\n        'Hyperlink',\n        {\n          name: 'Link',\n          linkAttribute: 'to',\n        },\n        {\n          name: 'Link2',\n          linkAttribute: ['to1', 'to2'],\n        },\n      ];\n      const context = {\n        settings: {\n          linkComponents,\n        },\n      };\n      assert.deepStrictEqual(linkComponentsUtil.getLinkComponents(context), new Map([\n        ['a', ['href']],\n        ['Hyperlink', ['href']],\n        ['Link', ['to']],\n        ['Link2', ['to1', 'to2']],\n      ]));\n    });\n  });\n\n  describe('getFormComponents', () => {\n    it('returns a default map of components', () => {\n      const context = {};\n      assert.deepStrictEqual(linkComponentsUtil.getFormComponents(context), new Map([\n        ['form', ['action']],\n      ]));\n    });\n\n    it('returns a map of components', () => {\n      const formComponents = [\n        'Form',\n        {\n          name: 'MyForm',\n          formAttribute: 'endpoint',\n        },\n        {\n          name: 'MyForm2',\n          formAttribute: ['endpoint1', 'endpoint2'],\n        },\n      ];\n      const context = {\n        settings: {\n          formComponents,\n        },\n      };\n      assert.deepStrictEqual(linkComponentsUtil.getFormComponents(context), new Map([\n        ['form', ['action']],\n        ['Form', ['action']],\n        ['MyForm', ['endpoint']],\n        ['MyForm2', ['endpoint1', 'endpoint2']],\n      ]));\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/pragma.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst SourceCode = require('eslint').SourceCode;\nconst espree = require('espree');\n\nconst getFromContext = require('../../lib/util/pragma').getFromContext;\n\nconst DEFAULT_CONFIG = {\n  ecmaVersion: 6,\n  comment: true,\n  tokens: true,\n  range: true,\n  loc: true,\n};\n\nconst DEFAULT_SETTINGS = {\n  react: {\n    pragma: 'React',\n  },\n};\n\nconst fakeContext = (code) => {\n  const ast = espree.parse(code, DEFAULT_CONFIG);\n  return {\n    getSourceCode: () => new SourceCode(code, ast),\n    settings: DEFAULT_SETTINGS,\n  };\n};\n\ndescribe('pragma', () => {\n  describe('getFromContext', () => {\n    it('finds the pragma in a block comment', () => {\n      const code = '/* @jsx jsx */';\n      assert.strictEqual(getFromContext(fakeContext(code)), 'jsx');\n    });\n\n    it('finds the pragma in a docstring comment', () => {\n      const code = '/** @jsx jsx */';\n      assert.strictEqual(getFromContext(fakeContext(code)), 'jsx');\n    });\n\n    it('finds the pragma in a line comment', () => {\n      const code = '// @jsx jsx';\n      assert.strictEqual(\n        getFromContext(fakeContext(code)),\n        'jsx'\n      );\n    });\n\n    it('defaults to the value of settings.react.pragma', () => {\n      const code = '';\n      assert.strictEqual(\n        getFromContext(fakeContext(code)),\n        DEFAULT_SETTINGS.react.pragma\n      );\n    });\n\n    it('returns React if the pragma is invalid', () => {\n      const code = '/* @jsx invalid-jsx-pragma */';\n      assert.equal(getFromContext(fakeContext(code)), 'React');\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/propWrapper.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst propWrapperUtil = require('../../lib/util/propWrapper');\n\ndescribe('PropWrapperFunctions', () => {\n  describe('getPropWrapperFunctions', () => {\n    it('returns set of functions if setting exists', () => {\n      const propWrapperFunctions = [\n        'Object.freeze',\n        {\n          property: 'forbidExtraProps',\n        },\n      ];\n      const context = {\n        settings: {\n          propWrapperFunctions,\n        },\n      };\n      assert.deepStrictEqual(propWrapperUtil.getPropWrapperFunctions(context), new Set(propWrapperFunctions));\n    });\n\n    it('returns empty set if no setting', () => {\n      const context = {\n        settings: {},\n      };\n      assert.deepStrictEqual(propWrapperUtil.getPropWrapperFunctions(context), new Set([]));\n    });\n  });\n\n  describe('isPropWrapperFunction', () => {\n    it('with string', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: ['Object.freeze'],\n        },\n      };\n      assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'Object.freeze'), true);\n    });\n\n    it('with Object with object and property keys', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: [\n            {\n              property: 'freeze',\n              object: 'Object',\n            },\n          ],\n        },\n      };\n      assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'Object.freeze'), true);\n    });\n\n    it('with Object with only property key', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: [\n            {\n              property: 'forbidExtraProps',\n            },\n          ],\n        },\n      };\n      assert.equal(propWrapperUtil.isPropWrapperFunction(context, 'forbidExtraProps'), true);\n    });\n  });\n\n  describe('getExactPropWrapperFunctions', () => {\n    it('returns set of functions if setting exists', () => {\n      const propWrapperFunctions = [\n        'Object.freeze',\n        {\n          property: 'forbidExtraProps',\n          exact: true,\n        },\n      ];\n      const context = {\n        settings: {\n          propWrapperFunctions,\n        },\n      };\n      assert.deepStrictEqual(propWrapperUtil.getExactPropWrapperFunctions(context), new Set([{\n        property: 'forbidExtraProps',\n        exact: true,\n      }]));\n    });\n\n    it('returns empty set if no exact prop wrappers', () => {\n      const propWrapperFunctions = [\n        'Object.freeze',\n        {\n          property: 'forbidExtraProps',\n        },\n      ];\n      const context = {\n        settings: {\n          propWrapperFunctions,\n        },\n      };\n      assert.deepStrictEqual(propWrapperUtil.getExactPropWrapperFunctions(context), new Set([]));\n    });\n\n    it('returns empty set if no setting', () => {\n      const context = {\n        settings: {},\n      };\n      assert.deepStrictEqual(propWrapperUtil.getExactPropWrapperFunctions(context), new Set([]));\n    });\n  });\n\n  describe('isExactPropWrapperFunction', () => {\n    it('with string', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: ['Object.freeze'],\n        },\n      };\n      assert.equal(propWrapperUtil.isExactPropWrapperFunction(context, 'Object.freeze'), false);\n    });\n\n    it('with Object with object and property keys', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: [\n            {\n              property: 'freeze',\n              object: 'Object',\n              exact: true,\n            },\n          ],\n        },\n      };\n      assert.equal(propWrapperUtil.isExactPropWrapperFunction(context, 'Object.freeze'), true);\n    });\n\n    it('with Object with only property key', () => {\n      const context = {\n        settings: {\n          propWrapperFunctions: [\n            {\n              property: 'forbidExtraProps',\n              exact: true,\n            },\n          ],\n        },\n      };\n      assert.equal(propWrapperUtil.isExactPropWrapperFunction(context, 'forbidExtraProps'), true);\n    });\n  });\n\n  describe('formatPropWrapperFunctions', () => {\n    it('with empty set', () => {\n      const propWrappers = new Set([]);\n      assert.equal(propWrapperUtil.formatPropWrapperFunctions(propWrappers), '');\n    });\n\n    it('with all allowed values', () => {\n      const propWrappers = new Set([\n        'Object.freeze',\n        {\n          property: 'exact',\n          exact: true,\n        },\n        {\n          property: 'bar',\n          object: 'foo',\n        },\n      ]);\n      assert.equal(propWrapperUtil.formatPropWrapperFunctions(propWrappers), '\\'Object.freeze\\', \\'exact\\', \\'foo.bar\\'');\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/variable.js",
    "content": "'use strict';\n\nconst assert = require('assert');\n\nconst getLatestVariableDefinition = require('../../lib/util/variable').getLatestVariableDefinition;\n\ndescribe('variable', () => {\n  describe('getLatestVariableDefinition', () => {\n    it('should return undefined for empty definitions', () => {\n      const variable = {\n        defs: [],\n      };\n      assert.equal(getLatestVariableDefinition(variable), undefined);\n    });\n\n    it('should return the latest definition', () => {\n      const variable = {\n        defs: [\n          'one',\n          'two',\n          'latest',\n        ],\n      };\n      assert.equal(getLatestVariableDefinition(variable), 'latest');\n    });\n  });\n});\n"
  },
  {
    "path": "tests/util/version.js",
    "content": "'use strict';\n\nconst path = require('path');\nconst assert = require('assert');\nconst sinon = require('sinon');\nconst versionUtil = require('../../lib/util/version');\n\ndescribe('Version', () => {\n  const base = path.resolve(__dirname, '..', 'fixtures', 'version');\n  let expectedErrorArgs = [];\n\n  beforeEach(() => {\n    sinon.stub(console, 'error');\n    expectedErrorArgs = [];\n    versionUtil.resetWarningFlag();\n    versionUtil.resetDetectedVersion();\n    versionUtil.resetDefaultVersion();\n  });\n\n  afterEach(() => {\n    const actualArgs = console.error.args; // eslint-disable-line no-console\n    console.error.restore(); // eslint-disable-line no-console\n    assert.deepEqual(actualArgs, expectedErrorArgs);\n  });\n\n  describe('Detect version', () => {\n    const context = { settings: { react: { version: 'detect', flowVersion: 'detect' } }, getFilename: () => path.resolve(base, 'test.js') };\n\n    afterEach(() => {\n      if (context.getFilename.restore) {\n        context.getFilename.restore();\n      }\n    });\n\n    it('matches detected version', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '>= 1.2.3'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 1.2.4'), false);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 0.92.0'), true);\n    });\n\n    it('matches detected version in sibling project', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-sibling', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.4'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.5'), false);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 2.92.0'), true);\n    });\n\n    it('matches detected version in child project', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version', 'detect-version-child', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '>= 3.4.5'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 3.4.6'), false);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 3.92.0'), true);\n    });\n\n    it('assumes latest version if react is not installed', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-missing', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '999.999.999'), true);\n\n      expectedErrorArgs = [\n        ['Warning: React version was set to \"detect\" in eslint-plugin-react settings, but the \"react\" package is not installed. Assuming latest React version for linting.'],\n      ];\n    });\n\n    it('uses default version from settings if provided and react is not installed', () => {\n      context.settings.react.defaultVersion = '16.14.0';\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-missing', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '16.14.0'), true);\n\n      expectedErrorArgs = [\n        ['Warning: React version was set to \"detect\" in eslint-plugin-react settings, but the \"react\" package is not installed. Assuming default React version for linting: \"16.14.0\".'],\n      ];\n\n      delete context.settings.react.defaultVersion;\n    });\n\n    it('fails nicely with an invalid default version of react', () => {\n      context.settings.react.defaultVersion = 'not semver';\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-missing', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '999.999.999'), true);\n\n      expectedErrorArgs = [\n        ['Warning: React version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “not semver”. Falling back to latest version as default.'],\n        ['Warning: React version was set to \"detect\" in eslint-plugin-react settings, but the \"react\" package is not installed. Assuming latest React version for linting.'],\n      ];\n\n      delete context.settings.react.defaultVersion;\n    });\n\n    it('warns only once for failure to detect react ', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-missing', 'test.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '999.999.999'), true);\n      assert.equal(versionUtil.testReactVersion(context, '999.999.999'), true);\n\n      expectedErrorArgs = [\n        ['Warning: React version was set to \"detect\" in eslint-plugin-react settings, but the \"react\" package is not installed. Assuming latest React version for linting.'],\n      ];\n    });\n\n    it('assumes latest version if flow-bin is not installed', () => {\n      assert.equal(versionUtil.testFlowVersion(context, '999.999.999'), true);\n\n      expectedErrorArgs = [\n        ['Warning: Flow version was set to \"detect\" in eslint-plugin-react settings, but the \"flow-bin\" package is not installed. Assuming latest Flow version for linting.'],\n      ];\n    });\n\n    it('works with virtual filename', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-sibling', 'test.js/0_fake.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.4'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.5'), false);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 2.92.0'), true);\n    });\n\n    it('works with recursive virtual filename', () => {\n      sinon.stub(context, 'getFilename').callsFake(() => path.resolve(base, 'detect-version-sibling', 'test.js/0_fake.md/1_fake.js'));\n\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.4'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 2.3.5'), false);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 2.92.0'), true);\n    });\n  });\n\n  describe('string version', () => {\n    const context = { settings: { react: { version: '15.0', flowVersion: '1.2' } } };\n    const invalidContext = { settings: { react: { version: 'latest', flowVersion: 'not semver' } } };\n\n    it('works with react', () => {\n      assert.equal(versionUtil.testReactVersion(context, '>= 0.14.0'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 15.0.0'), true);\n      assert.equal(versionUtil.testReactVersion(context, '>= 16.0.0'), false);\n    });\n\n    it('works with flow', () => {\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.1.0'), true);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.2.0'), true);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.3.0'), false);\n    });\n\n    it('fails nicely with an invalid react version', () => {\n      assert.equal(versionUtil.testReactVersion(invalidContext, '>= 15.0'), true);\n      expectedErrorArgs = [\n        ['Warning: React version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “latest”'],\n      ];\n    });\n\n    it('fails nicely with an invalid flow version', () => {\n      assert.equal(versionUtil.testFlowVersion(invalidContext, '>= 1.0'), true);\n      expectedErrorArgs = [\n        ['Warning: Flow version specified in eslint-plugin-react-settings must be a valid semver version, or \"detect\"; got “not semver”'],\n      ];\n    });\n  });\n\n  describe('non-string version', () => {\n    const context = { settings: { react: { version: 15.0, flowVersion: 1.2 } } };\n\n    it('works with react', () => {\n      assert.equal(versionUtil.testReactVersion(context, '>= 0.14.0'), true, '>= 0.14.0');\n      assert.equal(versionUtil.testReactVersion(context, '>= 15.0.0'), true, '>= 15.0.0');\n      assert.equal(versionUtil.testReactVersion(context, '>= 16.0.0'), false, '>= 16.0.0');\n\n      expectedErrorArgs = [\n        ['Warning: React version specified in eslint-plugin-react-settings must be a string; got “number”'],\n        ['Warning: React version specified in eslint-plugin-react-settings must be a string; got “number”'],\n        ['Warning: React version specified in eslint-plugin-react-settings must be a string; got “number”'],\n      ];\n    });\n\n    it('works with flow', () => {\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.1.0'), true);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.2.0'), true);\n      assert.equal(versionUtil.testFlowVersion(context, '>= 1.3.0'), false);\n\n      expectedErrorArgs = [\n        ['Warning: Flow version specified in eslint-plugin-react-settings must be a string; got “number”'],\n        ['Warning: Flow version specified in eslint-plugin-react-settings must be a string; got “number”'],\n        ['Warning: Flow version specified in eslint-plugin-react-settings must be a string; got “number”'],\n      ];\n    });\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2015\",       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */\n    \"module\": \"commonjs\",     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */\n    // \"lib\": [\"es2015\"],        /* Specify library files to be included in the compilation. */\n    \"allowJs\": true,          /* Allow javascript files to be compiled. */\n    \"checkJs\": true,          /* Report errors in .js files. */\n    \"noEmit\": true,           /* Do not emit outputs. */\n    \"esModuleInterop\": true,   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */\n\n    /* Strict Type-Checking Options */\n    // \"strict\": true,                        /* Enable all strict type-checking options. */\n    \"noImplicitAny\": false,                /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,              /* Enable strict null checks. */\n    // \"strictPropertyInitialization\": true,  /* Enable strict checking of property initialization in classes. */\n    \"strictFunctionTypes\": true,           /* Enable strict checking of function types. */\n    \"strictBindCallApply\": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */\n    \"noImplicitThis\": true,                /* Raise error on 'this' expressions with an implied 'any' type. */\n    \"alwaysStrict\": false,                 /* Parse in strict mode and emit \"use strict\" for each source file. */\n    \"resolveJsonModule\": true\n  },\n  \"include\": [\"lib\", \"types\"],\n}\n"
  },
  {
    "path": "types/rules/jsx-no-literals.d.ts",
    "content": "type RawElementConfig = {\n  noStrings?: boolean;\n  allowedStrings?: string[];\n  ignoreProps?: boolean;\n  noAttributeStrings?: boolean;\n  restrictedAttributes?: string[];\n};\n\ntype RawOverrideConfig = {\n  allowElement?: boolean;\n  applyToNestedElements?: boolean;\n};\n\ninterface RawElementOverrides {\n  elementOverrides?: Record<string, RawOverrideConfig>;\n}\n\nexport type RawConfig = RawElementConfig & RawElementOverrides;\n\ninterface ElementConfigType {\n  type: 'element';\n}\n\ninterface ElementConfigProperties {\n  noStrings: boolean;\n  allowedStrings: Set<string>;\n  ignoreProps: boolean;\n  noAttributeStrings: boolean;\n  restrictedAttributes: Set<string>;\n}\n\ninterface OverrideConfigProperties {\n  type: 'override';\n  name: string;\n  allowElement: boolean;\n  applyToNestedElements: boolean;\n}\n\nexport type ElementConfig = {\n  type: 'element';\n} & ElementConfigProperties;\n\nexport type OverrideConfig = OverrideConfigProperties & ElementConfigProperties;\n\ninterface ElementOverrides {\n  elementOverrides: Record<string, OverrideConfig>;\n}\n\nexport type Config = ElementConfig & ElementOverrides;\n\nexport type ResolvedConfig = Config | OverrideConfig;\n\n"
  },
  {
    "path": "types/string.prototype.repeat/index.d.ts",
    "content": "declare module 'string.prototype.repeat' {\n  function repeat(text: string, count: number): string;\n  export = repeat;\n}\n"
  }
]