diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e9269568bbdb..c10378eb0e9e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -64,7 +64,7 @@ Rules annotated with `@ActiveByDefault` will be marked as active in the `default Generally, this will not be the case for new rules. A rule that requires type resolution must be marked with `@RequiresTypeResolution`. -See [the type resolution wiki page](../docs/pages/gettingstarted/type-resolution.md) for +See [the type resolution wiki page](../website/docs/gettingstarted/type-resolution.md) for more detail on this topic. The rule defined above will translate to a rule entry in the `default-detekt-config.yml`: diff --git a/.github/workflows/codecoverage.yaml b/.github/workflows/codecoverage.yaml index 54fe075fefc2..346b3f7b17dc 100644 --- a/.github/workflows/codecoverage.yaml +++ b/.github/workflows/codecoverage.yaml @@ -8,6 +8,9 @@ on: branches: - '**' +env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + permissions: contents: read @@ -17,19 +20,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Generate Coverage Report - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: jacocoMergedReport - name: Publish Coverage if: success() - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # tag=v3 diff --git a/.github/workflows/deploy-snapshot.yaml b/.github/workflows/deploy-snapshot.yaml index 207a3584fa97..7f4f2b620235 100644 --- a/.github/workflows/deploy-snapshot.yaml +++ b/.github/workflows/deploy-snapshot.yaml @@ -5,6 +5,9 @@ on: branches: - main +env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + permissions: contents: read @@ -14,21 +17,21 @@ jobs: if: github.repository == 'detekt/detekt' && !contains(github.event.head_commit.message, 'ci skip') steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Build detekt - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: build - name: Deploy Snapshot - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 env: ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} diff --git a/.github/workflows/detekt-with-type-resolution.yaml b/.github/workflows/detekt-with-type-resolution.yaml index d27a29758397..cd04ad7913d4 100644 --- a/.github/workflows/detekt-with-type-resolution.yaml +++ b/.github/workflows/detekt-with-type-resolution.yaml @@ -10,6 +10,8 @@ on: env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }} + GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }} permissions: contents: read @@ -23,21 +25,21 @@ jobs: if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Run detekt-cli with argsfile - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: :detekt-cli:runWithArgsFile - name: Upload SARIF to Github using the upload-sarif action - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@0c670bbf0414f39666df6ce8e718ec5662c21e03 # tag=v2 if: ${{ always() }} with: sarif_file: build/detekt-report.sarif @@ -48,14 +50,14 @@ jobs: if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Run analysis - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: detektMain detektTest diff --git a/.github/workflows/fossascan.yaml b/.github/workflows/fossascan.yaml index b63a4cce5ac9..a7290c2eb7ac 100644 --- a/.github/workflows/fossascan.yaml +++ b/.github/workflows/fossascan.yaml @@ -14,9 +14,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Run FOSSA Scan - uses: fossas/fossa-action@v1 + uses: fossas/fossa-action@30055fd3dbc35d6ca57da934b5d8ac213a7871b4 # tag=v1 with: api-key: ${{ secrets.FOSSA_API_KEY }} diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index b6f0bdc1e23c..54db918ea774 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -16,6 +16,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout latest code - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b # tag=v1 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index ddd2131467c7..6f3ccec791e2 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -9,6 +9,6 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v4 + - uses: actions/labeler@9fd24f1f9d6ceb64ba34d181b329ee72f99978a0 # tag=v4 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/pre-merge.yaml b/.github/workflows/pre-merge.yaml index f581cf54aea0..d6a2c3b930f5 100644 --- a/.github/workflows/pre-merge.yaml +++ b/.github/workflows/pre-merge.yaml @@ -10,6 +10,8 @@ on: env: GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }} + GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }} permissions: contents: read @@ -28,31 +30,31 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: ${{ matrix.jdk }} distribution: 'temurin' - name: Build detekt - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: build -x detekt - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # tag=v3 with: name: heap-dump path: '**.hprof' if-no-files-found: ignore - name: Run detekt-cli --help - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: :detekt-cli:runWithHelpFlag - name: Run detekt-cli with argsfile - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: :detekt-cli:runWithArgsFile - name: Try to publish to Maven Local - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: publishToMavenLocal @@ -61,14 +63,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Verify Generated Detekt Config File - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: verifyGeneratorOutput @@ -77,13 +79,29 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Build and compile test snippets - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: test -Pcompile-test-snippets=true + + warnings-as-errors: + if: ${{ !contains(github.event.head_commit.message, 'ci skip') }} + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 + - name: Setup Java + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 + with: + java-version: 17 + distribution: 'temurin' + - name: Run with allWarningsAsErrors + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 + with: + arguments: build -x detekt -PwarningsAsErrors=true diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index d6fc2f89b256..4eca4cc4e798 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@v5 + - uses: actions/stale@9c1b1c6e115ca2af09755448e0dbba24e5061cc8 # tag=v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 90 diff --git a/.github/workflows/website.yaml b/.github/workflows/website.yaml index fc13a5076811..73ba0bce51d6 100644 --- a/.github/workflows/website.yaml +++ b/.github/workflows/website.yaml @@ -8,6 +8,9 @@ on: branches: - '**' +env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} + permissions: contents: write # for JamesIves/github-pages-deploy-action to push changes in repo @@ -17,23 +20,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repo - uses: actions/checkout@v3 + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Setup Java - uses: actions/setup-java@v3 + uses: actions/setup-java@2c7a4878f5d120bd643426d54ae1209b29cc01a3 # tag=v3 with: java-version: 17 distribution: 'temurin' - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3 with: node-version: '16' cache: 'yarn' cache-dependency-path: 'website/yarn.lock' - name: Build Detekt Documentation - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@cd3cedc781988c804f626f4cd2dc51d0bdf02a12 # tag=v2 with: arguments: :detekt-generator:generateDocumentation @@ -46,7 +49,7 @@ jobs: run: yarn build - name: Deploy Github Pages (only on main) - uses: JamesIves/github-pages-deploy-action@v4 + uses: JamesIves/github-pages-deploy-action@13046b614c663b56cba4dda3f30b9736a748b80d # tag=v4 if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} with: branch: gh-pages diff --git a/README.md b/README.md index 380aed4feea6..9f3531157725 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,32 @@ -# __detekt__ +# detekt [![Join the chat at #detekt on KotlinLang](https://img.shields.io/badge/%23detekt-on_slack-red.svg?logo=slack)](https://kotlinlang.slack.com/archives/C88E12QH4) [![Visit the website at detekt.dev/](https://img.shields.io/badge/visit-website-red.svg?logo=firefox)](https://detekt.dev/) [![Maven Central](https://img.shields.io/maven-central/v/io.gitlab.arturbosch.detekt/detekt-cli?label=MavenCentral&logo=apache-maven)](https://search.maven.org/artifact/io.gitlab.arturbosch.detekt/detekt-cli) -[![Gradle Plugin](https://img.shields.io/maven-metadata/v/https/plugins.gradle.org/m2/io/gitlab/arturbosch/detekt/io.gitlab.arturbosch.detekt.gradle.plugin/maven-metadata.xml.svg?label=Gradle&logo=gradle)](https://plugins.gradle.org/plugin/io.gitlab.arturbosch.detekt) +[![Gradle Plugin](https://img.shields.io/maven-central/v/io.gitlab.arturbosch.detekt/detekt-gradle-plugin?label=Gradle&logo=gradle)](https://plugins.gradle.org/plugin/io.gitlab.arturbosch.detekt) +[![Revved up by Gradle Enterprise](https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.detekt.dev/scans) ![Pre Merge Checks](https://github.com/detekt/detekt/workflows/Pre%20Merge%20Checks/badge.svg?branch=main) [![Codecov](https://codecov.io/gh/detekt/detekt/branch/main/graph/badge.svg)](https://codecov.io/gh/detekt/detekt) [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![FOSSA Status](https://app.fossa.com/api/projects/custom%2B25591%2Fgithub.com%2Fdetekt%2Fdetekt.svg?type=small)](https://app.fossa.com/projects/custom%2B25591%2Fgithub.com%2Fdetekt%2Fdetekt?ref=badge_small) -Meet _detekt_, a static code analysis tool for the _Kotlin_ programming language. -It operates on the abstract syntax tree provided by the Kotlin compiler. +Meet _detekt_, a static code analysis tool for the [_Kotlin_ programming language](https://kotlinlang.org/). +Visit [the project website](https://detekt.dev/) for installation guides, rule descriptions, configuration options and more. ![detekt in action](website/static/img/tutorial/detekt_in_action.png "detekt in action") ### Features -- Code smell analysis for your Kotlin projects -- Complexity reports based on lines of code, cyclomatic complexity and amount of code smells -- Highly configurable rule sets -- Suppression of findings with Kotlin's `@Suppress` and Java's `@SuppressWarnings` annotations -- Specification of quality gates which will break your build -- Code Smell baseline and suppression for legacy projects -- [Gradle plugin](#with-gradle) for code analysis via Gradle builds -- [SonarQube integration](https://github.com/detekt/sonar-kotlin) -- Extensibility by enabling incorporation of personal rule sets, `FileProcessListener's` and `OutputReport's` -- [IntelliJ integration](https://github.com/detekt/detekt-intellij-plugin) -- Third party integrations for [Maven](https://github.com/Ozsie/detekt-maven-plugin), [Bazel](https://github.com/buildfoundation/bazel_rules_detekt/) and Github Actions ([Docker based](https://github.com/marketplace/actions/detekt-all) and [Javascript based](https://github.com/marketplace/actions/setup-detekt)) - -### Project Website - -Visit [the project website](https://detekt.dev/) for installation guides, release notes, migration guides, rule descriptions and configuration options. +- Code smell analysis for your [Kotlin projects](https://kotlinlang.org/). +- Highly configurable rule sets. +- Code Smell baseline and suppression for legacy projects. +- Suppression of findings with `@Suppress` annotations. +- Support for different report formats: html, markdown, [SARIF](https://sarifweb.azurewebsites.net/) and xml (checkstyle). Is it not enough? You can extend detekt and create your own reports. +- Extensibility by enabling incorporation of personal rule sets, `FileProcessListener's` and `OutputReport's`. +- Complexity reports based on lines of code, cyclomatic complexity and number of code smells. +- First party integration with Gradle with our [Gradle plugin](#with-gradle). +- A community of [third party plugins](https://github.com/topics/detekt-plugin) that adds more rules and features to detekt. #### Quick-Links @@ -82,6 +77,7 @@ tasks.withType().configureEach { xml.required.set(true) // checkstyle like format mainly for integrations like Jenkins txt.required.set(true) // similar to the console output, contains issue signature to manually edit baseline files sarif.required.set(true) // standardized SARIF format (https://sarifweb.azurewebsites.net/) to support integrations with Github Code Scanning + md.required.set(true) // simple Markdown format } } @@ -110,17 +106,17 @@ If you want to use a SNAPSHOT version, you can find more info on [this documenta #### Requirements -Gradle 6.1+ is the minimum requirement. However, the recommended versions together with the other tools recommended versions are: +Gradle 6.7.1+ is the minimum requirement. However, the recommended versions together with the other tools recommended versions are: | Detekt Version | Gradle | Kotlin | AGP | Java Target Level | JDK Max Version | | -------------- | ------- | -------- | ------- | ----------------- | --------------- | -| `1.20.0` | `7.4.2` | `1.6.20` | `7.1.3` | `1.8` | `17` | +| `1.21.0` | `7.5` | `1.6.21` | `7.2.1` | `1.8` | `17` | The list of [recommended versions for previous detekt version is listed here](https://detekt.dev/compatibility.html). ### Adding more rule sets -detekt itself provides a wrapper over [ktlint](https://github.com/pinterest/ktlint) as a `formatting` rule set +detekt itself provides a wrapper over [ktlint](https://github.com/pinterest/ktlint) as the `formatting` rule set which can be easily added to the Gradle configuration: ```kotlin @@ -160,17 +156,19 @@ As mentioned in... Integrations: +- [IntelliJ integration](https://github.com/detekt/detekt-intellij-plugin) +- [SonarQube integration](https://github.com/detekt/sonar-kotlin) - [Codacy](https://www.codacy.com) - [Gradle plugin that configures Error Prone, Checkstyle, PMD, CPD, Lint, Detekt & Ktlint](https://github.com/vanniktech/gradle-code-quality-tools-plugin) - [Violations Lib](https://github.com/tomasbjerre/violations-lib) is a Java library for parsing report files like static code analysis. - [sputnik](https://github.com/TouK/sputnik) is a free tool for static code review and provides support for detekt -- [Novoda Gradle Static Analysis plugin](https://github.com/novoda/gradle-static-analysis-plugin) +- [Gradle Static Analysis plugin](https://github.com/GradleUp/static-analysis-plugin) - [Detekt Maven plugin](https://github.com/Ozsie/detekt-maven-plugin) that wraps the Detekt CLI - [Detekt Bazel plugin](https://github.com/buildfoundation/bazel_rules_detekt) that wraps the Detekt CLI - [Gradle plugin that helps facilitate GitHub PR checking and automatic commenting of violations](https://github.com/btkelly/gnag) - [Codefactor](http://codefactor.io/) - [GitHub Action: Detekt All](https://github.com/marketplace/actions/detekt-all) -- [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template) +- [GitHub Action: Setup detekt](https://github.com/marketplace/actions/setup-detekt) - [Sonatype Lift](https://github.com/marketplace/muse-dev) Custom rules and reports from 3rd parties: @@ -178,6 +176,7 @@ Custom rules and reports from 3rd parties: - [detekt-verify-implementation](https://github.com/cph-cachet/detekt-verify-implementation) by cph-cachet - [detekt-hint](https://github.com/mkohm/detekt-hint) by mkohm is a plugin to detekt that provides detection of design principle violations through integration with Danger - [GitLab report format](https://gitlab.com/cromefire_/detekt-gitlab-report) +- There are more third-party plugins out there. You can find some of them [in this list](https://github.com/topics/detekt-plugin). #### Credits diff --git a/build-logic/src/main/kotlin/Versions.kt b/build-logic/src/main/kotlin/Versions.kt index 47088dbedf4b..9039e486f26b 100644 --- a/build-logic/src/main/kotlin/Versions.kt +++ b/build-logic/src/main/kotlin/Versions.kt @@ -1,6 +1,6 @@ object Versions { - const val DETEKT: String = "1.21.0-RC1" + const val DETEKT: String = "1.21.0" const val SNAPSHOT_NAME: String = "main" const val JVM_TARGET: String = "1.8" diff --git a/build-logic/src/main/kotlin/module.gradle.kts b/build-logic/src/main/kotlin/module.gradle.kts index 64c00360cd49..d466c2dca02d 100644 --- a/build-logic/src/main/kotlin/module.gradle.kts +++ b/build-logic/src/main/kotlin/module.gradle.kts @@ -55,14 +55,12 @@ tasks.withType().configureEach { freeCompilerArgs = listOf( "-progressive", "-Xsuppress-version-warnings", - "-opt-in=kotlin.RequiresOptIn" ) - // Usage: ./gradlew build -PwarningsAsErrors=true. - // Note: currently there are warnings for detekt-gradle-plugin that seemingly can't be fixed + // Note: Currently there are warnings for detekt-gradle-plugin that seemingly can't be fixed // until Gradle releases an update (https://github.com/gradle/gradle/issues/16345) allWarningsAsErrors = when (project.name) { "detekt-gradle-plugin" -> false - else -> (project.findProperty("warningsAsErrors") == "true" || System.getenv("CI") == "true") + else -> project.findProperty("warningsAsErrors") == "true" } } } diff --git a/build-logic/src/main/kotlin/packaging.gradle.kts b/build-logic/src/main/kotlin/packaging.gradle.kts index a13ec760bfdb..f70fb143a7ca 100644 --- a/build-logic/src/main/kotlin/packaging.gradle.kts +++ b/build-logic/src/main/kotlin/packaging.gradle.kts @@ -66,10 +66,12 @@ if (signingKey.isNullOrBlank() || signingPwd.isNullOrBlank()) { logger.info("Signing disabled as the GPG key was not found") } else { logger.info("GPG Key found - Signing enabled") - signing { - useInMemoryPgpKeys(signingKey, signingPwd) - publishing.publications.forEach(::sign) - } +} + +signing { + useInMemoryPgpKeys(signingKey, signingPwd) + sign(publishing.publications) + isRequired = !(signingKey.isNullOrBlank() || signingPwd.isNullOrBlank()) } val String.byProperty: String? get() = findProperty(this) as? String diff --git a/build-logic/src/main/kotlin/releasing.gradle.kts b/build-logic/src/main/kotlin/releasing.gradle.kts index 3d8dc6b7c1c9..c44b5c97a0a7 100644 --- a/build-logic/src/main/kotlin/releasing.gradle.kts +++ b/build-logic/src/main/kotlin/releasing.gradle.kts @@ -66,9 +66,9 @@ tasks { register("incrementMajor") { doLast { updateVersion { it.nextMajor() } } } register("applyDocVersion") { - fileToUpdate.set(file("${rootProject.rootDir}/website/docusaurus.config.js")) - linePartToFind.set(" detektVersion:") - lineTransformation.set(" detektVersion: '${Versions.DETEKT}'") + fileToUpdate.set(file("${rootProject.rootDir}/website/src/remark/detektVersionReplace.js")) + linePartToFind.set("const detektVersion = ") + lineTransformation.set("const detektVersion = \"${Versions.DETEKT}\";") } } diff --git a/build.gradle.kts b/build.gradle.kts index 248a164a2745..15a04143a7f8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,8 +5,6 @@ plugins { id("releasing") id("io.gitlab.arturbosch.detekt") alias(libs.plugins.gradleVersions) - alias(libs.plugins.sonarqube) - alias(libs.plugins.dependencyAnalysis) } allprojects { @@ -38,6 +36,7 @@ allprojects { html.required.set(true) txt.required.set(true) sarif.required.set(true) + md.required.set(true) } } tasks.withType().configureEach { @@ -45,16 +44,6 @@ allprojects { } } -dependencyAnalysis { - issues { - all { - onUsedTransitiveDependencies { - severity("ignore") - } - } - } -} - val analysisDir = file(projectDir) val baselineFile = file("$rootDir/config/detekt/baseline.xml") val configFile = file("$rootDir/config/detekt/detekt.yml") @@ -82,6 +71,7 @@ val detektFormat by tasks.registering(Detekt::class) { xml.required.set(false) html.required.set(false) txt.required.set(false) + md.required.set(false) } } @@ -100,6 +90,7 @@ val detektAll by tasks.registering(Detekt::class) { xml.required.set(false) html.required.set(false) txt.required.set(false) + md.required.set(false) } } diff --git a/code-coverage-report/build.gradle.kts b/code-coverage-report/build.gradle.kts index 046a8cf777dc..7277b577397a 100644 --- a/code-coverage-report/build.gradle.kts +++ b/code-coverage-report/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { jacocoAggregation(projects.detektReportSarif) jacocoAggregation(projects.detektReportTxt) jacocoAggregation(projects.detektReportXml) + jacocoAggregation(projects.detektReportMd) jacocoAggregation(projects.detektRules) jacocoAggregation(projects.detektRulesComplexity) jacocoAggregation(projects.detektRulesCoroutines) @@ -50,7 +51,8 @@ tasks.check { configurations.allCodeCoverageReportClassDirectories.get().attributes { attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class, Category.LIBRARY)) attributes.attribute( - LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements::class, LibraryElements.CLASSES) + LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, + objects.named(LibraryElements::class, LibraryElements.CLASSES) ) } @@ -63,4 +65,5 @@ val customClassDirectories = configurations.allCodeCoverageReportClassDirectorie tasks.named("jacocoMergedReport", JacocoReport::class).configure { this.classDirectories.setFrom(customClassDirectories.files) + mustRunAfter(rootProject.project("detekt-generator").tasks.named("generateDocumentation")) } diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 3f0b319ce07f..62332182dba2 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -73,6 +73,8 @@ formatting: active: true EnumEntryNameCase: active: true + Filename: + active: false MaximumLineLength: active: false MultiLineIfElse: @@ -155,6 +157,8 @@ potential-bugs: style: CanBeNonNullable: active: true + CascadingCallWrapping: + active: true ClassOrdering: active: true CollapsibleIfStatements: @@ -179,7 +183,10 @@ style: ForbiddenImport: active: true imports: - - 'org.assertj.core.api.Assertions' + - value: 'org.assertj.core.api.Assertions' + reason: 'Import Assertions.assertThat instead.' + - value: 'org.junit.jupiter.api.Assertions*' + reason: 'Use AssertJ assertions instead.' ForbiddenMethodCall: active: true methods: @@ -188,6 +195,7 @@ style: - 'java.net.URL.openStream' - 'java.lang.Class.getResourceAsStream' - 'java.lang.ClassLoader.getResourceAsStream' + - 'org.jetbrains.kotlin.diagnostics.DiagnosticUtils.getLineAndColumnInPsiFile' ForbiddenVoid: active: true LibraryCodeMustSpecifyReturnType: @@ -266,3 +274,6 @@ style: VarCouldBeVal: active: true ignoreAnnotated: ['Parameter'] + WildcardImport: + active: true + excludeImports: [] diff --git a/detekt-api/api/detekt-api.api b/detekt-api/api/detekt-api.api index 8405d7309808..665e3f51d909 100644 --- a/detekt-api/api/detekt-api.api +++ b/detekt-api/api/detekt-api.api @@ -353,6 +353,7 @@ public final class io/gitlab/arturbosch/detekt/api/LazyRegex : kotlin/properties public final class io/gitlab/arturbosch/detekt/api/Location : io/gitlab/arturbosch/detekt/api/Compactable { public static final field Companion Lio/gitlab/arturbosch/detekt/api/Location$Companion; + public fun (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Lio/github/detekt/psi/FilePath;)V public fun (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Lio/github/detekt/psi/FilePath;)V public fun (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;)V public fun (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;)V @@ -367,6 +368,7 @@ public final class io/gitlab/arturbosch/detekt/api/Location : io/gitlab/arturbos public final fun copy (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;)Lio/gitlab/arturbosch/detekt/api/Location; public static synthetic fun copy$default (Lio/gitlab/arturbosch/detekt/api/Location;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;ILjava/lang/Object;)Lio/gitlab/arturbosch/detekt/api/Location; public fun equals (Ljava/lang/Object;)Z + public final fun getEndSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation; public final fun getFile ()Ljava/lang/String; public final fun getFilePath ()Lio/github/detekt/psi/FilePath; public final fun getSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation; diff --git a/detekt-api/build.gradle.kts b/detekt-api/build.gradle.kts index 1005ae138f74..4452ad608b7e 100644 --- a/detekt-api/build.gradle.kts +++ b/detekt-api/build.gradle.kts @@ -35,6 +35,10 @@ tasks.dokkaHtml { notCompatibleWithConfigurationCache("https://github.com/Kotlin/dokka/issues/1217") } +tasks.apiDump { + notCompatibleWithConfigurationCache("https://github.com/Kotlin/binary-compatibility-validator/issues/95") +} + apiValidation { ignoredPackages.add("io.gitlab.arturbosch.detekt.api.internal") } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt index 5f7fccd61866..99bed074c653 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.api import io.github.detekt.psi.FilePath +import io.github.detekt.psi.getLineAndColumnInPsiFile import io.github.detekt.psi.toFilePath import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.com.intellij.psi.PsiElement -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -14,7 +14,10 @@ import java.nio.file.Paths /** * Specifies a position within a source code fragment. */ -data class Location @Deprecated("Consider relative path by passing a [FilePath]") @JvmOverloads constructor( +data class Location +@Deprecated("Consider relative path by passing a [FilePath]") +@JvmOverloads +constructor( val source: SourceLocation, val text: TextLocation, @Deprecated( @@ -26,6 +29,8 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]" val file: String, val filePath: FilePath = FilePath.fromAbsolute(Paths.get(file)) ) : Compactable { + var endSource: SourceLocation = source + private set @Suppress("DEPRECATION") constructor( @@ -34,6 +39,16 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]" filePath: FilePath ) : this(source, text, filePath.absolutePath.toString(), filePath) + @Suppress("DEPRECATION") + constructor( + source: SourceLocation, + endSource: SourceLocation, + text: TextLocation, + filePath: FilePath, + ) : this(source, text, filePath.absolutePath.toString(), filePath) { + this.endSource = endSource + } + @Suppress("DEPRECATION") @Deprecated( """ @@ -62,24 +77,33 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]" fun from(element: PsiElement, offset: Int = 0): Location { val start = startLineAndColumn(element, offset) val sourceLocation = SourceLocation(start.line, start.column) + val end = endLineAndColumn(element, offset) + val endSourceLocation = SourceLocation(end.line, end.column) val textLocation = TextLocation(element.startOffset + offset, element.endOffset + offset) - return Location(sourceLocation, textLocation, element.containingFile.toFilePath()) + return Location(sourceLocation, endSourceLocation, textLocation, element.containingFile.toFilePath()) } /** - * Determines the line and column of a [PsiElement] in the source file. + * Determines the start line and column of a [PsiElement] in the source file. */ - fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn { - return try { - val range = element.textRange - DiagnosticUtils.getLineAndColumnInPsiFile( - element.containingFile, - TextRange(range.startOffset + offset, range.endOffset + offset) - ) - } catch (@Suppress("SwallowedException", "TooGenericExceptionCaught") e: IndexOutOfBoundsException) { - // #3317 If any rule mutates the PsiElement, searching the original PsiElement may throw exception. - PsiDiagnosticUtils.LineAndColumn(-1, -1, null) - } + fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn = + lineAndColumn( + element, + TextRange(element.textRange.startOffset + offset, element.textRange.endOffset + offset) + ) + + /** + * Determines the end line and column of a [PsiElement] in the source file. + */ + private fun endLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn = + lineAndColumn( + element, + TextRange(element.textRange.endOffset + offset, element.textRange.endOffset + offset) + ) + + private fun lineAndColumn(element: PsiElement, range: TextRange): PsiDiagnosticUtils.LineAndColumn { + return getLineAndColumnInPsiFile(element.containingFile, range) + ?: PsiDiagnosticUtils.LineAndColumn(-1, -1, null) } } } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt index 08411d63e727..e76bf39d35fa 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/SplitPattern.kt @@ -17,7 +17,8 @@ open class SplitPattern( .mapIf(removeTrailingAsterisks) { seq -> seq.map { it.removePrefix("*") } .map { it.removeSuffix("*") } - }.toList() + } + .toList() private fun Sequence.mapIf( condition: Boolean, @@ -81,6 +82,6 @@ fun String.simplePatternToRegex(): Regex { return this .replace(".", "\\.") .replace("*", ".*") - .replace("?", ".?") + .replace("?", ".") .toRegex() } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt index 117100b1985e..4cac91362d4f 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/Signatures.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments import java.io.File private val multipleWhitespaces = Regex("\\s{2,}") @@ -92,21 +93,15 @@ private fun buildClassSignature(classOrObject: KtClassOrObject): String { } private fun buildFunctionSignature(element: KtNamedFunction): String { - var methodStart = 0 - element.docComment?.let { - methodStart = it.endOffset - it.startOffset - } - var methodEnd = element.endOffset - element.startOffset - val typeReference = element.typeReference - if (typeReference != null) { - methodEnd = typeReference.endOffset - element.startOffset + val startOffset = element.startOffsetSkippingComments - element.startOffset + val endOffset = if (element.typeReference != null) { + element.typeReference?.endOffset ?: 0 } else { - element.valueParameterList?.let { - methodEnd = it.endOffset - element.startOffset - } - } - require(methodStart < methodEnd) { - "Error building function signature with range $methodStart - $methodEnd for element: ${element.text}" + element.valueParameterList?.endOffset ?: 0 + } - element.startOffset + + require(startOffset < endOffset) { + "Error building function signature with range $startOffset - $endOffset for element: ${element.text}" } - return element.text.substring(methodStart, methodEnd) + return element.text.substring(startOffset, endOffset) } diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlob.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlob.kt deleted file mode 100644 index e8e82613defe..000000000000 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlob.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.gitlab.arturbosch.detekt.api.internal - -/** - * This simple globbing implementation allows users to define patterns with `?` (any single character) - * and `*` (zero or more characters) wildcards. - */ -class SimpleGlob private constructor(private val regex: Regex) { - - fun matches(input: String) = regex.matches(input) - - companion object { - fun of(globPattern: String): SimpleGlob { - val regex = globPattern - .replace("\\", "\\\\") - .replace(".", "\\.") - .replace("*", ".*") - .replace("?", ".") - .toRegex() - return SimpleGlob(regex) - } - } -} diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt index 6da78a438adb..c0abcf85551e 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/AnnotationExcluderSpec.kt @@ -27,7 +27,9 @@ class AnnotationExcluderSpec(private val env: KotlinCoreEnvironment) { """.trimIndent() ) - @ParameterizedTest(name = "Given {0} is excluded when the {1} is found then the excluder returns {2} without type solving") + @ParameterizedTest( + name = "Given {0} is excluded when the {1} is found then the excluder returns {2} without type solving" + ) @CsvFileSource(resources = ["/annotation_excluder.csv"]) fun `all cases`(exclusion: String, annotation: String, shouldExclude: Boolean) { val (file, ktAnnotation) = createKtFile(annotation) @@ -36,7 +38,9 @@ class AnnotationExcluderSpec(private val env: KotlinCoreEnvironment) { assertThat(excluder.shouldExclude(listOf(ktAnnotation))).isEqualTo(shouldExclude) } - @ParameterizedTest(name = "Given {0} is excluded when the {1} is found then the excluder returns {2} with type solving") + @ParameterizedTest( + name = "Given {0} is excluded when the {1} is found then the excluder returns {2} with type solving" + ) @CsvFileSource(resources = ["/annotation_excluder.csv"]) fun `all cases - Type Solving`(exclusion: String, annotation: String, shouldExclude: Boolean) { val (file, ktAnnotation) = createKtFile(annotation) diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/LocationSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/LocationSpec.kt new file mode 100644 index 000000000000..b55dda3392bf --- /dev/null +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/LocationSpec.kt @@ -0,0 +1,35 @@ +package io.gitlab.arturbosch.detekt.api + +import io.github.detekt.test.utils.compileContentForTest +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.junit.jupiter.api.Test + +class LocationSpec { + + @Test + fun `start and end positions of block`() { + val code = """ + fun data(): Int { + return 0 + } + """.trimIndent() + val psiElement = compileContentForTest(code).findChildByClass(KtNamedFunction::class.java)!! + val location = Location.from(psiElement) + + assertThat("${location.source} - ${location.endSource}").isEqualTo("1:1 - 3:2") + } + + @Test + fun `start and end positions of fun keyword`() { + val code = """ + fun data(): Int { + return 0 + } + """.trimIndent() + val psiElement = compileContentForTest(code).findChildByClass(KtNamedFunction::class.java)!! + val location = Location.from(psiElement.funKeyword!!) + + assertThat("${location.source} - ${location.endSource}").isEqualTo("1:1 - 1:4") + } +} diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlobSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SimplePatternToRegexSpec.kt similarity index 83% rename from detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlobSpec.kt rename to detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SimplePatternToRegexSpec.kt index fd78c3828489..a508f953f7e1 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SimpleGlobSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/SimplePatternToRegexSpec.kt @@ -1,14 +1,14 @@ -package io.gitlab.arturbosch.detekt.api.internal +package io.gitlab.arturbosch.detekt.api import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -class SimpleGlobSpec { +internal class SimplePatternToRegexSpec { @Nested inner class `empty pattern` { - private val subject = SimpleGlob.of("") + private val subject = "".simplePatternToRegex() @Test fun `matches an empty string`() { @@ -25,7 +25,7 @@ class SimpleGlobSpec { @Nested inner class `blank pattern` { - private val subject = SimpleGlob.of(" \t") + private val subject = " \t".simplePatternToRegex() @Test fun `matches an empty string`() { @@ -42,7 +42,7 @@ class SimpleGlobSpec { @Nested inner class `Static pattern` { - private val subject = SimpleGlob.of("abc") + private val subject = "abc".simplePatternToRegex() @Test fun `matches the same string`() { @@ -63,7 +63,7 @@ class SimpleGlobSpec { inner class `single wildcard` { @Nested inner class `pattern with wildcard at the beginning` { - private val subject = SimpleGlob.of("*xyz") + private val subject = "*xyz".simplePatternToRegex() @Test fun `matches pattern exactly`() { @@ -86,7 +86,7 @@ class SimpleGlobSpec { @Nested inner class `Pattern with wildcard at the end` { - private val subject = SimpleGlob.of("xyz*") + private val subject = "xyz*".simplePatternToRegex() @Test fun `matches pattern exactly`() { @@ -109,7 +109,7 @@ class SimpleGlobSpec { @Nested inner class `Pattern with wildcard at the middle` { - private val subject = SimpleGlob.of("x*yz") + private val subject = "x*yz".simplePatternToRegex() @Test fun `matches pattern exactly`() { @@ -139,7 +139,7 @@ class SimpleGlobSpec { @Nested inner class `multiple wildcards` { - private val subject = SimpleGlob.of("x*yz*") + private val subject = "x*yz*".simplePatternToRegex() @Test fun `matches pattern`() { @@ -155,7 +155,7 @@ class SimpleGlobSpec { inner class `single wildcard` { @Nested inner class `pattern with wildcard at the beginning` { - private val subject = SimpleGlob.of("?xyz") + private val subject = "?xyz".simplePatternToRegex() @Test fun `matches with any character before`() { @@ -164,7 +164,7 @@ class SimpleGlobSpec { } @Test - fun `does not match with anything before`() { + fun `does not match with no character before`() { val actual = subject.matches("xyz") assertThat(actual).isFalse() } @@ -178,7 +178,7 @@ class SimpleGlobSpec { @Nested inner class `pattern with wildcard at the end` { - private val subject = SimpleGlob.of("xyz?") + private val subject = "xyz?".simplePatternToRegex() @Test fun `matches with any character after`() { @@ -187,7 +187,7 @@ class SimpleGlobSpec { } @Test - fun `does not match with anything after`() { + fun `does not match with no character after`() { val actual = subject.matches("xyz") assertThat(actual).isFalse() } @@ -201,7 +201,7 @@ class SimpleGlobSpec { @Nested inner class `pattern with wildcard at the middle` { - private val subject = SimpleGlob.of("x?yz") + private val subject = "x?yz".simplePatternToRegex() @Test fun `matches with any single character`() { @@ -219,11 +219,11 @@ class SimpleGlobSpec { @Nested inner class `multiple wildcards` { - private val subject = SimpleGlob.of("x?y?z") + private val subject = "x?y?z".simplePatternToRegex() @Test fun `matches pattern`() { - val actual = subject.matches("x.y.z") + val actual = subject.matches("x.y_z") assertThat(actual).isTrue() } } @@ -233,7 +233,7 @@ class SimpleGlobSpec { inner class `characters that have a special meaning in regular expression must be escaped` { @Nested inner class `Period` { - private val subject = SimpleGlob.of("a.b.c") + private val subject = "a.b.c".simplePatternToRegex() @Test fun `matches the same string`() { @@ -249,20 +249,14 @@ class SimpleGlobSpec { } @Nested - inner class `Backslash` { - private val subject = SimpleGlob.of("""ab\d""") + inner class `character classes and quantifiers` { + private val subject = """ab\d{2,5}\s\wc""".simplePatternToRegex() @Test - fun `matches the same string`() { - val actual = subject.matches("""ab\d""") + fun `can be used`() { + val actual = subject.matches("""ab123 Xc""") assertThat(actual).isTrue() } - - @Test - fun `does not match a other string`() { - val actual = subject.matches("ab5") - assertThat(actual).isFalse() - } } } @@ -270,7 +264,7 @@ class SimpleGlobSpec { inner class `invalid pattern` { @Test fun `fails during creation`() { - assertThatThrownBy { SimpleGlob.of("""a[b""") } + assertThatThrownBy { """a[b""".simplePatternToRegex() } .isInstanceOf(IllegalArgumentException::class.java) } } diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/PathMatchersSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/PathMatchersSpec.kt index 4ecd997ded56..173a02776d2a 100644 --- a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/PathMatchersSpec.kt +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/PathMatchersSpec.kt @@ -41,7 +41,9 @@ class PathMatchersSpec { fun `should work as a regex path matcher when syntax not specified`() { assertThatThrownBy { pathMatcher("regex:.*/detekt/api/.*") } .isInstanceOf(IllegalArgumentException::class.java) - .hasMessage("Only globbing patterns are supported as they are treated os-independently by the PathMatcher api.") + .hasMessage( + "Only globbing patterns are supported as they are treated os-independently by the PathMatcher api." + ) } } } diff --git a/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SignaturesSpec.kt b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SignaturesSpec.kt new file mode 100644 index 000000000000..acfcf1bf5f93 --- /dev/null +++ b/detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/internal/SignaturesSpec.kt @@ -0,0 +1,47 @@ +package io.gitlab.arturbosch.detekt.api.internal + +import io.github.detekt.test.utils.compileContentForTest +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.junit.jupiter.api.Test + +class SignaturesSpec { + @Test + fun `function with type reference`() { + val result = compileContentForTest("fun data(): Int = 0") + .findChildByClass(KtNamedFunction::class.java)!! + .buildFullSignature() + + assertThat(result).isEqualTo("Test.kt\$fun data(): Int") + } + + @Test + fun `function without type reference`() { + val result = compileContentForTest("fun data() = 0") + .findChildByClass(KtNamedFunction::class.java)!! + .buildFullSignature() + + assertThat(result).isEqualTo("Test.kt\$fun data()") + } + + @Test + fun `function with comments`() { + val result = compileContentForTest("/* comments */ fun data() = 0") + .findChildByClass(KtNamedFunction::class.java)!! + .buildFullSignature() + + assertThat(result).isEqualTo("Test.kt\$fun data()") + } + + @Test + fun `function throws exception`() { + assertThatThrownBy { + compileContentForTest("{ fun data() = 0 }") + .findChildByClass(KtNamedFunction::class.java)!! + .buildFullSignature() + } + .isInstanceOf(IllegalArgumentException::class.java) + .hasMessageContaining("Error building function signature") + } +} diff --git a/detekt-cli/build.gradle.kts b/detekt-cli/build.gradle.kts index edfd7cdd29a7..d14b3203fe9b 100644 --- a/detekt-cli/build.gradle.kts +++ b/detekt-cli/build.gradle.kts @@ -16,6 +16,11 @@ dependencies { implementation(libs.jcommander) implementation(projects.detektTooling) implementation(projects.detektParser) + implementation(libs.kotlin.compilerEmbeddable) { + version { + strictly(libs.versions.kotlin.get()) + } + } runtimeOnly(projects.detektCore) runtimeOnly(projects.detektRules) diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt index 4d2714a5d2d4..b223993bf1c3 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/CliArgs.kt @@ -79,7 +79,7 @@ class CliArgs { names = ["--report", "-r"], description = "Generates a report for given 'report-id' and stores it on given 'path'. " + "Entry should consist of: [report-id:path]. " + - "Available 'report-id' values: 'txt', 'xml', 'html', 'sarif'. " + + "Available 'report-id' values: 'txt', 'xml', 'html', 'md', 'sarif'. " + "These can also be used in combination with each other " + "e.g. '-r txt:reports/detekt.txt -r xml:reports/detekt.xml'" ) diff --git a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Spec.kt b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Spec.kt index a3347e86f131..cc920fdd848d 100644 --- a/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Spec.kt +++ b/detekt-cli/src/main/kotlin/io/gitlab/arturbosch/detekt/cli/Spec.kt @@ -41,7 +41,7 @@ internal fun CliArgs.createSpec(output: Appendable, error: Appendable): Processi config { useDefaultConfig = args.buildUponDefaultConfig - shouldValidateBeforeAnalysis = false + shouldValidateBeforeAnalysis = null knownPatterns = emptyList() // ^^ cli does not have these properties yet; specified in yaml config for now configPaths = config?.let { MultipleExistingPathConverter().convert(it) }.orEmpty() diff --git a/detekt-core/build.gradle.kts b/detekt-core/build.gradle.kts index 0d92502f418d..19e1355f421d 100644 --- a/detekt-core/build.gradle.kts +++ b/detekt-core/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(projects.detektMetrics) implementation(projects.detektPsiUtils) implementation(projects.detektReportHtml) + implementation(projects.detektReportMd) implementation(projects.detektReportTxt) implementation(projects.detektReportXml) implementation(projects.detektReportSarif) diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/BindingContext.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/BindingContext.kt index a19e1831a6e2..a60d35650355 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/BindingContext.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/BindingContext.kt @@ -33,6 +33,7 @@ internal fun generateBindingContext( val analyzer = AnalyzerWithCompilerReport( messageCollector, environment.configuration.languageVersionSettings, + false, ) analyzer.analyzeAndReport(files) { TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration( diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/ConfigValidators.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/ConfigValidators.kt index 8934b8234d44..bd00be46dc21 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/ConfigValidators.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/config/ConfigValidators.kt @@ -11,9 +11,11 @@ import io.gitlab.arturbosch.detekt.core.reporting.red import io.gitlab.arturbosch.detekt.core.reporting.yellow internal fun checkConfiguration(settings: ProcessingSettings, baseline: Config) { - val props = settings.config.subConfig("config") - val shouldValidate = props.valueOrDefault("validation", true) - + var shouldValidate = settings.spec.configSpec.shouldValidateBeforeAnalysis + if (shouldValidate == null) { + val props = settings.config.subConfig("config") + shouldValidate = props.valueOrDefault("validation", true) + } if (shouldValidate) { val validators = loadExtensions(settings) + DefaultPropertiesConfigValidator(settings, baseline) diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/reporting/Reporting.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/reporting/Reporting.kt index f353256ce581..20ee87e95c69 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/reporting/Reporting.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/reporting/Reporting.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.core.reporting import io.github.detekt.report.html.HtmlOutputReport +import io.github.detekt.report.md.MdOutputReport import io.github.detekt.report.sarif.SarifOutputReport import io.github.detekt.report.txt.TxtOutputReport import io.github.detekt.report.xml.XmlOutputReport @@ -11,13 +12,13 @@ import io.gitlab.arturbosch.detekt.api.Detektion import io.gitlab.arturbosch.detekt.api.Finding import io.gitlab.arturbosch.detekt.api.RuleSetId import io.gitlab.arturbosch.detekt.api.ThresholdedCodeSmell -import kotlin.text.Typography.ellipsis internal fun defaultReportMapping(reportId: String) = when (reportId) { TxtOutputReport::class.java.simpleName -> "txt" XmlOutputReport::class.java.simpleName -> "xml" HtmlOutputReport::class.java.simpleName -> "html" SarifOutputReport::class.java.simpleName -> "sarif" + MdOutputReport::class.java.simpleName -> "md" else -> reportId } @@ -79,7 +80,7 @@ private fun Finding.truncatedMessage(): String { .replace(messageReplacementRegex, " ") .trim() return when { - message.length > REPORT_MESSAGE_SIZE_LIMIT -> "${message.take(REPORT_MESSAGE_SIZE_LIMIT)}($ellipsis)" + message.length > REPORT_MESSAGE_SIZE_LIMIT -> "${message.take(REPORT_MESSAGE_SIZE_LIMIT)}(...)" else -> message } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/settings/EnvironmentAware.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/settings/EnvironmentAware.kt index 1bb2041255d2..89fa882894cd 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/settings/EnvironmentAware.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/settings/EnvironmentAware.kt @@ -55,5 +55,8 @@ internal fun CompilerSpec.parseLanguageVersion(): LanguageVersion? { } internal fun CompilerSpec.parseJvmTarget(): JvmTarget { - return checkNotNull(JvmTarget.fromString(jvmTarget)) { "Invalid value passed to --jvm-target" } + return checkNotNull(JvmTarget.fromString(jvmTarget)) { + "Invalid value ($jvmTarget) passed to --jvm-target," + + " must be one of ${JvmTarget.values().map(JvmTarget::description)}" + } } diff --git a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt index 3bddf2f45e46..397f8088d104 100644 --- a/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt +++ b/detekt-core/src/main/kotlin/io/gitlab/arturbosch/detekt/core/tooling/DefaultConfigProvider.kt @@ -32,7 +32,7 @@ class DefaultConfigProvider : DefaultConfigurationProvider { private fun configInputStream(extensionsSpec: ExtensionsSpec): InputStream { val outputStream = ByteArrayOutputStream() - requireNotNull(extensionsSpec.javaClass.getSafeResourceAsStream("/default-detekt-config.yml")) + requireNotNull(DefaultConfigProvider::class.java.getSafeResourceAsStream("/default-detekt-config.yml")) .use { it.copyTo(outputStream) } ExtensionFacade(extensionsSpec.plugins).pluginLoader diff --git a/detekt-core/src/main/resources/default-detekt-config.yml b/detekt-core/src/main/resources/default-detekt-config.yml index 0f356b190b93..bc710f29a52f 100644 --- a/detekt-core/src/main/resources/default-detekt-config.yml +++ b/detekt-core/src/main/resources/default-detekt-config.yml @@ -46,6 +46,7 @@ output-reports: # - 'TxtOutputReport' # - 'XmlOutputReport' # - 'HtmlOutputReport' + # - 'MdOutputReport' comments: active: true @@ -77,12 +78,15 @@ comments: searchInInnerClass: true searchInInnerObject: true searchInInnerInterface: true + searchInProtectedClass: false UndocumentedPublicFunction: active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + searchProtectedFunction: false UndocumentedPublicProperty: active: false excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + searchProtectedProperty: false complexity: active: true @@ -491,13 +495,17 @@ style: active: true CanBeNonNullable: active: false + CascadingCallWrapping: + active: false + includeElvis: true ClassOrdering: active: false CollapsibleIfStatements: active: false DataClassContainsFunctions: active: false - conversionFunctionPrefix: 'to' + conversionFunctionPrefix: + - 'to' DataClassShouldBeImmutable: active: false DestructuringDeclarationWithTooManyEntries: @@ -529,8 +537,10 @@ style: ForbiddenMethodCall: active: false methods: - - 'kotlin.io.print' - - 'kotlin.io.println' + - reason: 'print does not allow you to configure the output stream. Use a logger instead.' + value: 'kotlin.io.print' + - reason: 'println does not allow you to configure the output stream. Use a logger instead.' + value: 'kotlin.io.println' ForbiddenPublicDataClass: active: true excludes: ['**'] @@ -580,6 +590,9 @@ style: active: false MandatoryBracesLoops: active: false + MaxChainedCallsOnSameLine: + active: false + maxChainedCalls: 5 MaxLineLength: active: true maxLineLength: 120 @@ -621,7 +634,8 @@ style: ReturnCount: active: true max: 2 - excludedFunctions: 'equals' + excludedFunctions: + - 'equals' excludeLabeled: false excludeReturnFromLambda: true excludeGuardClauses: false @@ -637,6 +651,8 @@ style: excludeGuardClauses: false TrailingWhitespace: active: false + TrimMultilineRawString: + active: false UnderscoresInNumericLiterals: active: false acceptableLength: 4 @@ -659,6 +675,7 @@ style: active: false UnnecessaryParentheses: active: false + allowForUnclearPrecedence: false UntilInsteadOfRangeTo: active: false UnusedImports: @@ -702,6 +719,5 @@ style: ignoreLateinitVar: false WildcardImport: active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] excludeImports: - 'java.util.*' diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/CheckConfigurationSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/CheckConfigurationSpec.kt index b5830937bcd4..9a0d468063c7 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/CheckConfigurationSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/CheckConfigurationSpec.kt @@ -20,6 +20,28 @@ class SupportConfigValidationSpec { private val testDir = createTempDirectoryForTest("detekt-sample") private val spec = createNullLoggingSpec {} + @Test + fun `passes because config validation is disabled by tooling spec`() { + val config = yamlConfigFromContent( + """ + unknown_property: + unknown_var: "" + """ + ) + createProcessingSettings( + testDir, + config, + spec = createNullLoggingSpec { + config { + shouldValidateBeforeAnalysis = false + } + } + ).use { + assertThatCode { checkConfiguration(it, spec.getDefaultConfiguration()) } + .doesNotThrowAnyException() + } + } + @Test fun `fails when unknown properties are found`() { val config = yamlConfigFromContent( diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt index 8c45bc8c7623..b010d479e5e3 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/config/YamlConfigSpec.kt @@ -57,7 +57,9 @@ class YamlConfigSpec { @Suppress("UNUSED_VARIABLE") val ignored = config.valueOrDefault("style", "") } - .withMessage("Value \"{WildcardImport={active=true}, NoElseInWhenExpression={active=true}, MagicNumber={active=true, ignoreNumbers=[-1, 0, 1, 2]}}\" set for config parameter \"style\" is not of required type String.") + .withMessage( + "Value \"{WildcardImport={active=true}, NoElseInWhenExpression={active=true}, MagicNumber={active=true, ignoreNumbers=[-1, 0, 1, 2]}}\" set for config parameter \"style\" is not of required type String." + ) } } @@ -94,7 +96,9 @@ class YamlConfigSpec { .subConfig("Rule") .valueOrDefault("threshold", 6) } - .withMessage("Value \"v5.7\" set for config parameter \"RuleSet > Rule > threshold\" is not of required type Int.") + .withMessage( + "Value \"v5.7\" set for config parameter \"RuleSet > Rule > threshold\" is not of required type Int." + ) } @Test @@ -105,7 +109,9 @@ class YamlConfigSpec { .subConfig("Rule") .valueOrDefault("active", 1) } - .withMessage("Value \"[]\" set for config parameter \"RuleSet > Rule > active\" is not of required type Int.") + .withMessage( + "Value \"[]\" set for config parameter \"RuleSet > Rule > active\" is not of required type Int." + ) } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputFacadeSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputFacadeSpec.kt index 0562b374dc6f..2ca6dbad183a 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputFacadeSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputFacadeSpec.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.core.reporting import io.github.detekt.report.html.HtmlOutputReport +import io.github.detekt.report.md.MdOutputReport import io.github.detekt.report.txt.TxtOutputReport import io.github.detekt.report.xml.XmlOutputReport import io.github.detekt.test.utils.StringPrintStream @@ -24,6 +25,7 @@ class OutputFacadeSpec { val plainOutputPath = createTempFileForTest("detekt", ".txt") val htmlOutputPath = createTempFileForTest("detekt", ".html") val xmlOutputPath = createTempFileForTest("detekt", ".xml") + val mdOutputPath = createTempFileForTest("detekt", ".md") val spec = createNullLoggingSpec { project { @@ -33,6 +35,7 @@ class OutputFacadeSpec { report { "html" to htmlOutputPath } report { "txt" to plainOutputPath } report { "xml" to xmlOutputPath } + report { "md" to mdOutputPath } } logging { outputChannel = printStream @@ -44,7 +47,8 @@ class OutputFacadeSpec { assertThat(printStream.toString()).contains( "Successfully generated ${TxtOutputReport().name} at $plainOutputPath", "Successfully generated ${XmlOutputReport().name} at $xmlOutputPath", - "Successfully generated ${HtmlOutputReport().name} at $htmlOutputPath" + "Successfully generated ${HtmlOutputReport().name} at $htmlOutputPath", + "Successfully generated ${MdOutputReport().name} at $mdOutputPath" ) } } diff --git a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputReportsSpec.kt b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputReportsSpec.kt index 4f8aace147f6..7fdbbf25f200 100644 --- a/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputReportsSpec.kt +++ b/detekt-core/src/test/kotlin/io/gitlab/arturbosch/detekt/core/reporting/OutputReportsSpec.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.core.reporting import io.github.detekt.report.html.HtmlOutputReport +import io.github.detekt.report.md.MdOutputReport import io.github.detekt.report.txt.TxtOutputReport import io.github.detekt.report.xml.XmlOutputReport import io.github.detekt.test.utils.resourceAsPath @@ -28,11 +29,12 @@ class OutputReportsSpec { report { "txt" to Paths.get("/tmp/path2") } report { reportUnderTest to Paths.get("/tmp/path3") } report { "html" to Paths.get("D:_Gradle\\xxx\\xxx\\build\\reports\\detekt\\detekt.html") } + report { "md" to Paths.get("/tmp/path4") } }.build().reports.toList() @Test fun `should parse multiple report entries`() { - assertThat(reports).hasSize(4) + assertThat(reports).hasSize(5) } @Test @@ -66,6 +68,13 @@ class OutputReportsSpec { ) } + @Test + fun `it should properly parse MD report entry`() { + val mdRepot = reports[4] + assertThat(mdRepot.type).isEqualTo(defaultReportMapping(MdOutputReport::class.java.simpleName)) + assertThat(mdRepot.path).isEqualTo(Paths.get("/tmp/path4")) + } + @Nested inner class `default report ids` { diff --git a/detekt-core/src/test/resources/reporting/long-messages-report.txt b/detekt-core/src/test/resources/reporting/long-messages-report.txt index 23ab8780f8b7..f5141676cafd 100644 --- a/detekt-core/src/test/resources/reporting/long-messages-report.txt +++ b/detekt-core/src/test/resources/reporting/long-messages-report.txt @@ -1,5 +1,5 @@ Ruleset - 10min debt - LongRule - [This is just a long message that should be truncated after a given threshold is (…)] at File.kt:1:1 + LongRule - [This is just a long message that should be truncated after a given threshold is (...)] at File.kt:1:1 MultilineRule - [A multiline message.] at File.kt:1:1 Overall debt: 10min diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt index b01b80a9682a..defc385ea1e7 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/FormattingRule.kt @@ -3,7 +3,7 @@ package io.gitlab.arturbosch.detekt.formatting import com.pinterest.ktlint.core.KtLint import com.pinterest.ktlint.core.Rule.VisitorModifier.RunAsLateAsPossible import com.pinterest.ktlint.core.Rule.VisitorModifier.RunOnRootNodeOnly -import com.pinterest.ktlint.core.api.FeatureInAlphaState +import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties.codeStyleSetProperty import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import io.github.detekt.psi.fileName import io.github.detekt.psi.toFilePath @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset /** * Rule to detect formatting violations. */ -@OptIn(FeatureInAlphaState::class) abstract class FormattingRule(config: Config) : Rule(config) { abstract val wrapping: com.pinterest.ktlint.core.Rule @@ -53,15 +52,20 @@ abstract class FormattingRule(config: Config) : Rule(config) { override fun visit(root: KtFile) { this.root = root - root.node.putUserData(KtLint.ANDROID_USER_DATA_KEY, isAndroid) positionByOffset = KtLintLineColCalculator .calculateLineColByOffset(KtLintLineColCalculator.normalizeText(root.text)) - val editorConfigProperties = overrideEditorConfigProperties() + val editorConfigProperties = overrideEditorConfigProperties()?.toMutableMap() + ?: mutableMapOf() - if (!editorConfigProperties.isNullOrEmpty()) { + if (isAndroid) { + editorConfigProperties[codeStyleSetProperty] = "android" + } + + if (editorConfigProperties.isNotEmpty()) { val userData = (root.node.getUserData(KtLint.EDITOR_CONFIG_PROPERTIES_USER_DATA_KEY).orEmpty()) .toMutableMap() + editorConfigProperties.forEach { (editorConfigProperty, defaultValue) -> userData[editorConfigProperty.type.name] = Property.builder() .name(editorConfigProperty.type.name) @@ -81,18 +85,6 @@ abstract class FormattingRule(config: Config) : Rule(config) { return } - // KtLint 0.44.0 is assuming that KtLint.EDITOR_CONFIG_USER_DATA_KEY is available on all the nodes. - // If not, it crashes with a NPE. Here we're patching their behavior. - // This block is deprecated and will be removed in KtLint 0.46. But we have to suppress the - // deprecation warning because the ci runs with -Werror. - @Suppress("DEPRECATION") - if (node.getUserData(KtLint.EDITOR_CONFIG_USER_DATA_KEY) == null) { - node.putUserData( - KtLint.EDITOR_CONFIG_USER_DATA_KEY, - com.pinterest.ktlint.core.EditorConfig.Companion.fromMap(emptyMap()) - ) - } - wrapping.visit(node, autoCorrect) { offset, message, _ -> val (line, column) = positionByOffset(offset) val location = Location( diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt index 96fdaaa64e8b..0fa570cc4d3a 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/KtLintMultiRule.kt @@ -24,6 +24,7 @@ import io.gitlab.arturbosch.detekt.formatting.wrappers.ModifierListSpacing import io.gitlab.arturbosch.detekt.formatting.wrappers.ModifierOrdering import io.gitlab.arturbosch.detekt.formatting.wrappers.MultiLineIfElse import io.gitlab.arturbosch.detekt.formatting.wrappers.NoBlankLineBeforeRbrace +import io.gitlab.arturbosch.detekt.formatting.wrappers.NoBlankLinesInChainedMethodCalls import io.gitlab.arturbosch.detekt.formatting.wrappers.NoConsecutiveBlankLines import io.gitlab.arturbosch.detekt.formatting.wrappers.NoEmptyClassBody import io.gitlab.arturbosch.detekt.formatting.wrappers.NoEmptyFirstLineInMethodBlock @@ -59,7 +60,7 @@ import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyHolder import org.jetbrains.kotlin.psi.KtFile -import java.util.* +import java.util.LinkedList /** * Runs all KtLint rules. @@ -77,6 +78,7 @@ class KtLintMultiRule(config: Config = Config.empty) : MultiRule() { MaximumLineLength(config), ModifierOrdering(config), NoBlankLineBeforeRbrace(config), + NoBlankLinesInChainedMethodCalls(config), NoConsecutiveBlankLines(config), NoEmptyClassBody(config), NoLineBreakAfterElse(config), diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationOnSeparateLine.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationOnSeparateLine.kt index 718841f2e5c0..afe438a83179 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationOnSeparateLine.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationOnSeparateLine.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.AnnotationRule +import com.pinterest.ktlint.ruleset.standard.AnnotationRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.0.0") +@ActiveByDefault(since = "1.22.0") class AnnotationOnSeparateLine(config: Config) : FormattingRule(config) { override val wrapping = AnnotationRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationSpacing.kt index 5f4b4c83c7eb..f2ef0f611884 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/AnnotationSpacing.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.AnnotationSpacingRule +import com.pinterest.ktlint.ruleset.standard.AnnotationSpacingRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.0.0") +@ActiveByDefault(since = "1.22.0") class AnnotationSpacing(config: Config) : FormattingRule(config) { override val wrapping = AnnotationSpacingRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ArgumentListWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ArgumentListWrapping.kt index 2b8de2cdc5b6..ac35986edb74 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ArgumentListWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ArgumentListWrapping.kt @@ -1,21 +1,21 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties -import com.pinterest.ktlint.ruleset.experimental.ArgumentListWrappingRule +import com.pinterest.ktlint.ruleset.standard.ArgumentListWrappingRule import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.configWithAndroidVariants +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ -@OptIn(FeatureInAlphaState::class) @AutoCorrectable(since = "1.0.0") +@ActiveByDefault(since = "1.22.0") class ArgumentListWrapping(config: Config) : FormattingRule(config) { override val wrapping = ArgumentListWrappingRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/BlockCommentInitialStarAlignment.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/BlockCommentInitialStarAlignment.kt index bd427a1eb550..b2ff7280b4bd 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/BlockCommentInitialStarAlignment.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/BlockCommentInitialStarAlignment.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class BlockCommentInitialStarAlignment(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt index f2b5f8ccf6c4..969c11f29f38 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ChainWrapping.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt index f489224df752..01ccfae54414 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentSpacing.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentWrapping.kt index 9216c9375681..923ba37cc350 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/CommentWrapping.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.experimental.CommentWrappingRule import io.gitlab.arturbosch.detekt.api.Config @@ -11,7 +10,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-indentation) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class CommentWrapping(config: Config) : FormattingRule(config) { @@ -22,7 +21,6 @@ class CommentWrapping(config: Config) : FormattingRule(config) { @Configuration("indentation size") private val indentSize by config(4) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf( DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/DiscouragedCommentLocation.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/DiscouragedCommentLocation.kt index e6b0b1213d79..53c19cb15fb7 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/DiscouragedCommentLocation.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/DiscouragedCommentLocation.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class DiscouragedCommentLocation(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/EnumEntryNameCase.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/EnumEntryNameCase.kt index ef2663dd4076..5338c219fa67 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/EnumEntryNameCase.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/EnumEntryNameCase.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.EnumEntryNameCaseRule +import com.pinterest.ktlint.ruleset.standard.EnumEntryNameCaseRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.4.0") +@ActiveByDefault(since = "1.22.0") class EnumEntryNameCase(config: Config) : FormattingRule(config) { override val wrapping = EnumEntryNameCaseRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt index 64ee9f1da0de..1ef732390d40 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Filename.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. * * This rules overlaps with [naming>MatchingDeclarationName](https://detekt.dev/naming.html#matchingdeclarationname) * from the standard rules, make sure to enable just one. diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt index 8477433c6761..810f0f1d7fac 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FinalNewline.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.FinalNewlineRule import io.gitlab.arturbosch.detekt.api.Config @@ -12,7 +11,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. * * This rules overlaps with [style>NewLineAtEndOfFile](https://detekt.dev/style.html#newlineatendoffile) * from the standard rules, make sure to enable just one. The pro of this rule is that it can auto-correct the issue. @@ -27,7 +26,6 @@ class FinalNewline(config: Config) : FormattingRule(config) { @Configuration("report absence or presence of a newline") private val insertFinalNewLine by config(true) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf(DefaultEditorConfigProperties.insertNewLineProperty to insertFinalNewLine.toString()) } diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunKeywordSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunKeywordSpacing.kt index 7227500acfe2..81f4e1213a40 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunKeywordSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunKeywordSpacing.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class FunKeywordSpacing(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunctionTypeReferenceSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunctionTypeReferenceSpacing.kt index 8a8e19adc763..d5770b2cfee4 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunctionTypeReferenceSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/FunctionTypeReferenceSpacing.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class FunctionTypeReferenceSpacing(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt index a833b9cf7475..845834bcadac 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ImportOrdering.kt @@ -1,6 +1,5 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.ImportOrderingRule import io.gitlab.arturbosch.detekt.api.Config @@ -11,7 +10,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. * * For defining import layout patterns see the [KtLint Source Code](https://github.com/pinterest/ktlint/blob/a6ca5b2edf95cc70a138a9470cfb6c4fd5d9d3ce/ktlint-ruleset-standard/src/main/kotlin/com/pinterest/ktlint/ruleset/standard/ImportOrderingRule.kt) */ @@ -25,7 +24,6 @@ class ImportOrdering(config: Config) : FormattingRule(config) { @Configuration("the import ordering layout") private val layout: String by configWithAndroidVariants(IDEA_PATTERN, ASCII_PATTERN) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf(ImportOrderingRule.ideaImportsLayoutProperty to layout) diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt index 4c98d5bbb341..c5c100c74c64 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Indentation.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.IndentationRule import io.gitlab.arturbosch.detekt.api.Config @@ -14,7 +13,7 @@ import io.gitlab.arturbosch.detekt.formatting.FormattingRule import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** - * See [ktlint-website](https://ktlint.github.io#rule-indentation) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.19.0") @AutoCorrectable(since = "1.0.0") @@ -31,14 +30,14 @@ class Indentation(config: Config) : FormattingRule(config) { @Suppress("UnusedPrivateMember") private val continuationIndentSize by config(4) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf( DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), ) /** - * [wrapping] is working with file's [node] and we don't want to highlight the whole file + * [IndentationRule] has visitor modifier RunOnRootNodeOnly, so [node] is always the root file. + * Override the parent implementation to highlight the entire file. */ override fun getTextLocationForViolation(node: ASTNode, offset: Int): TextLocation { val relativeEnd = node.text diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/KdocWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/KdocWrapping.kt index 1fff0f207d28..1d104cafd1cc 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/KdocWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/KdocWrapping.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.experimental.KdocWrappingRule import io.gitlab.arturbosch.detekt.api.Config @@ -11,7 +10,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-indentation) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class KdocWrapping(config: Config) : FormattingRule(config) { @@ -22,7 +21,6 @@ class KdocWrapping(config: Config) : FormattingRule(config) { @Configuration("indentation size") private val indentSize by config(4) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf( DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt index 7f400a68fb7a..f8274d04bf91 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MaximumLineLength.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.MaxLineLengthRule import io.gitlab.arturbosch.detekt.api.Config @@ -12,14 +11,13 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. * * This rules overlaps with [style>MaxLineLength](https://detekt.dev/style.html#maxlinelength) * from the standard rules, make sure to enable just one or keep them aligned. The pro of this rule is that it can * auto-correct the issue. */ @ActiveByDefault(since = "1.0.0") -@OptIn(FeatureInAlphaState::class) class MaximumLineLength(config: Config) : FormattingRule(config) { override val wrapping = MaxLineLengthRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierListSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierListSpacing.kt index 926616dad6b3..87acc9b0240c 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierListSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierListSpacing.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class ModifierListSpacing(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt index 106fac23b59a..94ffe2316f14 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ModifierOrdering.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-modifier-order) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. * * This rules overlaps with [style>ModifierOrder](https://detekt.dev/style.html#modifierorder) * from the standard rules, make sure to enable just one. The pro of this rule is that it can auto-correct the issue. diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MultiLineIfElse.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MultiLineIfElse.kt index 4d42ee056cac..7fceed19463a 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MultiLineIfElse.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/MultiLineIfElse.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.MultiLineIfElseRule +import com.pinterest.ktlint.ruleset.standard.MultiLineIfElseRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-modifier-order) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.0.0") +@ActiveByDefault(since = "1.22.0") class MultiLineIfElse(config: Config) : FormattingRule(config) { override val wrapping = MultiLineIfElseRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt index 85e003bf1ece..437ca8ab0901 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLineBeforeRbrace.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLinesInChainedMethodCalls.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLinesInChainedMethodCalls.kt new file mode 100644 index 000000000000..dfc35b0cc4ef --- /dev/null +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoBlankLinesInChainedMethodCalls.kt @@ -0,0 +1,18 @@ +package io.gitlab.arturbosch.detekt.formatting.wrappers + +import com.pinterest.ktlint.ruleset.standard.NoBlankLinesInChainedMethodCallsRule +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault +import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable +import io.gitlab.arturbosch.detekt.formatting.FormattingRule + +/** + * See [ktlint-website](https://ktlint.github.io) for documentation. + */ +@ActiveByDefault(since = "1.22.0") +@AutoCorrectable(since = "1.22.0") +class NoBlankLinesInChainedMethodCalls(config: Config) : FormattingRule(config) { + + override val wrapping = NoBlankLinesInChainedMethodCallsRule() + override val issue = issueFor("Detects blank lines in chained method rules.") +} diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt index 5c35f1034a2b..dd2479e1e424 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoConsecutiveBlankLines.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-blank) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt index 422e4c381348..c379e6fc90d3 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyClassBody.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-empty-class-body) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyFirstLineInMethodBlock.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyFirstLineInMethodBlock.kt index 8ee87a60592f..61e1aa05ef65 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyFirstLineInMethodBlock.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoEmptyFirstLineInMethodBlock.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.NoEmptyFirstLineInMethodBlockRule +import com.pinterest.ktlint.ruleset.standard.NoEmptyFirstLineInMethodBlockRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.4.0") +@ActiveByDefault(since = "1.22.0") class NoEmptyFirstLineInMethodBlock(config: Config) : FormattingRule(config) { override val wrapping = NoEmptyFirstLineInMethodBlockRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt index 349240a35268..e5f3b6bd6bdf 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakAfterElse.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt index 7655af1ce9b7..bfabbae64f32 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoLineBreakBeforeAssignment.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt index cc89fe3fa6fb..d81fb568d017 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoMultipleSpaces.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt index 830e33dbf4a3..d2f6413a8ee6 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoSemicolons.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-semi) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt index 1dc1e1c46fc9..76a5b2b0333c 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoTrailingSpaces.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-trailing-whitespaces) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt index 35a084b80bbc..b9313798dd62 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnitReturn.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-unit-return) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt index 0c9280dfb685..9ce661acff11 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoUnusedImports.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt index e38d90474194..aea84fcdd37b 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/NoWildcardImports.kt @@ -1,6 +1,5 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.NoWildcardImportsRule import io.gitlab.arturbosch.detekt.api.Config @@ -10,7 +9,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-import) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") class NoWildcardImports(config: Config) : FormattingRule(config) { @@ -21,7 +20,6 @@ class NoWildcardImports(config: Config) : FormattingRule(config) { @Configuration("Defines allowed wildcard imports") private val packagesToUseImportOnDemandProperty by config(ALLOWED_WILDCARD_IMPORTS) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf( NoWildcardImportsRule.packagesToUseImportOnDemandProperty to packagesToUseImportOnDemandProperty diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt index af7154774ebf..7d99d34e3905 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/PackageName.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.PackageNameRule +import com.pinterest.ktlint.ruleset.standard.PackageNameRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @AutoCorrectable(since = "1.0.0") +@ActiveByDefault(since = "1.22.0") class PackageName(config: Config) : FormattingRule(config) { override val wrapping = PackageNameRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt index 2065399dc390..6a360326a8f0 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/ParameterListWrapping.kt @@ -1,7 +1,6 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.ParameterListWrappingRule import io.gitlab.arturbosch.detekt.api.Config @@ -13,7 +12,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") @@ -30,7 +29,6 @@ class ParameterListWrapping(config: Config) : FormattingRule(config) { @Suppress("UnusedPrivateMember") private val indentSize by config(4) - @OptIn(FeatureInAlphaState::class) override fun overrideEditorConfigProperties(): Map, String> = mapOf( DefaultEditorConfigProperties.maxLineLengthProperty to maxLineLength.toString() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundAngleBrackets.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundAngleBrackets.kt index 613cc263f429..67548b647c46 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundAngleBrackets.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundAngleBrackets.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.SpacingAroundAngleBracketsRule +import com.pinterest.ktlint.ruleset.standard.SpacingAroundAngleBracketsRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @AutoCorrectable(since = "1.16.0") +@ActiveByDefault(since = "1.22.0") class SpacingAroundAngleBrackets(config: Config) : FormattingRule(config) { override val wrapping = SpacingAroundAngleBracketsRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt index a7d8b8bee7ad..ceb4bafd93ed 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundColon.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt index 045996c3353e..e37622864348 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundComma.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt index 09a581fe919f..33c5e34f7728 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundCurly.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDot.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDot.kt index 803526b26909..faa9699b2e3f 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDot.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDot.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDoubleColon.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDoubleColon.kt index 26116a40e9a4..87931efce23e 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDoubleColon.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundDoubleColon.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.SpacingAroundDoubleColonRule +import com.pinterest.ktlint.ruleset.standard.SpacingAroundDoubleColonRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @AutoCorrectable(since = "1.10.0") +@ActiveByDefault(since = "1.22.0") class SpacingAroundDoubleColon(config: Config) : FormattingRule(config) { override val wrapping = SpacingAroundDoubleColonRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt index 3e97da9ab0a5..a0286fed8cb6 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundKeyword.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt index 0c27a1cf6ff9..7ac5bdb4f6ec 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundOperators.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt index cb73e040b5c4..6a5633fad943 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundParens.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt index 88354cedd36d..ed09bfe87b8a 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundRangeOperator.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundUnaryOperator.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundUnaryOperator.kt index 4adaedef062a..84d778004f83 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundUnaryOperator.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingAroundUnaryOperator.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.SpacingAroundUnaryOperatorRule +import com.pinterest.ktlint.ruleset.standard.SpacingAroundUnaryOperatorRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @AutoCorrectable(since = "1.16.0") +@ActiveByDefault(since = "1.22.0") class SpacingAroundUnaryOperator(config: Config) : FormattingRule(config) { override val wrapping = SpacingAroundUnaryOperatorRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithAnnotations.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithAnnotations.kt index 92b66a943cb9..5b3e0205b000 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithAnnotations.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithAnnotations.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.SpacingBetweenDeclarationsWithAnnotationsRule +import com.pinterest.ktlint.ruleset.standard.SpacingBetweenDeclarationsWithAnnotationsRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @AutoCorrectable(since = "1.10.0") +@ActiveByDefault(since = "1.22.0") class SpacingBetweenDeclarationsWithAnnotations(config: Config) : FormattingRule(config) { override val wrapping = SpacingBetweenDeclarationsWithAnnotationsRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithComments.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithComments.kt index 3b15666b7b54..8c1c72f68ef8 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithComments.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/SpacingBetweenDeclarationsWithComments.kt @@ -1,14 +1,16 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.ruleset.experimental.SpacingBetweenDeclarationsWithCommentsRule +import com.pinterest.ktlint.ruleset.standard.SpacingBetweenDeclarationsWithCommentsRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#spacing) for documentation. */ @AutoCorrectable(since = "1.10.0") +@ActiveByDefault(since = "1.22.0") class SpacingBetweenDeclarationsWithComments(config: Config) : FormattingRule(config) { override val wrapping = SpacingBetweenDeclarationsWithCommentsRule() diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt index 849d99740620..92f2964834a1 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/StringTemplate.kt @@ -7,7 +7,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-string-template) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.0.0") @AutoCorrectable(since = "1.0.0") diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt index 5445efae42fb..6570b68facb9 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TrailingComma.kt @@ -1,6 +1,5 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.experimental.trailingcomma.TrailingCommaRule import io.gitlab.arturbosch.detekt.api.Config @@ -10,9 +9,8 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ -@OptIn(FeatureInAlphaState::class) @AutoCorrectable(since = "1.20.0") class TrailingComma(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TypeArgumentListSpacing.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TypeArgumentListSpacing.kt index e2933533dce2..259fb2f03581 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TypeArgumentListSpacing.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/TypeArgumentListSpacing.kt @@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ @AutoCorrectable(since = "1.20.0") class TypeArgumentListSpacing(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/UnnecessaryParenthesesBeforeTrailingLambda.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/UnnecessaryParenthesesBeforeTrailingLambda.kt index 1d60ee32d264..9a3cf745cebd 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/UnnecessaryParenthesesBeforeTrailingLambda.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/UnnecessaryParenthesesBeforeTrailingLambda.kt @@ -1,15 +1,13 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers -import com.pinterest.ktlint.core.api.FeatureInAlphaState import com.pinterest.ktlint.ruleset.experimental.UnnecessaryParenthesesBeforeTrailingLambdaRule import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable import io.gitlab.arturbosch.detekt.formatting.FormattingRule /** - * See [ktlint-website](https://ktlint.github.io#rule-spacing) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for documentation. */ -@OptIn(FeatureInAlphaState::class) @AutoCorrectable(since = "1.20.0") class UnnecessaryParenthesesBeforeTrailingLambda(config: Config) : FormattingRule(config) { diff --git a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt index ee4a7412aaee..fc2ba013c8f1 100644 --- a/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt +++ b/detekt-formatting/src/main/kotlin/io/gitlab/arturbosch/detekt/formatting/wrappers/Wrapping.kt @@ -1,13 +1,19 @@ package io.gitlab.arturbosch.detekt.formatting.wrappers +import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties +import com.pinterest.ktlint.core.api.UsesEditorConfigProperties import com.pinterest.ktlint.ruleset.standard.WrappingRule import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.TextLocation +import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.AutoCorrectable +import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.formatting.FormattingRule +import org.jetbrains.kotlin.com.intellij.lang.ASTNode /** - * See [ktlint-website](https://ktlint.github.io#rule-indentation) for documentation. + * See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. */ @ActiveByDefault(since = "1.20.0") @AutoCorrectable(since = "1.20.0") @@ -15,4 +21,21 @@ class Wrapping(config: Config) : FormattingRule(config) { override val wrapping = WrappingRule() override val issue = issueFor("Reports missing newlines (e.g. between parentheses of a multi-line function call") + + @Configuration("indentation size") + private val indentSize by config(4) + + /** + * [Wrapping] has visitor modifier RunOnRootNodeOnly, so [node] is always the root file. + * Override the parent implementation to highlight the entire file. + */ + override fun getTextLocationForViolation(node: ASTNode, offset: Int): TextLocation { + // Use offset + 1 since Wrapping always reports the location of missing new line. + return TextLocation(offset, offset + 1) + } + + override fun overrideEditorConfigProperties(): Map, String> = + mapOf( + DefaultEditorConfigProperties.indentSizeProperty to indentSize.toString(), + ) } diff --git a/detekt-formatting/src/main/resources/config/config.yml b/detekt-formatting/src/main/resources/config/config.yml index 739a22e28ce0..8a620c0ecdf0 100644 --- a/detekt-formatting/src/main/resources/config/config.yml +++ b/detekt-formatting/src/main/resources/config/config.yml @@ -3,13 +3,13 @@ formatting: android: false autoCorrect: true AnnotationOnSeparateLine: - active: false + active: true autoCorrect: true AnnotationSpacing: - active: false + active: true autoCorrect: true ArgumentListWrapping: - active: false + active: true autoCorrect: true indentSize: 4 maxLineLength: 120 @@ -30,7 +30,7 @@ formatting: active: false autoCorrect: true EnumEntryNameCase: - active: false + active: true autoCorrect: true Filename: active: true @@ -67,11 +67,14 @@ formatting: active: true autoCorrect: true MultiLineIfElse: - active: false + active: true autoCorrect: true NoBlankLineBeforeRbrace: active: true autoCorrect: true + NoBlankLinesInChainedMethodCalls: + active: true + autoCorrect: true NoConsecutiveBlankLines: active: true autoCorrect: true @@ -79,7 +82,7 @@ formatting: active: true autoCorrect: true NoEmptyFirstLineInMethodBlock: - active: false + active: true autoCorrect: true NoLineBreakAfterElse: active: true @@ -106,14 +109,14 @@ formatting: active: true packagesToUseImportOnDemandProperty: 'java.util.*,kotlinx.android.synthetic.**' PackageName: - active: false + active: true autoCorrect: true ParameterListWrapping: active: true autoCorrect: true maxLineLength: 120 SpacingAroundAngleBrackets: - active: false + active: true autoCorrect: true SpacingAroundColon: active: true @@ -128,7 +131,7 @@ formatting: active: true autoCorrect: true SpacingAroundDoubleColon: - active: false + active: true autoCorrect: true SpacingAroundKeyword: active: true @@ -143,13 +146,13 @@ formatting: active: true autoCorrect: true SpacingAroundUnaryOperator: - active: false + active: true autoCorrect: true SpacingBetweenDeclarationsWithAnnotations: - active: false + active: true autoCorrect: true SpacingBetweenDeclarationsWithComments: - active: false + active: true autoCorrect: true StringTemplate: active: true @@ -168,3 +171,4 @@ formatting: Wrapping: active: true autoCorrect: true + indentSize: 4 diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/IndentationSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/IndentationSpec.kt index 4132f564fc01..dde037d753e9 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/IndentationSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/IndentationSpec.kt @@ -34,7 +34,7 @@ class IndentationSpec { @Test fun `places finding location to the indentation`() { subject.lint(code).assert() - .hasSourceLocation(2, 1) + .hasStartSourceLocation(2, 1) .hasTextLocations(13 to 14) } } diff --git a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/WrappingSpec.kt b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/WrappingSpec.kt index 529196b712fa..fce2fa2241be 100644 --- a/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/WrappingSpec.kt +++ b/detekt-formatting/src/test/kotlin/io/gitlab/arturbosch/detekt/formatting/WrappingSpec.kt @@ -2,7 +2,7 @@ package io.gitlab.arturbosch.detekt.formatting import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.formatting.wrappers.Wrapping -import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.assert import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -22,8 +22,16 @@ class WrappingSpec { class A() : B, C { } + + interface B + + interface C + """.trimIndent() - assertThat(subject.lint(code)).hasSize(1) + subject.lint(code).assert() + .hasSize(1) + .hasStartSourceLocation(1, 12) + .hasTextLocations(11 to 12) } } diff --git a/detekt-generator/build.gradle.kts b/detekt-generator/build.gradle.kts index ed37935d5738..8add8a7aa232 100644 --- a/detekt-generator/build.gradle.kts +++ b/detekt-generator/build.gradle.kts @@ -1,5 +1,3 @@ -import java.io.ByteArrayOutputStream - plugins { id("module") } @@ -10,6 +8,7 @@ dependencies { implementation(projects.detektRulesEmpty) implementation(projects.detektFormatting) implementation(projects.detektCli) + implementation(projects.detektUtils) implementation(libs.jcommander) testImplementation(projects.detektCore) @@ -67,16 +66,13 @@ val generateDocumentation by tasks.registering(JavaExec::class) { } val verifyGeneratorOutput by tasks.registering(Exec::class) { - notCompatibleWithConfigurationCache("cannot serialize object of type java.io.ByteArrayOutputStream") dependsOn(generateDocumentation) description = "Verifies that the default-detekt-config.yml is up-to-date" - val configDiff = ByteArrayOutputStream() - - commandLine = listOf("git", "diff", defaultConfigFile, deprecationFile) - standardOutput = configDiff + commandLine = listOf("git", "diff", "--quiet", defaultConfigFile, deprecationFile) + isIgnoreExitValue = true doLast { - if (configDiff.toString().isNotEmpty()) { + if (executionResult.get().exitValue == 1) { throw GradleException( "The default-detekt-config.yml is not up-to-date. " + "You can execute the generateDocumentation Gradle task " + diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt index 2db46a6beb6b..a9dbb1e11f89 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/DetektPrinter.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.generator +import io.github.detekt.utils.yaml import io.gitlab.arturbosch.detekt.generator.collection.RuleSetPage import io.gitlab.arturbosch.detekt.generator.out.MarkdownWriter import io.gitlab.arturbosch.detekt.generator.out.PropertiesWriter import io.gitlab.arturbosch.detekt.generator.out.YamlWriter -import io.gitlab.arturbosch.detekt.generator.out.yaml import io.gitlab.arturbosch.detekt.generator.printer.DeprecatedPrinter import io.gitlab.arturbosch.detekt.generator.printer.RuleSetPagePrinter import io.gitlab.arturbosch.detekt.generator.printer.defaultconfig.ConfigPrinter diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/ConfigurationCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/ConfigurationCollector.kt index 59d77b874a81..bc7a4b19dd05 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/ConfigurationCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/ConfigurationCollector.kt @@ -171,7 +171,9 @@ class ConfigurationCollector { private fun KtValueArgument.getReferenceIdentifierOrNull(): String? = (getArgumentExpression() as? KtCallableReferenceExpression) - ?.callableReference?.getIdentifier()?.text + ?.callableReference + ?.getIdentifier() + ?.text } private object ConfigWithAndroidVariantsSupport { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DefaultValue.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DefaultValue.kt index f3b481b2371c..1fb9be76bebd 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DefaultValue.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/DefaultValue.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.generator.collection +import io.github.detekt.utils.YamlNode +import io.github.detekt.utils.keyValue +import io.github.detekt.utils.list +import io.github.detekt.utils.listOfMaps import io.gitlab.arturbosch.detekt.api.ValuesWithReason -import io.gitlab.arturbosch.detekt.generator.out.YamlNode -import io.gitlab.arturbosch.detekt.generator.out.keyValue -import io.gitlab.arturbosch.detekt.generator.out.list -import io.gitlab.arturbosch.detekt.generator.out.listOfMaps sealed interface DefaultValue { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt index aaaffa31213b..6c7c4d9e6d02 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/MultiRuleCollector.kt @@ -64,7 +64,8 @@ class MultiRuleVisitor : DetektVisitor() { override fun visitSuperTypeList(list: KtSuperTypeList) { val isMultiRule = list.entries ?.mapNotNull { it.typeAsUserType?.referencedName } - ?.any { it == multiRule } ?: false + ?.any { it == multiRule } + ?: false val containingClass = list.containingClass() val className = containingClass?.name diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt index 679df61d68a2..862eb94c0d46 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt @@ -63,7 +63,8 @@ internal class RuleVisitor : DetektVisitor() { val isRule = list.entries ?.asSequence() ?.map { it.typeAsUserType?.referencedName } - ?.any { ruleClasses.contains(it) } ?: false + ?.any { ruleClasses.contains(it) } + ?: false val containingClass = list.containingClass() val className = containingClass?.name @@ -138,7 +139,8 @@ internal class RuleVisitor : DetektVisitor() { .singleOrNull { it.name == "issue" } ?.initializer as? KtCallExpression ) - ?.valueArguments.orEmpty() + ?.valueArguments + .orEmpty() if (arguments.size >= ISSUE_ARGUMENT_SIZE) { severity = getArgument(arguments[1], "Severity") diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleConfigurationPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleConfigurationPrinter.kt index 558ab6b62b4f..6ac43d2411ee 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleConfigurationPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleConfigurationPrinter.kt @@ -1,14 +1,14 @@ package io.gitlab.arturbosch.detekt.generator.printer +import io.github.detekt.utils.bold +import io.github.detekt.utils.code +import io.github.detekt.utils.crossOut +import io.github.detekt.utils.description +import io.github.detekt.utils.h4 +import io.github.detekt.utils.item +import io.github.detekt.utils.list +import io.github.detekt.utils.markdown import io.gitlab.arturbosch.detekt.generator.collection.Configuration -import io.gitlab.arturbosch.detekt.generator.out.bold -import io.gitlab.arturbosch.detekt.generator.out.code -import io.gitlab.arturbosch.detekt.generator.out.crossOut -import io.gitlab.arturbosch.detekt.generator.out.description -import io.gitlab.arturbosch.detekt.generator.out.h4 -import io.gitlab.arturbosch.detekt.generator.out.item -import io.gitlab.arturbosch.detekt.generator.out.list -import io.gitlab.arturbosch.detekt.generator.out.markdown internal object RuleConfigurationPrinter : DocumentationPrinter> { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt index 318ae70af2d6..9c171d7f8e03 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt @@ -1,14 +1,14 @@ package io.gitlab.arturbosch.detekt.generator.printer +import io.github.detekt.utils.MarkdownContent +import io.github.detekt.utils.bold +import io.github.detekt.utils.codeBlock +import io.github.detekt.utils.h3 +import io.github.detekt.utils.h4 +import io.github.detekt.utils.markdown +import io.github.detekt.utils.paragraph import io.gitlab.arturbosch.detekt.generator.collection.Active import io.gitlab.arturbosch.detekt.generator.collection.Rule -import io.gitlab.arturbosch.detekt.generator.out.MarkdownContent -import io.gitlab.arturbosch.detekt.generator.out.bold -import io.gitlab.arturbosch.detekt.generator.out.codeBlock -import io.gitlab.arturbosch.detekt.generator.out.h3 -import io.gitlab.arturbosch.detekt.generator.out.h4 -import io.gitlab.arturbosch.detekt.generator.out.markdown -import io.gitlab.arturbosch.detekt.generator.out.paragraph internal object RulePrinter : DocumentationPrinter { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinter.kt index db88a74c2238..46d0f003e5bc 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RuleSetPagePrinter.kt @@ -1,8 +1,8 @@ package io.gitlab.arturbosch.detekt.generator.printer +import io.github.detekt.utils.markdown +import io.github.detekt.utils.paragraph import io.gitlab.arturbosch.detekt.generator.collection.RuleSetPage -import io.gitlab.arturbosch.detekt.generator.out.markdown -import io.gitlab.arturbosch.detekt.generator.out.paragraph object RuleSetPagePrinter : DocumentationPrinter { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt index 486e36b94bdf..9131be470888 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/ConfigPrinter.kt @@ -1,7 +1,7 @@ package io.gitlab.arturbosch.detekt.generator.printer.defaultconfig +import io.github.detekt.utils.yaml import io.gitlab.arturbosch.detekt.generator.collection.RuleSetPage -import io.gitlab.arturbosch.detekt.generator.out.yaml import io.gitlab.arturbosch.detekt.generator.printer.DocumentationPrinter object ConfigPrinter : DocumentationPrinter> { @@ -81,5 +81,6 @@ object ConfigPrinter : DocumentationPrinter> { # - 'TxtOutputReport' # - 'XmlOutputReport' # - 'HtmlOutputReport' + # - 'MdOutputReport' """.trimIndent() } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/Exclusion.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/Exclusion.kt index 56a00af6ad5a..b2c6f3927140 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/Exclusion.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/Exclusion.kt @@ -27,7 +27,6 @@ private object TestExclusions : Exclusions() { override val ruleSets = emptySet() override val rules = setOf( "FunctionNaming", - "WildcardImport", "LateinitUsage", "StringLiteralDuplication", "SpreadOperator", diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt index 3034cd417a13..e412afc64d91 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt @@ -1,13 +1,13 @@ package io.gitlab.arturbosch.detekt.generator.printer.defaultconfig +import io.github.detekt.utils.YamlNode +import io.github.detekt.utils.keyValue +import io.github.detekt.utils.node import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.generator.collection.Configuration import io.gitlab.arturbosch.detekt.generator.collection.Rule import io.gitlab.arturbosch.detekt.generator.collection.RuleSetPage import io.gitlab.arturbosch.detekt.generator.collection.RuleSetProvider -import io.gitlab.arturbosch.detekt.generator.out.YamlNode -import io.gitlab.arturbosch.detekt.generator.out.keyValue -import io.gitlab.arturbosch.detekt.generator.out.node internal fun YamlNode.printRuleSetPage(ruleSetPage: RuleSetPage) { printRuleSet(ruleSetPage.ruleSet, ruleSetPage.rules) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt index 44b5d3cbef6d..0e2690929c08 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt @@ -10,8 +10,8 @@ class DeprecatedPrinterSpec { fun `prints the correct properties`() { val markdownString = DeprecatedPrinter.print(listOf(createRuleSetPage())) val expectedMarkdownString = """ - style>WildcardImport>conf2=use conf1 instead - style>WildcardImport>conf4=use conf3 instead + style>MagicNumber>conf2=use conf1 instead + style>MagicNumber>conf4=use conf3 instead """.trimIndent() assertThat(markdownString).isEqualTo(expectedMarkdownString) diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinterTest.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinterTest.kt index 35532232259e..ee016a857d52 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinterTest.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinterTest.kt @@ -1,5 +1,6 @@ package io.gitlab.arturbosch.detekt.generator.printer.defaultconfig +import io.github.detekt.utils.yaml import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.valuesWithReason import io.gitlab.arturbosch.detekt.generator.collection.Active @@ -8,7 +9,6 @@ import io.gitlab.arturbosch.detekt.generator.collection.DefaultValue import io.gitlab.arturbosch.detekt.generator.collection.Inactive import io.gitlab.arturbosch.detekt.generator.collection.Rule import io.gitlab.arturbosch.detekt.generator.collection.RuleSetProvider -import io.gitlab.arturbosch.detekt.generator.out.yaml import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt index 250acb3d3a08..c217da2e9ec4 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt @@ -59,7 +59,7 @@ internal fun createRuleSetPage(): RuleSetPage { internal fun createRules(): List { val rule1 = Rule( - name = "WildcardImport", + name = "MagicNumber", description = "a wildcard import", nonCompliantCodeExample = "import foo.*", compliantCodeExample = "import foo.bar", diff --git a/detekt-generator/src/test/resources/RuleSet.md b/detekt-generator/src/test/resources/RuleSet.md index 2b1821e39816..9943ce20efc9 100644 --- a/detekt-generator/src/test/resources/RuleSet.md +++ b/detekt-generator/src/test/resources/RuleSet.md @@ -1,6 +1,6 @@ style rule set -### WildcardImport +### MagicNumber a wildcard import diff --git a/detekt-generator/src/test/resources/RuleSetConfig.yml b/detekt-generator/src/test/resources/RuleSetConfig.yml index 85e774df9819..7719739ff266 100644 --- a/detekt-generator/src/test/resources/RuleSetConfig.yml +++ b/detekt-generator/src/test/resources/RuleSetConfig.yml @@ -7,9 +7,9 @@ style: rulesetconfig3: - 'first' - 'se*cond' - WildcardImport: + MagicNumber: active: true - excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts'] conf1: 'foo' conf3: - 'a' diff --git a/detekt-gradle-plugin/build.gradle.kts b/detekt-gradle-plugin/build.gradle.kts index 812f3bde8b82..572276d8fe0e 100644 --- a/detekt-gradle-plugin/build.gradle.kts +++ b/detekt-gradle-plugin/build.gradle.kts @@ -1,15 +1,12 @@ -import org.gradle.api.internal.classpath.ModuleRegistry -import org.gradle.kotlin.dsl.support.serviceOf - plugins { id("module") `java-gradle-plugin` `java-test-fixtures` idea - signing alias(libs.plugins.pluginPublishing) // We use this published version of the Detekt plugin to self analyse this project. - id("io.gitlab.arturbosch.detekt") version "1.20.0" + id("io.gitlab.arturbosch.detekt") version "1.21.0" + id("org.gradle.test-retry") version "1.4.0" } repositories { @@ -34,25 +31,6 @@ testing { implementation(libs.assertj) implementation(libs.kotlin.gradle) implementation(gradleKotlinDsl()) - - // See https://github.com/gradle/gradle/issues/16774#issuecomment-853407822 - runtimeOnly( - files( - serviceOf() - .getModule("gradle-tooling-api-builders") - .classpath - .asFiles - .first() - ) - ) - } - targets { - all { - testTask.configure { - inputs.property("androidSdkRoot", System.getenv("ANDROID_SDK_ROOT")).optional(true) - inputs.property("androidHome", System.getenv("ANDROID_HOME")).optional(true) - } - } } } register("functionalTest", JvmTestSuite::class) { @@ -61,6 +39,17 @@ testing { dependencies { implementation(libs.assertj) } + + targets { + all { + testTask.configure { + // If `androidSdkInstalled` is false, skip running DetektAndroidSpec + val isAndroidSdkInstalled = System.getenv("ANDROID_SDK_ROOT") != null || + System.getenv("ANDROID_HOME") != null + inputs.property("isAndroidSdkInstalled", isAndroidSdkInstalled).optional(true) + } + } + } } } } @@ -70,6 +59,10 @@ val functionalTestImplementation: Configuration by configurations.getting configurations.compileOnly { extendsFrom(pluginCompileOnly) } +pluginCompileOnly.attributes { + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class.java, "library")) +} + dependencies { compileOnly(libs.kotlin.gradlePluginApi) implementation(libs.sarif4k) @@ -82,14 +75,16 @@ dependencies { pluginCompileOnly(libs.kotlin.gradle) // We use this published version of the detekt-formatting to self analyse this project. - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.20.0") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.21.0") } gradlePlugin { plugins { - register("detektPlugin") { + create("detektPlugin") { id = "io.gitlab.arturbosch.detekt" implementationClass = "io.gitlab.arturbosch.detekt.DetektPlugin" + displayName = "Static code analysis for Kotlin" + description = "Static code analysis for Kotlin" } } // Source sets that require the Gradle TestKit dependency @@ -117,15 +112,7 @@ tasks.validatePlugins { pluginBundle { website = "https://detekt.dev" vcsUrl = "https://github.com/detekt/detekt" - description = "Static code analysis for Kotlin" tags = listOf("kotlin", "detekt", "code-analysis", "linter", "codesmells", "android") - - (plugins) { - "detektPlugin" { - id = "io.gitlab.arturbosch.detekt" - displayName = "Static code analysis for Kotlin" - } - } } tasks { @@ -151,6 +138,10 @@ tasks { ideaModule { notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13480") } + + publishPlugins { + notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/21283") + } } // Skip publishing of test fixture API & runtime variants @@ -163,20 +154,6 @@ tasks.withType().configureEach { notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13470") } -val signingKey = "SIGNING_KEY".byProperty -val signingPwd = "SIGNING_PWD".byProperty -if (signingKey.isNullOrBlank() || signingPwd.isNullOrBlank()) { - logger.info("Signing disabled as the GPG key was not found") -} else { - logger.info("GPG Key found - Signing enabled") - afterEvaluate { - signing { - useInMemoryPgpKeys(signingKey, signingPwd) - publishing.publications.forEach(::sign) - } - } -} - afterEvaluate { publishing { publications.filterIsInstance().forEach { @@ -206,4 +183,12 @@ afterEvaluate { } } -val String.byProperty: String? get() = findProperty(this) as? String +tasks.withType().configureEach { + retry { + @Suppress("MagicNumber") + if (System.getenv().containsKey("CI")) { + maxRetries.set(2) + maxFailures.set(20) + } + } +} diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektAndroidSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektAndroidSpec.kt index 5756abeb49a4..9bc52b99ba58 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektAndroidSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektAndroidSpec.kt @@ -3,6 +3,7 @@ package io.gitlab.arturbosch.detekt import io.gitlab.arturbosch.detekt.testkit.DslGradleRunner import io.gitlab.arturbosch.detekt.testkit.ProjectLayout import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test @@ -78,13 +79,23 @@ class DetektAndroidSpec { @DisplayName("task :app:detektTest") fun appDetektTest() { gradleRunner.runTasksAndCheckResult(":app:detektTest") { buildResult -> - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-releaseUnitTest.xml """) - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-debugUnitTest.xml """) - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-debugAndroidTest.xml """) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-releaseUnitTest.xml """ + ) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-debugUnitTest.xml """ + ) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-debugAndroidTest.xml """ + ) assertThat(buildResult.output).containsPattern("""--input \S*[/\\]app[/\\]src[/\\]test[/\\]java""") - assertThat(buildResult.output).containsPattern("""--input \S*[/\\]app[/\\]src[/\\]androidTest[/\\]java""") + assertThat(buildResult.output).containsPattern( + """--input \S*[/\\]app[/\\]src[/\\]androidTest[/\\]java""" + ) assertThat(buildResult.output).containsPattern("""--input \S*[/\\]app[/\\]src[/\\]test[/\\]kotlin""") - assertThat(buildResult.output).containsPattern("""--input \S*[/\\]app[/\\]src[/\\]androidTest[/\\]kotlin""") + assertThat(buildResult.output).containsPattern( + """--input \S*[/\\]app[/\\]src[/\\]androidTest[/\\]kotlin""" + ) assertThat(buildResult.output).contains("--report xml:") assertThat(buildResult.output).contains("--report sarif:") assertThat(buildResult.output).doesNotContain("--report txt:") @@ -190,9 +201,15 @@ class DetektAndroidSpec { @DisplayName("task :lib:detektTest") fun libDetektTest() { gradleRunner.runTasksAndCheckResult(":lib:detektTest") { buildResult -> - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-releaseUnitTest.xml """) - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-debugUnitTest.xml """) - assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-debugAndroidTest.xml """) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-releaseUnitTest.xml """ + ) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-debugUnitTest.xml """ + ) + assertThat(buildResult.output).containsPattern( + """--baseline \S*[/\\]detekt-baseline-debugAndroidTest.xml """ + ) assertThat(buildResult.output).contains("--report xml:") assertThat(buildResult.output).contains("--report sarif:") assertThat(buildResult.output).doesNotContain("--report txt:") @@ -206,6 +223,78 @@ class DetektAndroidSpec { } } + @Nested + inner class `android library depends on kotlin only library with configuration cache turned on` { + val projectLayout = ProjectLayout(numberOfSourceFilesInRootPerSourceDir = 0).apply { + addSubmodule( + name = "kotlin_only_lib", + numberOfSourceFilesPerSourceDir = 1, + numberOfCodeSmells = 1, + buildFileContent = """ + $KOTLIN_ONLY_LIB_PLUGIN_BLOCK + $DETEKT_REPORTS_BLOCK + """.trimIndent(), + srcDirs = listOf("src/main/java", "src/debug/java", "src/test/java", "src/androidTest/java"), + baselineFiles = listOf( + "detekt-baseline.xml", + "detekt-baseline-release.xml", + "detekt-baseline-debug.xml", + "detekt-baseline-releaseUnitTest.xml", + "detekt-baseline-debugUnitTest.xml", + "detekt-baseline-debugAndroidTest.xml" + ) + ) + addSubmodule( + name = "android_lib", + numberOfSourceFilesPerSourceDir = 1, + numberOfCodeSmells = 1, + buildFileContent = """ + $LIB_PLUGIN_BLOCK + $ANDROID_BLOCK + $DETEKT_REPORTS_BLOCK + + dependencies { + implementation(project(":kotlin_only_lib")) + } + """.trimIndent(), + srcDirs = listOf("src/main/java", "src/debug/java", "src/test/java", "src/androidTest/java"), + baselineFiles = listOf( + "detekt-baseline.xml", + "detekt-baseline-release.xml", + "detekt-baseline-debug.xml", + "detekt-baseline-releaseUnitTest.xml", + "detekt-baseline-debugUnitTest.xml", + "detekt-baseline-debugAndroidTest.xml" + ) + ) + } + val gradleRunner = createGradleRunnerAndSetupProject(projectLayout).also { + it.writeProjectFile("android_lib/src/main/AndroidManifest.xml", manifestContent()) + } + + @Test + @DisplayName("task :android_lib:detektMain") + @Disabled("https://github.com/detekt/detekt/issues/5150") + fun libDetektMain() { + gradleRunner.runTasksAndCheckResult( + "--configuration-cache", + ":android_lib:detektMain", + ) { buildResult -> + assertThat(buildResult.output).contains("Configuration cache") + assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-release.xml """) + assertThat(buildResult.output).containsPattern("""--baseline \S*[/\\]detekt-baseline-debug.xml """) + assertThat(buildResult.output).contains("--report xml:") + assertThat(buildResult.output).contains("--report sarif:") + assertThat(buildResult.output).doesNotContain("--report txt:") + assertThat(buildResult.tasks.map { it.path }).containsAll( + listOf( + ":android_lib:detektMain", + ) + ) + } + } + } + @Nested inner class `configures android tasks for different build variants` { @@ -498,6 +587,13 @@ private val LIB_PLUGIN_BLOCK = """ } """.trimIndent() +private val KOTLIN_ONLY_LIB_PLUGIN_BLOCK = """ + plugins { + kotlin("jvm") + id("io.gitlab.arturbosch.detekt") + } +""".trimIndent() + private val ANDROID_BLOCK = """ android { compileSdkVersion(30) diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt index 0b4aea6d21b6..5e0b082d6a6c 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt @@ -18,18 +18,15 @@ class DetektJvmSpec { kotlin("jvm") id("io.gitlab.arturbosch.detekt") } - repositories { mavenCentral() mavenLocal() } - detekt { reports { txt.destination = file("output-path.txt") } } - tasks.withType().configureEach { reports { txt.destination = file("output-path2.txt") @@ -43,7 +40,9 @@ class DetektJvmSpec { @Test fun `logs a warning`() { gradleRunner.runTasksAndCheckResult(":detektMain") { buildResult -> - assertThat(buildResult.output).contains("TXT report location set on detekt {} extension will be ignored for detektMain task.") + assertThat(buildResult.output).contains( + "TXT report location set on detekt {} extension will be ignored for detektMain task." + ) } } } @@ -58,12 +57,10 @@ class DetektJvmSpec { kotlin("jvm") id("io.gitlab.arturbosch.detekt") } - repositories { mavenCentral() mavenLocal() } - tasks.withType().configureEach { reports { txt.destination = file("output-path2.txt") @@ -77,7 +74,9 @@ class DetektJvmSpec { @Test fun `logs a warning`() { gradleRunner.runTasksAndCheckResult(":detektMain") { buildResult -> - assertThat(buildResult.output).doesNotContain("report location set on detekt {} extension will be ignored") + assertThat(buildResult.output).doesNotContain( + "report location set on detekt {} extension will be ignored" + ) } } } diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektMultiplatformSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektMultiplatformSpec.kt index e72d0197d726..9f1289d15aaa 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektMultiplatformSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektMultiplatformSpec.kt @@ -257,7 +257,10 @@ class DetektMultiplatformSpec { @Nested @EnabledOnOs(MAC) - @EnabledIf("io.gitlab.arturbosch.detekt.DetektMultiplatformSpecKt#isXCodeInstalled", disabledReason = "XCode is not installed.") + @EnabledIf( + "io.gitlab.arturbosch.detekt.DetektMultiplatformSpecKt#isXCodeInstalled", + disabledReason = "XCode is not installed." + ) inner class `multiplatform projects - iOS target` { val gradleRunner = setupProject { diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslSpec.kt index 33009439de84..d0b43e87d2fa 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/DetektTaskDslSpec.kt @@ -321,6 +321,9 @@ class DetektTaskDslSpec { | sarif { | enabled = false | } + | md { + | enabled = false + | } | } |} """ diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/GradleVersionSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/GradleVersionSpec.kt index 211d91501d8a..f876aa45f08b 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/GradleVersionSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/GradleVersionSpec.kt @@ -6,13 +6,13 @@ import org.gradle.testkit.runner.TaskOutcome import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import org.junit.jupiter.api.condition.EnabledForJreRange -import org.junit.jupiter.api.condition.JRE.JAVA_13 +import org.junit.jupiter.api.condition.JRE.JAVA_15 class GradleVersionSpec { @Test @DisplayName("Runs on version $gradleVersion") - @EnabledForJreRange(max = JAVA_13, disabledReason = "Gradle $gradleVersion unsupported on this Java version") + @EnabledForJreRange(max = JAVA_15, disabledReason = "Gradle $gradleVersion unsupported on this Java version") fun runsOnOldestSupportedGradleVersion() { val builder = DslTestBuilder.kotlin() val gradleRunner = builder.withGradleVersion(gradleVersion).build() @@ -22,6 +22,6 @@ class GradleVersionSpec { } companion object { - const val gradleVersion = "6.1" + const val gradleVersion = "6.7.1" } } diff --git a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/JvmSpec.kt b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/JvmSpec.kt index 6b3afbbce6c6..b6a614bd8ded 100644 --- a/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/JvmSpec.kt +++ b/detekt-gradle-plugin/src/functionalTest/kotlin/io/gitlab/arturbosch/detekt/JvmSpec.kt @@ -1,22 +1,23 @@ package io.gitlab.arturbosch.detekt +import io.gitlab.arturbosch.detekt.testkit.withResourceDir import org.assertj.core.api.Assertions.assertThat import org.gradle.testkit.runner.GradleRunner import org.junit.jupiter.api.Test -import java.io.File class JvmSpec { @Test fun `Type resolution on JVM`() { - val projectDir = checkNotNull(javaClass.classLoader.getResource("jvm")?.file) val result = GradleRunner.create() - .withProjectDir(File(projectDir)) + .withResourceDir("jvm") .withPluginClasspath() .withArguments("detektMain") .buildAndFail() assertThat(result.output).contains("failed with 2 weighted issues.") - assertThat(result.output).contains("Do not directly exit the process outside the `main` function. Throw an exception(…)") + assertThat(result.output).contains( + "Do not directly exit the process outside the `main` function. Throw an exception(...)" + ) assertThat(result.output).contains("Errors.kt:7:9") assertThat(result.output).contains("Errors.kt:12:16") } diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt index 2af5d07ae84a..8f0c8b977180 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/Detekt.kt @@ -189,6 +189,11 @@ open class Detekt @Inject constructor( @Optional get() = getTargetFileProvider(reports.sarif) + val mdReportFile: Provider + @OutputFile + @Optional + get() = getTargetFileProvider(reports.md) + internal val customReportFiles: ConfigurableFileCollection @OutputFiles @Optional @@ -217,6 +222,7 @@ open class Detekt @Inject constructor( DefaultReportArgument(DetektReportType.HTML, htmlReportFile.orNull), DefaultReportArgument(DetektReportType.TXT, txtReportFile.orNull), DefaultReportArgument(DetektReportType.SARIF, sarifReportFile.orNull), + DefaultReportArgument(DetektReportType.MD, mdReportFile.orNull), DebugArgument(debugProp.getOrElse(false)), ParallelArgument(parallelProp.getOrElse(false)), BuildUponDefaultConfigArgument(buildUponDefaultConfigProp.getOrElse(false)), diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt index cd5e24e1d661..d100b34ec2ae 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektExtension.kt @@ -45,9 +45,11 @@ open class DetektExtension @Inject constructor(objects: ObjectFactory) : CodeQua DEFAULT_TEST_SRC_DIR_KOTLIN, ) - var baseline: File? = objects.fileProperty() + var baseline: File? = objects + .fileProperty() .fileValue(File("detekt-baseline.xml")) - .get().asFile + .get() + .asFile var basePath: String? = null diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt index 124e72e2014b..0afbf1c25880 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReportType.kt @@ -5,7 +5,8 @@ enum class DetektReportType(val reportId: String, val extension: String) { XML("xml", "xml"), HTML("html", "html"), TXT("txt", "txt"), - SARIF("sarif", "sarif"); + SARIF("sarif", "sarif"), + MD("md", "md"); companion object { fun isWellKnownReportId(reportId: String) = reportId in values().map(DetektReportType::reportId) diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt index dcbf3e113977..9a084c1af58c 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/extensions/DetektReports.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.extensions import io.gitlab.arturbosch.detekt.extensions.DetektReportType.HTML +import io.gitlab.arturbosch.detekt.extensions.DetektReportType.MD import io.gitlab.arturbosch.detekt.extensions.DetektReportType.SARIF import io.gitlab.arturbosch.detekt.extensions.DetektReportType.TXT import io.gitlab.arturbosch.detekt.extensions.DetektReportType.XML @@ -19,6 +20,8 @@ open class DetektReports @Inject constructor(val objects: ObjectFactory) { val sarif: DetektReport = objects.newInstance(DetektReport::class.java, SARIF) + val md: DetektReport = objects.newInstance(DetektReport::class.java, MD) + val custom = mutableListOf() fun xml(action: Action): Unit = action.execute(xml) @@ -29,6 +32,8 @@ open class DetektReports @Inject constructor(val objects: ObjectFactory) { fun sarif(action: Action): Unit = action.execute(sarif) + fun md(action: Action): Unit = action.execute(md) + fun custom(action: Action): Unit = action.execute(createAndAddCustomReport()) private fun createAndAddCustomReport() = diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektMultiplatform.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektMultiplatform.kt index 4e124b1a292b..e9e456b356d2 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektMultiplatform.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektMultiplatform.kt @@ -116,7 +116,8 @@ internal class DetektMultiplatform(private val project: Project) { } registerCreateBaselineTask( - DetektPlugin.BASELINE_TASK_NAME + taskSuffix, extension + DetektPlugin.BASELINE_TASK_NAME + taskSuffix, + extension ) { setSource(inputSource) if (runWithTypeResolution) { @@ -145,6 +146,7 @@ internal fun Project.setReportOutputConventions(reports: DetektReports, extensio setReportOutputConvention(extension, reports.html, name, "html") setReportOutputConvention(extension, reports.txt, name, "txt") setReportOutputConvention(extension, reports.sarif, name, "sarif") + setReportOutputConvention(extension, reports.md, name, "md") } private fun Project.setReportOutputConvention( diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMerger.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMerger.kt index 2bfa89ce47b6..daebbbae9fff 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMerger.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMerger.kt @@ -2,6 +2,7 @@ package io.gitlab.arturbosch.detekt.report import org.w3c.dom.Document import org.w3c.dom.Node +import org.w3c.dom.NodeList import java.io.File import javax.xml.parsers.DocumentBuilderFactory import javax.xml.transform.OutputKeys @@ -16,42 +17,132 @@ object XmlReportMerger { private val documentBuilder by lazy { DocumentBuilderFactory.newInstance().newDocumentBuilder() } - fun merge(inputs: Collection, output: File) { - val document = documentBuilder.newDocument().apply { - xmlStandalone = true - val checkstyleNode = createElement("checkstyle") - checkstyleNode.setAttribute("version", "4.3") - appendChild(checkstyleNode) - } - inputs.filter { it.exists() }.forEach { - importNodesFromInput(it, document) - } + fun merge(reportFiles: Collection, output: File) { + val distinctErrorsBySourceFile = DetektCheckstyleReports(reportFiles) + .parseCheckstyleToSourceFileNodes() + .distinctErrorsGroupedBySourceFile() + + val mergedCheckstyle = createMergedCheckstyle(distinctErrorsBySourceFile) + TransformerFactory.newInstance().newTransformer().run { setOutputProperty(OutputKeys.INDENT, "yes") setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2") - transform(DOMSource(document), StreamResult(output.writer())) + transform(DOMSource(mergedCheckstyle), StreamResult(output.writer())) } } - private fun importNodesFromInput(input: File, document: Document) { - val checkstyleNode = documentBuilder.parse(input.inputStream()).documentElement.also { removeWhitespaces(it) } - (0 until checkstyleNode.childNodes.length).forEach { - val node = checkstyleNode.childNodes.item(it) - document.documentElement.appendChild(document.importNode(node, true)) + private fun createMergedCheckstyle(distinctErrorsBySourceFile: Map>): Document { + val mergedDocument = documentBuilder.newDocument().apply { + xmlStandalone = true } + val mergedCheckstyleNode = mergedDocument.createElement("checkstyle") + mergedCheckstyleNode.setAttribute("version", "4.3") + mergedDocument.appendChild(mergedCheckstyleNode) + + distinctErrorsBySourceFile.forEach { (fileName, errorNodes) -> + mergedCheckstyleNode.appendChild( + mergedDocument.createElement("file").apply { + setAttribute("name", fileName) + errorNodes.forEach { + appendChild(mergedDocument.importNode(it, true)) + } + } + ) + } + return mergedDocument + } + + /** A list of checkstyle xml files written by Detekt */ + private class DetektCheckstyleReports(private val files: Collection) { + + /** + * Parses a list of `file` nodes matching the following topology + * + * ```xml + * + * + * + * ``` + * + * @see CheckstyleSourceFileNodes + */ + fun parseCheckstyleToSourceFileNodes() = + CheckstyleSourceFileNodes( + files.filter { reportFile -> reportFile.exists() } + .flatMap { existingReportFile -> + val checkstyleNode = documentBuilder.parse(existingReportFile.inputStream()) + checkstyleNode.documentElement.childNodes.asSequence().filterWhitespace() + } + ) } /** - * Use code instead of XSLT to exclude whitespaces. + * A list of checkstyle `file` nodes that may contain 0 to many `error` nodes + * + * ```xml + * + * + * + * ``` */ - private fun removeWhitespaces(node: Node) { - (node.childNodes.length - 1 downTo 0).forEach { idx -> - val childNode = node.childNodes.item(idx) - if (childNode.nodeType == Node.TEXT_NODE && childNode.textContent.isBlank()) { - node.removeChild(childNode) + private class CheckstyleSourceFileNodes(private val nodes: List) { + + /** Returns a map containing only distinct error nodes, grouped by file name */ + fun distinctErrorsGroupedBySourceFile() = nodes + .flatMap { fileNode -> + val fileNameAttribute = fileNode.attributes.getNamedItem("name").nodeValue + val errorNodes = fileNode.childNodes.asSequence().filterWhitespace() + errorNodes.map { errorNode -> + CheckstyleErrorNodeWithFileData( + errorID = errorID(fileNameAttribute, errorNode), + fileName = fileNameAttribute, + errorNode = errorNode + ) + } + } + .distinctBy { it.errorID } + .groupBy({ it.fileName }, { it.errorNode }) + + private fun errorID(fileNameAttribute: String, errorNode: Node): Any { + // error nodes are expected to take the form of at least + val line = errorNode.attributes.getNamedItem("line")?.nodeValue + val column = errorNode.attributes.getNamedItem("column")?.nodeValue + val source = errorNode.attributes.getNamedItem("source")?.nodeValue + + return if (line != null && column != null && source != null) { + // data class provides convenient hashCode/equals based on these attributes + ErrorID(fileName = fileNameAttribute, line = line, column = column, source = source) } else { - removeWhitespaces(childNode) + // if the error node does not contain the expected attributes, + // use org.w3c.dom.Node's more strict hashCode/equals method to determine error uniqueness + errorNode } } + + private class CheckstyleErrorNodeWithFileData( + val errorID: Any, + val fileName: String, + val errorNode: Node + ) + + private data class ErrorID( + val fileName: String, + val line: String, + val column: String, + val source: String + ) + } + + /** + * Use code instead of XSLT to exclude whitespaces. + */ + private fun Sequence.filterWhitespace(): Sequence = asSequence().filterNot { + it.nodeType == Node.TEXT_NODE && it.textContent.isBlank() + } + + private fun NodeList.asSequence() = sequence { + for (index in 0 until length) { + yield(item(index)) + } } } diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt index d3a244d698b1..8b99d3c8c064 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektJvmSpec.kt @@ -19,7 +19,6 @@ class DetektJvmSpec { apply() repositories { mavenCentral() - mavenLocal() } tasks.withType(Detekt::class.java).configureEach { it.reports { reports -> diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektPlainSpec.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektPlainSpec.kt index 382c80ba8916..e5a9f4963887 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektPlainSpec.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/DetektPlainSpec.kt @@ -25,7 +25,6 @@ class DetektPlainSpec { repositories { mavenCentral() - mavenLocal() } configure { @@ -53,7 +52,6 @@ class DetektPlainSpec { repositories { mavenCentral() - mavenLocal() } tasks.withType(Detekt::class.java).configureEach { diff --git a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMergerSpec.kt b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMergerSpec.kt index 6a22dea2bfc2..4f34c6916750 100644 --- a/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMergerSpec.kt +++ b/detekt-gradle-plugin/src/test/kotlin/io/gitlab/arturbosch/detekt/report/XmlReportMergerSpec.kt @@ -9,7 +9,7 @@ private const val TAB = "\t" class XmlReportMergerSpec { @Test - fun `passes for same files`() { + fun `passes for no overlapping errors`() { val file1 = File.createTempFile("detekt1", "xml").apply { writeText( """ @@ -49,4 +49,78 @@ class XmlReportMergerSpec { """.trimIndent() assertThat(output.readText()).isEqualToIgnoringNewLines(expectedText) } + + @Test + fun `passes for all overlapping errors`() { + val text = """ + + + + $TAB + + + """.trimIndent() + val file1 = File.createTempFile("detekt1", "xml").apply { + writeText(text) + } + val file2 = File.createTempFile("detekt2", "xml").apply { + writeText(text) + } + val output = File.createTempFile("output", "xml") + XmlReportMerger.merge(setOf(file1, file2), output) + + val expectedText = """ + + + + + + """.trimIndent() + assertThat(output.readText()).isEqualToIgnoringNewLines(expectedText) + } + + @Test + fun `passes for some overlapping errors`() { + val file1 = File.createTempFile("detekt1", "xml").apply { + writeText( + """ + + + + $TAB + + + $TAB + + + """.trimIndent() + ) + } + val file2 = File.createTempFile("detekt2", "xml").apply { + writeText( + """ + + + + $TAB + + + """.trimIndent() + ) + } + val output = File.createTempFile("output", "xml") + XmlReportMerger.merge(setOf(file1, file2), output) + + val expectedText = """ + + + + + + + + + """.trimIndent() + assertThat(output.readText()).isEqualToIgnoringNewLines(expectedText) + } } diff --git a/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/DslGradleRunner.kt b/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/DslGradleRunner.kt index c28b56a4cae6..1b69a89b2d0c 100644 --- a/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/DslGradleRunner.kt +++ b/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/DslGradleRunner.kt @@ -9,7 +9,8 @@ import java.nio.file.Files import java.util.UUID @Suppress("TooManyFunctions", "ClassOrdering") -class DslGradleRunner @Suppress("LongParameterList") constructor( +class DslGradleRunner @Suppress("LongParameterList") +constructor( val projectLayout: ProjectLayout, val buildFileName: String, val mainBuildFileContent: String = "", @@ -18,7 +19,7 @@ class DslGradleRunner @Suppress("LongParameterList") constructor( val gradleVersionOrNone: String? = null, val dryRun: Boolean = false, val jvmArgs: String = "-Xmx2g -XX:MaxMetaspaceSize=1g", - val projectScript: Project.() -> Unit = {}, + val projectScript: Project.() -> Unit = {} ) { private val rootDir: File = Files.createTempDirectory("applyPlugin").toFile().apply { deleteOnExit() } diff --git a/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/GradleRunnerExtensions.kt b/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/GradleRunnerExtensions.kt new file mode 100644 index 000000000000..5705f213828f --- /dev/null +++ b/detekt-gradle-plugin/src/testFixtures/kotlin/io/gitlab/arturbosch/detekt/testkit/GradleRunnerExtensions.kt @@ -0,0 +1,16 @@ +package io.gitlab.arturbosch.detekt.testkit + +import org.gradle.testkit.runner.GradleRunner +import java.io.File +import java.nio.file.Files + +/** + * Copy project files from `resources` to temporary directories for isolation. + * This helps with the incremental build (up-to-date checks). + */ +fun GradleRunner.withResourceDir(resourcePath: String) = apply { + val resourceDir = File(javaClass.classLoader.getResource(resourcePath).file) + val projectDir = Files.createTempDirectory(resourcePath).toFile() + resourceDir.copyRecursively(projectDir) + withProjectDir(projectDir) +} diff --git a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt index d93f7b51e3a0..398a42066947 100644 --- a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt +++ b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt @@ -2,6 +2,7 @@ package io.github.detekt.metrics +import io.github.detekt.psi.getLineAndColumnInPsiFile import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiComment import org.jetbrains.kotlin.com.intellij.psi.PsiElement @@ -10,7 +11,6 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiCommentImpl import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiCoreCommentImpl import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.kdoc.psi.api.KDocElement import org.jetbrains.kotlin.kdoc.psi.impl.KDocElementImpl @@ -44,16 +44,7 @@ fun KtElement.linesOfCode(inFile: KtFile = this.containingKtFile): Int = .distinct() .count() -fun ASTNode.line(inFile: KtFile): Int = try { - DiagnosticUtils.getLineAndColumnInPsiFile(inFile, this.textRange).line -} catch (@Suppress("SwallowedException", "TooGenericExceptionCaught") e: IndexOutOfBoundsException) { - // When auto-correctable rules performs actual mutation, KtFile.text is updated but - // KtFile.viewProvider.document is not updated. This will cause crash in subsequent rules - // if they are using any function relying on the KtFile.viewProvider.document. - // The exception is silenced to return -1 while we should seek long-term solution for execution - // order of rules (#3445) - -1 -} +fun ASTNode.line(inFile: KtFile): Int = getLineAndColumnInPsiFile(inFile, this.textRange)?.line ?: -1 private val comments: Set> = setOf( PsiWhiteSpace::class.java, diff --git a/detekt-parser/build.gradle.kts b/detekt-parser/build.gradle.kts index e06bde35407f..75f444045dee 100644 --- a/detekt-parser/build.gradle.kts +++ b/detekt-parser/build.gradle.kts @@ -14,7 +14,7 @@ dependencies { } tasks.withType { - systemProperty("kotlinVersion", getKotlinPluginVersion() ?: embeddedKotlinVersion) + systemProperty("kotlinVersion", getKotlinPluginVersion()) doFirst { systemProperty("testClasspath", classpath.joinToString(";")) diff --git a/detekt-parser/src/main/kotlin/io/github/detekt/parser/KotlinEnvironmentUtils.kt b/detekt-parser/src/main/kotlin/io/github/detekt/parser/KotlinEnvironmentUtils.kt index b96a22961080..cbc3d4c94f7d 100644 --- a/detekt-parser/src/main/kotlin/io/github/detekt/parser/KotlinEnvironmentUtils.kt +++ b/detekt-parser/src/main/kotlin/io/github/detekt/parser/KotlinEnvironmentUtils.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoots import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots +import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots import org.jetbrains.kotlin.com.intellij.mock.MockProject import org.jetbrains.kotlin.com.intellij.openapi.Disposable import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer @@ -98,6 +99,7 @@ fun createCompilerConfiguration( addJavaSourceRoots(javaFiles) addKotlinSourceRoots(kotlinFiles) addJvmClasspathRoots(classpathFiles) + configureJdkClasspathRoots() } } diff --git a/detekt-psi-utils/api/detekt-psi-utils.api b/detekt-psi-utils/api/detekt-psi-utils.api index cdb632ca8a20..e73a4ff57bb4 100644 --- a/detekt-psi-utils/api/detekt-psi-utils.api +++ b/detekt-psi-utils/api/detekt-psi-utils.api @@ -33,6 +33,7 @@ public final class io/github/detekt/psi/KtFilesKt { public static final fun basePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/nio/file/Path; public static final fun fileNameWithoutSuffix (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/lang/String; public static final fun getFileName (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/lang/String; + public static final fun getLineAndColumnInPsiFile (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;Lorg/jetbrains/kotlin/com/intellij/openapi/util/TextRange;)Lorg/jetbrains/kotlin/diagnostics/PsiDiagnosticUtils$LineAndColumn; public static final fun relativePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/nio/file/Path; public static final fun toFilePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Lio/github/detekt/psi/FilePath; public static final fun toUnifiedString (Ljava/nio/file/Path;)Ljava/lang/String; @@ -106,6 +107,7 @@ public final class io/gitlab/arturbosch/detekt/rules/KtModifierListKt { public static final fun isOverride (Lorg/jetbrains/kotlin/psi/KtModifierListOwner;)Z public static final fun isProtected (Lorg/jetbrains/kotlin/psi/KtModifierListOwner;)Z public static final fun isPublicNotOverridden (Lorg/jetbrains/kotlin/psi/KtModifierListOwner;)Z + public static final fun isPublicNotOverridden (Lorg/jetbrains/kotlin/psi/KtModifierListOwner;Z)Z } public final class io/gitlab/arturbosch/detekt/rules/KtValueArgumentKt { @@ -134,6 +136,7 @@ public final class io/gitlab/arturbosch/detekt/rules/ThrowExtensionsKt { public final class io/gitlab/arturbosch/detekt/rules/TraversingKt { public static final fun isPublicInherited (Lorg/jetbrains/kotlin/psi/KtNamedDeclaration;)Z + public static final fun isPublicInherited (Lorg/jetbrains/kotlin/psi/KtNamedDeclaration;Z)Z } public final class io/gitlab/arturbosch/detekt/rules/TypeUtilsKt { diff --git a/detekt-psi-utils/build.gradle.kts b/detekt-psi-utils/build.gradle.kts index b3581319b20e..124b2ab9ed4d 100644 --- a/detekt-psi-utils/build.gradle.kts +++ b/detekt-psi-utils/build.gradle.kts @@ -10,6 +10,10 @@ dependencies { testImplementation(projects.detektTest) } +tasks.apiDump { + notCompatibleWithConfigurationCache("https://github.com/Kotlin/binary-compatibility-validator/issues/95") +} + apiValidation { ignoredPackages.add("io.github.detekt.psi.internal") } diff --git a/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt b/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt index 8b4b2be69c17..70f06268733e 100644 --- a/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt +++ b/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt @@ -1,6 +1,9 @@ package io.github.detekt.psi +import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.com.intellij.psi.PsiFile +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils +import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import java.io.File import java.nio.file.Path import java.nio.file.Paths @@ -68,6 +71,14 @@ fun PsiFile.toFilePath(): FilePath { } } +// #3317 If any rule mutates the PsiElement, searching the original PsiElement may throw an exception. +fun getLineAndColumnInPsiFile(file: PsiFile, range: TextRange): PsiDiagnosticUtils.LineAndColumn? { + return runCatching { + @Suppress("ForbiddenMethodCall") + DiagnosticUtils.getLineAndColumnInPsiFile(file, range) + }.getOrNull() +} + /** * Returns a system-independent string with UNIX system file separator. */ diff --git a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt index ea30d74838c8..97204905312d 100644 --- a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt +++ b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/KtModifierList.kt @@ -7,7 +7,14 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.psiUtil.isPublic fun KtModifierListOwner.isPublicNotOverridden() = - isPublic && !isOverride() + isPublicNotOverridden(false) + +fun KtModifierListOwner.isPublicNotOverridden(considerProtectedAsPublic: Boolean) = + if (considerProtectedAsPublic) { + isPublic || isProtected() + } else { + isPublic + } && !isOverride() fun KtModifierListOwner.isAbstract() = hasModifier(KtTokens.ABSTRACT_KEYWORD) diff --git a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt index 5141bdc96975..fec929f3c1e6 100644 --- a/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt +++ b/detekt-psi-utils/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/Traversing.kt @@ -20,10 +20,12 @@ inline fun KtElement.parentsOfTyp } } -fun KtNamedDeclaration.isPublicInherited(): Boolean { +fun KtNamedDeclaration.isPublicInherited(): Boolean = isPublicInherited(false) + +fun KtNamedDeclaration.isPublicInherited(considerProtectedAsPublic: Boolean): Boolean { var classOrObject = containingClassOrObject while (classOrObject != null) { - if (!classOrObject.isPublic) { + if (!classOrObject.isPublic && !(considerProtectedAsPublic && classOrObject.isProtected())) { return false } classOrObject = classOrObject.containingClassOrObject diff --git a/detekt-report-md/build.gradle.kts b/detekt-report-md/build.gradle.kts new file mode 100644 index 000000000000..1f7df0f6ae6c --- /dev/null +++ b/detekt-report-md/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("module") +} + +dependencies { + implementation(projects.detektMetrics) + implementation(projects.detektApi) + implementation(projects.detektUtils) + + testImplementation(testFixtures(projects.detektApi)) + testImplementation(libs.mockk) + testImplementation(libs.assertj) +} diff --git a/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt b/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt new file mode 100644 index 000000000000..45fed53e3c0b --- /dev/null +++ b/detekt-report-md/src/main/kotlin/io/github/detekt/report/md/MdOutputReport.kt @@ -0,0 +1,173 @@ +package io.github.detekt.report.md + +import io.github.detekt.metrics.ComplexityReportGenerator +import io.github.detekt.psi.toUnifiedString +import io.github.detekt.utils.MarkdownContent +import io.github.detekt.utils.codeBlock +import io.github.detekt.utils.emptyLine +import io.github.detekt.utils.h1 +import io.github.detekt.utils.h2 +import io.github.detekt.utils.h3 +import io.github.detekt.utils.item +import io.github.detekt.utils.list +import io.github.detekt.utils.markdown +import io.github.detekt.utils.paragraph +import io.gitlab.arturbosch.detekt.api.Detektion +import io.gitlab.arturbosch.detekt.api.Finding +import io.gitlab.arturbosch.detekt.api.OutputReport +import io.gitlab.arturbosch.detekt.api.ProjectMetric +import io.gitlab.arturbosch.detekt.api.SourceLocation +import io.gitlab.arturbosch.detekt.api.internal.whichDetekt +import java.time.OffsetDateTime +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter +import java.util.Locale +import kotlin.math.max +import kotlin.math.min + +private const val DETEKT_WEBSITE_BASE_URL = "https://detekt.dev" + +private const val EXTRA_LINES_IN_SNIPPET = 3 + +/** + * Contains rule violations in Markdown format report. + * [See](https://detekt.dev/docs/introduction/configurations/#output-reports) + */ +class MdOutputReport : OutputReport() { + override val ending: String = "md" + + override val name = "Markdown report" + + override fun render(detektion: Detektion) = markdown { + h1 { "detekt" } + + h2 { "Metrics" } + renderMetrics(detektion.metrics) + + h2 { "Complexity Report" } + renderComplexity(getComplexityMetrics(detektion)) + + renderFindings(detektion.findings) + emptyLine() + + paragraph { + val detektLink = link("detekt version ${renderVersion()}", "$DETEKT_WEBSITE_BASE_URL/") + "generated with $detektLink on ${renderDate()}" + } + } + + private fun renderVersion(): String = whichDetekt() ?: "unknown" + + private fun renderDate(): String { + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + return "${OffsetDateTime.now(ZoneOffset.UTC).format(formatter)} UTC" + } + + private fun getComplexityMetrics(detektion: Detektion): List { + return ComplexityReportGenerator.create(detektion).generate().orEmpty() + } +} + +private fun MarkdownContent.renderMetrics(metrics: Collection) { + list { + metrics.forEach { item { "%,d ${it.type}".format(Locale.US, it.value) } } + } +} + +private fun MarkdownContent.renderComplexity(complexityReport: List) { + list { + complexityReport.forEach { item { it.trim() } } + } +} + +private fun MarkdownContent.renderGroup(group: String, findings: List) { + findings + .groupBy { it.id } + .toList() + .sortedBy { (rule, _) -> rule } + .forEach { (rule, ruleFindings) -> + renderRule(rule, group, ruleFindings) + } +} + +private fun MarkdownContent.renderRule(rule: String, group: String, findings: List) { + h3 { "$group, $rule (%,d)".format(Locale.US, findings.size) } + paragraph { (findings.first().issue.description) } + + paragraph { + link( + "Documentation", + "$DETEKT_WEBSITE_BASE_URL/docs/rules/${group.toLowerCase(Locale.US)}#${rule.toLowerCase(Locale.US)}" + ) + } + + list { + findings + .sortedWith(compareBy({ it.file }, { it.location.source.line }, { it.location.source.column })) + .forEach { + item { renderFinding(it) } + } + } +} + +private fun MarkdownContent.renderFindings(findings: Map>) { + val total = findings.values + .asSequence() + .map { it.size } + .fold(0) { a, b -> a + b } + + h2 { "Findings (%,d)".format(Locale.US, total) } + + findings + .filter { it.value.isNotEmpty() } + .toList() + .sortedBy { (group, _) -> group } + .forEach { (group, groupFindings) -> + renderGroup(group, groupFindings) + } +} + +private fun MarkdownContent.renderFinding(finding: Finding): String { + val filePath = finding.location.filePath.relativePath ?: finding.location.filePath.absolutePath + val location = "${filePath.toUnifiedString()}:${finding.location.source.line}:${finding.location.source.column}" + + val message = if (finding.message.isNotEmpty()) { + codeBlock("") { finding.message } + } else { "" } + + val psiFile = finding.entity.ktElement?.containingFile + val snippet = if (psiFile != null) { + val lineSequence = psiFile.text.splitToSequence('\n') + snippetCode(lineSequence, finding.startPosition) + } else { "" } + + return "$location\n$message\n$snippet" +} + +private fun MarkdownContent.snippetCode(lines: Sequence, location: SourceLocation): String { + val dropLineCount = max(location.line - 1 - EXTRA_LINES_IN_SNIPPET, 0) + val takeLineCount = EXTRA_LINES_IN_SNIPPET + 1 + min(location.line - 1, EXTRA_LINES_IN_SNIPPET) + var currentLineNumber = dropLineCount + 1 + var text = "" + + val lineNoSpace = (currentLineNumber + takeLineCount).toString().length + + lines + .drop(dropLineCount) + .take(takeLineCount) + .forEach { line -> + val lineNo = ("$currentLineNumber ").take(lineNoSpace) + text += "$lineNo $line\n" + + if (currentLineNumber == location.line) { + val positions = currentLineNumber.toString().length + val lineErr = "!".repeat(positions) + " ".repeat(location.column + lineNoSpace - positions) + text += "$lineErr^ error\n" + } + currentLineNumber++ + } + + return codeBlock("kotlin") { text } +} + +internal fun MarkdownContent.link(text: String, url: String) = "[$text]($url)" diff --git a/detekt-report-md/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.OutputReport b/detekt-report-md/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.OutputReport new file mode 100644 index 000000000000..83fe5d76a71b --- /dev/null +++ b/detekt-report-md/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.OutputReport @@ -0,0 +1 @@ +io.github.detekt.report.md.MdOutputReport diff --git a/detekt-report-md/src/test/kotlin/io/github/detekt/report/md/MdOutputReportSpec.kt b/detekt-report-md/src/test/kotlin/io/github/detekt/report/md/MdOutputReportSpec.kt new file mode 100644 index 000000000000..cf8d96b56e27 --- /dev/null +++ b/detekt-report-md/src/test/kotlin/io/github/detekt/report/md/MdOutputReportSpec.kt @@ -0,0 +1,250 @@ +package io.github.detekt.report.md + +import io.github.detekt.metrics.CognitiveComplexity +import io.github.detekt.metrics.processors.commentLinesKey +import io.github.detekt.metrics.processors.complexityKey +import io.github.detekt.metrics.processors.linesKey +import io.github.detekt.metrics.processors.logicalLinesKey +import io.github.detekt.metrics.processors.sourceLinesKey +import io.gitlab.arturbosch.detekt.api.Detektion +import io.gitlab.arturbosch.detekt.api.Finding +import io.gitlab.arturbosch.detekt.api.ProjectMetric +import io.gitlab.arturbosch.detekt.api.internal.whichDetekt +import io.gitlab.arturbosch.detekt.test.TestDetektion +import io.gitlab.arturbosch.detekt.test.createEntity +import io.gitlab.arturbosch.detekt.test.createFinding +import io.gitlab.arturbosch.detekt.test.createIssue +import io.mockk.clearStaticMockk +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.kotlin.com.intellij.psi.PsiFile +import org.jetbrains.kotlin.psi.KtElement +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.time.OffsetDateTime +import java.time.ZoneOffset + +class MdOutputReportSpec { + private val mdReport = MdOutputReport() + private val detektion = createTestDetektionWithMultipleSmells() + private val result = mdReport.render(detektion) + + @BeforeEach + fun setup() { + mockkStatic(OffsetDateTime::class) + every { OffsetDateTime.now(ZoneOffset.UTC) } returns OffsetDateTime.of( + 2000, // year + 1, // month + 1, // dayOfMonth + 0, // hour + 0, // minute + 0, // second + 0, // nanoOfSecond + ZoneOffset.UTC // offset + ) + } + + @AfterEach + fun teardown() { + clearStaticMockk(OffsetDateTime::class) + } + + @Test + fun `renders Markdown structure correctly`() { + assertThat(result).contains("Metrics") + assertThat(result).contains("Complexity Report") + assertThat(result).contains("Findings") + } + + @Test + fun `contains zero findings`() { + val result = mdReport.render(TestDetektion()) + + assertThat(result).contains("Findings (0)") + } + + @Test + fun `contains the total number of findings`() { + assertThat(result).contains("Findings (3)") + } + + @Test + fun `renders the 'generated with' text correctly`() { + val header = "generated with [detekt version ${whichDetekt()}](https://detekt.dev/) on " + + assertThat(result).contains(header) + } + + @Test + fun `renders the right file locations`() { + assertThat(result).contains("src/main/com/sample/Sample1.kt:9:17") + assertThat(result).contains("src/main/com/sample/Sample2.kt:13:17") + assertThat(result).contains("src/main/com/sample/Sample3.kt:14:16") + } + + @Test + fun `renders the right number of issues per rule`() { + assertThat(result).contains("id_a (2)") + assertThat(result).contains("id_b (1)") + } + + @Test + fun `renders the right violation messages for the rules`() { + assertThat(result).contains("Message finding 1") + assertThat(result).contains("Message finding 2") + } + + @Test + fun `renders the right violation description for the rules`() { + assertThat(result).contains("Description id_a") + assertThat(result).contains("Description id_b") + } + + @Test + fun `renders the right documentation links for the rules`() { + val detektion = object : TestDetektion() { + override val findings: Map> = mapOf( + "Style" to listOf( + createFinding(createIssue("ValCouldBeVar"), createEntity("")) + ), + "empty" to listOf( + createFinding(createIssue("EmptyBody"), createEntity("")), + createFinding(createIssue("EmptyIf"), createEntity("")) + ) + ) + } + + val result = mdReport.render(detektion) + assertThat(result).contains("[Documentation](https://detekt.dev/docs/rules/style#valcouldbevar)") + assertThat(result).contains("[Documentation](https://detekt.dev/docs/rules/empty#emptybody)") + assertThat(result).contains("[Documentation](https://detekt.dev/docs/rules/empty#emptyif)") + } + + @Test + fun `asserts that the generated HTML is the same even if we change the order of the findings`() { + val findings = findings() + val reversedFindings = findings + .reversedArray() + .map { (section, findings) -> section to findings.asReversed() } + .toTypedArray() + + val firstDetektion = createMdDetektion(*findings) + val secondDetektion = createMdDetektion(*reversedFindings) + + val firstReport = mdReport.render(firstDetektion) + val secondReport = mdReport.render(secondDetektion) + + assertThat(firstReport).isEqualTo(secondReport) + } +} + +private fun mockKtElement(): KtElement { + val ktElementMock = mockk() + val psiFileMock = mockk() + val code = """ + package com.example.test + + import io.github.* + + class Test() { + val greeting: String = "Hello, World!" + + init { + println(greetings) + } + + fun foo() { + println(greetings) + return this + } + } + """.trimIndent() + + every { psiFileMock.text } returns code + every { ktElementMock.containingFile } returns psiFileMock + return ktElementMock +} + +private fun createTestDetektionWithMultipleSmells(): Detektion { + val entity1 = createEntity( + path = "src/main/com/sample/Sample1.kt", + position = 9 to 17, + text = 17..20, + ktElement = mockKtElement(), + basePath = "/Users/tester/detekt/" + ) + val entity2 = createEntity( + path = "src/main/com/sample/Sample2.kt", + ktElement = mockKtElement(), + position = 13 to 17, + basePath = "/Users/tester/detekt/" + ) + val entity3 = createEntity( + path = "src/main/com/sample/Sample3.kt", + position = 14 to 16, + ktElement = mockKtElement(), + basePath = "/Users/tester/detekt/" + ) + + val issueA = createIssue("id_a") + val issueB = createIssue("id_b") + + return createMdDetektion( + "Section-1" to listOf( + createFinding(issueA, entity1, "Message finding 1"), + createFinding(issueA, entity2, "Message finding 2") + ), + "Section-2" to listOf( + createFinding(issueB, entity3, "") + ) + ).also { + it.addData(complexityKey, 10) + it.addData(CognitiveComplexity.KEY, 10) + it.addData(sourceLinesKey, 20) + it.addData(logicalLinesKey, 10) + it.addData(commentLinesKey, 2) + it.addData(linesKey, 2222) + } +} + +private fun createMdDetektion(vararg findingPairs: Pair>): Detektion { + return object : TestDetektion() { + override val findings: Map> = findingPairs.toMap() + + override val metrics: Collection = listOf( + ProjectMetric("M1", 10_000), + ProjectMetric("M2", 2) + ) + } +} + +private fun findings(): Array>> { + val issueA = createIssue("id_a") + val issueB = createIssue("id_b") + val issueC = createIssue("id_c") + + val entity1 = createEntity("src/main/com/sample/Sample1.kt", 11 to 5) + val entity2 = createEntity("src/main/com/sample/Sample1.kt", 22 to 2) + val entity3 = createEntity("src/main/com/sample/Sample1.kt", 11 to 2) + val entity4 = createEntity("src/main/com/sample/Sample2.kt", 1 to 1) + + return arrayOf( + "Section 1" to listOf( + createFinding(issueA, entity1), + createFinding(issueA, entity2), + createFinding(issueA, entity3), + createFinding(issueA, entity4), + createFinding(issueB, entity2), + createFinding(issueB, entity1), + createFinding(issueB, entity4) + ), + "Section 2" to listOf( + createFinding(issueB, entity3), + createFinding(issueC, entity1), + createFinding(issueC, entity2) + ) + ) +} diff --git a/detekt-report-sarif/build.gradle.kts b/detekt-report-sarif/build.gradle.kts index 3734494fe7e8..3e1ad5d37ed1 100644 --- a/detekt-report-sarif/build.gradle.kts +++ b/detekt-report-sarif/build.gradle.kts @@ -10,4 +10,5 @@ dependencies { testImplementation(projects.detektTestUtils) testImplementation(testFixtures(projects.detektApi)) testImplementation(libs.assertj) + testImplementation(projects.detektTest) } diff --git a/detekt-report-sarif/src/main/kotlin/io/github/detekt/report/sarif/Results.kt b/detekt-report-sarif/src/main/kotlin/io/github/detekt/report/sarif/Results.kt index 728cfa0ef144..3d146e536346 100644 --- a/detekt-report-sarif/src/main/kotlin/io/github/detekt/report/sarif/Results.kt +++ b/detekt-report-sarif/src/main/kotlin/io/github/detekt/report/sarif/Results.kt @@ -23,26 +23,43 @@ private fun SeverityLevel.toResultLevel() = when (this) { SeverityLevel.INFO -> Level.Note } -private fun Finding.toResult(ruleSetId: RuleSetId) = io.github.detekt.sarif4k.Result( - ruleID = "detekt.$ruleSetId.$id", - level = severity.toResultLevel(), - locations = (listOf(location) + references.map { it.location }).map(Location::toLocation).toSet().toList(), - message = Message(text = messageOrDescription()) -) - -private fun Location.toLocation() = io.github.detekt.sarif4k.Location( - physicalLocation = PhysicalLocation( - region = Region( - startLine = source.line.toLong(), - startColumn = source.column.toLong(), - ), - artifactLocation = if (filePath.relativePath != null) { - ArtifactLocation( - uri = filePath.relativePath?.toUnifiedString(), - uriBaseID = SRCROOT - ) - } else { - ArtifactLocation(uri = filePath.absolutePath.toUnifiedString()) - } +private fun Finding.toResult(ruleSetId: RuleSetId): io.github.detekt.sarif4k.Result { + val code = entity.ktElement?.containingFile?.text + + return io.github.detekt.sarif4k.Result( + ruleID = "detekt.$ruleSetId.$id", + level = severity.toResultLevel(), + locations = (listOf(location) + references.map { it.location }).map { it.toLocation(code) }.distinct().toList(), + message = Message(text = messageOrDescription()) + ) +} + +private fun Location.toLocation(code: String?): io.github.detekt.sarif4k.Location { + var endLine: Long? = null + var endColumn: Long? = null + + if (code != null) { + val snippet = code.take(text.end).split('\n') + endLine = snippet.size.toLong() + endColumn = snippet.last().length.toLong() + 1 + } + + return io.github.detekt.sarif4k.Location( + physicalLocation = PhysicalLocation( + region = Region( + startLine = source.line.toLong(), + startColumn = source.column.toLong(), + endLine = endLine, + endColumn = endColumn + ), + artifactLocation = if (filePath.relativePath != null) { + ArtifactLocation( + uri = filePath.relativePath?.toUnifiedString(), + uriBaseID = SRCROOT + ) + } else { + ArtifactLocation(uri = filePath.absolutePath.toUnifiedString()) + } + ) ) -) +} diff --git a/detekt-report-sarif/src/test/kotlin/io/github/detekt/report/sarif/SarifOutputReportSpec.kt b/detekt-report-sarif/src/test/kotlin/io/github/detekt/report/sarif/SarifOutputReportSpec.kt index f2f1550bf9f7..d2935e69ddc4 100644 --- a/detekt-report-sarif/src/test/kotlin/io/github/detekt/report/sarif/SarifOutputReportSpec.kt +++ b/detekt-report-sarif/src/test/kotlin/io/github/detekt/report/sarif/SarifOutputReportSpec.kt @@ -3,16 +3,26 @@ package io.github.detekt.report.sarif import io.github.detekt.test.utils.readResourceContent import io.github.detekt.tooling.api.VersionProvider import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Finding +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Location +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.SeverityLevel +import io.gitlab.arturbosch.detekt.api.SourceLocation +import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.api.UnstableApi import io.gitlab.arturbosch.detekt.api.internal.whichOS import io.gitlab.arturbosch.detekt.test.EmptySetupContext import io.gitlab.arturbosch.detekt.test.TestDetektion +import io.gitlab.arturbosch.detekt.test.compileAndLint import io.gitlab.arturbosch.detekt.test.createEntity import io.gitlab.arturbosch.detekt.test.createFindingForRelativePath import io.gitlab.arturbosch.detekt.test.createIssue import org.assertj.core.api.Assertions.assertThat +import org.jetbrains.kotlin.psi.KtClassOrObject import org.junit.jupiter.api.Test import java.nio.file.Paths @@ -66,10 +76,117 @@ class SarifOutputReportSpec { assertThat(report).isEqualToIgnoringWhitespace(systemAwareExpectedReport) } + + @Test + fun `region should be bounded with word`() { + /** + * Region constraints in Snippet for word 'TestClass' + * @sample Snippet.code + */ + val startLine = 3 + val startColumn = 7 + val endLine = 3 + val endColumn = 15 + + val refEntity = TestRule().compileAndLint(Snippet.code).first().entity + val location = Location( + SourceLocation(startLine, startColumn), + TextLocation( + startLine + (startColumn - 1) * Snippet.lineLength, + endColumn + (endLine - 1) * Snippet.lineLength + ), + filePath = refEntity.location.filePath + ) + + val result = TestDetektion( + createFinding( + ruleName = "TestSmellB", + entity = refEntity.copy(location = location), + severity = SeverityLevel.WARNING + ) + ) + + val report = SarifOutputReport() + .apply { init(EmptySetupContext()) } + .render(result) + + assertThat(report) + .containsIgnoringWhitespaces(constrainRegion(startLine, startColumn, endLine, endColumn)) + } + + @Test + fun `region should be bounded with block`() { + /** + * Region constraints in Snippet for curly braces + * @sample Snippet.code + */ + val startLine = 3 + val startColumn = 17 + val endLine = 5 + val endColumn = 1 + + val refEntity = TestRule().compileAndLint(Snippet.code).first().entity + val location = Location( + SourceLocation(startLine, startColumn), + TextLocation( + startLine + (startColumn - 1) * Snippet.lineLength, + endColumn + (endLine - 1) * Snippet.lineLength + ), + filePath = refEntity.location.filePath + ) + + val result = TestDetektion( + createFinding( + ruleName = "TestSmellB", + entity = refEntity.copy(location = location), + severity = SeverityLevel.WARNING + ) + ) + + val report = SarifOutputReport() + .apply { init(EmptySetupContext()) } + .render(result) + + assertThat(report) + .containsIgnoringWhitespaces(constrainRegion(startLine, startColumn, endLine, endColumn)) + } +} + +private object Snippet { + // Each line of code is 50 chars long + const val lineLength = 50 + val code = """ + // 4567890123456789012345678901234567890123456789 + // 0000001111111111222222222233333333334444444444 + class TestClass { /////////////////////////////// + val greeting: String = "Hello, World!"/////// + }//////////////////////////////////////////////// + """.trimIndent() +} + +private fun constrainRegion(startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) = """ + "region": { + "endColumn": ${endColumn + 1}, + "endLine": $endLine, + "startColumn": $startColumn, + "startLine": $startLine + } +""" + +class TestRule : Rule() { + override val issue = Issue(javaClass.simpleName, Severity.Warning, "", Debt.FIVE_MINS) + + override fun visitClassOrObject(classOrObject: KtClassOrObject) { + report(CodeSmell(issue, Entity.atName(classOrObject), message = "Error")) + } } -private fun createFinding(ruleName: String, severity: SeverityLevel): Finding { - return object : CodeSmell(createIssue(ruleName), createEntity("TestFile.kt"), "TestMessage") { +private fun createFinding( + ruleName: String, + severity: SeverityLevel, + entity: Entity = createEntity("TestFile.kt") +): Finding { + return object : CodeSmell(createIssue(ruleName), entity, "TestMessage") { override val severity: SeverityLevel get() = severity } diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt index a6222ece6ee3..2fc021d9fe26 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArguments.kt @@ -42,7 +42,7 @@ class NamedArguments(config: Config = Config.empty) : Rule(config) { Debt.FIVE_MINS ) - @Configuration("number of parameters that triggers this inspection") + @Configuration("number of arguments that triggers this inspection") private val threshold: Int by config(defaultValue = 3) @Configuration("ignores when argument values are the same as the parameter names") @@ -50,7 +50,7 @@ class NamedArguments(config: Config = Config.empty) : Rule(config) { override fun visitCallExpression(expression: KtCallExpression) { if (bindingContext == BindingContext.EMPTY) return - val valueArguments = expression.valueArguments + val valueArguments = expression.valueArguments.filterNot { it is KtLambdaArgument } if (valueArguments.size > threshold && expression.canNameArguments()) { val message = "This function call has ${valueArguments.size} arguments. To call a function with more " + "than $threshold arguments you should set the name of each argument." diff --git a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt index ed619afaddae..d0ed5b44ad16 100644 --- a/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt +++ b/detekt-rules-complexity/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/TooManyFunctions.kt @@ -156,7 +156,8 @@ class TooManyFunctions(config: Config = Config.empty) : Rule(config) { declarations .filterIsInstance() .count { !isIgnoredFunction(it) } - } ?: 0 + } + ?: 0 private fun isIgnoredFunction(function: KtNamedFunction): Boolean = when { ignoreDeprecated && function.hasAnnotation(DEPRECATED) -> true diff --git a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt index e66fc783ab73..c5027ee7eba8 100644 --- a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt +++ b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/ComplexMethodSpec.kt @@ -129,7 +129,7 @@ class ComplexMethodSpec { ) val subject = ComplexMethod(config) - assertThat(subject.lint(path)).hasSourceLocations(SourceLocation(43, 5)) + assertThat(subject.lint(path)).hasStartSourceLocations(SourceLocation(43, 5)) } @Test @@ -137,7 +137,7 @@ class ComplexMethodSpec { val config = TestConfig(mapOf("threshold" to "4")) val subject = ComplexMethod(config) - assertThat(subject.lint(path)).hasSourceLocations( + assertThat(subject.lint(path)).hasStartSourceLocations( SourceLocation(6, 5), SourceLocation(15, 5), SourceLocation(25, 5), @@ -235,7 +235,7 @@ class ComplexMethodSpec { private fun assertExpectedComplexityValue(code: String, config: TestConfig, expectedValue: Int) { val findings = ComplexMethod(config).lint(code) - assertThat(findings).hasSourceLocations(SourceLocation(1, 5)) + assertThat(findings).hasStartSourceLocations(SourceLocation(1, 5)) assertThat(findings.first()) .isThresholded() diff --git a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt index e8cc3e4b6f05..641b90d38ced 100644 --- a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt +++ b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/LargeClassSpec.kt @@ -16,7 +16,7 @@ class LargeClassSpec { fun `should detect only the nested large class which exceeds threshold 70`() { val findings = subject(threshold = 70).lint(resourceAsPath("NestedClasses.kt")) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocations(SourceLocation(12, 15)) + assertThat(findings).hasStartSourceLocations(SourceLocation(12, 15)) } @Test diff --git a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt index f3039cda62a4..b077cca74f05 100644 --- a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt +++ b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NamedArgumentsSpec.kt @@ -196,6 +196,18 @@ class NamedArgumentsSpec(val env: KotlinCoreEnvironment) { val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) } + + @Test + fun `does not count lambda argument`() { + val code = """ + fun test(n: Int) { + require(n == 2) { "N is not 2" } + } + """ + val subject = NamedArguments(TestConfig(mapOf("threshold" to 1))) + val findings = subject.compileAndLintWithContext(env, code) + assertThat(findings).hasSize(0) + } } @Nested diff --git a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedScopeFunctionsSpec.kt b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedScopeFunctionsSpec.kt index df1817d52b59..583ab5dd918f 100644 --- a/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedScopeFunctionsSpec.kt +++ b/detekt-rules-complexity/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/complexity/NestedScopeFunctionsSpec.kt @@ -116,7 +116,7 @@ class NestedScopeFunctionsSpec(private val env: KotlinCoreEnvironment) { } private fun expectSourceLocation(location: Pair) { - assertThat(actual).hasSourceLocation(location.first, location.second) + assertThat(actual).hasStartSourceLocation(location.first, location.second) } private fun expectFunctionInMsg(scopeFunction: String) { diff --git a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt index 463b1b064e74..5b18e5837560 100644 --- a/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt +++ b/detekt-rules-coroutines/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/coroutines/SuspendFunWithCoroutineScopeReceiver.kt @@ -67,7 +67,10 @@ class SuspendFunWithCoroutineScopeReceiver(config: Config) : Rule(config) { private fun checkReceiver(function: KtNamedFunction) { val suspendModifier = function.modifierList?.getModifier(KtTokens.SUSPEND_KEYWORD) ?: return val receiver = bindingContext[BindingContext.FUNCTION, function] - ?.extensionReceiverParameter?.value?.type ?: return + ?.extensionReceiverParameter + ?.value + ?.type + ?: return if (receiver.isCoroutineScope()) { report( CodeSmell( diff --git a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt index 70dddc21f57c..c9f971d32852 100644 --- a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt +++ b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClass.kt @@ -44,6 +44,9 @@ class UndocumentedPublicClass(config: Config = Config.empty) : Rule(config) { @Configuration("if inner interfaces should be searched") private val searchInInnerInterface: Boolean by config(true) + @Configuration("if protected classes should be searched") + private val searchInProtectedClass: Boolean by config(false) + override fun visitClass(klass: KtClass) { if (requiresDocumentation(klass)) { reportIfUndocumented(klass) @@ -81,7 +84,7 @@ class UndocumentedPublicClass(config: Config = Config.empty) : Rule(config) { } private fun isPublicAndPublicInherited(element: KtClassOrObject) = - element.isPublicInherited() && element.isPublicNotOverridden() + element.isPublicInherited(searchInProtectedClass) && element.isPublicNotOverridden(searchInProtectedClass) private fun KtObjectDeclaration.isCompanionWithoutName() = isCompanion() && nameAsSafeName.asString() == "Companion" diff --git a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt index df1691573dfc..c229e25ce076 100644 --- a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt +++ b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunction.kt @@ -7,6 +7,9 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.Configuration +import io.gitlab.arturbosch.detekt.rules.isProtected import io.gitlab.arturbosch.detekt.rules.isPublicNotOverridden import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtNamedFunction @@ -27,6 +30,9 @@ class UndocumentedPublicFunction(config: Config = Config.empty) : Rule(config) { Debt.TWENTY_MINS ) + @Configuration("if protected functions should be searched") + private val searchProtectedFunction: Boolean by config(false) + override fun visitNamedFunction(function: KtNamedFunction) { if (function.funKeyword == null && function.isLocal) return @@ -42,5 +48,9 @@ class UndocumentedPublicFunction(config: Config = Config.empty) : Rule(config) { } private fun KtNamedFunction.shouldBeDocumented() = - parents.filterIsInstance().all { it.isPublic } && isPublicNotOverridden() + if (searchProtectedFunction) { + parents.filterIsInstance().all { it.isPublic || it.isProtected() } + } else { + parents.filterIsInstance().all { it.isPublic } + } && isPublicNotOverridden(searchProtectedFunction) } diff --git a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicProperty.kt b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicProperty.kt index 361d8c8c6381..62edb37efd03 100644 --- a/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicProperty.kt +++ b/detekt-rules-documentation/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicProperty.kt @@ -7,6 +7,8 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.rules.isPublicInherited import io.gitlab.arturbosch.detekt.rules.isPublicNotOverridden import org.jetbrains.kotlin.psi.KtNamedDeclaration @@ -31,6 +33,9 @@ class UndocumentedPublicProperty(config: Config = Config.empty) : Rule(config) { Debt.TWENTY_MINS ) + @Configuration("if protected functions should be searched") + private val searchProtectedProperty: Boolean by config(false) + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor) { if (constructor.isPublicInherited()) { val comment = constructor.containingClassOrObject?.docComment?.text @@ -43,7 +48,7 @@ class UndocumentedPublicProperty(config: Config = Config.empty) : Rule(config) { } override fun visitProperty(property: KtProperty) { - if (property.isPublicInherited() && !property.isLocal && property.shouldBeDocumented()) { + if (property.isPublicInherited(searchProtectedProperty) && !property.isLocal && property.shouldBeDocumented()) { report(property) } super.visitProperty(property) @@ -58,7 +63,7 @@ class UndocumentedPublicProperty(config: Config = Config.empty) : Rule(config) { } private fun KtProperty.shouldBeDocumented() = - docComment == null && isTopLevelOrInPublicClass() && isPublicNotOverridden() + docComment == null && isTopLevelOrInPublicClass() && isPublicNotOverridden(searchProtectedProperty) private fun KtProperty.isTopLevelOrInPublicClass() = isTopLevel || containingClassOrObject?.isPublic == true diff --git a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt index 894ab5ad5cc2..9cd06e0c8e85 100644 --- a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt +++ b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicClassSpec.kt @@ -9,6 +9,7 @@ private const val SEARCH_IN_NESTED_CLASS = "searchInNestedClass" private const val SEARCH_IN_INNER_CLASS = "searchInInnerClass" private const val SEARCH_IN_INNER_OBJECT = "searchInInnerObject" private const val SEARCH_IN_INNER_INTERFACE = "searchInInnerInterface" +private const val SEARCH_IN_PROTECTED_CLASS = "searchInProtectedClass" class UndocumentedPublicClassSpec { val subject = UndocumentedPublicClass() @@ -233,4 +234,23 @@ class UndocumentedPublicClassSpec { """ assertThat(subject.compileAndLint(code)).isEmpty() } + + @Test + fun `does not report protected class by default`() { + val code = """ + protected class Test { + } + """ + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports protected class if configured`() { + val code = """ + protected class Test { + } + """ + val subject = UndocumentedPublicClass(TestConfig(mapOf(SEARCH_IN_PROTECTED_CLASS to "true"))) + assertThat(subject.compileAndLint(code)).hasSize(1) + } } diff --git a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt index 86d255fec6dd..39f4167ff10e 100644 --- a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt +++ b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicFunctionSpec.kt @@ -1,10 +1,13 @@ package io.gitlab.arturbosch.detekt.rules.documentation +import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.compileAndLint import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test +private const val SEARCH_PROTECTED_FUN = "searchProtectedFunction" + class UndocumentedPublicFunctionSpec { val subject = UndocumentedPublicFunction() @@ -141,6 +144,27 @@ class UndocumentedPublicFunctionSpec { assertThat(subject.compileAndLint(code)).isEmpty() } + @Test + fun `does not report protected functions by default`() { + val code = """ + open class Test { + protected fun noComment1() {} + } + """ + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports protected functions if configured`() { + val code = """ + open class Test { + protected fun noComment1() {} + } + """ + val subject = UndocumentedPublicFunction(TestConfig(mapOf(SEARCH_PROTECTED_FUN to "true"))) + assertThat(subject.compileAndLint(code)).hasSize(1) + } + @Nested inner class `nested class` { @Test diff --git a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicPropertySpec.kt b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicPropertySpec.kt index 053ea6c6f906..1e5fbe9bbbe9 100644 --- a/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicPropertySpec.kt +++ b/detekt-rules-documentation/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/documentation/UndocumentedPublicPropertySpec.kt @@ -1,10 +1,13 @@ package io.gitlab.arturbosch.detekt.rules.documentation +import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.compileAndLint import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test +private const val SEARCH_PROTECTED_PROPERTY = "searchProtectedProperty" + class UndocumentedPublicPropertySpec { val subject = UndocumentedPublicProperty() @@ -213,6 +216,27 @@ class UndocumentedPublicPropertySpec { assertThat(subject.compileAndLint(code)).isEmpty() } + @Test + fun `does not report undocumented protected properties by default`() { + val code = """ + open class Test { + protected val a = 1 + } + """ + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports undocumented protected properties if configured`() { + val code = """ + open class Test { + protected val a = 1 + } + """ + val subject = UndocumentedPublicProperty(TestConfig(mapOf(SEARCH_PROTECTED_PROPERTY to "true"))) + assertThat(subject.compileAndLint(code)).hasSize(1) + } + @Nested inner class `public properties in nested classes` { diff --git a/detekt-rules-empty/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt b/detekt-rules-empty/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt index 1c1ad463f84a..5254750568f5 100644 --- a/detekt-rules-empty/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt +++ b/detekt-rules-empty/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/empty/EmptyFunctionBlockSpec.kt @@ -21,7 +21,7 @@ class EmptyFunctionBlockSpec { protected fun stuff() {} } """ - assertThat(subject.compileAndLint(code)).hasSourceLocation(2, 27) + assertThat(subject.compileAndLint(code)).hasStartSourceLocation(2, 27) } @Test @@ -51,7 +51,7 @@ class EmptyFunctionBlockSpec { fun b() {} } """ - assertThat(subject.compileAndLint(code)).hasSourceLocation(2, 13) + assertThat(subject.compileAndLint(code)).hasStartSourceLocation(2, 13) } @Nested @@ -89,7 +89,7 @@ class EmptyFunctionBlockSpec { @Test fun `should not flag overridden functions`() { val config = TestConfig(mapOf(IGNORE_OVERRIDDEN_FUNCTIONS to "true")) - assertThat(EmptyFunctionBlock(config).compileAndLint(code)).hasSourceLocation(1, 13) + assertThat(EmptyFunctionBlock(config).compileAndLint(code)).hasStartSourceLocation(1, 13) } } @@ -115,7 +115,7 @@ class EmptyFunctionBlockSpec { @Test fun `should not flag overridden functions with commented body`() { - assertThat(subject.compileAndLint(code)).hasSourceLocation(12, 31) + assertThat(subject.compileAndLint(code)).hasStartSourceLocation(12, 31) } @Test diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/AvoidReferentialEquality.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/AvoidReferentialEquality.kt index a86219142649..1b249949f4af 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/AvoidReferentialEquality.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/AvoidReferentialEquality.kt @@ -11,7 +11,7 @@ import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution -import io.gitlab.arturbosch.detekt.api.internal.SimpleGlob +import io.gitlab.arturbosch.detekt.api.simplePatternToRegex import io.gitlab.arturbosch.detekt.rules.fqNameOrNull import org.jetbrains.kotlin.lexer.KtTokens.EQEQEQ import org.jetbrains.kotlin.lexer.KtTokens.EXCLEQEQEQ @@ -50,11 +50,11 @@ class AvoidReferentialEquality(config: Config) : Rule(config) { "The types are defined by a list of simple glob patterns (supporting `*` and `?` wildcards) " + "that match the fully qualified type name." ) - private val forbiddenTypePatterns: List by config( + private val forbiddenTypePatterns: List by config( listOf( "kotlin.String" ) - ) { it.map(SimpleGlob::of) } + ) { it.map(String::simplePatternToRegex) } override fun visitBinaryExpression(expression: KtBinaryExpression) { super.visitBinaryExpression(expression) diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExitOutsideMain.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExitOutsideMain.kt index 451dd84b5196..d40c3c347a55 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExitOutsideMain.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ExitOutsideMain.kt @@ -58,7 +58,7 @@ class ExitOutsideMain(config: Config = Config.empty) : Rule(config) { override fun visitCallExpression(expression: KtCallExpression) { super.visitCallExpression(expression) - if (context == BindingContext.EMPTY) return + if (bindingContext == BindingContext.EMPTY) return if (expression.getStrictParentOfType()?.isMainFunction() == true) return val fqName = expression.getResolvedCall(bindingContext)?.resultingDescriptor?.fqNameOrNull() ?: return diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt index 04c95bae66e1..da3b6e64487f 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperator.kt @@ -17,8 +17,8 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPrefixExpression -import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentOfType import org.jetbrains.kotlin.psi.psiUtil.leaves +import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall @@ -62,7 +62,7 @@ class UnusedUnaryOperator(config: Config = Config.empty) : Rule(config) { .none { it is PsiWhiteSpace && it.textContains('\n') } ) return - val parentOrSelf = (expression.getTopmostParentOfType() ?: expression) as KtExpression + val parentOrSelf = expression.parentBinaryExpressionOrThis() if (parentOrSelf.isUsedAsExpression(bindingContext)) return val operatorDescriptor = expression.operationReference.getResolvedCall(bindingContext) @@ -72,4 +72,8 @@ class UnusedUnaryOperator(config: Config = Config.empty) : Rule(config) { val message = "This '${parentOrSelf.text}' is not used" report(CodeSmell(issue, Entity.from(expression), message)) } + + private fun KtExpression.parentBinaryExpressionOrThis(): KtExpression { + return parents.takeWhile { it is KtBinaryExpression }.lastOrNull() as? KtBinaryExpression ?: this + } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/CastToNullableTypeSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/CastToNullableTypeSpec.kt index 0e8cfde05ae3..9be0ba15c301 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/CastToNullableTypeSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/CastToNullableTypeSpec.kt @@ -16,7 +16,7 @@ class CastToNullableTypeSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 22) + assertThat(findings).hasStartSourceLocation(2, 22) assertThat(findings[0]).hasMessage("Use the safe cast ('as? String') instead of 'as String?'.") } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DoubleMutabilityForCollectionSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DoubleMutabilityForCollectionSpec.kt index 40dace89da9f..d2c201441c7e 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DoubleMutabilityForCollectionSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DoubleMutabilityForCollectionSpec.kt @@ -30,7 +30,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -42,7 +42,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -54,7 +54,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -66,7 +66,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -78,7 +78,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -90,7 +90,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -102,7 +102,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -114,7 +114,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -135,7 +135,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(3, 5) + assertThat(result).hasStartSourceLocation(3, 5) } @Test @@ -157,7 +157,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(4, 5) + assertThat(result).hasStartSourceLocation(4, 5) } @Test @@ -180,7 +180,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(5, 5) + assertThat(result).hasStartSourceLocation(5, 5) } } @@ -357,7 +357,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -367,7 +367,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -377,7 +377,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -387,7 +387,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -397,7 +397,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -407,7 +407,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -417,7 +417,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -427,7 +427,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(1, 1) + assertThat(result).hasStartSourceLocation(1, 1) } @Test @@ -446,7 +446,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 1) + assertThat(result).hasStartSourceLocation(2, 1) } @Test @@ -466,7 +466,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(3, 1) + assertThat(result).hasStartSourceLocation(3, 1) } @Test @@ -487,7 +487,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(4, 1) + assertThat(result).hasStartSourceLocation(4, 1) } } @@ -642,7 +642,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -654,7 +654,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -666,7 +666,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -678,7 +678,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -690,7 +690,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -702,7 +702,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -714,7 +714,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -726,7 +726,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = subject.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(2, 5) + assertThat(result).hasStartSourceLocation(2, 5) } @Test @@ -747,7 +747,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(3, 5) + assertThat(result).hasStartSourceLocation(3, 5) } @Test @@ -769,7 +769,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(4, 5) + assertThat(result).hasStartSourceLocation(4, 5) } @Test @@ -792,7 +792,7 @@ class DoubleMutabilityForCollectionSpec(private val env: KotlinCoreEnvironment) """ val result = rule.compileAndLintWithContext(env, code) assertThat(result).hasSize(1) - assertThat(result).hasSourceLocation(5, 5) + assertThat(result).hasStartSourceLocation(5, 5) } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ElseCaseInsteadOfExhaustiveWhenSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ElseCaseInsteadOfExhaustiveWhenSpec.kt index e28c2b8abb6a..f503e33ae5cd 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ElseCaseInsteadOfExhaustiveWhenSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/ElseCaseInsteadOfExhaustiveWhenSpec.kt @@ -86,7 +86,7 @@ class ElseCaseInsteadOfExhaustiveWhenSpec(private val env: KotlinCoreEnvironment } } """ - assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + assertThat(subject.lintWithContext(env, code)).isEmpty() } } @@ -148,7 +148,7 @@ class ElseCaseInsteadOfExhaustiveWhenSpec(private val env: KotlinCoreEnvironment } } """ - assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + assertThat(subject.lintWithContext(env, code)).isEmpty() } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValueSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValueSpec.kt index a6a6a1340fb3..5de9c9be5660 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValueSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/IgnoredReturnValueSpec.kt @@ -206,7 +206,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { val findings = subject.lintWithContext(env, code, annotationClass) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(7, 5) + assertThat(findings).hasStartSourceLocation(7, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -227,7 +227,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(9, 5) + assertThat(findings).hasStartSourceLocation(9, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -294,7 +294,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(12, 10) + assertThat(findings).hasStartSourceLocation(12, 10) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -314,7 +314,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(9, 5) + assertThat(findings).hasStartSourceLocation(9, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -335,7 +335,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(9, 20) + assertThat(findings).hasStartSourceLocation(9, 20) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -356,7 +356,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(9, 14) + assertThat(findings).hasStartSourceLocation(9, 14) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -376,7 +376,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(8, 11) + assertThat(findings).hasStartSourceLocation(8, 11) assertThat(findings[0]).hasMessage("The call isTheAnswer is returning a value that is ignored.") } @@ -730,7 +730,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(8, 5) + assertThat(findings).hasStartSourceLocation(8, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -791,7 +791,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(9, 5) + assertThat(findings).hasStartSourceLocation(9, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } @@ -807,7 +807,7 @@ class IgnoredReturnValueSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 5) + assertThat(findings).hasStartSourceLocation(4, 5) assertThat(findings[0]).hasMessage("The call listOfChecked is returning a value that is ignored.") } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt index 42bda1090d96..1f7ab05aee43 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt @@ -3,6 +3,7 @@ package io.gitlab.arturbosch.detekt.rules.bugs import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext +import io.gitlab.arturbosch.detekt.test.lintWithContext import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.junit.jupiter.api.Nested @@ -33,10 +34,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: RED. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: RED. Either add missing cases or a default `else` case." + ) } @Test @@ -55,10 +58,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: RED, null. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: RED, null. Either add missing cases or a default `else` case." + ) } @Test @@ -78,10 +83,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: null. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: null. Either add missing cases or a default `else` case." + ) } @Test @@ -151,10 +158,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: VariantC. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: VariantC. Either add missing cases or a default `else` case." + ) } @Test @@ -174,10 +183,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: null. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: null. Either add missing cases or a default `else` case." + ) } @Test @@ -196,10 +207,12 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { } } """ - val actual = subject.compileAndLintWithContext(env, code) + val actual = subject.lintWithContext(env, code) assertThat(actual).hasSize(1) assertThat(actual.first().issue.id).isEqualTo("MissingWhenCase") - assertThat(actual.first().message).isEqualTo("When expression is missing cases: VariantC, null. Either add missing cases or a default `else` case.") + assertThat(actual.first().message).isEqualTo( + "When expression is missing cases: VariantC, null. Either add missing cases or a default `else` case." + ) } @Test diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/NullableToStringCallSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/NullableToStringCallSpec.kt index 2cd3bfe64cfa..4542f6ce73d3 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/NullableToStringCallSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/NullableToStringCallSpec.kt @@ -153,7 +153,6 @@ class NullableToStringCallSpec(private val env: KotlinCoreEnvironment) { data class Bar(val a: Any) fun test6(bar: Bar?) { if (bar == null) return - val x = bar?.a.toString() val y = "${'$'}{bar?.a}" } """ diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt index a507cd5f31b2..decd8dcf3daf 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt @@ -2,6 +2,7 @@ package io.gitlab.arturbosch.detekt.rules.bugs import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext +import io.gitlab.arturbosch.detekt.test.lintWithContext import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.junit.jupiter.api.Nested @@ -113,7 +114,7 @@ class RedundantElseInWhenSpec(private val env: KotlinCoreEnvironment) { } } """ - assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + assertThat(subject.lintWithContext(env, code)).isEmpty() } } @@ -203,7 +204,7 @@ class RedundantElseInWhenSpec(private val env: KotlinCoreEnvironment) { } } """ - assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + assertThat(subject.lintWithContext(env, code)).isEmpty() } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessarySafeCallSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessarySafeCallSpec.kt index 5b3037eecf88..688f61e356ee 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessarySafeCallSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessarySafeCallSpec.kt @@ -50,8 +50,8 @@ class UnnecessarySafeCallSpec(private val env: KotlinCoreEnvironment) { } """ val findings = subject.compileAndLintWithContext(env, code) - assertThat(findings).hasSize(2) - assertThat(findings).hasTextLocations(48 to 59, 48 to 70) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(48 to 59) } } diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCatchBlockSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCatchBlockSpec.kt index 98e6a584f326..a9ebdbb393df 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCatchBlockSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnreachableCatchBlockSpec.kt @@ -23,7 +23,7 @@ class UnreachableCatchBlockSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 7) + assertThat(findings).hasStartSourceLocation(4, 7) } @Test @@ -38,7 +38,7 @@ class UnreachableCatchBlockSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 7) + assertThat(findings).hasStartSourceLocation(4, 7) } @Test @@ -54,7 +54,7 @@ class UnreachableCatchBlockSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(2) - assertThat(findings).hasSourceLocations( + assertThat(findings).hasStartSourceLocations( SourceLocation(4, 7), SourceLocation(5, 7) ) diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt index 7683fbe216b2..893b23bc3ee5 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnusedUnaryOperatorSpec.kt @@ -20,7 +20,7 @@ class UnusedUnaryOperatorSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 9) + assertThat(findings).hasStartSourceLocation(3, 9) assertThat(findings[0]).hasMessage("This '+ 3' is not used") } @@ -34,7 +34,7 @@ class UnusedUnaryOperatorSpec(private val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 9) + assertThat(findings).hasStartSourceLocation(3, 9) assertThat(findings[0]).hasMessage("This '- 3' is not used") } @@ -122,4 +122,20 @@ class UnusedUnaryOperatorSpec(private val env: KotlinCoreEnvironment) { val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).isEmpty() } + + @Test + fun `var assignment by if expression`() { + val code = """ + fun test(b: Boolean) { + var x = 0 + x = if (b) { + -1 + } else { + 1 + } + } + """ + val findings = subject.compileAndLintWithContext(env, code) + assertThat(findings).isEmpty() + } } diff --git a/detekt-rules-exceptions/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt b/detekt-rules-exceptions/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt index 05c87835d9c9..2df376892ec6 100644 --- a/detekt-rules-exceptions/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt +++ b/detekt-rules-exceptions/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/exceptions/ThrowingNewInstanceOfSameExceptionSpec.kt @@ -46,7 +46,9 @@ class ThrowingNewInstanceOfSameExceptionSpec { } @Nested - @DisplayName("a catch block which throws a new instance of the same exception type without wrapping the caught exception") + @DisplayName( + "a catch block which throws a new instance of the same exception type without wrapping the caught exception" + ) inner class CatchBlockThrowingSameExceptionWithoutWrapping { val code = """ fun x() { diff --git a/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNaming.kt b/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNaming.kt index e28cea260aaf..2bb5c283402d 100644 --- a/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNaming.kt +++ b/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNaming.kt @@ -12,6 +12,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution import io.gitlab.arturbosch.detekt.rules.fqNameOrNull import io.gitlab.arturbosch.detekt.rules.identifierName +import io.gitlab.arturbosch.detekt.rules.isConstant import io.gitlab.arturbosch.detekt.rules.isOverride import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtParameter @@ -40,7 +41,8 @@ class BooleanPropertyNaming(config: Config = Config.empty) : Rule(config) { private val ignoreOverridden: Boolean by config(true) override val issue = Issue( - javaClass.simpleName, Severity.CodeSmell, + javaClass.simpleName, + Severity.CodeSmell, "Boolean property name should follow the naming convention set in the projects configuration.", Debt.FIVE_MINS ) @@ -68,8 +70,9 @@ class BooleanPropertyNaming(config: Config = Config.empty) : Rule(config) { val typeName = getTypeName(declaration) val isBooleanType = typeName == KOTLIN_BOOLEAN_TYPE_NAME || typeName == JAVA_BOOLEAN_TYPE_NAME + val isNonConstantBooleanType = isBooleanType && !declaration.isConstant() - if (isBooleanType && !name.contains(allowedPattern) && !isIgnoreOverridden(declaration)) { + if (isNonConstantBooleanType && !name.contains(allowedPattern) && !isIgnoreOverridden(declaration)) { report(reportCodeSmell(declaration, name)) } } diff --git a/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt b/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt index cd2f1cc8c940..6acc1a419fb8 100644 --- a/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt +++ b/detekt-rules-naming/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationName.kt @@ -79,7 +79,7 @@ class MatchingDeclarationName(config: Config = Config.empty) : Rule(config) { val declarationName = declaration.name val filename = file.fileNameWithoutSuffix() if (declarationName != filename && hasNoMatchingTypeAlias(filename)) { - val entity = Entity.from(declaration).copy(ktElement = file) + val entity = Entity.atName(declaration).copy(ktElement = file) report( CodeSmell( issue, diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNamingSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNamingSpec.kt index a6fa028720e7..0b112ef86c23 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNamingSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/BooleanPropertyNamingSpec.kt @@ -270,6 +270,18 @@ class BooleanPropertyNamingSpec(val env: KotlinCoreEnvironment) { assertThat(findings).hasSize(1) } + @Test + fun `should not warn about Kotlin Boolean if it is a constant val`() { + val code = """ + object Test { + const val CONSTANT_VAL_BOOLEAN = true + } + """ + val findings = subject.compileAndLintWithContext(env, code) + + assertThat(findings).hasSize(0) + } + @Test fun `should warn about Kotlin Boolean override if isIgnoreOverridden is false`() { val code = """ diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNamingSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNamingSpec.kt index e9c0e445a765..59dc5ca06353 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNamingSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/FunctionNamingSpec.kt @@ -48,7 +48,7 @@ class FunctionNamingSpec { } interface I { fun shouldNotBeFlagged() } """ - assertThat(FunctionNaming().compileAndLint(code)).hasSourceLocation(3, 13) + assertThat(FunctionNaming().compileAndLint(code)).hasStartSourceLocation(3, 13) } @Test @@ -84,7 +84,7 @@ class FunctionNamingSpec { } interface I { @Suppress("FunctionNaming") fun SHOULD_BE_FLAGGED() } """ - assertThat(FunctionNaming().compileAndLint(code)).hasSourceLocation(3, 13) + assertThat(FunctionNaming().compileAndLint(code)).hasStartSourceLocation(3, 13) } @Test @@ -96,7 +96,7 @@ class FunctionNamingSpec { interface I { fun SHOULD_BE_FLAGGED() } """ val config = TestConfig(mapOf(FunctionNaming.IGNORE_OVERRIDDEN to "false")) - assertThat(FunctionNaming(config).compileAndLint(code)).hasSourceLocations( + assertThat(FunctionNaming(config).compileAndLint(code)).hasStartSourceLocations( SourceLocation(2, 18), SourceLocation(4, 19) ) @@ -107,6 +107,6 @@ class FunctionNamingSpec { val code = """ fun `7his is a function name _`() = Unit """ - assertThat(FunctionNaming().compileAndLint(code)).hasSourceLocations(SourceLocation(1, 5)) + assertThat(FunctionNaming().compileAndLint(code)).hasStartSourceLocations(SourceLocation(1, 5)) } } diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationNameSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationNameSpec.kt index 123b56d201cb..89cb46cfa9b3 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationNameSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/MatchingDeclarationNameSpec.kt @@ -132,7 +132,7 @@ class MatchingDeclarationNameSpec { fun `should not pass for object declaration`() { val ktFile = compileContentForTest("object O", filename = "Objects.kt") val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 8) } @Test @@ -142,14 +142,14 @@ class MatchingDeclarationNameSpec { filename = "Objects.kt" ) val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 45) } @Test fun `should not pass for class declaration`() { val ktFile = compileContentForTest("class C", filename = "Classes.kt") val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 7) } @Test @@ -163,14 +163,14 @@ class MatchingDeclarationNameSpec { filename = "ClassUtils.kt" ) val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 7) } @Test fun `should not pass for interface declaration`() { val ktFile = compileContentForTest("interface I", filename = "Not_I.kt") val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 11) } @Test @@ -184,7 +184,7 @@ class MatchingDeclarationNameSpec { filename = "E.kt" ) val findings = MatchingDeclarationName().lint(ktFile) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 12) } @Test @@ -211,7 +211,7 @@ class MatchingDeclarationNameSpec { val findings = MatchingDeclarationName( TestConfig("mustBeFirst" to "false") ).lint(ktFile) - assertThat(findings).hasSourceLocation(3, 1) + assertThat(findings).hasStartSourceLocation(3, 7) } } } diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NoNameShadowingSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NoNameShadowingSpec.kt index e6f707169b9b..ed16f59845b2 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NoNameShadowingSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/NoNameShadowingSpec.kt @@ -19,7 +19,7 @@ class NoNameShadowingSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 9) + assertThat(findings).hasStartSourceLocation(2, 9) assertThat(findings[0]).hasMessage("Name shadowed: i") } diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt index 3ab372728239..2c8dc13eb3b2 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/ObjectPropertyNamingSpec.kt @@ -64,7 +64,7 @@ class ObjectPropertyNamingSpec { ${PublicConst.positive} } """ - assertThat(subject.compileAndLint(code)).hasSourceLocation(2, 15) + assertThat(subject.compileAndLint(code)).hasStartSourceLocation(2, 15) } } @@ -130,7 +130,7 @@ class ObjectPropertyNamingSpec { } } """ - assertThat(subject.compileAndLint(code)).hasSourceLocation(3, 19) + assertThat(subject.compileAndLint(code)).hasStartSourceLocation(3, 19) } } diff --git a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNamingSpec.kt b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNamingSpec.kt index 0c9e783e6315..78c33c6982d2 100644 --- a/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNamingSpec.kt +++ b/detekt-rules-naming/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/naming/VariableNamingSpec.kt @@ -18,7 +18,7 @@ class VariableNamingSpec { } """ assertThat(VariableNaming().compileAndLint(code)) - .hasSourceLocations( + .hasStartSourceLocations( SourceLocation(2, 17), SourceLocation(3, 9), SourceLocation(4, 9) @@ -68,7 +68,7 @@ class VariableNamingSpec { """ val config = TestConfig(mapOf(IGNORE_OVERRIDDEN to "false")) assertThat(VariableNaming(config).compileAndLint(code)) - .hasSourceLocations( + .hasStartSourceLocations( SourceLocation(2, 18), SourceLocation(5, 18) ) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullable.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullable.kt index ba14ae34d9b5..a65ed2e7cebd 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullable.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullable.kt @@ -14,13 +14,13 @@ import io.gitlab.arturbosch.detekt.rules.isNonNullCheck import io.gitlab.arturbosch.detekt.rules.isNullCheck import io.gitlab.arturbosch.detekt.rules.isOpen import io.gitlab.arturbosch.detekt.rules.isOverride -import org.jetbrains.kotlin.com.intellij.codeInsight.NullableNotNullManager.isNullable import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtConstantExpression @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.KtWhenConditionWithExpression import org.jetbrains.kotlin.psi.KtWhenExpression import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType +import org.jetbrains.kotlin.psi.psiUtil.isFirstStatement import org.jetbrains.kotlin.psi.psiUtil.isPrivate import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.smartcasts.getKotlinTypeForComparison @@ -84,6 +85,11 @@ import org.jetbrains.kotlin.types.isNullable * println(a) * } * } + * + * fun foo(a: Int?) { + * if (a == null) return + * println(a) + * } * * * @@ -137,11 +143,13 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { function.valueParameters.asSequence() .filter { it.typeReference?.typeElement is KtNullableType - }.mapNotNull { parameter -> + } + .mapNotNull { parameter -> bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parameter]?.let { it to parameter } - }.forEach { (descriptor, param) -> + } + .forEach { (descriptor, param) -> candidateDescriptors.add(descriptor) nullableParams[descriptor] = NullableParam(param) } @@ -174,8 +182,9 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { // the param, either via an if/when check or with a safe-qualified expression. .filter { val onlyNonNullCheck = validSingleChildExpression && it.isNonNullChecked && !it.isNullChecked - it.isNonNullForced || onlyNonNullCheck - }.forEach { nullableParam -> + it.isNonNullForced || it.isNullCheckReturnsUnit || onlyNonNullCheck + } + .forEach { nullableParam -> report( CodeSmell( issue, @@ -233,9 +242,24 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { override fun visitIfExpression(expression: KtIfExpression) { expression.condition.evaluateCheckStatement(expression.`else`) + if (expression.isFirstStatement()) { + evaluateNullCheckReturnsUnit(expression.condition, expression.then) + } super.visitIfExpression(expression) } + private fun evaluateNullCheckReturnsUnit(condition: KtExpression?, then: KtExpression?) { + val thenExpression = if (then is KtBlockExpression) then.firstStatement else then + if (thenExpression !is KtReturnExpression) return + if (thenExpression.returnedExpression != null) return + + if (condition is KtBinaryExpression && condition.isNullCheck()) { + getDescriptor(condition.left, condition.right) + ?.let { nullableParams[it] } + ?.let { it.isNullCheckReturnsUnit = true } + } + } + override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression) { updateNullableParam(expression.receiverExpression) { it.isNonNullChecked = true } super.visitSafeQualifiedExpression(expression) @@ -321,15 +345,6 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { val rightExpression = right val nonNullChecks = mutableListOf() - fun getDescriptor(leftExpression: KtExpression?, rightExpression: KtExpression?): CallableDescriptor? { - return when { - leftExpression is KtNameReferenceExpression -> leftExpression - rightExpression is KtNameReferenceExpression -> rightExpression - else -> null - }?.getResolvedCall(bindingContext) - ?.resultingDescriptor - } - if (isNullCheck()) { getDescriptor(leftExpression, rightExpression) ?.let { nullableParams[it] } @@ -344,6 +359,15 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { return nonNullChecks } + private fun getDescriptor(leftExpression: KtExpression?, rightExpression: KtExpression?): CallableDescriptor? { + return when { + leftExpression is KtNameReferenceExpression -> leftExpression + rightExpression is KtNameReferenceExpression -> rightExpression + else -> null + }?.getResolvedCall(bindingContext) + ?.resultingDescriptor + } + private fun KtIsExpression.evaluateIsExpression(): List { val descriptor = this.leftHandSide.getResolvedCall(bindingContext)?.resultingDescriptor ?: return emptyList() @@ -415,6 +439,7 @@ class CanBeNonNullable(config: Config = Config.empty) : Rule(config) { var isNullChecked = false var isNonNullChecked = false var isNonNullForced = false + var isNullCheckReturnsUnit = false } private inner class PropertyCheckVisitor : DetektVisitor() { diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrapping.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrapping.kt new file mode 100644 index 000000000000..3dba019a61a6 --- /dev/null +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrapping.kt @@ -0,0 +1,109 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.Configuration +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtQualifiedExpression +import org.jetbrains.kotlin.psi.KtUnaryExpression + +/** + * Requires that all chained calls are placed on a new line if a preceding one is. + * + * + * foo() + * .bar().baz() + * + * + * + * foo().bar().baz() + * + * foo() + * .bar() + * .baz() + * + */ +class CascadingCallWrapping(config: Config = Config.empty) : Rule(config) { + override val issue = Issue( + id = javaClass.simpleName, + severity = Severity.Style, + description = "If a chained call is wrapped to a new line, subsequent chained calls should be as well.", + debt = Debt.FIVE_MINS, + ) + + @Configuration("require trailing elvis expressions to be wrapped on a new line") + private val includeElvis: Boolean by config(true) + + override fun visitQualifiedExpression(expression: KtQualifiedExpression) { + super.visitQualifiedExpression(expression) + + checkExpression(expression, callExpression = expression.selectorExpression) + } + + override fun visitBinaryExpression(expression: KtBinaryExpression) { + super.visitBinaryExpression(expression) + + if (includeElvis && expression.operationToken == KtTokens.ELVIS) { + checkExpression(expression, callExpression = expression.right) + } + } + + private fun checkExpression(expression: KtExpression, callExpression: KtExpression?) { + if (!expression.containsNewline() && expression.receiverContainsNewline()) { + val callTextOrEmpty = callExpression?.text?.let { " `$it`" }.orEmpty() + report( + CodeSmell( + issue = issue, + entity = Entity.from(expression), + message = "Chained call$callTextOrEmpty should be wrapped to a new line since preceding calls were." + ) + ) + } + } + + @Suppress("ReturnCount") + private fun KtExpression.containsNewline(): Boolean { + val lhs: KtExpression + val rhs: KtExpression + + when (this) { + is KtQualifiedExpression -> { + lhs = receiverExpression + rhs = selectorExpression ?: return false + } + is KtBinaryExpression -> { + if (operationToken != KtTokens.ELVIS) return false + lhs = left ?: return false + rhs = right ?: return false + } + else -> return false + } + + val receiverEnd = lhs.startOffsetInParent + lhs.textLength + val selectorStart = rhs.startOffsetInParent + + return (receiverEnd until selectorStart).any { text[it] == '\n' } + } + + private fun KtExpression.receiverContainsNewline(): Boolean { + val lhs = when (this) { + is KtQualifiedExpression -> receiverExpression + is KtBinaryExpression -> left ?: return false + else -> return false + } + + return when (lhs) { + is KtQualifiedExpression -> lhs.containsNewline() + is KtUnaryExpression -> (lhs.baseExpression as? KtQualifiedExpression)?.containsNewline() == true + else -> false + } + } +} diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt index 925365b21548..499f86a54643 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctions.kt @@ -7,7 +7,6 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity -import io.gitlab.arturbosch.detekt.api.SplitPattern import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.rules.isOverride @@ -38,7 +37,7 @@ class DataClassContainsFunctions(config: Config = Config.empty) : Rule(config) { ) @Configuration("allowed conversion function names") - private val conversionFunctionPrefix: SplitPattern by config("to") { SplitPattern(it) } + private val conversionFunctionPrefix: List by config(listOf("to")) override fun visitClass(klass: KtClass) { if (klass.isData()) { @@ -50,15 +49,18 @@ class DataClassContainsFunctions(config: Config = Config.empty) : Rule(config) { } private fun checkFunction(klass: KtClass, function: KtNamedFunction) { - if (!function.isOverride() && !conversionFunctionPrefix.startWith(function.name)) { - report( - CodeSmell( - issue, - Entity.atName(function), - "The data class ${klass.name} contains functions which are not registered " + - "conversion functions. The offending method is called ${function.name}" - ) + if (function.isOverride()) return + + val functionName = function.name + if (functionName != null && conversionFunctionPrefix.any { functionName.startsWith(it) }) return + + report( + CodeSmell( + issue, + Entity.atName(function), + "The data class ${klass.name} contains functions which are not registered " + + "conversion functions. The offending method is called $functionName" ) - } + ) } } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt index 9f8393b1c4b8..58e7eaeb37a4 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethod.kt @@ -9,6 +9,7 @@ import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution import io.gitlab.arturbosch.detekt.rules.fqNameOrNull +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.load.java.isFromJava import org.jetbrains.kotlin.psi.KtBlockExpression @@ -17,7 +18,8 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall -import org.jetbrains.kotlin.types.ErrorType +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.error.ErrorType import org.jetbrains.kotlin.types.typeUtil.supertypes /** @@ -26,13 +28,13 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes * Prefer the usage of the indexed access operator `[]` for map or list element access or insert methods. * * - * val map = Map() + * val map = mutableMapOf() * map.put("key", "value") * val value = map.get("key") * * * - * val map = Map() + * val map = mutableMapOf() * map["key"] = "value" * val value = map["key"] * @@ -52,31 +54,58 @@ class ExplicitCollectionElementAccessMethod(config: Config = Config.empty) : Rul super.visitDotQualifiedExpression(expression) if (bindingContext == BindingContext.EMPTY) return val call = expression.selectorExpression as? KtCallExpression ?: return - if (isIndexableGetter(call) || (isIndexableSetter(call) && unusedReturnValue(call))) { + if (isIndexGetterRecommended(call) || isIndexSetterRecommended(call)) { report(CodeSmell(issue, Entity.from(expression), issue.description)) } } - private fun isIndexableGetter(expression: KtCallExpression): Boolean { - if (expression.calleeExpression?.text != "get") return false - val descriptor = expression.getFunctionDescriptor() ?: return false - return descriptor.isOperator && descriptor.typeParameters.isEmpty() + private fun isIndexGetterRecommended(expression: KtCallExpression): Boolean { + val getter = + if (expression.calleeExpression?.text == "get") expression.getFunctionDescriptor() + else null + if (getter == null) return false + + return canReplace(getter) && shouldReplace(getter) } - private fun isIndexableSetter(expression: KtCallExpression): Boolean = + private fun isIndexSetterRecommended(expression: KtCallExpression): Boolean = when (expression.calleeExpression?.text) { "set" -> { - val function = expression.getFunctionDescriptor() - when { - function == null -> false - !function.isOperator -> false - else -> !(function.isFromJava && function.valueParameters.size > 2) - } + val setter = expression.getFunctionDescriptor() + if (setter == null) false + else canReplace(setter) && shouldReplace(setter) } // `put` isn't an operator function, but can be replaced with indexer when the caller is Map. "put" -> isCallerMap(expression) else -> false - } + } && unusedReturnValue(expression) + + private fun KtCallExpression.getFunctionDescriptor(): FunctionDescriptor? = + getResolvedCall(bindingContext)?.resultingDescriptor as? FunctionDescriptor + + private fun canReplace(function: FunctionDescriptor): Boolean { + // Can't use index operator when insufficient information is available to infer type variable. + // For now, this is an incomplete check and doesn't report edge cases (e.g. inference using return type). + val genericParameterTypeNames = function.valueParameters.map { it.original.type.toString() }.toSet() + val typeParameterNames = function.typeParameters.map { it.name.asString() } + if (!genericParameterTypeNames.containsAll(typeParameterNames)) return false + + return function.isOperator + } + + private fun shouldReplace(function: FunctionDescriptor): Boolean { + // The intent of kotlin operation functions is to support indexed accessed, so should always be replaced. + if (!function.isFromJava) return true + + // It does not always make sense for all Java get/set functions to be replaced by index accessors. + // Only recommend known collection types. + val javaClass = function.containingDeclaration as? ClassDescriptor ?: return false + return javaClass.fqNameSafe.asString() in setOf( + "java.util.ArrayList", + "java.util.HashMap", + "java.util.LinkedHashMap" + ) + } private fun isCallerMap(expression: KtCallExpression): Boolean { val caller = expression.getQualifiedExpressionForSelector()?.receiverExpression @@ -90,8 +119,4 @@ class ExplicitCollectionElementAccessMethod(config: Config = Config.empty) : Rul private fun unusedReturnValue(expression: KtCallExpression): Boolean = expression.parent.parent is KtBlockExpression - - private fun KtCallExpression.getFunctionDescriptor(): FunctionDescriptor? { - return getResolvedCall(bindingContext)?.resultingDescriptor as? FunctionDescriptor - } } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt index c6076fa9bf5d..852845eba2f3 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitItLambdaParameter.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.psi.KtLambdaExpression /** * Lambda expressions are one of the core features of the language. They often include very small chunks of * code using only one parameter. In this cases Kotlin can supply the implicit `it` parameter - * to make code more concise. It fits most usecases, but when faced larger or nested chunks of code, + * to make code more concise. It fits most use cases, but when faced larger or nested chunks of code, * you might want to add an explicit name for the parameter. Naming it just `it` is meaningless and only * makes your code misleading, especially when dealing with nested functions. * @@ -55,11 +55,16 @@ class ExplicitItLambdaParameter(val config: Config) : Rule(config) { super.visitLambdaExpression(lambdaExpression) val parameterNames = lambdaExpression.valueParameters.map { it.name } if (IT_LITERAL in parameterNames) { + val message = if (parameterNames.size == 1) { + "This explicit usage of `it` as the lambda parameter name can be omitted." + } else { + "`it` should not be used as name for a lambda parameter." + } report( CodeSmell( issue, Entity.from(lambdaExpression), - "This explicit usage of `it` as the lambda parameter name can be omitted." + message ) ) } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt index 069c1e65fa43..ed6a1b474c84 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImport.kt @@ -10,6 +10,7 @@ import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.api.simplePatternToRegex +import io.gitlab.arturbosch.detekt.api.valuesWithReason import org.jetbrains.kotlin.psi.KtImportDirective /** @@ -17,7 +18,6 @@ import org.jetbrains.kotlin.psi.KtImportDirective * or deprecated APIs. Detekt will then report all imports that are forbidden. * * - * package foo * import kotlin.jvm.JvmField * import kotlin.SinceKotlin * @@ -33,8 +33,8 @@ class ForbiddenImport(config: Config = Config.empty) : Rule(config) { ) @Configuration("imports which should not be used") - private val imports: List by config(emptyList()) { - it.distinct().map(String::simplePatternToRegex) + private val imports: List by config(valuesWithReason()) { list -> + list.map { Forbidden(it.value.simplePatternToRegex(), it.reason) } } @Configuration("reports imports which match the specified regular expression. For example `net.*R`.") @@ -44,18 +44,29 @@ class ForbiddenImport(config: Config = Config.empty) : Rule(config) { super.visitImportDirective(importDirective) val import = importDirective.importedFqName?.asString().orEmpty() - if (imports.any { it.matches(import) } || containsForbiddenPattern(import)) { - report( - CodeSmell( - issue, - Entity.from(importDirective), - "The import " + - "$import has been forbidden in the Detekt config." - ) - ) + + val forbidden = imports.find { it.import.matches(import) } + val reason = if (forbidden != null) { + if (forbidden.reason != null) { + "The import `$import` has been forbidden: ${forbidden.reason}" + } else { + defaultReason(import) + } + } else { + if (containsForbiddenPattern(import)) defaultReason(import) else null + } + + if (reason != null) { + report(CodeSmell(issue, Entity.from(importDirective), reason)) } } + private fun defaultReason(forbiddenImport: String): String { + return "The import `$forbiddenImport` has been forbidden in the detekt config." + } + private fun containsForbiddenPattern(import: String): Boolean = forbiddenPatterns.pattern.isNotEmpty() && forbiddenPatterns.containsMatchIn(import) } + +private data class Forbidden(val import: Regex, val reason: String?) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCall.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCall.kt index ca4226d314a1..a49cfb05eb21 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCall.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCall.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.rules.style import io.github.detekt.tooling.api.FunctionMatcher +import io.github.detekt.tooling.api.FunctionMatcher.Companion.fromFunctionSignature import io.gitlab.arturbosch.detekt.api.CodeSmell import io.gitlab.arturbosch.detekt.api.Config import io.gitlab.arturbosch.detekt.api.Debt @@ -11,12 +12,21 @@ import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.config import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution +import io.gitlab.arturbosch.detekt.api.valuesWithReason +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtCallableReferenceExpression +import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPostfixExpression import org.jetbrains.kotlin.psi.KtPrefixExpression +import org.jetbrains.kotlin.psi.psiUtil.isDotSelector +import org.jetbrains.kotlin.psi2ir.unwrappedGetMethod +import org.jetbrains.kotlin.psi2ir.unwrappedSetMethod import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall /** @@ -28,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall * import java.lang.System * fun main() { * System.gc() + * System::gc * } * * @@ -52,12 +63,14 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) { "`fun String.hello(a: Int)` you should add the receiver parameter as the first parameter like this: " + "`hello(kotlin.String, kotlin.Int)`" ) - private val methods: List by config( - listOf( - "kotlin.io.print", - "kotlin.io.println", + private val methods: List by config( + valuesWithReason( + "kotlin.io.print" to "print does not allow you to configure the output stream. Use a logger instead.", + "kotlin.io.println" to "println does not allow you to configure the output stream. Use a logger instead.", ) - ) { it.map(FunctionMatcher::fromFunctionSignature) } + ) { list -> + list.map { Forbidden(fromFunctionSignature(it.value), it.reason) } + } override fun visitCallExpression(expression: KtCallExpression) { super.visitCallExpression(expression) @@ -69,6 +82,13 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) { check(expression.operationReference) } + override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { + super.visitDotQualifiedExpression(expression) + if (expression.getCalleeExpressionIfAny()?.isDotSelector() == true) { + check(expression) + } + } + override fun visitPrefixExpression(expression: KtPrefixExpression) { super.visitPrefixExpression(expression) check(expression.operationReference) @@ -79,18 +99,34 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) { check(expression.operationReference) } + override fun visitCallableReferenceExpression(expression: KtCallableReferenceExpression) { + super.visitCallableReferenceExpression(expression) + check(expression.callableReference) + } + private fun check(expression: KtExpression) { if (bindingContext == BindingContext.EMPTY) return val descriptors = expression.getResolvedCall(bindingContext)?.resultingDescriptor?.let { - listOf(it) + it.overriddenDescriptors + val foundDescriptors = if (it is PropertyDescriptor) { + listOfNotNull(it.unwrappedGetMethod, it.unwrappedSetMethod) + } else { + listOf(it) + } + foundDescriptors + foundDescriptors.flatMap(CallableDescriptor::getOverriddenDescriptors) } ?: return for (descriptor in descriptors) { - methods.find { it.match(descriptor) }?.let { functionMatcher -> - val message = "The method $functionMatcher has been forbidden in the Detekt config." + methods.find { it.value.match(descriptor) }?.let { forbidden -> + val message = if (forbidden.reason != null) { + "The method `${forbidden.value}` has been forbidden: ${forbidden.reason}" + } else { + "The method `${forbidden.value}` has been forbidden in the detekt config." + } report(CodeSmell(issue, Entity.from(expression), message)) } } } + + private data class Forbidden(val value: FunctionMatcher, val reason: String?) } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt index fb3e65023497..6e67b33309a0 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenVoid.kt @@ -80,7 +80,8 @@ class ForbiddenVoid(config: Config = Config.empty) : Rule(config) { private fun KtTypeReference.isPartOfReturnTypeOfFunction() = getStrictParentOfType() ?.typeReference - ?.anyDescendantOfType { it == this } ?: false + ?.anyDescendantOfType { it == this } + ?: false private fun KtTypeReference.isParameterTypeOfFunction() = getStrictParentOfType() != null diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLine.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLine.kt new file mode 100644 index 000000000000..f64f09a2974b --- /dev/null +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLine.kt @@ -0,0 +1,100 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.Configuration +import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution +import org.jetbrains.kotlin.descriptors.PackageViewDescriptor +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtImportDirective +import org.jetbrains.kotlin.psi.KtPackageDirective +import org.jetbrains.kotlin.psi.KtQualifiedExpression +import org.jetbrains.kotlin.psi.KtReferenceExpression +import org.jetbrains.kotlin.psi.KtUnaryExpression +import org.jetbrains.kotlin.resolve.BindingContext + +/** + * Limits the number of chained calls which can be placed on a single line. + * + * + * a().b().c().d().e().f() + * + * + * + * a().b().c() + * .d().e().f() + * + */ +@RequiresTypeResolution +class MaxChainedCallsOnSameLine(config: Config = Config.empty) : Rule(config) { + override val issue = Issue( + id = javaClass.simpleName, + severity = Severity.Style, + description = "Chained calls beyond the maximum should be wrapped to a new line.", + debt = Debt.FIVE_MINS, + ) + + @Configuration("maximum chained calls allowed on a single line") + private val maxChainedCalls: Int by config(defaultValue = 5) + + @Suppress("ReturnCount") + override fun visitQualifiedExpression(expression: KtQualifiedExpression) { + super.visitQualifiedExpression(expression) + + if (bindingContext == BindingContext.EMPTY) return + + val parent = expression.parent + + // skip if the parent is also a call on the same line to avoid duplicated warnings + if (parent is KtQualifiedExpression && !parent.callOnNewLine()) return + + if (parent is KtImportDirective || parent is KtPackageDirective) return + + val chainedCalls = expression.countChainedCalls() + 1 + if (chainedCalls > maxChainedCalls) { + report( + CodeSmell( + issue = issue, + entity = Entity.from(expression), + message = "$chainedCalls chained calls on a single line; more than $maxChainedCalls calls should " + + "be wrapped to a new line." + ) + ) + } + } + + private fun KtExpression.countChainedCalls(): Int { + return when (this) { + is KtQualifiedExpression -> when { + receiverExpression.isReferenceToPackage() || callOnNewLine() -> 0 + else -> receiverExpression.countChainedCalls() + 1 + } + is KtUnaryExpression -> baseExpression?.countChainedCalls() ?: 0 + else -> 0 + } + } + + private fun KtExpression.isReferenceToPackage(): Boolean { + val selectorOrThis = (this as? KtQualifiedExpression)?.selectorExpression ?: this + if (selectorOrThis !is KtReferenceExpression) return false + return bindingContext[BindingContext.REFERENCE_TARGET, selectorOrThis] is PackageViewDescriptor + } + + private fun KtQualifiedExpression.callOnNewLine(): Boolean { + val receiver = receiverExpression + val selector = selectorExpression ?: return false + + val receiverEnd = receiver.startOffsetInParent + receiver.textLength + val selectorStart = selector.startOffsetInParent + + return text + .subSequence(startIndex = receiverEnd, endIndex = selectorStart) + .contains('\n') + } +} diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt index a04bbcd17bbd..903b1bc6e3cc 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt @@ -1,5 +1,6 @@ package io.gitlab.arturbosch.detekt.rules.style +import io.github.detekt.psi.getLineAndColumnInPsiFile import io.github.detekt.psi.toFilePath import io.gitlab.arturbosch.detekt.api.CodeSmell import io.gitlab.arturbosch.detekt.api.Config @@ -13,7 +14,6 @@ import io.gitlab.arturbosch.detekt.api.SourceLocation import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -33,11 +33,11 @@ class NewLineAtEndOfFile(config: Config = Config.empty) : Rule(config) { override fun visitKtFile(file: KtFile) { val text = file.text if (text.isNotEmpty() && !text.endsWith('\n')) { - val coords = DiagnosticUtils.getLineAndColumnInPsiFile( + val coords = getLineAndColumnInPsiFile( file, TextRange(file.endOffset, file.endOffset) ) - val sourceLocation = SourceLocation(coords.line, coords.column) + val sourceLocation = SourceLocation(coords?.line ?: 0, coords?.column ?: 0) val textLocation = TextLocation(file.endOffset, file.endOffset) val location = Location(sourceLocation, textLocation, file.containingFile.toFilePath()) report( diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt index 889644bad636..c70b79712508 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NullableBooleanCheck.kt @@ -46,23 +46,16 @@ class NullableBooleanCheck(config: Config = Config.empty) : Rule(config) { expression.right?.isBooleanConstant() == true && expression.left?.getType(bindingContext)?.isBooleanOrNullableBoolean() == true ) { - if (expression.right?.text == "true") { - report( - CodeSmell( - issue, - Entity.from(expression), - "The nullable boolean check `${expression.text}` should use `!= false` rather than `?: true`", - ) + val messageSuffix = + if (expression.right?.text == "true") "`!= false` rather than `?: true`" + else "`== true` rather than `?: false`" + report( + CodeSmell( + issue = issue, + entity = Entity.from(expression), + message = "The nullable boolean check `${expression.text}` should use $messageSuffix", ) - } else { - report( - CodeSmell( - issue, - Entity.from(expression), - "The nullable boolean check `${expression.text}` should use `== true` rather than `?: false`", - ) - ) - } + ) } super.visitBinaryExpression(expression) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambda.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambda.kt index afe2e62c442a..c4bbb2625272 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambda.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambda.kt @@ -102,7 +102,8 @@ class ObjectLiteralToLambda(config: Config = Config.empty) : Rule(config) { if ( declaration.name == null && bindingContext.getType(expression) - ?.singleSuperTypeOrNull()?.couldBeSamInterface == true && + ?.singleSuperTypeOrNull() + ?.couldBeSamInterface == true && declaration.hasConvertibleMethod() ) { report(CodeSmell(issue, Entity.from(expression), issue.description)) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantExplicitType.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantExplicitType.kt index bf41d0411310..8b28cd4f1231 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantExplicitType.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantExplicitType.kt @@ -7,6 +7,7 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.psi.KtCallExpression @@ -43,6 +44,7 @@ import org.jetbrains.kotlin.types.typeUtil.isLong * } * */ +@RequiresTypeResolution class RedundantExplicitType(config: Config) : Rule(config) { override val issue = Issue( diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt index 2c7fb1a8c3ff..d0ffdba332c4 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCount.kt @@ -59,8 +59,8 @@ class ReturnCount(config: Config = Config.empty) : Rule(config) { @Configuration("define the maximum number of return statements allowed per function") private val max: Int by config(2) - @Configuration("define functions to be ignored by this check") - private val excludedFunctions: SplitPattern by config("equals") { SplitPattern(it) } + @Configuration("define a list of function names to be ignored by this check") + private val excludedFunctions: SplitPattern by config(listOf("equals")) { SplitPattern(it.joinToString(",")) } @Configuration("if labeled return statements should be ignored") private val excludeLabeled: Boolean by config(false) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt index 644c95d1566c..ad645ea96fe6 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/SerialVersionUIDInSerializableClass.kt @@ -100,7 +100,8 @@ class SerialVersionUIDInSerializableClass(config: Config = Config.empty) : Rule( private fun hasLongAssignment(property: KtProperty): Boolean { val assignmentText = property.children - .singleOrNull { it is KtConstantExpression || it is KtPrefixExpression }?.text + .singleOrNull { it is KtConstantExpression || it is KtPrefixExpression } + ?.text return assignmentText != null && assignmentText.last() == 'L' && assignmentText.substring(0, assignmentText.length - 1).toLongOrNull() != null } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt index 7d6cbc250cc9..834e95b2f7d7 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt @@ -24,11 +24,13 @@ class StyleGuideProvider : DefaultRuleSetProvider { ruleSetId, listOf( CanBeNonNullable(config), + CascadingCallWrapping(config), ClassOrdering(config), CollapsibleIfStatements(config), DestructuringDeclarationWithTooManyEntries(config), ReturnCount(config), ThrowsCount(config), + TrimMultilineRawString(config), NewLineAtEndOfFile(config), WildcardImport(config), FileParsingRule(config), @@ -98,6 +100,7 @@ class StyleGuideProvider : DefaultRuleSetProvider { UseOrEmpty(config), UseAnyOrNoneInsteadOfFind(config), UnnecessaryBackticks(config), + MaxChainedCallsOnSameLine(config), ) ) } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawString.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawString.kt new file mode 100644 index 000000000000..d2d215ee919e --- /dev/null +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawString.kt @@ -0,0 +1,74 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtStringTemplateExpression +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis + +/** + * All the Raw strings that have more than one line should be followed by `trimMargin()` or `trimIndent()`. + * + * + * """ + * Hello World! + * How are you? + * """ + * + * + * + * """ + * | Hello World! + * | How are you? + * """.trimMargin() + * + * """ + * Hello World! + * How are you? + * """.trimIndent() + * + * """Hello World! How are you?""" + * + */ +class TrimMultilineRawString(val config: Config) : Rule(config) { + override val issue = Issue( + javaClass.simpleName, + Severity.Style, + "Multiline raw strings should be followed by `trimMargin()` or `trimIndent()`.", + Debt.FIVE_MINS + ) + + override fun visitStringTemplateExpression(expression: KtStringTemplateExpression) { + super.visitStringTemplateExpression(expression) + + if (expression.text.lines().count() <= 1) return + + val nextCall = expression.getQualifiedExpressionForSelectorOrThis() + .getQualifiedExpressionForReceiver() + ?.selectorExpression + ?.asKtCallExpression() + ?.calleeExpression + ?.text + + if (nextCall !in trimFunctions) { + report( + CodeSmell( + issue, + Entity.from(expression), + "Multiline raw strings should be followed by `trimMargin()` or `trimIndent()`", + ) + ) + } + } +} + +private fun KtExpression.asKtCallExpression(): KtCallExpression? = this as? KtCallExpression + +private val trimFunctions = listOf("trimIndent", "trimMargin") diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt index 5d4e526a5497..84487eb3929f 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClass.kt @@ -14,6 +14,7 @@ import io.gitlab.arturbosch.detekt.api.internal.Configuration import io.gitlab.arturbosch.detekt.rules.isAbstract import io.gitlab.arturbosch.detekt.rules.isInternal import io.gitlab.arturbosch.detekt.rules.isProtected +import org.jetbrains.kotlin.com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.psi.KtCallableDeclaration @@ -21,6 +22,8 @@ import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.isAbstract import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassMemberScope +import org.jetbrains.kotlin.types.typeUtil.isInterface /** * This rule inspects `abstract` classes. In case an `abstract class` does not have any concrete members it should be @@ -79,25 +82,13 @@ class UnnecessaryAbstractClass(config: Config = Config.empty) : Rule(config) { super.visitClass(klass) } - @Suppress("ComplexMethod") private fun KtClass.check() { val nameIdentifier = this.nameIdentifier ?: return if (annotationExcluder.shouldExclude(annotationEntries) || isInterface() || !isAbstract()) return val members = members() when { - members.isNotEmpty() -> { - val (abstractMembers, concreteMembers) = members.partition { it.isAbstract() } - if (abstractMembers.isEmpty() && !hasInheritedMember(true)) { - report(CodeSmell(issue, Entity.from(nameIdentifier), noAbstractMember)) - return - } - if (abstractMembers.any { it.isInternal() || it.isProtected() } || hasConstructorParameter()) { - return - } - if (concreteMembers.isEmpty() && !hasInheritedMember(false)) { - report(CodeSmell(issue, Entity.from(nameIdentifier), noConcreteMember)) - } - } + members.isNotEmpty() -> checkMembers(members, nameIdentifier) + hasInheritedMember(true) && isAnyParentAbstract() -> return !hasConstructorParameter() -> report(CodeSmell(issue, Entity.from(nameIdentifier), noConcreteMember)) else -> @@ -105,6 +96,21 @@ class UnnecessaryAbstractClass(config: Config = Config.empty) : Rule(config) { } } + private fun KtClass.checkMembers( + members: List, + nameIdentifier: PsiElement + ) { + val (abstractMembers, concreteMembers) = members.partition { it.isAbstract() } + when { + abstractMembers.isEmpty() && !hasInheritedMember(true) -> + report(CodeSmell(issue, Entity.from(nameIdentifier), noAbstractMember)) + abstractMembers.any { it.isInternal() || it.isProtected() } || hasConstructorParameter() -> + Unit + concreteMembers.isEmpty() && !hasInheritedMember(false) -> + report(CodeSmell(issue, Entity.from(nameIdentifier), noConcreteMember)) + } + } + private fun KtClass.members() = body?.children?.filterIsInstance().orEmpty() + primaryConstructor?.valueParameters?.filter { it.hasValOrVar() }.orEmpty() @@ -122,4 +128,9 @@ class UnnecessaryAbstractClass(config: Config = Config.empty) : Rule(config) { } } } + + private fun KtClass.isAnyParentAbstract() = + (bindingContext[BindingContext.CLASS, this]?.unsubstitutedMemberScope as? LazyClassMemberScope) + ?.supertypes + ?.all { it.isInterface() } == false } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt index 5ed096491015..dc9a4647843b 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApply.kt @@ -10,7 +10,9 @@ import io.gitlab.arturbosch.detekt.api.Severity import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution import io.gitlab.arturbosch.detekt.rules.receiverIsUsed +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtNameReferenceExpression @@ -75,11 +77,20 @@ class UnnecessaryApply(config: Config) : Rule(config) { @Suppress("ReturnCount") private fun KtCallExpression.hasOnlyOneMemberAccessStatement(): Boolean { val lambda = lambdaArguments.firstOrNull()?.getLambdaExpression() ?: return false - val singleStatement = lambda.bodyExpression?.statements?.singleOrNull() ?: return false - if (singleStatement !is KtThisExpression && + var singleStatement = lambda.bodyExpression?.statements?.singleOrNull() ?: return false + + if (singleStatement is KtBinaryExpression) { + if (singleStatement.operationToken !in KtTokens.ALL_ASSIGNMENTS) return false + + // for an assignment expression only consider whether members on the LHS use the apply{} context + singleStatement = singleStatement.left ?: return false + } else if (singleStatement !is KtThisExpression && singleStatement !is KtReferenceExpression && singleStatement !is KtDotQualifiedExpression - ) return false + ) { + return false + } + val lambdaDescriptor = bindingContext[BindingContext.FUNCTION, lambda.functionLiteral] ?: return false return singleStatement.collectDescendantsOfType { val resolvedCall = it.getResolvedCall(bindingContext) diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticks.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticks.kt index 8a496aea3f45..b0463b9e0740 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticks.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryBackticks.kt @@ -42,16 +42,16 @@ class UnnecessaryBackticks(config: Config = Config.empty) : Rule(config) { super.visitKtElement(element) } - @Suppress("ReturnCount") private fun PsiElement.hasUnnecessaryBackticks(): Boolean { - val text = this.text - if (!text.startsWith("`") || !text.endsWith("`")) return false - val unquoted = text.drop(1).dropLast(1) - if (!unquoted.isIdentifier() || unquoted.isKeyword()) return false - val stringTemplateEntry = getStrictParentOfType() - return stringTemplateEntry == null || canPlaceAfterSimpleNameEntry(stringTemplateEntry.nextSibling) + return when { + (!text.startsWith("`") || !text.endsWith("`")) -> false + (!unquoted.isIdentifier() || unquoted.isKeyword()) -> false + else -> canPlaceAfterSimpleNameEntry( + getStrictParentOfType()?.nextSibling + ) + } } private fun String.isKeyword() = this in KEYWORDS || this.all { it == '_' } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt index c33c408b681a..8731a1c92686 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParentheses.kt @@ -7,7 +7,17 @@ import io.gitlab.arturbosch.detekt.api.Entity import io.gitlab.arturbosch.detekt.api.Issue import io.gitlab.arturbosch.detekt.api.Rule import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.config +import io.gitlab.arturbosch.detekt.api.internal.Configuration +import org.jetbrains.kotlin.com.intellij.psi.PsiElement +import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.parsing.KotlinExpressionParsing.Precedence +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtIsExpression import org.jetbrains.kotlin.psi.KtParenthesizedExpression import org.jetbrains.kotlin.psi.KtPsiUtil @@ -46,17 +56,97 @@ class UnnecessaryParentheses(config: Config = Config.empty) : Rule(config) { Debt.FIVE_MINS ) + @Configuration( + "allow parentheses when not strictly required but precedence may be unclear, such as `(a && b) || c`" + ) + private val allowForUnclearPrecedence: Boolean by config(defaultValue = false) + + @Suppress("ReturnCount") override fun visitParenthesizedExpression(expression: KtParenthesizedExpression) { super.visitParenthesizedExpression(expression) - if (expression.expression == null) return + val inner = expression.expression ?: return + val outer = expression.parent + + if (outer is KtDelegatedSuperTypeEntry) return + + if (!KtPsiUtil.areParenthesesUseless(expression)) return + + if (allowForUnclearPrecedence && inner.isBinaryOperationPrecedenceUnclearWithParent()) return + + val message = "Parentheses in ${expression.text} are unnecessary and can be replaced with: " + + KtPsiUtil.deparenthesize(expression)?.text + report(CodeSmell(issue, Entity.from(expression), message)) + } + + companion object { + /** + * Map from operators to a set of other operators between which precedence can be unclear. + * + * This is built from a mapping of [Precedence] to other, greater, [Precedence](s) which should be considered + * unclear when mixed as child binary expressions. + */ + @Suppress("CommentOverPrivateProperty") + private val childToUnclearPrecedenceParentsMapping: Map> = arrayOf( + Precedence.ELVIS to arrayOf( + Precedence.EQUALITY, // (a ?: b) == c + Precedence.COMPARISON, // (a ?: b) > c + Precedence.IN_OR_IS, // (a ?: b) in c + ), + + Precedence.SIMPLE_NAME to arrayOf( + Precedence.ELVIS, // a ?: (b to c) + Precedence.SIMPLE_NAME, // (a to b) to c + ), + + // (a * b) + c + Precedence.MULTIPLICATIVE to arrayOf(Precedence.ADDITIVE), + + // (a && b) || c + Precedence.CONJUNCTION to arrayOf(Precedence.DISJUNCTION), + ) + .onEach { (child, parents) -> + parents.forEach { check(child <= it) } + } + .flatMap { (child, parents) -> + child.operations.types.map { childOp -> + childOp to parents.flatMapTo(mutableSetOf()) { parentOp -> parentOp.operations.types.toList() } + } + } + .toMap() + + /** + * Retrieves the [IElementType] of the binary operation from this element if it is a non-assignment binary + * expression, or null otherwise. + */ + private fun PsiElement.binaryOp(): IElementType? { + return when (this) { + is KtBinaryExpression -> + operationReference.takeUnless { operationToken in KtTokens.ALL_ASSIGNMENTS } + is KtBinaryExpressionWithTypeRHS -> operationReference + is KtIsExpression -> operationReference + else -> null + }?.getReferencedNameElementType() + } + + /** + * Returns either the parent of this [KtExpression] or its first parent expression which is not a + * [KtParenthesizedExpression]. + */ + private fun KtExpression.firstNonParenParent(): PsiElement? { + return generateSequence(parent) { (it as? KtParenthesizedExpression)?.parent } + .firstOrNull { it !is KtParenthesizedExpression } + } - if (expression.parent is KtDelegatedSuperTypeEntry) return + /** + * Determines whether this is a binary expression whose operation precedence is unclear with the parent binary + * operation per [childToUnclearPrecedenceParentsMapping]. + */ + private fun KtExpression.isBinaryOperationPrecedenceUnclearWithParent(): Boolean { + val innerOp = binaryOp() ?: return false + val outerOp = firstNonParenParent()?.binaryOp() ?: return false - if (KtPsiUtil.areParenthesesUseless(expression)) { - val message = "Parentheses in ${expression.text} are unnecessary and can be replaced with: " + - "${KtPsiUtil.deparenthesize(expression)?.text}" - report(CodeSmell(issue, Entity.from(expression), message)) + return childToUnclearPrecedenceParentsMapping[innerOp]?.contains(outerOp) == true } } } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt index e5b1853974e7..6da0c9505299 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImports.kt @@ -54,26 +54,44 @@ class UnusedImports(config: Config) : Rule(config) { private val staticReferences = mutableSetOf() private val namedReferencesInKDoc = mutableSetOf() + private val namedReferencesAsString: Set by lazy { + namedReferences.mapTo(mutableSetOf()) { it.text.trim('`') } + } + private val staticReferencesAsString: Set by lazy { + staticReferences.mapTo(mutableSetOf()) { it.text.trim('`') } + } + private val fqNames: Set by lazy { + namedReferences.mapNotNullTo(mutableSetOf()) { it.fqNameOrNull() } + } + + /** + * All [namedReferences] whose [KtReferenceExpression.fqNameOrNull] cannot be resolved + * mapped to their text. String matches to such references shouldn't be marked as unused + * imports since they could match the unknown value being imported. + */ + @Suppress("CommentOverPrivateProperty") + private val unresolvedNamedReferencesAsString: Set by lazy { + namedReferences.mapNotNullTo(mutableSetOf()) { + if (it.fqNameOrNull() == null) it.text.trim('`') else null + } + } + fun unusedImports(): List { fun KtImportDirective.isFromSamePackage() = importedFqName?.parent() == currentPackage && alias == null @Suppress("ReturnCount") fun KtImportDirective.isNotUsed(): Boolean { - val namedReferencesAsString = namedReferences.map { it.text.trim('`') } - val staticReferencesAsString = staticReferences.map { it.text.trim('`') } if (aliasName in (namedReferencesInKDoc + namedReferencesAsString)) return false val identifier = identifier() if (identifier in namedReferencesInKDoc || identifier in staticReferencesAsString) return false return if (bindingContext == BindingContext.EMPTY) { identifier !in namedReferencesAsString } else { - val fqNames = namedReferences.mapNotNull { - val descriptor = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, it] - ?: bindingContext[BindingContext.REFERENCE_TARGET, it] - descriptor?.getImportableDescriptor()?.fqNameOrNull() - } - importPath?.fqName?.let { it !in fqNames } == true + val fqNameUsed = importPath?.fqName?.let { it in fqNames } == true + val unresolvedNameUsed = identifier in unresolvedNamedReferencesAsString + + !fqNameUsed && !unresolvedNameUsed } } @@ -135,6 +153,12 @@ class UnusedImports(config: Config) : Rule(config) { namedReferencesInKDoc.add(str.split(".")[0]) } } + + private fun KtReferenceExpression.fqNameOrNull(): FqName? { + val descriptor = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this] + ?: bindingContext[BindingContext.REFERENCE_TARGET, this] + return descriptor?.getImportableDescriptor()?.fqNameOrNull() + } } companion object { diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt index 592499c2e768..9180de718ad6 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt @@ -153,7 +153,7 @@ private class UnusedFunctionVisitor( else -> emptyList() } unusedFunctions.map { - CodeSmell(issue, Entity.from(it), "Private function `$functionName` is unused.") + CodeSmell(issue, Entity.atName(it), "Private function `$functionName` is unused.") } } } @@ -212,7 +212,7 @@ private class UnusedParameterVisitor(allowedNames: Regex) : UnusedMemberVisitor( override fun getUnusedReports(issue: Issue): List { return unusedParameters.map { - CodeSmell(issue, Entity.from(it), "Function parameter `${it.nameAsSafeName.identifier}` is unused.") + CodeSmell(issue, Entity.atName(it), "Function parameter `${it.nameAsSafeName.identifier}` is unused.") } } @@ -284,7 +284,7 @@ private class UnusedPropertyVisitor(allowedNames: Regex) : UnusedMemberVisitor(a .map { CodeSmell( issue, - Entity.from(it), + Entity.atName(it), "Private property `${it.nameAsSafeName.identifier}` is unused." ) } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UselessCallOnNotNull.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UselessCallOnNotNull.kt index 0c12e3d61e85..8f6e0eb6a920 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UselessCallOnNotNull.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UselessCallOnNotNull.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall import org.jetbrains.kotlin.resolve.calls.util.getType import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull -import org.jetbrains.kotlin.types.ErrorType +import org.jetbrains.kotlin.types.error.ErrorType import org.jetbrains.kotlin.types.isNullable /* diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullableSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullableSpec.kt index d0e67b42caf9..4b20456b0b4e 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullableSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CanBeNonNullableSpec.kt @@ -897,6 +897,52 @@ class CanBeNonNullableSpec(val env: KotlinCoreEnvironment) { assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1) } + @Test + fun `does report null-check returning unit type`() { + val code = """ + fun foo(a: Int?) { + if (a == null) return + println(a) + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `does report null-check returning unit type in block`() { + val code = """ + fun foo(a: Int?) { + if (a == null) { return } + println(a) + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `does not report guard statement with side effect ahead`() { + val code = """ + fun foo(a: Int?) { + println("side effect") + if (a == null) return + println(a) + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(0) + } + + @Test + fun `does not report null-check returning non-unit type`() { + val code = """ + fun foo(a: Int?): Int { + if (a == null) return 0 + println(a) + return a + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(0) + } + @Test fun `does not report when the parameter is checked on non-nullity with an else statement`() { val code = """ diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrappingSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrappingSpec.kt new file mode 100644 index 000000000000..a9c141253c98 --- /dev/null +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/CascadingCallWrappingSpec.kt @@ -0,0 +1,178 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.test.TestConfig +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.compileAndLint +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +class CascadingCallWrappingSpec { + private val subject = CascadingCallWrapping(Config.empty) + + @Test + fun `reports missing wrapping`() { + val code = """ + val a = 0 + .plus(0).plus(0).plus(0) + """ + + assertThat(subject.compileAndLint(code)) + .hasSize(1) + .hasTextLocations(8 to 30) + .first() + .hasMessage("Chained call `plus(0)` should be wrapped to a new line since preceding calls were.") + } + + @Test + fun `does not report when chained calls are on a single line`() { + val code = """ + val a = 0.plus(0).plus(0) + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does not report wrapped calls`() { + val code = """ + val a = 0 + .plus(0) + .plus(0) + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does not report unwrapped initial calls`() { + val code = """ + val a = 0.plus(0).plus(0) + .plus(0) + .plus(0) + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports missing wrapping for safe qualified calls`() { + val code = """ + val a = 0 + ?.plus(0)?.plus(0) + """ + + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `reports missing wrapping for calls with non-null assertions`() { + val code = """ + val a = 0!! + .plus(0)!!.plus(0) + """ + + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `reports missing wrapping for properties`() { + val code = """ + val a = "" + .plus("").length + + val b = "" + .length.plus(0) + """ + + assertThat(subject.compileAndLint(code)).hasSize(2) + } + + @Nested + inner class `with multiline calls` { + @Test + fun `does not report with wrapping`() { + val code = """ + val a = 0 + .plus( + 0 + ) + .let { + 0 + } + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports missing wrapping`() { + val code = """ + val a = 0 + .plus( + 0 + ) + .let { + 0 + }.plus( + 0 + ) + """ + + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `does not report when calls are multiline but never wrapped`() { + val code = """ + val a = 0.plus( + 0 + ).let { + 0 + } + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does not report for single multiline call`() { + val code = """ + val a = 0.plus( + 0 + ) + """ + + assertThat(subject.compileAndLint(code)).isEmpty() + } + } + + @Nested + inner class `with elvis operators` { + private val subjectIncludingElvis = CascadingCallWrapping(TestConfig(mapOf("includeElvis" to true))) + private val subjectExcludingElvis = CascadingCallWrapping(TestConfig(mapOf("includeElvis" to false))) + + @Test + fun `does not report with wrapping`() { + val code = """ + val a = 0 + .plus(0) + ?: 0 + """ + + assertThat(subjectIncludingElvis.compileAndLint(code)).isEmpty() + assertThat(subjectExcludingElvis.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports missing wrapping`() { + val code = """ + val a = 0 + .plus(0) ?: 0 + """ + + assertThat(subjectIncludingElvis.compileAndLint(code)).hasSize(1) + assertThat(subjectExcludingElvis.compileAndLint(code)).isEmpty() + } + } +} diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt index d78b0e82f742..cdf1fb497d93 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/DataClassContainsFunctionsSpec.kt @@ -29,11 +29,18 @@ class DataClassContainsFunctionsSpec { } @Test - fun `reports valid data class without conversion function`() { + fun `reports valid data class without conversion function string`() { val config = TestConfig(mapOf(CONVERSION_FUNCTION_PREFIX to "")) val rule = DataClassContainsFunctions(config) assertThat(rule.compileAndLint(code)).hasSize(2) } + + @Test + fun `reports valid data class without conversion function list`() { + val config = TestConfig(mapOf(CONVERSION_FUNCTION_PREFIX to emptyList())) + val rule = DataClassContainsFunctions(config) + assertThat(rule.compileAndLint(code)).hasSize(2) + } } @Test diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethodSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethodSpec.kt index c6d0394e1cbf..2456dce4646f 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethodSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ExplicitCollectionElementAccessMethodSpec.kt @@ -296,6 +296,30 @@ class ExplicitCollectionElementAccessMethodSpec { } } + @Nested + inner class `Java non-collection types` { + @Test + fun `does not report ByteBuffer get`() { + val code = """ + fun f() { + val buffer = java.nio.ByteBuffer() + buffer.get(byteArrayOf(0x42)) + } + """ + assertThat(subject.lintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not report Field get`() { + val code = """ + fun f(field: java.lang.reflect.Field) { + val value = field.get(null) // access static field + } + """ + assertThat(subject.lintWithContext(env, code)).isEmpty() + } + } + @Nested inner class `custom operators` { @@ -438,28 +462,14 @@ class ExplicitCollectionElementAccessMethodSpec { @Nested @KotlinCoreEnvironmentTest(additionalJavaSourcePaths = ["java"]) inner class WithAdditionalJavaSources(val env: KotlinCoreEnvironment) { - @Test - fun `reports setter from java with 2 or less parameters`() { - // this test case ensures that the test environment are set up correctly. + fun `does not report setters defined in java which are unlikely to be collection accessors`() { val code = """ import com.example.fromjava.Rect fun foo() { val rect = Rect() rect.set(0, 1) - } - """ - assertThat(subject.lintWithContext(env, code)).hasSize(1) - } - - @Test - fun `does not report if the function has 3 or more arguments and it's defined in java - #4288`() { - val code = """ - import com.example.fromjava.Rect - - fun foo() { - val rect = Rect() rect.set(0, 1, 2) } """ diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt index 4e89ca8ef308..18370f8a8077 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenImportSpec.kt @@ -1,7 +1,9 @@ package io.gitlab.arturbosch.detekt.rules.style +import io.gitlab.arturbosch.detekt.api.ValueWithReason import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint +import io.gitlab.arturbosch.detekt.test.toConfig import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test @@ -29,43 +31,61 @@ class ForbiddenImportSpec { @Test fun `should report nothing when imports are blank`() { - val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to " "))).lint(code) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf(" ")))).lint(code) assertThat(findings).isEmpty() } @Test fun `should report nothing when imports do not match`() { - val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to "org.*"))).lint(code) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("org.*")))).lint(code) assertThat(findings).isEmpty() } @Test @DisplayName("should report kotlin.* when imports are kotlin.*") fun reportKotlinWildcardImports() { - val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to "kotlin.*"))).lint(code) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("kotlin.*")))).lint(code) + assertThat(findings) + .extracting("message") + .containsExactlyInAnyOrder( + "The import `kotlin.jvm.JvmField` has been forbidden in the detekt config.", + "The import `kotlin.SinceKotlin` has been forbidden in the detekt config.", + ) + } + + @Test + @DisplayName("should report kotlin.* when imports are kotlin.* with reasons") + fun reportKotlinWildcardImports2() { + val config = TestConfig(mapOf(IMPORTS to listOf(ValueWithReason("kotlin.*", "I'm just joking!").toConfig()))) + val findings = ForbiddenImport(config).lint(code) assertThat(findings).hasSize(2) + assertThat(findings[0].message) + .isEqualTo("The import `kotlin.jvm.JvmField` has been forbidden: I'm just joking!") + assertThat(findings[1].message) + .isEqualTo("The import `kotlin.SinceKotlin` has been forbidden: I'm just joking!") } @Test @DisplayName("should report kotlin.SinceKotlin when specified via fully qualified name") fun reportKotlinSinceKotlinWhenFqdnSpecified() { - val findings = - ForbiddenImport(TestConfig(mapOf(IMPORTS to "kotlin.SinceKotlin"))).lint(code) - assertThat(findings).hasSize(1) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("kotlin.SinceKotlin")))).lint(code) + assertThat(findings) + .hasSize(1) } @Test @DisplayName("should report kotlin.SinceKotlin and kotlin.jvm.JvmField when specified via fully qualified names") fun reportMultipleConfiguredImportsCommaSeparated() { val findings = - ForbiddenImport(TestConfig(mapOf(IMPORTS to "kotlin.SinceKotlin,kotlin.jvm.JvmField"))).lint( - code - ) + ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("kotlin.SinceKotlin", "kotlin.jvm.JvmField")))) + .lint(code) assertThat(findings).hasSize(2) } @Test - @DisplayName("should report kotlin.SinceKotlin and kotlin.jvm.JvmField when specified via fully qualified names list") + @DisplayName( + "should report kotlin.SinceKotlin and kotlin.jvm.JvmField when specified via fully qualified names list" + ) fun reportMultipleConfiguredImportsInList() { val findings = ForbiddenImport( @@ -81,14 +101,14 @@ class ForbiddenImportSpec { @Test @DisplayName("should report kotlin.SinceKotlin when specified via kotlin.Since*") fun reportsKotlinSinceKotlinWhenSpecifiedWithWildcard() { - val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to "kotlin.Since*"))).lint(code) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("kotlin.Since*")))).lint(code) assertThat(findings).hasSize(1) } @Test @DisplayName("should report all of com.example.R.string, net.example.R.dimen, and net.example.R.dimension") fun preAndPostWildcard() { - val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to "*.R.*"))).lint(code) + val findings = ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("*.R.*")))).lint(code) assertThat(findings).hasSize(3) } @@ -96,7 +116,7 @@ class ForbiddenImportSpec { @DisplayName("should report net.example.R.dimen but not net.example.R.dimension") fun doNotReportSubstringOfFqdn() { val findings = - ForbiddenImport(TestConfig(mapOf(IMPORTS to "net.example.R.dimen"))).lint(code) + ForbiddenImport(TestConfig(mapOf(IMPORTS to listOf("net.example.R.dimen")))).lint(code) assertThat(findings).hasSize(1) } @@ -112,5 +132,9 @@ class ForbiddenImportSpec { val findings = ForbiddenImport(TestConfig(mapOf(FORBIDDEN_PATTERNS to "net.*R|com.*expiremental"))).lint(code) assertThat(findings).hasSize(2) + assertThat(findings[0].message) + .isEqualTo("The import `net.example.R.dimen` has been forbidden in the detekt config.") + assertThat(findings[1].message) + .isEqualTo("The import `net.example.R.dimension` has been forbidden in the detekt config.") } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCallSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCallSpec.kt index 0edded786989..1102c0eb9fbb 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCallSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenMethodCallSpec.kt @@ -23,11 +23,18 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { } """ val findings = ForbiddenMethodCall(TestConfig()).compileAndLintWithContext(env, code) - assertThat(findings).hasSize(2) - assertThat(findings).hasSourceLocations( - SourceLocation(2, 5), - SourceLocation(3, 5) - ) + + assertThat(findings) + .hasSize(2) + .hasStartSourceLocations( + SourceLocation(2, 5), + SourceLocation(3, 5), + ) + .extracting("message") + .containsExactly( + "The method `kotlin.io.print` has been forbidden: print does not allow you to configure the output stream. Use a logger instead.", + "The method `kotlin.io.println` has been forbidden: println does not allow you to configure the output stream. Use a logger instead.", + ) } @Test @@ -38,11 +45,9 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { System.out.println("hello") } """ - val findings = - ForbiddenMethodCall(TestConfig(mapOf(METHODS to " "))).compileAndLintWithContext( - env, - code - ) + val findings = ForbiddenMethodCall( + TestConfig(mapOf(METHODS to listOf(" "))) + ).compileAndLintWithContext(env, code) assertThat(findings).isEmpty() } @@ -112,22 +117,6 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { assertThat(findings).hasTextLocations(48 to 64, 76 to 80) } - @Test - fun `should report multiple different methods config with sting`() { - val code = """ - import java.lang.System - fun main() { - System.out.println("hello") - System.gc() - } - """ - val findings = ForbiddenMethodCall( - TestConfig(mapOf(METHODS to "java.io.PrintStream.println, java.lang.System.gc")) - ).compileAndLintWithContext(env, code) - assertThat(findings).hasSize(2) - assertThat(findings).hasTextLocations(48 to 64, 76 to 80) - } - @Test fun `should report equals operator`() { val code = """ @@ -200,8 +189,9 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { val findings = ForbiddenMethodCall( TestConfig(mapOf(METHODS to listOf("java.time.LocalDate.now()"))) ).compileAndLintWithContext(env, code) - assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(5, 26) + assertThat(findings).hasStartSourceLocation(5, 26) + assertThat(findings[0]) + .hasMessage("The method `java.time.LocalDate.now()` has been forbidden in the detekt config.") } @Test @@ -219,7 +209,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { TestConfig(mapOf(METHODS to listOf("java.time.LocalDate.now(java.time.Clock)"))) ).compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(6, 27) + assertThat(findings).hasStartSourceLocation(6, 27) } @Test @@ -234,7 +224,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { TestConfig(mapOf(METHODS to listOf("java.time.LocalDate.of(kotlin.Int, kotlin.Int, kotlin.Int)"))) ).compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 26) + assertThat(findings).hasStartSourceLocation(3, 26) } @Test @@ -249,7 +239,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { TestConfig(mapOf(METHODS to listOf("java.time.LocalDate.of(kotlin.Int,kotlin.Int,kotlin.Int)"))) ).compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 26) + assertThat(findings).hasStartSourceLocation(3, 26) } @Test @@ -267,7 +257,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { TestConfig(mapOf(METHODS to listOf("io.gitlab.arturbosch.detekt.rules.style.`some, test`()"))) ).compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(6, 13) + assertThat(findings).hasStartSourceLocation(6, 13) } @Test @@ -290,7 +280,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { ) ).compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(6, 13) + assertThat(findings).hasStartSourceLocation(6, 13) } @Test @@ -429,7 +419,7 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { ).compileAndLintWithContext(env, code) assertThat(findings) .hasSize(1) - .hasSourceLocation(5, 16) + .hasStartSourceLocation(5, 16) } @Test @@ -439,7 +429,83 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) { ).compileAndLintWithContext(env, code) assertThat(findings) .hasSize(1) - .hasSourceLocation(6, 9) + .hasStartSourceLocation(6, 9) + } + } + + @Nested + inner class `Java getter calls` { + + @Test + fun `should report Java getter call`() { + val code = """ + import java.util.Calendar + + fun main() { + val calendar = Calendar.getInstance() + val day = calendar.getFirstDayOfWeek() + } + """ + val findings = + ForbiddenMethodCall(TestConfig(mapOf(METHODS to listOf("java.util.Calendar.getFirstDayOfWeek")))).compileAndLintWithContext( + env, + code + ) + assertThat(findings).hasSize(1) } + + @Test + fun `should report property getters call`() { + val code = """ + import java.util.Calendar + + fun main() { + val calendar = Calendar.getInstance() + val day = calendar.firstDayOfWeek + } + """ + val findings = + ForbiddenMethodCall(TestConfig(mapOf(METHODS to listOf("java.util.Calendar.getFirstDayOfWeek")))).compileAndLintWithContext( + env, + code + ) + assertThat(findings).hasSize(1) + } + } + + @Test + fun `should report property setters call`() { + val code = """ + import java.util.Calendar + + fun main() { + val calendar = Calendar.getInstance() + calendar.firstDayOfWeek = 1 + } + """ + val findings = + ForbiddenMethodCall(TestConfig(mapOf(METHODS to listOf("java.util.Calendar.setFirstDayOfWeek")))).compileAndLintWithContext( + env, + code + ) + assertThat(findings).hasSize(1) + } + + @Test + fun `should report reference call`() { + val code = """ + import java.util.Calendar + + fun main() { + val calendar = Calendar.getInstance() + calendar.let(calendar::compareTo) + } + """ + val findings = + ForbiddenMethodCall(TestConfig(mapOf(METHODS to listOf("java.util.Calendar.compareTo")))).compileAndLintWithContext( + env, + code + ) + assertThat(findings).hasSize(1) } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenSuppressSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenSuppressSpec.kt index 668b7c941473..3fd6714e5c46 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenSuppressSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ForbiddenSuppressSpec.kt @@ -24,7 +24,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 1) + assertThat(findings).hasStartSourceLocation(3, 1) assertThat(findings.first()).hasMessage( "Cannot @Suppress rule \"ARule\" due to the current configuration." ) @@ -38,7 +38,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 1) assertThat(findings.first()).hasMessage( "Cannot @Suppress rule \"ARule\" due to the current configuration." ) @@ -54,7 +54,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 1) + assertThat(findings).hasStartSourceLocation(3, 1) assertThat(findings.first()).hasMessage( "Cannot @Suppress rule \"ARule\" due to the current configuration." ) @@ -72,7 +72,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 5) + assertThat(findings).hasStartSourceLocation(4, 5) assertThat(findings.first()).hasMessage( "Cannot @Suppress rule \"ARule\" due to the current configuration." ) @@ -133,7 +133,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 1) assertThat(findings.first()).hasMessage( "Cannot @Suppress rules \"ARule\", \"BRule\" " + "due to the current configuration." @@ -150,7 +150,7 @@ internal class ForbiddenSuppressSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 1) + assertThat(findings).hasStartSourceLocation(3, 1) assertThat(findings.first()).hasMessage( "Cannot @Suppress rule \"BRule\" due to the current configuration." ) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt index 9d132d003501..b674cf7dd2fd 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/FunctionOnlyReturningConstantSpec.kt @@ -71,7 +71,9 @@ class FunctionOnlyReturningConstantSpec { } @Test - @DisplayName("does not report excluded annotated function which returns a constant when given \"kotlin.SinceKotlin\"") + @DisplayName( + "does not report excluded annotated function which returns a constant when given \"kotlin.SinceKotlin\"" + ) fun ignoreAnnotatedFunctionWhichReturnsConstantWhenGivenKotlinSinceKotlin() { val config = TestConfig(mapOf(EXCLUDE_ANNOTATED_FUNCTION to "kotlin.SinceKotlin")) val rule = FunctionOnlyReturningConstant(config) @@ -79,7 +81,9 @@ class FunctionOnlyReturningConstantSpec { } @Test - @DisplayName("does not report excluded annotated function which returns a constant when given listOf(\"kotlin.SinceKotlin\")") + @DisplayName( + "does not report excluded annotated function which returns a constant when given listOf(\"kotlin.SinceKotlin\")" + ) fun ignoreAnnotatedFunctionWhichReturnsConstantWhenGivenListOfKotlinSinceKotlin() { val config = TestConfig(mapOf(EXCLUDE_ANNOTATED_FUNCTION to listOf("kotlin.SinceKotlin"))) val rule = FunctionOnlyReturningConstant(config) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt index 3075bed107d0..ea9d7c09b4b2 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MagicNumberSpec.kt @@ -39,7 +39,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 15) + assertThat(findings).hasStartSourceLocation(1, 15) } } @@ -73,7 +73,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 13) + assertThat(findings).hasStartSourceLocation(1, 13) } } @@ -107,7 +107,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 14) + assertThat(findings).hasStartSourceLocation(1, 14) } } @@ -124,7 +124,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 15) + assertThat(findings).hasStartSourceLocation(1, 15) } } @@ -135,7 +135,7 @@ class MagicNumberSpec { @Test fun `should be reported by default`() { val findings = MagicNumber().lint(code) - assertThat(findings).hasSourceLocation(1, 15) + assertThat(findings).hasStartSourceLocation(1, 15) } @Test @@ -154,14 +154,14 @@ class MagicNumberSpec { fun `should not be ignored when ignoredNumbers contains 2 but not -2`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to listOf("1", "2", "3", "-1", "0")))) .lint(code) - assertThat(findings).hasSourceLocation(1, 15) + assertThat(findings).hasStartSourceLocation(1, 15) } @Test fun `should not be ignored when ignoredNumbers contains 2 but not -2 config with string`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to "1,2,3,-1,0"))) .lint(code) - assertThat(findings).hasSourceLocation(1, 15) + assertThat(findings).hasStartSourceLocation(1, 15) } } @@ -195,7 +195,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 16) + assertThat(findings).hasStartSourceLocation(1, 16) } } @@ -229,7 +229,7 @@ class MagicNumberSpec { @Test fun `should be reported when ignoredNumbers is empty`() { val findings = MagicNumber(TestConfig(mapOf(IGNORE_NUMBERS to emptyList()))).lint(code) - assertThat(findings).hasSourceLocation(1, 13) + assertThat(findings).hasStartSourceLocation(1, 13) } } @@ -291,7 +291,7 @@ class MagicNumberSpec { @Test fun `should be reported by default`() { val findings = MagicNumber().lint(code) - assertThat(findings).hasSourceLocation(1, 13) + assertThat(findings).hasStartSourceLocation(1, 13) } @Test @@ -321,7 +321,7 @@ class MagicNumberSpec { fun `should be reported`() { val findings = MagicNumber().lint(code) assertThat(findings) - .hasSourceLocations( + .hasStartSourceLocations( SourceLocation(1, 17), SourceLocation(1, 21), SourceLocation(1, 24), @@ -345,7 +345,7 @@ class MagicNumberSpec { @Test fun `should be reported`() { val findings = MagicNumber().lint(code) - assertThat(findings).hasSourceLocations( + assertThat(findings).hasStartSourceLocations( SourceLocation(3, 9), SourceLocation(3, 21), SourceLocation(4, 9), @@ -405,7 +405,7 @@ class MagicNumberSpec { @Test fun `should be reported by default`() { val findings = MagicNumber().lint(code) - assertThat(findings).hasSourceLocation(1, 12) + assertThat(findings).hasStartSourceLocation(1, 12) } @Test @@ -486,7 +486,7 @@ class MagicNumberSpec { val findings = MagicNumber(config).lint(code) assertThat(findings) - .hasSourceLocations( + .hasStartSourceLocations( SourceLocation(1, 17), SourceLocation(3, 24), SourceLocation(4, 33), @@ -601,7 +601,7 @@ class MagicNumberSpec { ) val findings = MagicNumber(config).lint(code) - assertThat(findings).hasSourceLocation(4, 35) + assertThat(findings).hasStartSourceLocation(4, 35) } @Test @@ -616,7 +616,7 @@ class MagicNumberSpec { val findings = MagicNumber(config).lint(code) assertThat(findings) - .hasSourceLocations( + .hasStartSourceLocations( SourceLocation(4, 35), SourceLocation(5, 43) ) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLineSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLineSpec.kt new file mode 100644 index 000000000000..f1240d13bfb0 --- /dev/null +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxChainedCallsOnSameLineSpec.kt @@ -0,0 +1,145 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest +import io.gitlab.arturbosch.detekt.test.TestConfig +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext +import io.gitlab.arturbosch.detekt.test.lint +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.junit.jupiter.api.Test + +@KotlinCoreEnvironmentTest +class MaxChainedCallsOnSameLineSpec(private val env: KotlinCoreEnvironment) { + @Test + fun `does not report 2 calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0.plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not report 3 calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0.plus(0).plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `reports 4 calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0.plus(0).plus(0).plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `reports 4 safe qualified calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0?.plus(0)?.plus(0)?.plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `reports 4 non-null asserted calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0!!.plus(0)!!.plus(0)!!.plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `reports once for 7 calls on a single line with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "val a = 0.plus(0).plus(0).plus(0).plus(0).plus(0).plus(0)" + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `does not report 5 calls on separate lines with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val a = 0 + .plus(0) + .plus(0) + .plus(0) + .plus(0) + """ + + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not report 3 calls on same line with wrapped calls with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val a = 0.plus(0).plus(0) + .plus(0).plus(0).plus(0) + .plus(0).plus(0).plus(0) + """ + + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `reports 4 calls on same line with wrapped calls with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val a = 0.plus(0).plus(0).plus(0) + .plus(0) + .plus(0) + """ + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `reports 4 calls on wrapped line with with a max of 3`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val a = 0 + .plus(0) + .plus(0).plus(0).plus(0).plus(0) + .plus(0) + """ + + assertThat(rule.compileAndLintWithContext(env, code)).hasSize(1) + } + + @Test + fun `does not report long imports`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "import a.b.c.d.e" + + assertThat(rule.lint(code)).isEmpty() + } + + @Test + fun `does not report long package declarations`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = "package a.b.c.d.e" + + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not count package references as chained calls`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val x = kotlin.math.floor(1.0).plus(1).plus(1) + """ + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not count a package reference as chained calls`() { + val rule = MaxChainedCallsOnSameLine(TestConfig(mapOf("maxChainedCalls" to 3))) + val code = """ + val x = kotlin.run { 1 }.plus(1).plus(1) + """ + assertThat(rule.compileAndLintWithContext(env, code)).isEmpty() + } +} diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt index fb2abb65d99f..b9a814dca7f1 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MaxLineLengthSpec.kt @@ -258,7 +258,7 @@ class MaxLineLengthSpec { rule.visit(fileContent) assertThat(rule.findings).hasSize(1) - assertThat(rule.findings).hasSourceLocations(SourceLocation(6, 5)) + assertThat(rule.findings).hasStartSourceLocations(SourceLocation(6, 5)) } } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt index f3786d258b57..97dd7c3da6fc 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/MayBeConstSpec.kt @@ -87,7 +87,7 @@ class MayBeConstSpec { val x = 1 """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(1, 5) ) } @@ -98,7 +98,7 @@ class MayBeConstSpec { @JvmField val x = 1 """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(1, 15) ) } @@ -111,7 +111,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(2, 19) ) } @@ -126,7 +126,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(3, 13) ) } @@ -143,7 +143,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(3, 9) ) } @@ -159,7 +159,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(4, 13) ) } @@ -173,7 +173,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(3, 9) ) } @@ -187,7 +187,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(3, 9) ) } @@ -203,7 +203,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(5, 9) ) } @@ -217,7 +217,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(1).hasSourceLocations( + assertThat(subject.findings).hasSize(1).hasStartSourceLocations( SourceLocation(3, 17) ) } @@ -363,7 +363,7 @@ class MayBeConstSpec { } """ subject.compileAndLint(code) - assertThat(subject.findings).hasSize(3).hasSourceLocations( + assertThat(subject.findings).hasSize(3).hasStartSourceLocations( SourceLocation(4, 13), SourceLocation(7, 17), SourceLocation(11, 13) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt index 85d79712cd38..b1cf36d45ca1 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFileSpec.kt @@ -18,7 +18,7 @@ class NewLineAtEndOfFileSpec { fun `should flag a kt file not containing new line at the end`() { val code = "class Test" assertThat(subject.compileAndLint(code)).hasSize(1) - .hasSourceLocation(1, 11) + .hasStartSourceLocation(1, 11) } @Test diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambdaSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambdaSpec.kt index 7452591d2961..ca0b3e89673e 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambdaSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ObjectLiteralToLambdaSpec.kt @@ -33,7 +33,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(4, 9)) + .hasStartSourceLocations(SourceLocation(4, 9)) } @Test @@ -52,7 +52,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(5, 5)) + .hasStartSourceLocations(SourceLocation(5, 5)) } @Test @@ -73,7 +73,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(6, 9)) + .hasStartSourceLocations(SourceLocation(6, 9)) } @Test @@ -91,7 +91,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(4, 9)) + .hasStartSourceLocations(SourceLocation(4, 9)) } @Test @@ -109,7 +109,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(5, 9)) + .hasStartSourceLocations(SourceLocation(5, 9)) } @Test @@ -130,7 +130,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(7, 5)) + .hasStartSourceLocations(SourceLocation(7, 5)) } @Test @@ -146,7 +146,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(4, 9)) + .hasStartSourceLocations(SourceLocation(4, 9)) } } @@ -337,7 +337,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(1, 9)) + .hasStartSourceLocations(SourceLocation(1, 9)) } @Test @@ -353,7 +353,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(2, 9)) + .hasStartSourceLocations(SourceLocation(2, 9)) } @Test @@ -466,7 +466,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(6, 5)) + .hasStartSourceLocations(SourceLocation(6, 5)) } @Test @@ -489,7 +489,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(7, 9)) + .hasStartSourceLocations(SourceLocation(7, 9)) } @Test @@ -534,7 +534,7 @@ class ObjectLiteralToLambdaSpec { subject.compileAndLintWithContext(env, code) .assert() .hasSize(1) - .hasSourceLocations(SourceLocation(5, 19)) + .hasStartSourceLocations(SourceLocation(5, 19)) } } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt index 05991eed9587..72171b786809 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/OptionalWhenBracesSpec.kt @@ -66,7 +66,7 @@ class OptionalWhenBracesSpec { """ assertThat(subject.compileAndLint(code)) .hasSize(2) - .hasSourceLocations(SourceLocation(7, 17), SourceLocation(10, 17)) + .hasStartSourceLocations(SourceLocation(7, 17), SourceLocation(10, 17)) } @Test @@ -87,7 +87,7 @@ class OptionalWhenBracesSpec { """ assertThat(subject.compileAndLint(code)) .hasSize(1) - .hasSourceLocations(SourceLocation(3, 9)) + .hasStartSourceLocations(SourceLocation(3, 9)) } @Nested diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt index 1bc59f6c5829..b1e473ff2604 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ProtectedMemberInFinalClassSpec.kt @@ -22,7 +22,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 5) + assertThat(findings).hasStartSourceLocation(2, 5) } @Test @@ -37,7 +37,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 5) + assertThat(findings).hasStartSourceLocation(3, 5) } @Test @@ -49,7 +49,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 5) + assertThat(findings).hasStartSourceLocation(2, 5) } @Test @@ -63,7 +63,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 9) + assertThat(findings).hasStartSourceLocation(3, 9) } @Test @@ -77,7 +77,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(2) - assertThat(findings).hasSourceLocations( + assertThat(findings).hasStartSourceLocations( SourceLocation(2, 5), SourceLocation(3, 9) ) @@ -96,7 +96,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(3) - assertThat(findings).hasSourceLocations( + assertThat(findings).hasStartSourceLocations( SourceLocation(2, 5), SourceLocation(2, 5), SourceLocation(4, 13) @@ -116,7 +116,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 13) + assertThat(findings).hasStartSourceLocation(4, 13) } @Test @@ -130,7 +130,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(3, 9) + assertThat(findings).hasStartSourceLocation(3, 9) } @Test @@ -140,7 +140,7 @@ class ProtectedMemberInFinalClassSpec { """ val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(1, 42) + assertThat(findings).hasStartSourceLocation(1, 42) } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantHigherOrderMapUsageSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantHigherOrderMapUsageSpec.kt index d73d3da62697..6d562f0f2e1a 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantHigherOrderMapUsageSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/RedundantHigherOrderMapUsageSpec.kt @@ -24,7 +24,7 @@ class RedundantHigherOrderMapUsageSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 10) + assertThat(findings).hasStartSourceLocation(4, 10) assertThat(findings[0]).hasMessage("This 'map' call can be removed.") } @@ -44,7 +44,7 @@ class RedundantHigherOrderMapUsageSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(5, 10) + assertThat(findings).hasStartSourceLocation(5, 10) assertThat(findings[0]).hasMessage("This 'map' call can be replaced with 'onEach' or 'forEach'.") } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt index 9abd3b37a9b5..1ce28adf704a 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/ReturnCountSpec.kt @@ -347,7 +347,7 @@ class ReturnCountSpec { TestConfig( mapOf( MAX to "2", - EXCLUDED_FUNCTIONS to "test1,test2" + EXCLUDED_FUNCTIONS to listOf("test1", "test2") ) ) ).compileAndLint(code) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawStringSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawStringSpec.kt new file mode 100644 index 000000000000..d09235756ac1 --- /dev/null +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/TrimMultilineRawStringSpec.kt @@ -0,0 +1,87 @@ +@file:Suppress("StringTemplate") + +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.test.compileAndLint +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class TrimMultilineRawStringSpec { + val subject = TrimMultilineRawString(Config.empty) + + @Test + fun `raises multiline raw strings without trim`() { + val code = """ + val a = ${TQ} + Hello world! + ${TQ} + """ + subject.compileAndLint(code) + assertThat(subject.findings).hasSize(1) + } + + @Test + fun `raises multiline raw strings with lenght`() { + val code = """ + val a = ${TQ} + Hello world! + ${TQ}.length + """ + subject.compileAndLint(code) + assertThat(subject.findings).hasSize(1) + } + + @Test + fun `doesn't raise multiline raw strings without trimIndent`() { + val code = """ + val a = ${TQ} + Hello world! + ${TQ}.trimIndent() + """ + subject.compileAndLint(code) + assertThat(subject.findings).isEmpty() + } + + @Test + fun `doesn't raise multiline raw strings without trimMargin`() { + val code = """ + val a = ${TQ} + |Hello world! + ${TQ}.trimMargin() + """ + subject.compileAndLint(code) + assertThat(subject.findings).isEmpty() + } + + @Test + fun `doesn't raise multiline raw strings without trimMargin with parameter`() { + val code = """ + val a = ${TQ} + >Hello world! + ${TQ}.trimMargin(">") + """ + subject.compileAndLint(code) + assertThat(subject.findings).isEmpty() + } + + @Test + fun `don't raise one line raw strings`() { + val code = """ + val a = ${TQ}Hello world!${TQ} + """ + subject.compileAndLint(code) + assertThat(subject.findings).isEmpty() + } + + @Test + fun `doesn't raise if it is not a raw string`() { + val code = """ + val a = "Hello world!" + """ + subject.compileAndLint(code) + assertThat(subject.findings).isEmpty() + } +} + +private const val TQ = "\"\"\"" diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt index ba65e69f96ce..b6b2066444c4 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryAbstractClassSpec.kt @@ -31,7 +31,7 @@ class UnnecessaryAbstractClassSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertFindingMessage(findings, message) - assertThat(findings).hasSourceLocation(1, 16) + assertThat(findings).hasStartSourceLocation(1, 16) } @Nested @@ -41,7 +41,7 @@ class UnnecessaryAbstractClassSpec(val env: KotlinCoreEnvironment) { val code = "abstract class A" val findings = subject.compileAndLintWithContext(env, code) assertFindingMessage(findings, message) - assertThat(findings).hasSourceLocation(1, 16) + assertThat(findings).hasStartSourceLocation(1, 16) } @Test @@ -86,8 +86,37 @@ class UnnecessaryAbstractClassSpec(val env: KotlinCoreEnvironment) { } abstract class B : A() """ + assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + } + + @Test + fun `does not report abstract class that inherits from an abstract class and an interface in that order`() { + val code = """ + interface I + + @Deprecated("We don't care about this first class") + abstract class A { + abstract val i: Int + } + abstract class B: A(), I + """ val findings = subject.compileAndLintWithContext(env, code) - assertFindingMessage(findings, message) + assertThat(findings).isEmpty() + } + + @Test + fun `does not report abstract class that inherits from an interface and an abstract class in that order`() { + val code = """ + interface I + + @Deprecated("We don't care about this first class") + abstract class A { + abstract val i: Int + } + abstract class B: I, A() + """ + val findings = subject.compileAndLintWithContext(env, code) + assertThat(findings).isEmpty() } } @@ -175,7 +204,7 @@ class UnnecessaryAbstractClassSpec(val env: KotlinCoreEnvironment) { val code = "abstract class A(val i: Int)" val findings = subject.compileAndLintWithContext(env, code) assertFindingMessage(findings, message) - assertThat(findings).hasSourceLocation(1, 16) + assertThat(findings).hasStartSourceLocation(1, 16) } @Test @@ -190,7 +219,7 @@ class UnnecessaryAbstractClassSpec(val env: KotlinCoreEnvironment) { val code = "abstract class A(i: Int)" val findings = subject.compileAndLintWithContext(env, code) assertFindingMessage(findings, message) - assertThat(findings).hasSourceLocation(1, 16) + assertThat(findings).hasStartSourceLocation(1, 16) } @Test diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt index cd051c8214ce..b9f6ce081ea5 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryApplySpec.kt @@ -117,12 +117,12 @@ class UnnecessaryApplySpec(val env: KotlinCoreEnvironment) { class C { var prop = 0 } - + fun main() { val list = ArrayList() list.add( if (true) { - C().apply { + C().apply { prop = 1 } } else { @@ -235,6 +235,50 @@ class UnnecessaryApplySpec(val env: KotlinCoreEnvironment) { } } + @Nested + inner class `unnecessary apply expressions that can be changed to assignment` { + @Test + fun `reports apply with a single assignment whose result is unused`() { + assertThat( + subject.compileAndLintWithContext( + env, + """ + class C { + var prop = 0 + } + + fun main() { + val c = C() + c.apply { + prop = 1 + } + } + """ + ) + ).hasSize(1) + } + + @Test + fun `does not report apply with a single assignment whose result is used`() { + assertThat( + subject.compileAndLintWithContext( + env, + """ + class C { + var prop = 0 + } + + fun main() { + val c = C().apply { + prop = 1 + } + } + """ + ) + ).isEmpty() + } + } + @Nested inner class `reported false positives - #1305` { diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt index e896d9c24621..809e94e0bc0d 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnnecessaryParenthesesSpec.kt @@ -1,33 +1,39 @@ package io.gitlab.arturbosch.detekt.rules.style -import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.test.TestConfig import io.gitlab.arturbosch.detekt.test.lint import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource class UnnecessaryParenthesesSpec { - val subject = UnnecessaryParentheses(Config.empty) - - @Test - fun `with unnecessary parentheses on val assignment`() { + @ParameterizedTest + @MethodSource("cases") + fun `with unnecessary parentheses on val assignment`(testCase: RuleTestCase) { val code = "val local = (5)" - assertThat(subject.lint(code)).hasSize(1) + + assertThat(testCase.rule.lint(code)).hasSize(1) } - @Test - fun `with unnecessary parentheses on val assignment operation`() { + @ParameterizedTest + @MethodSource("cases") + fun `with unnecessary parentheses on val assignment operation`(testCase: RuleTestCase) { val code = "val local = (5 + 3)" - assertThat(subject.lint(code)).hasSize(1) + + assertThat(testCase.rule.lint(code)).hasSize(1) } - @Test - fun `with unnecessary parentheses on function call`() { + @ParameterizedTest + @MethodSource("cases") + fun `with unnecessary parentheses on function call`(testCase: RuleTestCase) { val code = "val local = 3.plus((5))" - assertThat(subject.lint(code)).hasSize(1) + + assertThat(testCase.rule.lint(code)).hasSize(1) } - @Test - fun `unnecessary parentheses in other parentheses`() { + @ParameterizedTest + @MethodSource("cases") + fun `unnecessary parentheses in other parentheses`(testCase: RuleTestCase) { val code = """ fun x(a: String, b: String) { if ((a equals b)) { @@ -35,11 +41,13 @@ class UnnecessaryParenthesesSpec { } } """ - assertThat(subject.lint(code)).hasSize(1) + + assertThat(testCase.rule.lint(code)).hasSize(1) } - @Test - fun `does not report unnecessary parentheses around lambdas`() { + @ParameterizedTest + @MethodSource("cases") + fun `does not report unnecessary parentheses around lambdas`(testCase: RuleTestCase) { val code = """ fun function (a: (input: String) -> Unit) { a.invoke("TEST") @@ -49,11 +57,13 @@ class UnnecessaryParenthesesSpec { function({ input -> println(input) }) } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `doesn't report function calls containing lambdas and other parameters`() { + @ParameterizedTest + @MethodSource("cases") + fun `doesn't report function calls containing lambdas and other parameters`(testCase: RuleTestCase) { val code = """ fun function (integer: Int, a: (input: String) -> Unit) { a.invoke("TEST") @@ -63,21 +73,25 @@ class UnnecessaryParenthesesSpec { function(1, { input -> println(input) }) } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `does not report unnecessary parentheses when assigning a lambda to a val`() { + @ParameterizedTest + @MethodSource("cases") + fun `does not report unnecessary parentheses when assigning a lambda to a val`(testCase: RuleTestCase) { val code = """ fun f() { instance.copy(value = { false }) } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `does not report well behaved parentheses`() { + @ParameterizedTest + @MethodSource("cases") + fun `does not report well behaved parentheses`(testCase: RuleTestCase) { val code = """ fun x(a: String, b: String) { if (a equals b) { @@ -85,11 +99,13 @@ class UnnecessaryParenthesesSpec { } } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `does not report well behaved parentheses in super constructors`() { + @ParameterizedTest + @MethodSource("cases") + fun `does not report well behaved parentheses in super constructors`(testCase: RuleTestCase) { val code = """ class TestSpek : SubjectSpek({ describe("a simple test") { @@ -98,11 +114,13 @@ class UnnecessaryParenthesesSpec { } }) """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `does not report well behaved parentheses in constructors`() { + @ParameterizedTest + @MethodSource("cases") + fun `does not report well behaved parentheses in constructors`(testCase: RuleTestCase) { val code = """ class TestSpek({ describe("a simple test") { @@ -111,11 +129,13 @@ class UnnecessaryParenthesesSpec { } }) """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `should not report lambdas within super constructor calls`() { + @ParameterizedTest + @MethodSource("cases") + fun `should not report lambdas within super constructor calls`(testCase: RuleTestCase) { val code = """ class Clazz( private val func: (X, Y) -> Z @@ -123,11 +143,13 @@ class UnnecessaryParenthesesSpec { constructor() : this({ first, second -> true }) } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `should not report call to function with two lambda parameters with one as block body`() { + @ParameterizedTest + @MethodSource("cases") + fun `should not report call to function with two lambda parameters with one as block body`(testCase: RuleTestCase) { val code = """ class Clazz { fun test(first: (Int) -> Unit, second: (Int) -> Unit) { @@ -140,11 +162,13 @@ class UnnecessaryParenthesesSpec { } } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `should not report call to function with two lambda parameters`() { + @ParameterizedTest + @MethodSource("cases") + fun `should not report call to function with two lambda parameters`(testCase: RuleTestCase) { val code = """ class Clazz { fun test(first: (Int) -> Unit, second: (Int) -> Unit) { @@ -157,11 +181,15 @@ class UnnecessaryParenthesesSpec { } } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `should not report call to function with multiple lambdas as parameters but also other parameters`() { + @ParameterizedTest + @MethodSource("cases") + fun `should not report call to function with multiple lambdas as parameters but also other parameters`( + testCase: RuleTestCase, + ) { val code = """ class Clazz { fun test(text: String, first: () -> Unit, second: () -> Unit) { @@ -174,14 +202,133 @@ class UnnecessaryParenthesesSpec { } } """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() } - @Test - fun `should not report interface delegation with parenthesis - #3851`() { + @ParameterizedTest + @MethodSource("cases") + fun `should not report interface delegation with parenthesis - #3851`(testCase: RuleTestCase) { val code = """ class Clazz: Comparable by ("hello".filter { it != 'l' }) """ - assertThat(subject.lint(code)).isEmpty() + + assertThat(testCase.rule.lint(code)).isEmpty() + } + + @ParameterizedTest + @MethodSource("cases") + fun `numeric expressions when precedence is unclear`(testCase: RuleTestCase) { + val code = """ + val a1 = (1 * 2) + 3 + val a2 = (1 / 2) + 3 + val a3 = (1 % 2) + 3 + + val b1 = 3 + (1 * 2) + val b2 = 3 + (1 / 2) + val b3 = 3 + (1 % 2) + + val c = (4 + 5) * 3 // parens required + """ + + assertThat(testCase.rule.lint(code)).hasSize(if (testCase.allowForUnclearPrecedence) 0 else 6) + } + + @ParameterizedTest + @MethodSource("cases") + fun `numeric expressions when precedence is clear`(testCase: RuleTestCase) { + val code = """ + val a1 = (1 + 2) + val a2 = (1 * 2) + val a3 = (1 + 2 * 3) + val b1 = (1 + 2) + 3 + val b2 = (1 * 2) * 3 + """ + + assertThat(testCase.rule.lint(code)).hasSize(5) + } + + @ParameterizedTest + @MethodSource("cases") + fun `boolean expressions when precedence is unclear`(testCase: RuleTestCase) { + val code = """ + val a1 = (true && false) || false + val a2 = (true && false) || (false && true) // 2 warnings when disallowed + val b = false || (true && false) + val c = (true || false) && false // parens required + """ + + assertThat(testCase.rule.lint(code)).hasSize(if (testCase.allowForUnclearPrecedence) 0 else 4) + } + + @ParameterizedTest + @MethodSource("cases") + fun `boolean expressions when precedence is clear`(testCase: RuleTestCase) { + val code = """ + val a1 = (true && false) + val a2 = (true || false) + val a3 = (true && false || false) + val b1 = (true && false) && false + val b2 = (true || false) || false + """ + + assertThat(testCase.rule.lint(code)).hasSize(5) + } + + @ParameterizedTest + @MethodSource("cases") + fun `infix operators when precedence is unclear`(testCase: RuleTestCase) { + val code = """ + val d = (true and false) or false + val e = false or (true and false) // parens required + """ + + assertThat(testCase.rule.lint(code)).hasSize(if (testCase.allowForUnclearPrecedence) 0 else 1) + } + + @ParameterizedTest + @MethodSource("cases") + fun `elvis operators when precedence is unclear`(testCase: RuleTestCase) { + val code = """ + val a1 = null ?: (1 to 2) // parens required + val a2 = (null ?: 1) to 2 + + val b1 = null ?: (1 == 2) // parens required + val b2 = (null ?: 1) == 2 + + val c1 = null ?: (1 > 2) // parens required + val c2 = (null ?: 1) > 2 + + val d1 = null ?: (1 in 2) // parens required + val d2 = (null ?: 1) in 2 + """ + + assertThat(testCase.rule.lint(code)).hasSize(if (testCase.allowForUnclearPrecedence) 0 else 4) + } + + @ParameterizedTest + @MethodSource("cases") + fun `multiple wrapping parentheses`(testCase: RuleTestCase) { + val code = """ + val a = ((false || (((true && false))))) + """ + + assertThat(testCase.rule.lint(code)).hasSize(if (testCase.allowForUnclearPrecedence) 4 else 5) + } + + companion object { + class RuleTestCase(val allowForUnclearPrecedence: Boolean) { + val rule = UnnecessaryParentheses( + TestConfig(mapOf("allowForUnclearPrecedence" to allowForUnclearPrecedence)) + ) + } + + @JvmStatic + fun cases(): List { + return listOf( + RuleTestCase(allowForUnclearPrecedence = false), + RuleTestCase(allowForUnclearPrecedence = true), + ) + } } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt index d9425c640d53..ca6fbf5ca670 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedImportsSpec.kt @@ -634,4 +634,36 @@ class UnusedImportsSpec(val env: KotlinCoreEnvironment) { assertThat(subject.lintWithContext(env, mainFile, additionalFile)).isEmpty() } + + @Test + fun `does not report imports which detekt cannot resolve but have string matches`() { + val mainFile = """ + import x.y.z.foo + import x.y.z.Bar + + fun test() { + foo() + foo("", 123) + foo + + Bar().baz() + } + """ + + assertThat(subject.lintWithContext(env, mainFile)).isEmpty() + } + + @Test + fun `reports imports which detekt cannot resolve and do not have string matches`() { + val mainFile = """ + import x.y.z.foo + import x.y.z.Bar + + fun test() { + 2 + 3 + } + """ + + assertThat(subject.lintWithContext(env, mainFile)).hasSize(2) + } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt index 84cc5bacf1db..ff7a305e5d15 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateClassSpec.kt @@ -23,7 +23,7 @@ class UnusedPrivateClassSpec { val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 1) } @Nested @@ -39,7 +39,7 @@ class UnusedPrivateClassSpec { val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(1, 1) + assertThat(findings).hasStartSourceLocation(1, 1) } @Test @@ -52,7 +52,7 @@ class UnusedPrivateClassSpec { val findings = subject.compileAndLint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 1) + assertThat(findings).hasStartSourceLocation(2, 1) } @Test @@ -435,7 +435,7 @@ class UnusedPrivateClassSpec { """ val findings = UnusedPrivateClass().lint(code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(10, 5) + assertThat(findings).hasStartSourceLocation(10, 5) } } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt index c538acf537bf..f7e39e0cb5d2 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt @@ -1320,8 +1320,8 @@ class UnusedPrivateMemberSpec(val env: KotlinCoreEnvironment) { } """ val findings = subject.compileAndLintWithContext(env, code) - assertThat(findings).hasSize(1).hasSourceLocations( - SourceLocation(3, 5) + assertThat(findings).hasSize(1).hasStartSourceLocations( + SourceLocation(3, 30) ) } } @@ -1593,4 +1593,48 @@ class UnusedPrivateMemberSpec(val env: KotlinCoreEnvironment) { assertThat(subject.lintWithContext(env, code)).hasSize(0) } } + + @Nested + inner class `highlights declaration name` { + @Test + fun function() { + val code = """ + class Test { + /** + * kdoc + */ + private fun foo() = 1 + } + """ + assertThat(subject.lint(code)).hasSize(1).hasStartSourceLocation(5, 17) + } + + @Test + fun property() { + val code = """ + class Test { + /** + * kdoc + */ + private val foo = 1 + } + """ + assertThat(subject.lint(code)).hasSize(1).hasStartSourceLocation(5, 17) + } + + @Test + fun parameter() { + val code = """ + class Test { + fun test( + /** + * kdoc + */ + x: Int + ) = 1 + } + """ + assertThat(subject.lint(code)).hasSize(1).hasStartSourceLocation(6, 9) + } + } } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseCheckOrErrorSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseCheckOrErrorSpec.kt index 28d7ff8e7277..3e67126601fd 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseCheckOrErrorSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseCheckOrErrorSpec.kt @@ -22,7 +22,7 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { if (a < 0) throw IllegalStateException() } """ - assertThat(subject.lint(code)).hasSourceLocation(3, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(3, 16) } @Test @@ -33,7 +33,7 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { if (a < 0) throw IllegalStateException("More details") } """ - assertThat(subject.lint(code)).hasSourceLocation(3, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(3, 16) } @Test @@ -45,7 +45,7 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { else -> throw IllegalStateException() } """ - assertThat(subject.lint(code)).hasSourceLocation(4, 17) + assertThat(subject.lint(code)).hasStartSourceLocation(4, 17) } @Test @@ -56,7 +56,7 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { if (a < 0) throw java.lang.IllegalStateException() } """ - assertThat(subject.lint(code)).hasSourceLocation(3, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(3, 16) } @Test @@ -67,7 +67,7 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { if (a < 0) throw kotlin.IllegalStateException() } """ - assertThat(subject.lint(code)).hasSourceLocation(3, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(3, 16) } @Test @@ -106,13 +106,13 @@ class UseCheckOrErrorSpec(val env: KotlinCoreEnvironment) { @Test fun `reports an issue if the exception thrown as the only action in a function`() { val code = """fun doThrow() = throw IllegalStateException("message")""" - assertThat(subject.lint(code)).hasSourceLocation(1, 17) + assertThat(subject.lint(code)).hasStartSourceLocation(1, 17) } @Test fun `reports an issue if the exception thrown as the only action in a function block`() { val code = """fun doThrow() { throw IllegalStateException("message") }""" - assertThat(subject.lint(code)).hasSourceLocation(1, 17) + assertThat(subject.lint(code)).hasStartSourceLocation(1, 17) } @Test diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIfEmptyOrIfBlankSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIfEmptyOrIfBlankSpec.kt index 539199c3f69c..6955ff5e4795 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIfEmptyOrIfBlankSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIfEmptyOrIfBlankSpec.kt @@ -26,7 +26,7 @@ class UseIfEmptyOrIfBlankSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 29) + assertThat(findings).hasStartSourceLocation(4, 29) assertThat(findings[0]).hasMessage("This 'isBlank' call can be replaced with 'ifBlank'") } @@ -45,7 +45,7 @@ class UseIfEmptyOrIfBlankSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 29) + assertThat(findings).hasStartSourceLocation(4, 29) assertThat(findings[0]).hasMessage("This 'isNotBlank' call can be replaced with 'ifBlank'") } @@ -61,7 +61,7 @@ class UseIfEmptyOrIfBlankSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 29) + assertThat(findings).hasStartSourceLocation(4, 29) assertThat(findings[0]).hasMessage("This 'isEmpty' call can be replaced with 'ifEmpty'") } @@ -80,7 +80,7 @@ class UseIfEmptyOrIfBlankSpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(4, 29) + assertThat(findings).hasStartSourceLocation(4, 29) assertThat(findings[0]).hasMessage("This 'isNotEmpty' call can be replaced with 'ifEmpty'") } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIsNullOrEmptySpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIsNullOrEmptySpec.kt index a0e436052325..b7a6f6844caf 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIsNullOrEmptySpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseIsNullOrEmptySpec.kt @@ -24,7 +24,7 @@ class UseIsNullOrEmptySpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 9) + assertThat(findings).hasStartSourceLocation(2, 9) assertThat(findings[0]).hasMessage( "This 'x == null || x.isEmpty()' can be replaced with 'isNullOrEmpty()' call" ) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmptySpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmptySpec.kt index ea9b2900b854..09d1466dcd26 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmptySpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseOrEmptySpec.kt @@ -22,7 +22,7 @@ class UseOrEmptySpec(val env: KotlinCoreEnvironment) { """ val findings = subject.compileAndLintWithContext(env, code) assertThat(findings).hasSize(1) - assertThat(findings).hasSourceLocation(2, 13) + assertThat(findings).hasStartSourceLocation(2, 13) assertThat(findings[0]).hasMessage("This '?: emptyList()' can be replaced with 'orEmpty()' call") } diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseRequireSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseRequireSpec.kt index 84d11edcc85d..a726d9e96c9f 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseRequireSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UseRequireSpec.kt @@ -22,7 +22,7 @@ class UseRequireSpec(val env: KotlinCoreEnvironment) { doSomething() } """ - assertThat(subject.lint(code)).hasSourceLocation(2, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(2, 16) } @Test @@ -33,7 +33,7 @@ class UseRequireSpec(val env: KotlinCoreEnvironment) { doSomething() } """ - assertThat(subject.lint(code)).hasSourceLocation(2, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(2, 16) } @Test @@ -44,7 +44,7 @@ class UseRequireSpec(val env: KotlinCoreEnvironment) { doSomething() } """ - assertThat(subject.lint(code)).hasSourceLocation(2, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(2, 16) } @Test @@ -55,7 +55,7 @@ class UseRequireSpec(val env: KotlinCoreEnvironment) { doSomething() } """ - assertThat(subject.lint(code)).hasSourceLocation(2, 16) + assertThat(subject.lint(code)).hasStartSourceLocation(2, 16) } @Test diff --git a/detekt-test-utils/build.gradle.kts b/detekt-test-utils/build.gradle.kts index de2a88d0ff52..edbf660c62cd 100644 --- a/detekt-test-utils/build.gradle.kts +++ b/detekt-test-utils/build.gradle.kts @@ -13,3 +13,7 @@ dependencies { testImplementation(libs.assertj) runtimeOnly(libs.kotlin.scriptingCompilerEmbeddable) } + +tasks.apiDump { + notCompatibleWithConfigurationCache("https://github.com/Kotlin/binary-compatibility-validator/issues/95") +} diff --git a/detekt-test-utils/src/main/kotlin/io/github/detekt/test/utils/KtTestCompiler.kt b/detekt-test-utils/src/main/kotlin/io/github/detekt/test/utils/KtTestCompiler.kt index 7cc9c03c3480..37a379112252 100644 --- a/detekt-test-utils/src/main/kotlin/io/github/detekt/test/utils/KtTestCompiler.kt +++ b/detekt-test-utils/src/main/kotlin/io/github/detekt/test/utils/KtTestCompiler.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoots import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots +import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots import org.jetbrains.kotlin.com.intellij.openapi.project.Project import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt @@ -58,6 +59,7 @@ internal object KtTestCompiler : KtCompiler() { addJvmClasspathRoot(kotlinxCoroutinesCorePath()) addJvmClasspathRoots(additionalRootPaths) addJavaSourceRoots(additionalJavaSourceRootPaths) + configureJdkClasspathRoots() } val parentDisposable = Disposer.newDisposable() diff --git a/detekt-test/api/detekt-test.api b/detekt-test/api/detekt-test.api index 6dc7d0b93acd..51940bfa5d92 100644 --- a/detekt-test/api/detekt-test.api +++ b/detekt-test/api/detekt-test.api @@ -7,8 +7,12 @@ public final class io/gitlab/arturbosch/detekt/test/FindingAssert : org/assertj/ public final class io/gitlab/arturbosch/detekt/test/FindingsAssert : org/assertj/core/api/AbstractListAssert { public fun (Ljava/util/List;)V + public final fun hasEndSourceLocation (II)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; + public final fun hasEndSourceLocations ([Lio/gitlab/arturbosch/detekt/api/SourceLocation;)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; public final fun hasSourceLocation (II)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; public final fun hasSourceLocations ([Lio/gitlab/arturbosch/detekt/api/SourceLocation;)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; + public final fun hasStartSourceLocation (II)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; + public final fun hasStartSourceLocations ([Lio/gitlab/arturbosch/detekt/api/SourceLocation;)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; public final fun hasTextLocations ([Ljava/lang/String;)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; public final fun hasTextLocations ([Lkotlin/Pair;)Lio/gitlab/arturbosch/detekt/test/FindingsAssert; public synthetic fun newAbstractIterableAssert (Ljava/lang/Iterable;)Lorg/assertj/core/api/AbstractIterableAssert; @@ -56,6 +60,10 @@ public final class io/gitlab/arturbosch/detekt/test/TestConfig$Companion { public final fun invoke ([Lkotlin/Pair;)Lio/gitlab/arturbosch/detekt/test/TestConfig; } +public final class io/gitlab/arturbosch/detekt/test/TestConfigKt { + public static final fun toConfig (Lio/gitlab/arturbosch/detekt/api/ValueWithReason;)Ljava/util/Map; +} + public final class io/gitlab/arturbosch/detekt/test/ThresholdedCodeSmellAssert : org/assertj/core/api/AbstractAssert { public fun (Lio/gitlab/arturbosch/detekt/api/ThresholdedCodeSmell;)V public final fun hasThreshold (I)V diff --git a/detekt-test/build.gradle.kts b/detekt-test/build.gradle.kts index 842b58e60a78..1740fae4ac07 100644 --- a/detekt-test/build.gradle.kts +++ b/detekt-test/build.gradle.kts @@ -10,3 +10,7 @@ dependencies { compileOnly(libs.assertj) implementation(projects.detektCore) } + +tasks.apiDump { + notCompatibleWithConfigurationCache("https://github.com/Kotlin/binary-compatibility-validator/issues/95") +} diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt index 45697c95a7f5..cd69600c8be1 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/FindingsAssertions.kt @@ -27,7 +27,10 @@ class FindingsAssert(actual: List) : override fun toAssert(value: Finding?, description: String?): FindingAssert = FindingAssert(value).`as`(description) - fun hasSourceLocations(vararg expected: SourceLocation) = apply { + @Deprecated("Use hasStartSourceLocations instead", ReplaceWith("hasStartSourceLocations(*expected)")) + fun hasSourceLocations(vararg expected: SourceLocation) = hasStartSourceLocations(*expected) + + fun hasStartSourceLocations(vararg expected: SourceLocation) = apply { val actualSources = actual.asSequence() .map { it.location.source } .sortedWith(compareBy({ it.line }, { it.column })) @@ -37,13 +40,35 @@ class FindingsAssert(actual: List) : if (!Objects.deepEquals(actualSources.toList(), expectedSources.toList())) { failWithMessage( - "Expected source locations to be ${expectedSources.toList()} but was ${actualSources.toList()}" + "Expected start source locations to be ${expectedSources.toList()} but was ${actualSources.toList()}" ) } } - fun hasSourceLocation(line: Int, column: Int) = apply { - hasSourceLocations(SourceLocation(line, column)) + fun hasEndSourceLocations(vararg expected: SourceLocation) = apply { + val actualSources = actual.asSequence() + .map { it.location.endSource } + .sortedWith(compareBy({ it.line }, { it.column })) + + val expectedSources = expected.asSequence() + .sortedWith(compareBy({ it.line }, { it.column })) + + if (!Objects.deepEquals(actualSources.toList(), expectedSources.toList())) { + failWithMessage( + "Expected end source locations to be ${expectedSources.toList()} but was ${actualSources.toList()}" + ) + } + } + + @Deprecated("Use hasStartSourceLocation instead", ReplaceWith("hasStartSourceLocation(line, column)")) + fun hasSourceLocation(line: Int, column: Int) = hasStartSourceLocation(line, column) + + fun hasStartSourceLocation(line: Int, column: Int) = apply { + hasStartSourceLocations(SourceLocation(line, column)) + } + + fun hasEndSourceLocation(line: Int, column: Int) = apply { + hasEndSourceLocations(SourceLocation(line, column)) } fun hasTextLocations(vararg expected: Pair) = apply { diff --git a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt index a84ad05e2c4c..7659bec664d5 100644 --- a/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt +++ b/detekt-test/src/main/kotlin/io/gitlab/arturbosch/detekt/test/TestConfig.kt @@ -1,6 +1,7 @@ package io.gitlab.arturbosch.detekt.test import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.ValueWithReason import io.gitlab.arturbosch.detekt.core.config.tryParseBasedOnDefault import io.gitlab.arturbosch.detekt.core.config.valueOrDefaultInternal @@ -53,3 +54,7 @@ open class TestConfig( operator fun invoke(vararg pairs: Pair) = TestConfig(mapOf(*pairs)) } } + +fun ValueWithReason.toConfig(): Map { + return mapOf("value" to value, "reason" to reason) +} diff --git a/detekt-tooling/api/detekt-tooling.api b/detekt-tooling/api/detekt-tooling.api index 8cd9687dfbdc..fbabfcc95325 100644 --- a/detekt-tooling/api/detekt-tooling.api +++ b/detekt-tooling/api/detekt-tooling.api @@ -45,6 +45,7 @@ public abstract class io/github/detekt/tooling/api/DetektError : java/lang/Runti public abstract interface class io/github/detekt/tooling/api/DetektProvider { public static final field Companion Lio/github/detekt/tooling/api/DetektProvider$Companion; public abstract fun get (Lio/github/detekt/tooling/api/spec/ProcessingSpec;)Lio/github/detekt/tooling/api/Detekt; + public abstract fun getPriority ()I } public final class io/github/detekt/tooling/api/DetektProvider$Companion { @@ -52,6 +53,10 @@ public final class io/github/detekt/tooling/api/DetektProvider$Companion { public static synthetic fun load$default (Lio/github/detekt/tooling/api/DetektProvider$Companion;Ljava/lang/ClassLoader;ILjava/lang/Object;)Lio/github/detekt/tooling/api/DetektProvider; } +public final class io/github/detekt/tooling/api/DetektProvider$DefaultImpls { + public static fun getPriority (Lio/github/detekt/tooling/api/DetektProvider;)I +} + public abstract class io/github/detekt/tooling/api/FunctionMatcher { public static final field Companion Lio/github/detekt/tooling/api/FunctionMatcher$Companion; public abstract fun match (Lorg/jetbrains/kotlin/descriptors/CallableDescriptor;)Z @@ -100,7 +105,7 @@ public abstract interface class io/github/detekt/tooling/api/spec/ConfigSpec { public abstract fun getConfigPaths ()Ljava/util/Collection; public abstract fun getKnownPatterns ()Ljava/util/Collection; public abstract fun getResources ()Ljava/util/Collection; - public abstract fun getShouldValidateBeforeAnalysis ()Z + public abstract fun getShouldValidateBeforeAnalysis ()Ljava/lang/Boolean; public abstract fun getUseDefaultConfig ()Z } @@ -233,12 +238,12 @@ public final class io/github/detekt/tooling/dsl/ConfigSpecBuilder : io/github/de public final fun getConfigPaths ()Ljava/util/Collection; public final fun getKnownPatterns ()Ljava/util/Collection; public final fun getResources ()Ljava/util/Collection; - public final fun getShouldValidateBeforeAnalysis ()Z + public final fun getShouldValidateBeforeAnalysis ()Ljava/lang/Boolean; public final fun getUseDefaultConfig ()Z public final fun setConfigPaths (Ljava/util/Collection;)V public final fun setKnownPatterns (Ljava/util/Collection;)V public final fun setResources (Ljava/util/Collection;)V - public final fun setShouldValidateBeforeAnalysis (Z)V + public final fun setShouldValidateBeforeAnalysis (Ljava/lang/Boolean;)V public final fun setUseDefaultConfig (Z)V } diff --git a/detekt-tooling/build.gradle.kts b/detekt-tooling/build.gradle.kts index f203bda4320c..36e23ca15a3b 100644 --- a/detekt-tooling/build.gradle.kts +++ b/detekt-tooling/build.gradle.kts @@ -10,6 +10,10 @@ dependencies { testImplementation(libs.assertj) } +tasks.apiDump { + notCompatibleWithConfigurationCache("https://github.com/Kotlin/binary-compatibility-validator/issues/95") +} + apiValidation { ignoredPackages.add("io.github.detekt.tooling.internal") } diff --git a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/DetektProvider.kt b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/DetektProvider.kt index 6dce9d633736..3100b9a8b503 100644 --- a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/DetektProvider.kt +++ b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/DetektProvider.kt @@ -8,6 +8,13 @@ import java.util.ServiceLoader */ interface DetektProvider { + /** + * Is used to choose the highest priority provider if more than one are found on the classpath. + * + * Can be useful to stub/mock detekt instances for tests. + */ + val priority: Int get() = -1 + /** * Configure a [Detekt] instance based on given [ProcessingSpec]. */ @@ -21,6 +28,8 @@ interface DetektProvider { fun load( classLoader: ClassLoader = DetektProvider::class.java.classLoader ): DetektProvider = - ServiceLoader.load(DetektProvider::class.java, classLoader).first() + ServiceLoader.load(DetektProvider::class.java, classLoader) + .maxByOrNull { it.priority } + ?: error("No implemention of DetektProvider found.") } } diff --git a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/spec/ConfigSpec.kt b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/spec/ConfigSpec.kt index 0b0c08da3698..beb0cfa0d955 100644 --- a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/spec/ConfigSpec.kt +++ b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/api/spec/ConfigSpec.kt @@ -10,7 +10,7 @@ interface ConfigSpec { * * Unknown properties to detekt will get reported as errors. */ - val shouldValidateBeforeAnalysis: Boolean + val shouldValidateBeforeAnalysis: Boolean? /** * Property patterns which should be excluded from validation. diff --git a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/dsl/ConfigSpecBuilder.kt b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/dsl/ConfigSpecBuilder.kt index eab3f0dc4750..0f72fe181592 100644 --- a/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/dsl/ConfigSpecBuilder.kt +++ b/detekt-tooling/src/main/kotlin/io/github/detekt/tooling/dsl/ConfigSpecBuilder.kt @@ -7,7 +7,7 @@ import java.nio.file.Path @ProcessingModelDsl class ConfigSpecBuilder : Builder { - var shouldValidateBeforeAnalysis: Boolean = true + var shouldValidateBeforeAnalysis: Boolean? = null var knownPatterns: Collection = emptyList() var useDefaultConfig: Boolean = false // false to be backwards compatible in 1.X @@ -24,7 +24,7 @@ class ConfigSpecBuilder : Builder { } private data class ConfigModel( - override val shouldValidateBeforeAnalysis: Boolean, + override val shouldValidateBeforeAnalysis: Boolean?, override val knownPatterns: Collection, override val useDefaultConfig: Boolean, override val resources: Collection, diff --git a/detekt-tooling/src/test/kotlin/io/github/detekt/tooling/api/DetektProviderSpec.kt b/detekt-tooling/src/test/kotlin/io/github/detekt/tooling/api/DetektProviderSpec.kt new file mode 100644 index 000000000000..1cc0bebaa627 --- /dev/null +++ b/detekt-tooling/src/test/kotlin/io/github/detekt/tooling/api/DetektProviderSpec.kt @@ -0,0 +1,20 @@ +package io.github.detekt.tooling.api + +import io.github.detekt.tooling.api.spec.ProcessingSpec +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class DetektProviderSpec { + + @Test + fun `load provider with highest priority`() { + val provider = DetektProvider.load() + + assertThat(provider.priority).isEqualTo(100) + } +} + +class PrioritizedProvider : DetektProvider { + override val priority: Int = 100 + override fun get(processingSpec: ProcessingSpec): Detekt = error("No instances.") +} diff --git a/detekt-tooling/src/test/resources/META-INF/services/io.github.detekt.tooling.api.DetektProvider b/detekt-tooling/src/test/resources/META-INF/services/io.github.detekt.tooling.api.DetektProvider new file mode 100644 index 000000000000..6901985c9430 --- /dev/null +++ b/detekt-tooling/src/test/resources/META-INF/services/io.github.detekt.tooling.api.DetektProvider @@ -0,0 +1 @@ +io.github.detekt.tooling.api.PrioritizedProvider diff --git a/detekt-utils/build.gradle.kts b/detekt-utils/build.gradle.kts index ed0de36f81c2..1598ef9274ca 100644 --- a/detekt-utils/build.gradle.kts +++ b/detekt-utils/build.gradle.kts @@ -1,3 +1,7 @@ plugins { id("module") } + +dependencies { + testImplementation(libs.assertj) +} diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt b/detekt-utils/src/main/kotlin/io/github/detekt/utils/Markdown.kt similarity index 97% rename from detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt rename to detekt-utils/src/main/kotlin/io/github/detekt/utils/Markdown.kt index 5989a3ecd939..a6879f4f6cfb 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Markdown.kt +++ b/detekt-utils/src/main/kotlin/io/github/detekt/utils/Markdown.kt @@ -1,6 +1,6 @@ @file:Suppress("detekt.TooManyFunctions") -package io.gitlab.arturbosch.detekt.generator.out +package io.github.detekt.utils sealed class Markdown(open var content: String = "") { fun append(value: String) { diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt b/detekt-utils/src/main/kotlin/io/github/detekt/utils/Yaml.kt similarity index 98% rename from detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt rename to detekt-utils/src/main/kotlin/io/github/detekt/utils/Yaml.kt index 100f1cbf7ba2..92d3ab2c2008 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/out/Yaml.kt +++ b/detekt-utils/src/main/kotlin/io/github/detekt/utils/Yaml.kt @@ -1,4 +1,4 @@ -package io.gitlab.arturbosch.detekt.generator.out +package io.github.detekt.utils sealed class YML(open val indent: Int = 0, open var content: String = "") { fun append(value: String) { diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/out/YamlSpec.kt b/detekt-utils/src/test/kotlin/io/github/detekt/utils/YamlSpec.kt similarity index 99% rename from detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/out/YamlSpec.kt rename to detekt-utils/src/test/kotlin/io/github/detekt/utils/YamlSpec.kt index 7dd481ba9a6b..fcae48f37e35 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/out/YamlSpec.kt +++ b/detekt-utils/src/test/kotlin/io/github/detekt/utils/YamlSpec.kt @@ -1,4 +1,4 @@ -package io.gitlab.arturbosch.detekt.generator.out +package io.github.detekt.utils import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Nested diff --git a/gradle.properties b/gradle.properties index 2ed1bffb5f8f..41510ff430d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,8 @@ kotlin.code.style=official -systemProp.sonar.host.url=http://localhost:9000 +kotlin.incremental.useClasspathSnapshot=true systemProp.dependency.analysis.test.analysis=false org.gradle.parallel=true org.gradle.caching=true org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m -Dfile.encoding=UTF-8 -org.gradle.unsafe.configuration-cache=false +org.gradle.unsafe.configuration-cache=true +systemProp.org.gradle.kotlin.dsl.precompiled.accessors.strict=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 95e33d9c0616..0f5e8328a2b0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,13 +1,13 @@ [versions] -dokka = "1.6.21" +dokka = "1.7.10" jacoco = "0.8.8" -kotlin = "1.6.21" -ktlint = "0.45.2" -junit = "5.8.2" +kotlin = "1.7.10" +ktlint = "0.46.1" +junit = "5.9.0" contester = "0.2.0" [libraries] -githubRelease-gradle = "com.github.breadmoirai:github-release:2.3.7" +githubRelease-gradle = "com.github.breadmoirai:github-release:2.4.1" nexusStaging-gradle = "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0" semver4j-gradle = "com.vdurmont:semver4j:3.1.0" @@ -18,8 +18,8 @@ kotlin-scriptUtil = { module = "org.jetbrains.kotlin:kotlin-script-util", versio kotlin-scriptingCompilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable", version.ref = "kotlin" } kotlin-stdlibJdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } -kotlinx-html = "org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.5" -kotlinx-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2" +kotlinx-html = "org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.0" +kotlinx-coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" android-gradle = "com.android.tools.build:gradle:7.2.1" @@ -33,19 +33,17 @@ spek-dsl = { module = "org.spekframework.spek2:spek-dsl-jvm", version = "2.0.18" junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } sarif4k = "io.github.detekt.sarif4k:sarif4k:0.0.1" -assertj = "org.assertj:assertj-core:3.20.2" +assertj = "org.assertj:assertj-core:3.23.1" reflections = "org.reflections:reflections:0.10.2" -mockk = "io.mockk:mockk:1.12.4" +mockk = "io.mockk:mockk:1.12.5" snakeyaml = "org.yaml:snakeyaml:1.30" jcommander = "com.beust:jcommander:1.82" contester-breakpoint = { module = "io.github.davidburstrom.contester:contester-breakpoint", version.ref = "contester" } contester-driver = { module = "io.github.davidburstrom.contester:contester-driver", version.ref = "contester" } [plugins] -binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.10.0" } -dependencyAnalysis = { id = "com.autonomousapps.dependency-analysis", version = "1.4.0" } +binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.11.0" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } gradleVersions = { id = "com.github.ben-manes.versions", version = "0.42.0" } -pluginPublishing = { id = "com.gradle.plugin-publish", version = "0.21.0" } +pluginPublishing = { id = "com.gradle.plugin-publish", version = "1.0.0" } shadow = { id = "com.github.johnrengelman.shadow", version = "7.1.2" } -sonarqube = { id = "org.sonarqube", version = "3.3" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 92f06b50fd65..2ec77e51a9c9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/scripts/github-milestone-report.main.kts b/scripts/github-milestone-report.main.kts index 3c2d4ec68e83..f766a7a2811b 100755 --- a/scripts/github-milestone-report.main.kts +++ b/scripts/github-milestone-report.main.kts @@ -7,7 +7,8 @@ * You need kotlin 1.3.70+ installed on your machine */ -@file:Suppress("detekt.CommentSpacing") // for the exec line +// for the exec line +@file:Suppress("detekt.CommentSpacing") @file:DependsOn("org.kohsuke:github-api:1.135") @file:DependsOn("com.github.ajalt:clikt:2.8.0") @@ -50,7 +51,7 @@ class GithubMilestoneReport : CliktCommand() { var ghIssues: List = ghRepository.getIssues(GHIssueState.CLOSED, ghMilestone) if (filterExisting) { - val changeLogContent = File("./docs/pages/changelog 1.x.x.md").readText() + val changeLogContent = File("./website/docs/introduction/changelog 1.x.x.md").readText() ghIssues = ghIssues.filter { "[#${it.number}]" !in changeLogContent } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 01d85e685008..6bd4a0a283a2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,6 +17,7 @@ include("detekt-metrics") include("detekt-parser") include("detekt-psi-utils") include("detekt-report-html") +include("detekt-report-md") include("detekt-report-sarif") include("detekt-report-txt") include("detekt-report-xml") @@ -41,13 +42,13 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") // build scan plugin can only be applied in settings file plugins { // check https://gradle.com/enterprise/releases with new versions. GE plugin version should not lag behind Gradle version - id("com.gradle.enterprise") version "3.10.1" + id("com.gradle.enterprise") version "3.10.3" id("com.gradle.common-custom-user-data-gradle-plugin") version "1.7.2" } -gradleEnterprise { - val isCiBuild = System.getenv("CI") != null +val isCiBuild = System.getenv("CI") != null +gradleEnterprise { buildScan { publishAlways() @@ -66,6 +67,21 @@ gradleEnterprise { } } +buildCache { + local { + isEnabled = true + } + remote { + isPush = isCiBuild + isEnabled = true + url = uri("https://ge.detekt.dev/cache/") + credentials { + username = System.getenv("GRADLE_CACHE_USERNAME") + password = System.getenv("GRADLE_CACHE_PASSWORD") + } + } +} + dependencyResolutionManagement { repositories { mavenCentral() diff --git a/website/docs/_detekt-version-banner.mdx b/website/docs/_detekt-version-banner.mdx deleted file mode 100644 index 9380373b6050..000000000000 --- a/website/docs/_detekt-version-banner.mdx +++ /dev/null @@ -1,5 +0,0 @@ -import DetektVersion from "./_detekt-version.jsx"; - -:::info -The latest released version of Detekt is **** -::: diff --git a/website/docs/_detekt-version.jsx b/website/docs/_detekt-version.jsx deleted file mode 100644 index 376377d06216..000000000000 --- a/website/docs/_detekt-version.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; - -const DetektVersion = () => ( - {useDocusaurusContext().siteConfig.customFields.detektVersion} -); - -export default DetektVersion \ No newline at end of file diff --git a/website/docs/gettingstarted/cli.mdx b/website/docs/gettingstarted/cli.mdx index 03afbb985d3e..ef7092c7145a 100644 --- a/website/docs/gettingstarted/cli.mdx +++ b/website/docs/gettingstarted/cli.mdx @@ -8,7 +8,6 @@ summary: sidebar_position: 1 --- -import DetektVersionBanner from "../_detekt-version-banner.mdx"; import CliOptions from "./_cli-options.md"; ## Install the cli @@ -22,9 +21,14 @@ brew install detekt detekt [options] ``` -### Any OS: +### Windows, with [Scoop](https://scoop.sh/) - +```powershell +scoop install detekt +detekt [options] +``` + +### Any OS: ```sh curl -sSLO https://github.com/detekt/detekt/releases/download/v[detekt_version]/detekt-cli-[detekt_version].zip diff --git a/website/docs/gettingstarted/gradle.mdx b/website/docs/gettingstarted/gradle.mdx index 535b29ed9417..59925c8c2300 100644 --- a/website/docs/gettingstarted/gradle.mdx +++ b/website/docs/gettingstarted/gradle.mdx @@ -8,9 +8,7 @@ summary: sidebar_position: 2 --- -import DetektVersionBanner from "../\_detekt-version-banner.mdx"; - -Detekt requires **Gradle 6.1** or higher. We, however, recommend using the version of Gradle that is [listed in this table](/docs/introduction/compatibility). +Detekt requires **Gradle 6.7.1** or higher. We, however, recommend using the version of Gradle that is [listed in this table](/docs/introduction/compatibility). ## Available plugin tasks @@ -21,7 +19,7 @@ The detekt Gradle plugin will generate multiple tasks: - By default, the standard rule set without any ignore list is executed on sources files located in `src/main/java`, `src/test/java`, `src/main/kotlin` and `src/test/kotlin`. - Reports are automatically generated in xml, - html, txt, and sarif format and can be found in `build/reports/detekt/detekt.[xml|html|txt|sarif]` respectively. + html, txt, md, and sarif format and can be found in `build/reports/detekt/detekt.[xml|html|txt|md|sarif]` respectively. - Please note that the `detekt` task is automatically run when executing `gradle check`. - You may specify Gradle task CLI option for auto correction, such as `gradle detekt --auto-correct`. - `detektGenerateConfig` - Generates a default detekt configuration file into your project directory. @@ -48,7 +46,7 @@ the name of the build variant in their name, unless otherwise configured, such a `detekt-productionDebug.xml`. If both, a `detekt-main.xml` and a `detekt.xml` baseline file exists in place, the more specific one - `detekt-main.xml` - -takes precendence when the `detektMain` task is executed, likewise for Android variant-specific baseline files. +takes precedence when the `detektMain` task is executed, likewise for Android variant-specific baseline files. _NOTE:_ When analyzing Android projects that make use of specific code generators, such as Data Binding, Kotlin synthetic view accessors or else, you might see warnings output while Detekt runs. This is due to the inability to gather the @@ -64,8 +62,6 @@ Using the plugins DSL: #### Groovy DSL - - ```groovy plugins { id "io.gitlab.arturbosch.detekt" version "[detekt_version]" @@ -318,6 +314,9 @@ tasks.named("detekt").configure { // Enable/Disable SARIF report (default: false) sarif.required.set(true) sarif.outputLocation.set(file("build/reports/detekt.sarif")) + // Enable/Disable MD report (default: false) + md.required.set(true) + md.outputLocation.set(file("build/reports/detekt.md")) custom { // The simple class name of your custom report. reportId = "CustomJsonReport" diff --git a/website/docs/gettingstarted/gradletask.md b/website/docs/gettingstarted/gradletask.md index af35e08a118f..6fd265f63a3f 100644 --- a/website/docs/gettingstarted/gradletask.md +++ b/website/docs/gettingstarted/gradletask.md @@ -8,13 +8,9 @@ summary: sidebar_position: 3 --- -import DetektVersionBanner from "../\_detekt-version-banner.mdx"; - 1. Add following lines to your build.gradle file. 2. Run `gradle detekt` - - ###### Groovy DSL ```groovy repositories { diff --git a/website/docs/gettingstarted/mavenanttask.md b/website/docs/gettingstarted/mavenanttask.md index 86458babeada..b832a9bb7c7a 100644 --- a/website/docs/gettingstarted/mavenanttask.md +++ b/website/docs/gettingstarted/mavenanttask.md @@ -8,13 +8,9 @@ summary: sidebar_position: 4 --- -import DetektVersionBanner from "../\_detekt-version-banner.mdx"; - 1. Add following lines to your pom.xml. 2. Run `mvn verify` (when using the verify phase as we are doing here) - - ```xml diff --git a/website/docs/gettingstarted/type-resolution.md b/website/docs/gettingstarted/type-resolution.md index cd1715579d8c..295f4a47a16e 100644 --- a/website/docs/gettingstarted/type-resolution.md +++ b/website/docs/gettingstarted/type-resolution.md @@ -51,7 +51,11 @@ All the rules that require type resolution are annotated with [`@RequiresTypeRes Moreover, their official documentation in the Detekt website will mention _Requires Type Resolution_ ([like here](/docs/rules/potential-bugs#unnecessarysafecall)). -{% include note.html content="Please note that we do have some rules that have mixed behavior whether type resolution is enabled or not. Those rules are listed here: [#2994](https://github.com/detekt/detekt/issues/2994)" %} +:::caution + +Please note that we do have some rules that have mixed behavior whether type resolution is enabled or not. Those rules are listed here: [#2994](https://github.com/detekt/detekt/issues/2994) + +::: Before opening an issue that you're rule is not working, please verify, whether your rule requires type resolution and check if you have type resolution enabled. diff --git a/website/docs/intro.mdx b/website/docs/intro.mdx index 19303703732b..630ee21624cf 100644 --- a/website/docs/intro.mdx +++ b/website/docs/intro.mdx @@ -5,31 +5,25 @@ sidebar_position: 1 summary: --- -import DetektVersionBanner from "./\_detekt-version-banner.mdx"; - ![detekt logo](/img/logo.svg "detekt logo") ![detekt in action](/img/tutorial/detekt_in_action.png "detekt in action") ### Features -- Code smell analysis for your Kotlin projects -- Complexity report based on logical lines of code, McCabe complexity and amount of code smells -- Highly configurable (rule set or rule level) -- Suppress findings with Kotlin's `@Suppress` and Java's `@SuppressWarnings` annotations -- Specify code smell thresholds to break your build or print a warning -- Code Smell baseline and ignore lists for legacy projects -- [Gradle plugin](/docs/gettingstarted/gradle) for code analysis via Gradle builds -- [SonarQube integration](https://github.com/detekt/sonar-kotlin) -- Extensible by own rule sets and `FileProcessListener's` -- [IntelliJ integration](https://github.com/detekt/detekt-intellij-plugin) -- Unofficial [Maven plugin](https://github.com/Ozsie/detekt-maven-plugin) by [Ozsie](https://github.com/Ozsie) +- Code smell analysis for your [Kotlin projects](https://kotlinlang.org/). +- Highly configurable rule sets. +- Code Smell baseline and suppression for legacy projects. +- Suppression of findings with `@Suppress` annotations. +- Support for different report formats: html, markdown, [SARIF](https://sarifweb.azurewebsites.net/) and xml (checkstyle). Is it not enough? You can extend detekt and create your own reports. +- Extensibility by enabling incorporation of personal rule sets, `FileProcessListener's` and `OutputReport's`. +- Complexity reports based on lines of code, cyclomatic complexity and number of code smells. +- First party integration with Gradle with our [Gradle plugin](#with-gradle). +- A community of [third party plugins](https://github.com/topics/detekt-plugin) that adds more rules and features to detekt. ### Quick Start with Gradle Apply the following configuration to your Gradle project build file: - - ```kotlin plugins { id("io.gitlab.arturbosch.detekt").version("[detekt_version]") @@ -70,6 +64,7 @@ tasks.withType().configureEach { html.required.set(true) txt.required.set(true) sarif.required.set(true) + md.required.set(true) } } ``` @@ -82,6 +77,7 @@ tasks.withType(Detekt).configureEach { html.required.set(true) txt.required.set(true) sarif.required.set(true) + md.required.set(true) } } ``` @@ -90,7 +86,7 @@ See [reporting](/docs/introduction/reporting) docs for more details on configuri ### Adding more rule sets -detekt itself provides a wrapper over [ktlint](https://github.com/pinterest/ktlint) as a `formatting` rule set +detekt itself provides a wrapper over [ktlint](https://github.com/pinterest/ktlint) as the `formatting` rule set which can be easily added to the gradle configuration: ```gradle diff --git a/website/docs/introduction/changelog 1.x.x.md b/website/docs/introduction/changelog 1.x.x.md index f9040eacce73..7bfa6c93b82a 100644 --- a/website/docs/introduction/changelog 1.x.x.md +++ b/website/docs/introduction/changelog 1.x.x.md @@ -5,22 +5,76 @@ keywords: [changelog, release-notes, migration] sidebar_position: 1 --- -#### 1.21.0-RC1 - 2022-06-02 +#### 1.21.0 - 2022-07-16 + +We're delighted to announce the next upcoming stable release of Detekt: `1.21.0` 🎉 +This release is coming with 6 new rules, new API and functionalities and several stability improvements. + +We want to thank you very much [our Sponsors](https://github.com/sponsors/detekt) for the support in those last months. The work behind Detekt is all happening on a voluntary basis, and we're more than grateful for all the support we get from the Open Source Ecosystem. + +We're also excited to announce that we're now having an [Open Source Gradle Enterprise](https://ge.detekt.dev) instance. When building the Detekt projects, you'll benefit from the Gradle Remote Cache that this instance is providing! + +Finally, we want to take the opportunity to thank our contributors for testing, bug reporting and helping +us release this new version of Detekt. You're more than welcome to join our community on the [#detekt](https://kotlinlang.slack.com/archives/C88E12QH4) channel on KotlinLang's Slack (you can [get an invite here](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up)). ##### Notable Changes - We enabled ~30 new rules by default which we believe are now stable enough. - [#4875](https://github.com/detekt/detekt/pull/4875) -- We added **3** new Rules to Detekt +- We added **6** new Rules to Detekt - `NullableBooleanCheck` - [#4872](https://github.com/detekt/detekt/pull/4872) - `CouldBeSequence` - [#4855](https://github.com/detekt/detekt/pull/4855) - `UnnecessaryBackticks` - [#4764](https://github.com/detekt/detekt/pull/4764) -- We now allow users and rule authors to specify a **reason** for every value in the config file - [#4611](https://github.com/detekt/detekt/pull/4611) -- We now report as warnings the in the config file that should converted to be an array - [#4793](https://github.com/detekt/detekt/pull/4793) + - `ForbiddenSuppress` - [#4899](https://github.com/detekt/detekt/pull/4899) + - `MaxChainedCallsOnSameLine` - [#4985](https://github.com/detekt/detekt/pull/4985) + - `CascadingCallWrapping` - [#4979](https://github.com/detekt/detekt/pull/4979) +- We added support for Markdown reports - [#4858](https://github.com/detekt/detekt/pull/4858) +- We now allow users and rule authors to specify a **reason** for every value in the config file - [#4611](https://github.com/detekt/detekt/pull/4611) Please note that this feature requires a rule to be extended to support it. If you're a rule author you can start using it right away in your rule. We're looking into using this feature in some first party rule starting from Detekt `1.22.0`. +- We now report as warnings the Strings in the config file that can be converted to be an array - [#4793](https://github.com/detekt/detekt/pull/4793) - We added a dependency on **ConTester** to help us verify concurrency scenarios for Detekt - [#4672](https://github.com/detekt/detekt/pull/4672) - For contributors: we restructured our build setup to be use **Gradle composite build** - [#4751](https://github.com/detekt/detekt/pull/4751) +##### Migration + +We fixed a bug related to function with KDocs and how their location in the source code was calculated (see [#4961](https://github.com/detekt/detekt/pull/4961) and [#4887](https://github.com/detekt/detekt/issues/4887)). + +Because of this, some users might have to **recreate their baseline** as the location of such functions are not matched anymore against the baseline. You can do so by deleting your old baseline and invoking the `detektBaseline` task (or the corresponding task, based on your configuration). + ##### Changelog +- ReturnCount: Make configuration parameter more explicit - [#5062](https://github.com/detekt/detekt/pull/5062) +- Remove redundant null check - [#5061](https://github.com/detekt/detekt/pull/5061) +- Drop redundant Gradle workaround - [#5057](https://github.com/detekt/detekt/pull/5057) +- Update ktlint links from website to readme - [#5056](https://github.com/detekt/detekt/pull/5056) +- Improve extensions.doc format with admonitions - [#5055](https://github.com/detekt/detekt/pull/5055) +- Update docusaurus monorepo to v2.0.0-beta.22 - [#5050](https://github.com/detekt/detekt/pull/5050) +- Enable strict Kotlin DSL precompiled script plugins accessors generation - [#5048](https://github.com/detekt/detekt/pull/5048) +- MaxChainedCallsOnSameLine: don't count package references as chained calls - [#5036](https://github.com/detekt/detekt/pull/5036) +- Xml Report Merger now merges duplicate smells across input report files - [#5033](https://github.com/detekt/detekt/pull/5033) +- Add ending line and column to Location.kt - [#5032](https://github.com/detekt/detekt/pull/5032) +- Fix type resolution link in Contributing.md - [#5027](https://github.com/detekt/detekt/pull/5027) +- #5014 Fix MaxChainedCallsOnSameLine false positives - [#5020](https://github.com/detekt/detekt/pull/5020) +- Add endColumn/endLine to SARIF region - [#5011](https://github.com/detekt/detekt/pull/5011) +- Removed UnnecessaryAbstractClass if it inherits from a abstract class - [#5009](https://github.com/detekt/detekt/pull/5009) +- Only recommend using index accessors for Java classes that are known collections - [#4994](https://github.com/detekt/detekt/pull/4994) +- UnusedImports: fix false positive for unresolved imports - [#4882](https://github.com/detekt/detekt/pull/4882) +- Fix Signatures.kt:buildFunctionSignature - [#4961](https://github.com/detekt/detekt/pull/4961) +- Loading a specific resource from a module must use class from module - [#5008](https://github.com/detekt/detekt/pull/5008) +- Update github/codeql-action digest to 3f62b75 - [#5007](https://github.com/detekt/detekt/pull/5007) +- Show finding at declaration name instead of the whole declaration - [#5003](https://github.com/detekt/detekt/pull/5003) +- NamedArguments: don't count trailing lambda argument - [#5002](https://github.com/detekt/detekt/pull/5002) +- Address TextLocation for Wrapping - [#4998](https://github.com/detekt/detekt/pull/4998) +- Support markdown report in Gradle plugin - [#4995](https://github.com/detekt/detekt/pull/4995) +- Fix false-negative for CanBeNonNullable - [#4993](https://github.com/detekt/detekt/pull/4993) +- Give a better error message for --jvm-target - [#4978](https://github.com/detekt/detekt/pull/4978) +- Fix rule code samples to be valid Kotlin code - [#4969](https://github.com/detekt/detekt/pull/4969) +- Use plain ASCII output in standard reports - [#4968](https://github.com/detekt/detekt/pull/4968) +- UnnecessaryApply: fix false negative for assignment - [#4948](https://github.com/detekt/detekt/pull/4948) +- Support disabling config validation via tooling spec - [#4937](https://github.com/detekt/detekt/pull/4937) +- UnusedPrivateMember: highlight declaration name - [#4928](https://github.com/detekt/detekt/pull/4928) +- Provide a priority field for DetektProvider - [#4923](https://github.com/detekt/detekt/pull/4923) +- CastToNullableType: allow casting null keyword - [#4907](https://github.com/detekt/detekt/pull/4907) +- Update plugin com.gradle.common-custom-user-data-gradle-plugin to v1.7.2 - [#4897](https://github.com/detekt/detekt/pull/4897) +- Set strict dependency on tested Kotlin compiler version - [#4822](https://github.com/detekt/detekt/pull/4822) - Simplify regular expressions - [#4893](https://github.com/detekt/detekt/pull/4893) - Remove redundant character escape in RegExp - [#4892](https://github.com/detekt/detekt/pull/4892) - Reformat Markdown files to comply with the spec - [#4891](https://github.com/detekt/detekt/pull/4891) @@ -68,6 +122,11 @@ sidebar_position: 1 ##### Dependency Updates +- Update dependency gradle to v7.5 - [#5074](https://github.com/detekt/detekt/pull/5074) +- Update plugin binaryCompatibilityValidator to v0.11.0 - [#5069](https://github.com/detekt/detekt/pull/5069) +- Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.6.3 - [#4976](https://github.com/detekt/detekt/pull/4976) +- Update dependency org.jetbrains.dokka to v1.7.0 - [#4974](https://github.com/detekt/detekt/pull/4974) +- Update plugin binaryCompatibilityValidator to v0.10.1 - [#4954](https://github.com/detekt/detekt/pull/4954) - Update dependency org.jetbrains.kotlinx:kotlinx-coroutines-core to v1.6.2 - [#4868](https://github.com/detekt/detekt/pull/4868) - Update dependency com.android.tools.build:gradle to v7.2.1 - [#4861](https://github.com/detekt/detekt/pull/4861) - Update plugin binaryCompatibilityValidator to v0.10.0 - [#4837](https://github.com/detekt/detekt/pull/4837) @@ -82,6 +141,10 @@ sidebar_position: 1 ##### Housekeeping & Refactorings +- Fix `ComplexMethod` debt and refactor code - [#5029](https://github.com/detekt/detekt/pull/5029) +- Fix ReturnCount debt and refactor code - [#5026](https://github.com/detekt/detekt/pull/5026) +- Add test for ForbiddenMethodCall with getters - [#5018](https://github.com/detekt/detekt/pull/5018) +- Measure flakyness on Windows CI - [#4742](https://github.com/detekt/detekt/pull/4742) - Declare nested test classes as non-static - [#4894](https://github.com/detekt/detekt/pull/4894) - Remove deprecated usages in gradle-plugin test - [#4889](https://github.com/detekt/detekt/pull/4889) - Remove reference to contributor list - [#4871](https://github.com/detekt/detekt/pull/4871) diff --git a/website/docs/introduction/compatibility.md b/website/docs/introduction/compatibility.md index 41e868bc318d..84203eb01c74 100644 --- a/website/docs/introduction/compatibility.md +++ b/website/docs/introduction/compatibility.md @@ -28,6 +28,7 @@ Consider **aligning** your Gradle plugin versions with the one listed below, as | Detekt Version | Gradle Version | Kotlin Version | AGP Version | Java Target Level | JDK Version | |----------------|----------------|----------------|-------------|-------------------|-------------| +| `1.21.0` | `7.5` | `1.6.21` | `7.2.1` | `1.8` | `17` | | `1.20.0` | `7.4.2` | `1.6.20` | `7.1.3` | `1.8` | `17` | | `1.19.0` | `7.3.0` | `1.5.31` | `4.2.2` | `1.8` | `17` | | `1.18.0` | `7.0.1` | `1.5.21` | `4.2.0` | `1.8` | `16` | diff --git a/website/docs/introduction/configurations.md b/website/docs/introduction/configurations.md index 40fe937d4218..26f7b2bde40e 100644 --- a/website/docs/introduction/configurations.md +++ b/website/docs/introduction/configurations.md @@ -126,6 +126,7 @@ output-reports: # - 'TxtOutputReport' # - 'XmlOutputReport' # - 'SarifOutputReport' + # - 'MdOutputReport' ``` diff --git a/website/docs/introduction/extensions.md b/website/docs/introduction/extensions.md index 011306f6b251..4e8097b6b262 100644 --- a/website/docs/introduction/extensions.md +++ b/website/docs/introduction/extensions.md @@ -5,8 +5,6 @@ keywords: [extensions, rulesets] sidebar_position: 9 --- -import DetektVersionBanner from "../\_detekt-version-banner.mdx"; - The following page describes how to extend detekt and how to customize it to your domain-specific needs. The associated **code samples** to this guide can be found in the package [detekt/detekt-sample-extensions](https://github.com/detekt/detekt/tree/main/detekt-sample-extensions). @@ -15,9 +13,13 @@ The associated **code samples** to this guide can be found in the package [detek _detekt_ uses the `ServiceLoader` pattern to collect all instances of `RuleSetProvider` interfaces. So it is possible to define rules/rule sets and enhance _detekt_ with your own flavor. -Attention: You need a `resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider` file which +:::caution Attention + +You need a `resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider` file which has as content the fully qualified name of your `RuleSetProvider` e.g. `io.gitlab.arturbosch.detekt.sample.extensions.SampleProvider`. +::: + You can use our [GitHub template](https://github.com/detekt/detekt-custom-rule-template) to have a basic scaffolding to develop your own custom rules. Another option is to clone the provided [detekt/detekt-sample-extensions](https://github.com/detekt/detekt/tree/main/detekt-sample-extensions) project. @@ -106,9 +108,13 @@ By specifying the rule set and rule ids, _detekt_ will use the sub configuration ```val threshold = valueOrDefault("threshold", THRESHOLD)``` -Note: As of version 1.2.0 detekt now verifies if all configured properties actually exist in a configuration created by `--generate-config`. +:::note + +As of version 1.2.0 detekt now verifies if all configured properties actually exist in a configuration created by `--generate-config`. This means that by default detekt does not know about your new properties. -Therefore we need to mention them in the configuration under `config>excludes`: +Therefore we need to mention them in the configuration under `config>excludes`. + +::: ```yaml config: @@ -158,6 +164,7 @@ class NumberOfLoopsProcessor : FileProcessListener { } } ``` + To let detekt know about the new processor, we specify a `resources/META-INF/services/io.gitlab.arturbosch.detekt.api.FileProcessListener` file with the full qualify name of our processor as the content: `io.gitlab.arturbosch.detekt.sample.extensions.processors.NumberOfLoopsProcessor`. @@ -221,11 +228,9 @@ To enable it, we add the published dependency to `detekt` via the `detektPlugins ###### Gradle (Kotlin/Groovy DSL) - - ```kotlin dependencies { - detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:{{ site.detekt_version }}") + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:[detekt_version]") } ``` @@ -247,4 +252,4 @@ you created a pure kotlin module which has no Android dependencies. `apply plugi In detekt you can write custom rules which can manipulate your code base. For this a cli flag `--auto-correct` and the gradle plugin property `autoCorrect` exists. -Only write auto correcting code within the `Rule#withAutoCorrect()`-function. \ No newline at end of file +Only write auto correcting code within the `Rule#withAutoCorrect()`-function. diff --git a/website/docs/introduction/reporting.md b/website/docs/introduction/reporting.md index b73b7670e324..eb7be2611ff5 100644 --- a/website/docs/introduction/reporting.md +++ b/website/docs/introduction/reporting.md @@ -37,7 +37,12 @@ XML is a machine-readable format that can be integrated with CI tools. It is com [SARIF](https://sarifweb.azurewebsites.net/) is a standard format for the output of static analysis tools. It is a JSON format with a defined [schema](https://docs.oasis-open.org/sarif/sarif/v2.0/csprd02/schemas/). It is currently supported -by Github Code Scanning and we expect more consuming tools will be adopt this format in the future. +by GitHub Code Scanning, and we expect more consuming tools will adopt this format in the future. + +### MD +Markdown is a lightweight markup language for creating formatted text using a plain-text editor. +The output structure looks similar to HTML format. +About [markdown](https://github.github.com/gfm/#what-is-markdown-) on GitHub. ## Severity For machine-readable format, it is possible to configure the severity of each finding to fit diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index ff1b5827b462..7c0019427653 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -3,6 +3,7 @@ const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const detektVersionReplace = require('./src/remark/detektVersionReplace'); /** @type {import('@docusaurus/types').Config} */ const config = { @@ -25,6 +26,7 @@ const config = { docs: { sidebarPath: require.resolve('./sidebars.js'), editUrl: 'https://github.com/detekt/detekt/edit/main/website/', + remarkPlugins: [detektVersionReplace], }, blog: { showReadingTime: true, @@ -72,6 +74,7 @@ const config = { { to: '/docs/rules/performance', from: '/performance.html' }, { to: '/docs/rules/potential-bugs', from: '/potential-bugs.html' }, { to: '/docs/rules/style', from: '/style.html' }, + { to: '/docs/introduction/suppressors', from: '/suppressors.html'} ], }, ], @@ -124,7 +127,7 @@ const config = { }, { label: 'Getting Started with the CLI', - to: '/docs/gettingstarted/gradle', + to: '/docs/gettingstarted/cli', }, { label: 'Rules Documentation', @@ -178,9 +181,6 @@ const config = { }, }), - customFields: { - detektVersion: '1.21.0-RC1' - }, }; module.exports = config; diff --git a/website/package.json b/website/package.json index 9230f6c2cf27..77e03a33280c 100644 --- a/website/package.json +++ b/website/package.json @@ -16,14 +16,14 @@ "generate-and-build": "../gradlew -p .. :detekt-generator:generateDocumentation && docusaurus build" }, "dependencies": { - "@docusaurus/core": "2.0.0-beta.21", - "@docusaurus/plugin-client-redirects": "2.0.0-beta.21", - "@docusaurus/preset-classic": "2.0.0-beta.21", + "@docusaurus/core": "2.0.0-rc.1", + "@docusaurus/plugin-client-redirects": "2.0.0-rc.1", + "@docusaurus/preset-classic": "2.0.0-rc.1", "@mdx-js/react": "1.6.22", - "clsx": "1.1.1", - "prism-react-renderer": "1.3.3", - "react": "18.1.0", - "react-dom": "18.1.0" + "clsx": "1.2.1", + "prism-react-renderer": "1.3.5", + "react": "18.2.0", + "react-dom": "18.2.0" }, "browserslist": { "production": [ diff --git a/website/src/remark/detektVersionReplace.js b/website/src/remark/detektVersionReplace.js new file mode 100644 index 000000000000..8c4920e30888 --- /dev/null +++ b/website/src/remark/detektVersionReplace.js @@ -0,0 +1,19 @@ +const visit = require("unist-util-visit"); + +// Remark plugin that is replacing the [detekt_version] with the latest +// released version. Please note that this field is updated automatically +// by the `:detekt-generator:generateDocumentation` task. +const detektVersion = "1.21.0"; + +const plugin = (options) => { + const transformer = async (ast) => { + visit(ast, "code", (node) => { + if (node.value.includes("[detekt_version]")) { + node.value = node.value.replace("[detekt_version]", detektVersion); + } + }); + }; + return transformer; +}; + +module.exports = plugin; diff --git a/website/yarn.lock b/website/yarn.lock index bad96ccf2cd3..4eeaf10b4f66 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -2,17 +2,24 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.6.3": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.6.3.tgz#76832fffb6405ac2c87bac5a040b8a31a1cdef80" - integrity sha512-dqQqRt01fX3YuVFrkceHsoCnzX0bLhrrg8itJI1NM68KjrPYQPYsE+kY8EZTCM4y8VDnhqJErR73xe/ZsV+qAA== +"@algolia/autocomplete-core@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.7.1.tgz#025538b8a9564a9f3dd5bcf8a236d6951c76c7d1" + integrity sha512-eiZw+fxMzNQn01S8dA/hcCpoWCOCwcIIEUtHHdzN5TGB3IpzLbuhqFeTfh2OUhhgkE8Uo17+wH+QJ/wYyQmmzg== dependencies: - "@algolia/autocomplete-shared" "1.6.3" + "@algolia/autocomplete-shared" "1.7.1" -"@algolia/autocomplete-shared@1.6.3": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.6.3.tgz#52085ce89a755977841ed0a463aa31ce8f1dea97" - integrity sha512-UV46bnkTztyADFaETfzFC5ryIdGVb2zpAoYgu0tfcuYWjhg1KbLXveFffZIrGVoboqmAk1b+jMrl6iCja1i3lg== +"@algolia/autocomplete-preset-algolia@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.1.tgz#7dadc5607097766478014ae2e9e1c9c4b3f957c8" + integrity sha512-pJwmIxeJCymU1M6cGujnaIYcY3QPOVYZOXhFkWVM7IxKzy272BwCvMFMyc5NpG/QmiObBxjo7myd060OeTNJXg== + dependencies: + "@algolia/autocomplete-shared" "1.7.1" + +"@algolia/autocomplete-shared@1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.1.tgz#95c3a0b4b78858fed730cf9c755b7d1cd0c82c74" + integrity sha512-eTmGVqY3GeyBTT8IWiB2K5EuURAqhnumfktAEoHxfDY2o7vg2rSnO16ZtIG0fMgt3py28Vwgq42/bVEuaQV7pg== "@algolia/cache-browser-local-storage@4.13.0": version "4.13.0" @@ -241,15 +248,22 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== -"@babel/compat-data@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" - integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== +"@babel/compat-data@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== "@babel/core@7.12.9": version "7.12.9" @@ -294,21 +308,21 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/core@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.2.tgz#87b2fcd7cce9becaa7f5acebdc4f09f3dd19d876" - integrity sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ== +"@babel/core@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.6.tgz#54a107a3c298aee3fe5e1947a6464b9b6faca03d" + integrity sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ== dependencies: "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-compilation-targets" "^7.18.2" - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helpers" "^7.18.2" - "@babel/parser" "^7.18.0" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.6" + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helpers" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -324,13 +338,13 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d" - integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== +"@babel/generator@^7.18.6", "@babel/generator@^7.18.7": + version "7.18.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.7.tgz#2aa78da3c05aadfc82dbac16c99552fc802284bd" + integrity sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A== dependencies: - "@babel/types" "^7.18.2" - "@jridgewell/gen-mapping" "^0.3.0" + "@babel/types" "^7.18.7" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" "@babel/helper-annotate-as-pure@^7.16.7": @@ -340,6 +354,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" @@ -348,6 +369,14 @@ "@babel/helper-explode-assignable-expression" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.6.tgz#f14d640ed1ee9246fb33b8255f08353acfe70e6a" + integrity sha512-KT10c1oWEpmrIRYnthbzHgoOf6B+Xd6a5yhdbNtdhtG7aO1or5HViuf1TQR36xY/QprXA5nvxO6nAjhJ4y38jw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" @@ -358,23 +387,13 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-compilation-targets@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe" - integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== - dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.20.2" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz#67a85a10cbd5fc7f1457fec2e7f45441dc6c754b" - integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ== +"@babel/helper-compilation-targets@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz#18d35bfb9f83b1293c22c55b3d576c1315b6ed96" + integrity sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" + "@babel/compat-data" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" browserslist "^4.20.2" semver "^6.3.0" @@ -391,18 +410,18 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" -"@babel/helper-create-class-features-plugin@^7.17.12", "@babel/helper-create-class-features-plugin@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.0.tgz#fac430912606331cb075ea8d82f9a4c145a4da19" - integrity sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg== +"@babel/helper-create-class-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.6.tgz#6f15f8459f3b523b39e00a99982e2c040871ed72" + integrity sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-member-expression-to-functions" "^7.18.6" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-create-regexp-features-plugin@^7.16.7": version "7.17.0" @@ -412,13 +431,13 @@ "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^5.0.1" -"@babel/helper-create-regexp-features-plugin@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.12.tgz#bb37ca467f9694bbe55b884ae7a5cc1e0084e4fd" - integrity sha512-b2aZrV4zvutr9AIa6/gA3wsZKRwTKYoDxYiFKcESS3Ug2GTXzwBEvMuuFLhCQpEnRXs1zng4ISAXSUxxKBIcxw== +"@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^5.0.1" + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" "@babel/helper-define-polyfill-provider@^0.3.1": version "0.3.1" @@ -441,10 +460,10 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-environment-visitor@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz#8a6d2dedb53f6bf248e31b4baf38739ee4a637bd" - integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ== +"@babel/helper-environment-visitor@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz#b7eee2b5b9d70602e59d1a6cad7dd24de7ca6cd7" + integrity sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q== "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" @@ -453,6 +472,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" @@ -461,6 +487,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.17.0" +"@babel/helper-function-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz#8334fecb0afba66e6d87a7e8c6bb7fed79926b83" + integrity sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/helper-hoist-variables@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" @@ -468,6 +502,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" @@ -475,6 +516,13 @@ dependencies: "@babel/types" "^7.17.0" +"@babel/helper-member-expression-to-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.6.tgz#44802d7d602c285e1692db0bad9396d007be2afc" + integrity sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" @@ -482,6 +530,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7": version "7.17.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" @@ -496,19 +551,19 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" -"@babel/helper-module-transforms@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd" - integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA== +"@babel/helper-module-transforms@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.8.tgz#4f8408afead0188cfa48672f9d0e5787b61778c8" + integrity sha512-che3jvZwIcZxrwh63VfnFTUzcAM9v/lznYkkRxIBGMPt1SudOKHAEec0SIRCfiuIzTcF7VGj/CaTT6gY4eWxvA== dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.0" - "@babel/types" "^7.18.0" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.8" + "@babel/types" "^7.18.8" "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" @@ -517,6 +572,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-plugin-utils@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" @@ -527,10 +589,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-plugin-utils@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" - integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== +"@babel/helper-plugin-utils@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz#9448974dd4fb1d80fefe72e8a0af37809cd30d6d" + integrity sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg== "@babel/helper-remap-async-to-generator@^7.16.8": version "7.16.8" @@ -541,6 +603,16 @@ "@babel/helper-wrap-function" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-remap-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz#fa1f81acd19daee9d73de297c0308783cd3cfc23" + integrity sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-wrap-function" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -552,16 +624,16 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/helper-replace-supers@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.2.tgz#41fdfcc9abaf900e18ba6e5931816d9062a7b2e0" - integrity sha512-XzAIyxx+vFnrOxiQrToSUOzUOn0e1J2Li40ntddek1Y69AXUTXoDJ40/D5RdjFu7s7qHiaeoTiempZcbuVXh2Q== +"@babel/helper-replace-supers@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.6.tgz#efedf51cfccea7b7b8c0f00002ab317e7abfe420" + integrity sha512-fTf7zoXnUGl9gF25fXCWE26t7Tvtyn6H4hkLSYhATwJvw2uYxd3aoXplMSe0g9XbwK7bmxNes7+FGO0rB/xC0g== dependencies: - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-member-expression-to-functions" "^7.18.6" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" "@babel/helper-simple-access@^7.17.7": version "7.17.7" @@ -570,12 +642,12 @@ dependencies: "@babel/types" "^7.17.0" -"@babel/helper-simple-access@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" - integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ== +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== dependencies: - "@babel/types" "^7.18.2" + "@babel/types" "^7.18.6" "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" @@ -584,6 +656,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-skip-transparent-expression-wrappers@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.6.tgz#7dff00a5320ca4cf63270e5a0eca4b268b7380d9" + integrity sha512-4KoLhwGS9vGethZpAhYnMejWkX64wsnHPDwvOsKWU6Fg4+AlK2Jz3TyjQLMEPvz+1zemi/WBdkYxCD0bAfIkiw== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -591,16 +670,33 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + "@babel/helper-wrap-function@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" @@ -611,6 +707,16 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-wrap-function@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.6.tgz#ec44ea4ad9d8988b90c3e465ba2382f4de81a073" + integrity sha512-I5/LZfozwMNbwr/b1vhhuYD+J/mU+gfGAj5td7l5Rv9WYmH6i3Om69WGKNmlIpsVW/mF6O5bvTKbvDQZVgjqOw== + dependencies: + "@babel/helper-function-name" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/helpers@^7.12.5", "@babel/helpers@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" @@ -620,14 +726,14 @@ "@babel/traverse" "^7.17.9" "@babel/types" "^7.17.0" -"@babel/helpers@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.2.tgz#970d74f0deadc3f5a938bfa250738eb4ac889384" - integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg== +"@babel/helpers@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.6.tgz#4c966140eaa1fcaa3d5a8c09d7db61077d4debfd" + integrity sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ== dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" "@babel/highlight@^7.16.7": version "7.17.9" @@ -638,15 +744,24 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.12.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== -"@babel/parser@^7.18.0", "@babel/parser@^7.18.3": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef" - integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== +"@babel/parser@^7.18.6", "@babel/parser@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.8.tgz#822146080ac9c62dac0823bb3489622e0bc1cbdf" + integrity sha512-RSKRfYX20dyH+elbJK2uqAkVyucL+xXzhqlMD5/ZXx+dAAwpyB7HsvnHe/ZUGOF+xLr5Wx9/JoXVTj6BQE2/oA== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" @@ -655,12 +770,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.17.12.tgz#1dca338caaefca368639c9ffb095afbd4d420b1e" - integrity sha512-xCJQXl4EeQ3J9C4yOmpTrtVGmzpm2iSzyxbkZHw7UCnZBftHpF/hpII80uWVyVrc40ytIClHjgWGTG1g/yB+aw== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": version "7.16.7" @@ -671,14 +786,14 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-proposal-optional-chaining" "^7.16.7" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.17.12.tgz#0d498ec8f0374b1e2eb54b9cb2c4c78714c77753" - integrity sha512-/vt0hpIw0x4b6BLKUkwlvEoiGZYYLNZ96CzyHYPbtG2jZGz6LBe7/V+drYrc/d+ovrF9NBi0pmtvmNb/FsWtRQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.6.tgz#b4e4dbc2cd1acd0133479918f7c6412961c9adb8" + integrity sha512-Udgu8ZRgrBrttVz6A0EVL0SJ1z+RLbIeqsu632SA1hf0awEppD6TvdznoH+orIF8wtFFAV/Enmw9Y+9oV8TQcw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.6" "@babel/plugin-proposal-async-generator-functions@^7.16.8": version "7.16.8" @@ -689,13 +804,14 @@ "@babel/helper-remap-async-to-generator" "^7.16.8" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-async-generator-functions@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.17.12.tgz#094a417e31ce7e692d84bab06c8e2a607cbeef03" - integrity sha512-RWVvqD1ooLKP6IqWTA5GyFVX2isGEgC5iFxKzfYOIy/QEFdxYyCybBDtIGjipHpb9bDWHzcqGqFakf+mVmBTdQ== +"@babel/plugin-proposal-async-generator-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" + integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@^7.16.7": @@ -706,13 +822,13 @@ "@babel/helper-create-class-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-class-properties@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.17.12.tgz#84f65c0cc247d46f40a6da99aadd6438315d80a4" - integrity sha512-U0mI9q8pW5Q9EaTHFPwSVusPMV/DV9Mm8p7csqROFLtIE9rBF5piLqyrBGigftALrBcsBGu4m38JneAe7ZDLXw== +"@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-class-static-block@^7.16.7": version "7.17.6" @@ -723,13 +839,13 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-class-static-block@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.0.tgz#7d02253156e3c3793bdb9f2faac3a1c05f0ba710" - integrity sha512-t+8LsRMMDE74c6sV7KShIw13sqbqd58tlqNrsWoWBTIMw7SVQ0cZ905wLNS/FBCy/3PyooRHLFFlfrUNyyz5lA== +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-dynamic-import@^7.16.7": @@ -740,6 +856,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-export-namespace-from@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" @@ -748,12 +872,12 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.17.12.tgz#b22864ccd662db9606edb2287ea5fd1709f05378" - integrity sha512-j7Ye5EWdwoXOpRmo5QmRyHPsDIe6+u70ZYZrd7uz+ebPYFKfRcLcNu3Ro0vOlJ5zuv8rU7xa+GttNiRzX56snQ== +"@babel/plugin-proposal-export-namespace-from@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.6.tgz#1016f0aa5ab383bbf8b3a85a2dcaedf6c8ee7491" + integrity sha512-zr/QcUlUo7GPo6+X1wC98NJADqmy5QTFWWhqeQWiki4XHafJtLl/YMGkmRB2szDD2IYJCCdBTd4ElwhId9T7Xw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-proposal-json-strings@^7.16.7": @@ -764,12 +888,12 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.17.12.tgz#f4642951792437233216d8c1af370bb0fbff4664" - integrity sha512-rKJ+rKBoXwLnIn7n6o6fulViHMrOThz99ybH+hKHcOZbnN14VuMnH9fo2eHE69C8pO4uX1Q7t2HYYIDmv8VYkg== +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-proposal-logical-assignment-operators@^7.16.7": @@ -780,12 +904,12 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-logical-assignment-operators@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.17.12.tgz#c64a1bcb2b0a6d0ed2ff674fd120f90ee4b88a23" - integrity sha512-EqFo2s1Z5yy+JeJu7SFfbIUtToJTVlC61/C7WLKDntSw4Sz6JNAIfL7zQ74VvirxpjB5kz/kIx0gCcb+5OEo2Q== +"@babel/plugin-proposal-logical-assignment-operators@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.6.tgz#3b9cac6f1ffc2aa459d111df80c12020dfc6b665" + integrity sha512-zMo66azZth/0tVd7gmkxOkOjs2rpHyhpcFo565PUP37hSp6hSd9uUKIfTDFMz58BwqgQKhJ9YxtM5XddjXVn+Q== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": @@ -796,12 +920,12 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.17.12.tgz#1e93079bbc2cbc756f6db6a1925157c4a92b94be" - integrity sha512-ws/g3FSGVzv+VH86+QvgtuJL/kR67xaEIF2x0iPqdDfYW6ra6JF3lKVBkWynRLcNtIC1oCTfDRVxmm2mKzy+ag== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-proposal-numeric-separator@^7.16.7": @@ -812,6 +936,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" @@ -832,16 +964,16 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.16.7" -"@babel/plugin-proposal-object-rest-spread@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.0.tgz#79f2390c892ba2a68ec112eb0d895cfbd11155e8" - integrity sha512-nbTv371eTrFabDfHLElkn9oyf9VG+VKK6WMzhY2o4eHKaG19BToD9947zzGMO6I/Irstx9d8CwX6njPNIAR/yw== +"@babel/plugin-proposal-object-rest-spread@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.6.tgz#ec93bba06bfb3e15ebd7da73e953d84b094d5daf" + integrity sha512-9yuM6wr4rIsKa1wlUAbZEazkCrgw2sMPEXCr4Rnwetu7cEW1NydkCWytLuYletbf8vFxdJxFhwEZqMpOx2eZyw== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-compilation-targets" "^7.17.10" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/compat-data" "^7.18.6" + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.17.12" + "@babel/plugin-transform-parameters" "^7.18.6" "@babel/plugin-proposal-optional-catch-binding@^7.16.7": version "7.16.7" @@ -851,6 +983,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" @@ -860,13 +1000,13 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.17.12.tgz#f96949e9bacace3a9066323a5cf90cfb9de67174" - integrity sha512-7wigcOs/Z4YWlK7xxjkvaIw84vGhDv/P1dFGQap0nHkc8gFKY/r+hXc8Qzf5k1gY7CvGIcHqAnOagVKJJ1wVOQ== +"@babel/plugin-proposal-optional-chaining@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.6.tgz#46d4f2ffc20e87fad1d98bc4fa5d466366f6aa0b" + integrity sha512-PatI6elL5eMzoypFAiYDpYQyMtXTn+iMhuxxQt5mAXD4fEmKorpSI3PHd+i3JXBJN3xyA6MvJv7at23HffFHwA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.6" "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-proposal-private-methods@^7.16.11": @@ -877,13 +1017,13 @@ "@babel/helper-create-class-features-plugin" "^7.16.10" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-private-methods@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.17.12.tgz#c2ca3a80beb7539289938da005ad525a038a819c" - integrity sha512-SllXoxo19HmxhDWm3luPz+cPhtoTSKLJE9PXshsfrOzBqs60QP0r8OaJItrPhAj0d7mZMnNF0Y1UUggCDgMz1A== +"@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-private-property-in-object@^7.16.7": version "7.16.7" @@ -895,14 +1035,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-private-property-in-object@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.17.12.tgz#b02efb7f106d544667d91ae97405a9fd8c93952d" - integrity sha512-/6BtVi57CJfrtDNKfK5b66ydK2J5pXUKBKSPD2G1whamMuEnZWgoOIfO8Vf9F/DoD4izBLD/Au4NMQfruzzykg== +"@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": @@ -913,13 +1053,13 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-unicode-property-regex@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.17.12.tgz#3dbd7a67bd7f94c8238b394da112d86aaf32ad4d" - integrity sha512-Wb9qLjXf3ZazqXA7IvI7ozqRIXIGPtSo+L5coFmEkhTQK18ao4UDDD0zdTGAarmbLj2urpRwrc6893cu5Bfh0A== +"@babel/plugin-proposal-unicode-property-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -956,12 +1096,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.17.12.tgz#58096a92b11b2e4e54b24c6a0cc0e5e607abcedd" - integrity sha512-n/loy2zkq9ZEM8tEOwON9wTQSTNDTDEz6NujPtJGLU7qObzT1N4c4YZZf8E6ATB2AjNQg/Ib2AIpO03EZaCehw== +"@babel/plugin-syntax-import-assertions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" + integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" @@ -984,12 +1124,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-syntax-jsx@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz#834035b45061983a491f60096f61a2e7c5674a47" - integrity sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog== +"@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" @@ -1054,12 +1194,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-syntax-typescript@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz#b54fc3be6de734a56b87508f99d6428b5b605a7b" - integrity sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw== +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-arrow-functions@^7.16.7": version "7.16.7" @@ -1068,12 +1208,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-arrow-functions@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz#dddd783b473b1b1537ef46423e3944ff24898c45" - integrity sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA== +"@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-async-to-generator@^7.16.8": version "7.16.8" @@ -1084,14 +1224,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-remap-async-to-generator" "^7.16.8" -"@babel/plugin-transform-async-to-generator@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.17.12.tgz#dbe5511e6b01eee1496c944e35cdfe3f58050832" - integrity sha512-J8dbrWIOO3orDzir57NRsjg4uxucvhby0L/KZuGsWDj0g7twWK3g7JhJhOrXtuXiw8MeiSdJ3E0OW9H8LYEzLQ== +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" "@babel/plugin-transform-block-scoped-functions@^7.16.7": version "7.16.7" @@ -1100,6 +1240,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-block-scoping@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" @@ -1107,12 +1254,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-block-scoping@^7.17.12": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.4.tgz#7988627b3e9186a13e4d7735dc9c34a056613fb9" - integrity sha512-+Hq10ye+jlvLEogSOtq4mKvtk7qwcUQ1f0Mrueai866C82f844Yom2cttfJdMdqRLTxWpsbfbkIkOIfovyUQXw== +"@babel/plugin-transform-block-scoping@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.6.tgz#b5f78318914615397d86a731ef2cc668796a726c" + integrity sha512-pRqwb91C42vs1ahSAWJkxOxU1RHWDn16XAa6ggQ72wjLlWyYeAcLvTtE0aM8ph3KNydy9CQF2nLYcjq1WysgxQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-classes@^7.16.7": version "7.16.7" @@ -1128,18 +1275,18 @@ "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" -"@babel/plugin-transform-classes@^7.17.12": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.4.tgz#51310b812a090b846c784e47087fa6457baef814" - integrity sha512-e42NSG2mlKWgxKUAD9EJJSkZxR67+wZqzNxLSpc51T8tRU5SLFHsPmgYR5yr7sdgX4u+iHA1C5VafJ6AyImV3A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-replace-supers" "^7.18.2" - "@babel/helper-split-export-declaration" "^7.16.7" +"@babel/plugin-transform-classes@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.8.tgz#7e85777e622e979c85c701a095280360b818ce49" + integrity sha512-RySDoXdF6hgHSHuAW4aLGyVQdmvEX/iJtjVre52k0pxRq4hzqze+rAVP++NmNv596brBpYmaiKgTZby7ziBnVg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.16.7": @@ -1149,12 +1296,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-computed-properties@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.17.12.tgz#bca616a83679698f3258e892ed422546e531387f" - integrity sha512-a7XINeplB5cQUWMg1E/GI1tFz3LfK021IjV1rj1ypE+R7jHm+pIHmHl25VNkZxtx9uuYp7ThGk8fur1HHG7PgQ== +"@babel/plugin-transform-computed-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.6.tgz#5d15eb90e22e69604f3348344c91165c5395d032" + integrity sha512-9repI4BhNrR0KenoR9vm3/cIc1tSBIo+u1WVjKCAynahj25O8zfbiE6JtAtHPGQSs4yZ+bA8mRasRP+qc+2R5A== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-destructuring@^7.16.7": version "7.17.7" @@ -1163,12 +1310,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-destructuring@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.0.tgz#dc4f92587e291b4daa78aa20cc2d7a63aa11e858" - integrity sha512-Mo69klS79z6KEfrLg/1WkmVnB8javh75HX4pi2btjvlIoasuxilEyjtsQW6XPrubNd7AQy0MMaNIaQE4e7+PQw== +"@babel/plugin-transform-destructuring@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.6.tgz#a98b0e42c7ffbf5eefcbcf33280430f230895c6f" + integrity sha512-tgy3u6lRp17ilY8r1kP4i2+HDUwxlVqq3RTc943eAWSzGgpU1qhiKpqZ5CMyHReIYPHdo3Kg8v8edKtDqSVEyQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" @@ -1178,6 +1325,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-dotall-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-duplicate-keys@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" @@ -1185,12 +1340,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-duplicate-keys@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.17.12.tgz#a09aa709a3310013f8e48e0e23bc7ace0f21477c" - integrity sha512-EA5eYFUG6xeerdabina/xIoB95jJ17mAkR8ivx6ZSu9frKShBjpOGZPn511MTDTkiCO+zXnzNczvUM69YSf3Zw== +"@babel/plugin-transform-duplicate-keys@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.6.tgz#e6c94e8cd3c9dd8a88144f7b78ae22975a7ff473" + integrity sha512-NJU26U/208+sxYszf82nmGYqVF9QN8py2HFTblPT9hbawi8+1C5a9JubODLTGFuT0qlkqVinmkwOD13s0sZktg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-exponentiation-operator@^7.16.7": version "7.16.7" @@ -1200,6 +1355,14 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-for-of@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" @@ -1207,12 +1370,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-for-of@^7.18.1": - version "7.18.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.1.tgz#ed14b657e162b72afbbb2b4cdad277bf2bb32036" - integrity sha512-+TTB5XwvJ5hZbO8xvl2H4XaMDOAK57zF4miuC9qQJgysPNEAZZ9Z69rdF5LJkozGdZrjBIUAIyKUWRMmebI7vg== +"@babel/plugin-transform-for-of@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-function-name@^7.16.7": version "7.16.7" @@ -1223,6 +1386,15 @@ "@babel/helper-function-name" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-function-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.6.tgz#6a7e4ae2893d336fd1b8f64c9f92276391d0f1b4" + integrity sha512-kJha/Gbs5RjzIu0CxZwf5e3aTTSlhZnHMT8zPWnJMjNpLOUgqevg+PN5oMH68nMCXnfiMo4Bhgxqj59KHTlAnA== + dependencies: + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" @@ -1230,12 +1402,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-literals@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.17.12.tgz#97131fbc6bbb261487105b4b3edbf9ebf9c830ae" - integrity sha512-8iRkvaTjJciWycPIZ9k9duu663FT7VrBdNqNgxnVXEFwOIp55JWcZd23VBRySYbnS3PwQ3rGiabJBBBGj5APmQ== +"@babel/plugin-transform-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.6.tgz#9d6af353b5209df72960baf4492722d56f39a205" + integrity sha512-x3HEw0cJZVDoENXOp20HlypIHfl0zMIhMVZEBVTfmqbObIpsMxMbmU5nOEO8R7LYT+z5RORKPlTI5Hj4OsO9/Q== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-member-expression-literals@^7.16.7": version "7.16.7" @@ -1244,6 +1416,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-modules-amd@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" @@ -1253,13 +1432,13 @@ "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-amd@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.0.tgz#7ef1002e67e36da3155edc8bf1ac9398064c02ed" - integrity sha512-h8FjOlYmdZwl7Xm2Ug4iX2j7Qy63NANI+NQVWQzv6r25fqgg7k2dZl03p95kvqNclglHs4FZ+isv4p1uXMA+QA== +"@babel/plugin-transform-modules-amd@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-commonjs@^7.16.8": @@ -1272,14 +1451,14 @@ "@babel/helper-simple-access" "^7.17.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz#1aa8efa2e2a6e818b6a7f2235fceaf09bdb31e9e" - integrity sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ== +"@babel/plugin-transform-modules-commonjs@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-simple-access" "^7.18.2" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.16.7": @@ -1293,15 +1472,15 @@ "@babel/helper-validator-identifier" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.18.0": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz#3d6fd9868c735cce8f38d6ae3a407fb7e61e6d46" - integrity sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg== +"@babel/plugin-transform-modules-systemjs@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.6.tgz#026511b7657d63bf5d4cf2fd4aeb963139914a54" + integrity sha512-UbPYpXxLjTw6w6yXX2BYNxF3p6QY225wcTkfQCy3OMnSlS/C3xGtwUjEzGkldb/sy6PWLiCQ3NbYfjWUTI3t4g== dependencies: - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-umd@^7.16.7": @@ -1312,13 +1491,13 @@ "@babel/helper-module-transforms" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-modules-umd@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.0.tgz#56aac64a2c2a1922341129a4597d1fd5c3ff020f" - integrity sha512-d/zZ8I3BWli1tmROLxXLc9A6YXvGK8egMxHp+E/rRwMh1Kip0AP77VwZae3snEJ33iiWwvNv2+UIIhfalqhzZA== +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": version "7.16.8" @@ -1327,13 +1506,13 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.16.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.12.tgz#9c4a5a5966e0434d515f2675c227fd8cc8606931" - integrity sha512-vWoWFM5CKaTeHrdUJ/3SIOTRV+MBVGybOC9mhJkaprGNt5demMymDW24yC74avb915/mIRe3TgNb/d8idvnCRA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-new-target@^7.16.7": version "7.16.7" @@ -1342,12 +1521,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-new-target@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz#10842cd605a620944e81ea6060e9e65c265742e3" - integrity sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w== +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-object-super@^7.16.7": version "7.16.7" @@ -1357,6 +1536,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" @@ -1364,12 +1551,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-parameters@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.17.12.tgz#eb467cd9586ff5ff115a9880d6fdbd4a846b7766" - integrity sha512-6qW4rWo1cyCdq1FkYri7AHpauchbGLXpdwnYsfxFb+KtddHENfsY5JZb35xUwkK5opOLcJ3BNd2l7PhRYGlwIA== +"@babel/plugin-transform-parameters@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-property-literals@^7.16.7": version "7.16.7" @@ -1378,6 +1565,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-react-constant-elements@^7.14.5": version "7.17.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.17.6.tgz#6cc273c2f612a6a50cb657e63ee1303e5e68d10a" @@ -1392,6 +1586,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-react-jsx-development@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" @@ -1399,6 +1600,13 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.16.7" +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx@^7.16.7": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz#eac1565da176ccb1a715dae0b4609858808008c1" @@ -1410,16 +1618,16 @@ "@babel/plugin-syntax-jsx" "^7.16.7" "@babel/types" "^7.17.0" -"@babel/plugin-transform-react-jsx@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz#2aa20022709cd6a3f40b45d60603d5f269586dba" - integrity sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ== +"@babel/plugin-transform-react-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.6.tgz#2721e96d31df96e3b7ad48ff446995d26bc028ff" + integrity sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-jsx" "^7.17.12" - "@babel/types" "^7.17.12" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.18.6" "@babel/plugin-transform-react-pure-annotations@^7.16.7": version "7.16.7" @@ -1429,6 +1637,14 @@ "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-regenerator@^7.16.7": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c" @@ -1436,12 +1652,12 @@ dependencies: regenerator-transform "^0.15.0" -"@babel/plugin-transform-regenerator@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz#44274d655eb3f1af3f3a574ba819d3f48caf99d5" - integrity sha512-C8YdRw9uzx25HSIzwA7EM7YP0FhCe5wNvJbZzjVNHHPGVcDJ3Aie+qGYYdS1oVQgn+B3eAIJbWFLrJ4Jipv7nw== +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" regenerator-transform "^0.15.0" "@babel/plugin-transform-reserved-words@^7.16.7": @@ -1451,23 +1667,23 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-reserved-words@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.17.12.tgz#7dbd349f3cdffba751e817cf40ca1386732f652f" - integrity sha512-1KYqwbJV3Co03NIi14uEHW8P50Md6KqFgt0FfpHdK6oyAHQVTosgPuPSiWud1HX0oYJ1hGRRlk0fP87jFpqXZA== +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-runtime@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz#04637de1e45ae8847ff14b9beead09c33d34374d" - integrity sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg== +"@babel/plugin-transform-runtime@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.6.tgz#77b14416015ea93367ca06979710f5000ff34ccb" + integrity sha512-8uRHk9ZmRSnWqUgyae249EJZ94b0yAGLBIqzZzl+0iEdbno55Pmlt/32JZsHwXD9k/uZj18Aqqk35wBX4CBTXA== dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + babel-plugin-polyfill-corejs2 "^0.3.1" + babel-plugin-polyfill-corejs3 "^0.5.2" + babel-plugin-polyfill-regenerator "^0.3.1" semver "^6.3.0" "@babel/plugin-transform-shorthand-properties@^7.16.7": @@ -1477,6 +1693,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-spread@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" @@ -1485,13 +1708,13 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" -"@babel/plugin-transform-spread@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.17.12.tgz#c112cad3064299f03ea32afed1d659223935d1f5" - integrity sha512-9pgmuQAtFi3lpNUstvG9nGfk9DkrdmWNp9KeKPFmuZCpEnxRzYlS8JgwPjYj+1AWDOSvoGN0H30p1cBOmT/Svg== +"@babel/plugin-transform-spread@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.6.tgz#82b080241965f1689f0a60ecc6f1f6575dbdb9d6" + integrity sha512-ayT53rT/ENF8WWexIRg9AiV9h0aIteyWn5ptfZTZQrjk/+f3WdrJGCY4c9wcgl2+MKkKPhzbYp97FTsquZpDCw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.6" "@babel/plugin-transform-sticky-regex@^7.16.7": version "7.16.7" @@ -1500,6 +1723,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-template-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" @@ -1507,12 +1737,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-template-literals@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.2.tgz#31ed6915721864847c48b656281d0098ea1add28" - integrity sha512-/cmuBVw9sZBGZVOMkpAEaVLwm4JmK2GZ1dFKOGGpMzEHWFmyZZ59lUU0PdRr8YNYeQdNzTDwuxP2X2gzydTc9g== +"@babel/plugin-transform-template-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.6.tgz#b763f4dc9d11a7cce58cf9a490d82e80547db9c2" + integrity sha512-UuqlRrQmT2SWRvahW46cGSany0uTlcj8NYOS5sRGYi8FxPYPoLd5DDmMd32ZXEj2Jq+06uGVQKHxa/hJx2EzKw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-typeof-symbol@^7.16.7": version "7.16.7" @@ -1521,12 +1751,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-typeof-symbol@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.17.12.tgz#0f12f57ac35e98b35b4ed34829948d42bd0e6889" - integrity sha512-Q8y+Jp7ZdtSPXCThB6zjQ74N3lj0f6TDh1Hnf5B+sYlzQ8i5Pjp8gW0My79iekSpT4WnI06blqP6DT0OmaXXmw== +"@babel/plugin-transform-typeof-symbol@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.6.tgz#486bb39d5a18047358e0d04dc0d2f322f0b92e92" + integrity sha512-7m71iS/QhsPk85xSjFPovHPcH3H9qeyzsujhTc+vcdnsXavoWYJ74zx0lP5RhpC5+iDnVLO+PPMHzC11qels1g== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-typescript@^7.16.7": version "7.16.8" @@ -1537,14 +1767,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-typescript" "^7.16.7" -"@babel/plugin-transform-typescript@^7.17.12": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz#587eaf6a39edb8c06215e550dc939faeadd750bf" - integrity sha512-l4vHuSLUajptpHNEOUDEGsnpl9pfRLsN1XUoDQDD/YBuXTM+v37SHGS+c6n4jdcZy96QtuUuSvZYMLSSsjH8Mw== +"@babel/plugin-transform-typescript@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" + integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-typescript" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-typescript" "^7.18.6" "@babel/plugin-transform-unicode-escapes@^7.16.7": version "7.16.7" @@ -1553,6 +1783,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-escapes@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" + integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-unicode-regex@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" @@ -1561,6 +1798,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/preset-env@^7.15.6": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" @@ -1641,38 +1886,38 @@ core-js-compat "^3.20.2" semver "^6.3.0" -"@babel/preset-env@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.2.tgz#f47d3000a098617926e674c945d95a28cb90977a" - integrity sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q== - dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-compilation-targets" "^7.18.2" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.17.12" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.17.12" - "@babel/plugin-proposal-async-generator-functions" "^7.17.12" - "@babel/plugin-proposal-class-properties" "^7.17.12" - "@babel/plugin-proposal-class-static-block" "^7.18.0" - "@babel/plugin-proposal-dynamic-import" "^7.16.7" - "@babel/plugin-proposal-export-namespace-from" "^7.17.12" - "@babel/plugin-proposal-json-strings" "^7.17.12" - "@babel/plugin-proposal-logical-assignment-operators" "^7.17.12" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.17.12" - "@babel/plugin-proposal-numeric-separator" "^7.16.7" - "@babel/plugin-proposal-object-rest-spread" "^7.18.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" - "@babel/plugin-proposal-optional-chaining" "^7.17.12" - "@babel/plugin-proposal-private-methods" "^7.17.12" - "@babel/plugin-proposal-private-property-in-object" "^7.17.12" - "@babel/plugin-proposal-unicode-property-regex" "^7.17.12" +"@babel/preset-env@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.6.tgz#953422e98a5f66bc56cd0b9074eaea127ec86ace" + integrity sha512-WrthhuIIYKrEFAwttYzgRNQ5hULGmwTj+D6l7Zdfsv5M7IWV/OZbUfbeL++Qrzx1nVJwWROIFhCHRYQV4xbPNw== + dependencies: + "@babel/compat-data" "^7.18.6" + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.6" + "@babel/plugin-proposal-async-generator-functions" "^7.18.6" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.6" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.6" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.18.6" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.6" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.17.12" + "@babel/plugin-syntax-import-assertions" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -1682,43 +1927,43 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.17.12" - "@babel/plugin-transform-async-to-generator" "^7.17.12" - "@babel/plugin-transform-block-scoped-functions" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.17.12" - "@babel/plugin-transform-classes" "^7.17.12" - "@babel/plugin-transform-computed-properties" "^7.17.12" - "@babel/plugin-transform-destructuring" "^7.18.0" - "@babel/plugin-transform-dotall-regex" "^7.16.7" - "@babel/plugin-transform-duplicate-keys" "^7.17.12" - "@babel/plugin-transform-exponentiation-operator" "^7.16.7" - "@babel/plugin-transform-for-of" "^7.18.1" - "@babel/plugin-transform-function-name" "^7.16.7" - "@babel/plugin-transform-literals" "^7.17.12" - "@babel/plugin-transform-member-expression-literals" "^7.16.7" - "@babel/plugin-transform-modules-amd" "^7.18.0" - "@babel/plugin-transform-modules-commonjs" "^7.18.2" - "@babel/plugin-transform-modules-systemjs" "^7.18.0" - "@babel/plugin-transform-modules-umd" "^7.18.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.17.12" - "@babel/plugin-transform-new-target" "^7.17.12" - "@babel/plugin-transform-object-super" "^7.16.7" - "@babel/plugin-transform-parameters" "^7.17.12" - "@babel/plugin-transform-property-literals" "^7.16.7" - "@babel/plugin-transform-regenerator" "^7.18.0" - "@babel/plugin-transform-reserved-words" "^7.17.12" - "@babel/plugin-transform-shorthand-properties" "^7.16.7" - "@babel/plugin-transform-spread" "^7.17.12" - "@babel/plugin-transform-sticky-regex" "^7.16.7" - "@babel/plugin-transform-template-literals" "^7.18.2" - "@babel/plugin-transform-typeof-symbol" "^7.17.12" - "@babel/plugin-transform-unicode-escapes" "^7.16.7" - "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.18.6" + "@babel/plugin-transform-classes" "^7.18.6" + "@babel/plugin-transform-computed-properties" "^7.18.6" + "@babel/plugin-transform-destructuring" "^7.18.6" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.6" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.6" + "@babel/plugin-transform-function-name" "^7.18.6" + "@babel/plugin-transform-literals" "^7.18.6" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.18.6" + "@babel/plugin-transform-modules-commonjs" "^7.18.6" + "@babel/plugin-transform-modules-systemjs" "^7.18.6" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.18.6" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.18.6" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.6" + "@babel/plugin-transform-typeof-symbol" "^7.18.6" + "@babel/plugin-transform-unicode-escapes" "^7.18.6" + "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.18.2" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" + "@babel/types" "^7.18.6" + babel-plugin-polyfill-corejs2 "^0.3.1" + babel-plugin-polyfill-corejs3 "^0.5.2" + babel-plugin-polyfill-regenerator "^0.3.1" core-js-compat "^3.22.1" semver "^6.3.0" @@ -1745,17 +1990,17 @@ "@babel/plugin-transform-react-jsx-development" "^7.16.7" "@babel/plugin-transform-react-pure-annotations" "^7.16.7" -"@babel/preset-react@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.17.12.tgz#62adbd2d1870c0de3893095757ed5b00b492ab3d" - integrity sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA== +"@babel/preset-react@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-react-display-name" "^7.16.7" - "@babel/plugin-transform-react-jsx" "^7.17.12" - "@babel/plugin-transform-react-jsx-development" "^7.16.7" - "@babel/plugin-transform-react-pure-annotations" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" "@babel/preset-typescript@^7.15.0": version "7.16.7" @@ -1766,19 +2011,19 @@ "@babel/helper-validator-option" "^7.16.7" "@babel/plugin-transform-typescript" "^7.16.7" -"@babel/preset-typescript@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz#40269e0a0084d56fc5731b6c40febe1c9a4a3e8c" - integrity sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg== +"@babel/preset-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" + integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-typescript" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-typescript" "^7.18.6" -"@babel/runtime-corejs3@^7.18.3": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.3.tgz#52f0241a31e0ec61a6187530af6227c2846bd60c" - integrity sha512-l4ddFwrc9rnR+EJsHsh+TJ4A35YqQz/UqcjtlX2ov53hlJYG5CxtQmNZxyajwDVmCxwy++rtvGU5HazCK4W41Q== +"@babel/runtime-corejs3@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.6.tgz#6f02c5536911f4b445946a2179554b95c8838635" + integrity sha512-cOu5wH2JFBgMjje+a+fz2JNIWU4GzYpl05oSob3UDvBEh6EuIn+TXFHMmBbhSb+k/4HMzgKCQfEEDArAWNF9Cw== dependencies: core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" @@ -1790,10 +2035,10 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.18.3": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" - integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== +"@babel/runtime@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.6.tgz#6a1ef59f838debd670421f8c7f2cbb8da9751580" + integrity sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ== dependencies: regenerator-runtime "^0.13.4" @@ -1806,6 +2051,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" @@ -1822,19 +2076,19 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.2.tgz#b77a52604b5cc836a9e1e08dca01cba67a12d2e8" - integrity sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.18.0" - "@babel/types" "^7.18.2" +"@babel/traverse@^7.18.6", "@babel/traverse@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.8.tgz#f095e62ab46abf1da35e5a2011f43aee72d8d5b0" + integrity sha512-UNg/AcSySJYR/+mIcJQDCv00T+AqRO7j/ZEJLzpaYtgM48rMg5MnkJgyNqkzo88+p4tfRvZJCEiwwfG6h4jkRg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.7" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.8" + "@babel/types" "^7.18.8" debug "^4.1.0" globals "^11.1.0" @@ -1846,12 +2100,12 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354" - integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== +"@babel/types@^7.18.6", "@babel/types@^7.18.7", "@babel/types@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.8.tgz#c5af199951bf41ba4a6a9a6d0d8ad722b30cd42f" + integrity sha512-qwpdsmraq0aJ3osLJRApsc2ouSJCdnMeZwB0DhbtHAtRpZNZCdlbRnHIgcRKzdE1g0iOGg644fzjOBcdOz9cPw== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" "@colors/colors@1.5.0": @@ -1859,43 +2113,44 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@docsearch/css@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.1.0.tgz#6781cad43fc2e034d012ee44beddf8f93ba21f19" - integrity sha512-bh5IskwkkodbvC0FzSg1AxMykfDl95hebEKwxNoq4e5QaGzOXSBgW8+jnMFZ7JU4sTBiB04vZWoUSzNrPboLZA== +"@docsearch/css@3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.1.1.tgz#e0976bf995e383f8ee8657306311b9cb95016330" + integrity sha512-utLgg7E1agqQeqCJn05DWC7XXMk4tMUUnL7MZupcknRu2OzGN13qwey2qA/0NAKkVBGugiWtON0+rlU0QIPojg== -"@docsearch/react@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.1.0.tgz#da943a64c01ee82b04e53b691806469272f943f7" - integrity sha512-bjB6ExnZzf++5B7Tfoi6UXgNwoUnNOfZ1NyvnvPhWgCMy5V/biAtLL4o7owmZSYdAKeFSvZ5Lxm0is4su/dBWg== +"@docsearch/react@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.1.1.tgz#3dffb5db8cf9eb95d6e732cf038264bfc10191ed" + integrity sha512-cfoql4qvtsVRqBMYxhlGNpvyy/KlCoPqjIsJSZYqYf9AplZncKjLBTcwBu6RXFMVCe30cIFljniI4OjqAU67pQ== dependencies: - "@algolia/autocomplete-core" "1.6.3" - "@docsearch/css" "3.1.0" + "@algolia/autocomplete-core" "1.7.1" + "@algolia/autocomplete-preset-algolia" "1.7.1" + "@docsearch/css" "3.1.1" algoliasearch "^4.0.0" -"@docusaurus/core@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-beta.21.tgz#50897317b22dbd94b1bf91bb30c2a0fddd15a806" - integrity sha512-qysDMVp1M5UozK3u/qOxsEZsHF7jeBvJDS+5ItMPYmNKvMbNKeYZGA0g6S7F9hRDwjIlEbvo7BaX0UMDcmTAWA== +"@docusaurus/core@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-rc.1.tgz#828d93d241171565d8947a9ab404091e04759141" + integrity sha512-b9FX0Z+EddfQ6wAiNh+Wx4fysKfcvEcWJrZ5USROn3C+EVU5P4luaa8mwWK//O+hTwD9ur7/A44IZ/tWCTAoLQ== dependencies: - "@babel/core" "^7.18.2" - "@babel/generator" "^7.18.2" + "@babel/core" "^7.18.6" + "@babel/generator" "^7.18.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-runtime" "^7.18.2" - "@babel/preset-env" "^7.18.2" - "@babel/preset-react" "^7.17.12" - "@babel/preset-typescript" "^7.17.12" - "@babel/runtime" "^7.18.3" - "@babel/runtime-corejs3" "^7.18.3" - "@babel/traverse" "^7.18.2" - "@docusaurus/cssnano-preset" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/mdx-loader" "2.0.0-beta.21" + "@babel/plugin-transform-runtime" "^7.18.6" + "@babel/preset-env" "^7.18.6" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.18.6" + "@babel/runtime" "^7.18.6" + "@babel/runtime-corejs3" "^7.18.6" + "@babel/traverse" "^7.18.8" + "@docusaurus/cssnano-preset" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/mdx-loader" "2.0.0-rc.1" "@docusaurus/react-loadable" "5.5.2" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-common" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" - "@slorber/static-site-generator-webpack-plugin" "^4.0.4" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-common" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" + "@slorber/static-site-generator-webpack-plugin" "^4.0.7" "@svgr/webpack" "^6.2.1" autoprefixer "^10.4.7" babel-loader "^8.2.5" @@ -1908,10 +2163,10 @@ combine-promises "^1.1.0" commander "^5.1.0" copy-webpack-plugin "^11.0.0" - core-js "^3.22.7" + core-js "^3.23.3" css-loader "^6.7.1" css-minimizer-webpack-plugin "^4.0.0" - cssnano "^5.1.9" + cssnano "^5.1.12" del "^6.1.1" detect-port "^1.3.0" escape-html "^1.0.3" @@ -1924,7 +2179,7 @@ import-fresh "^3.3.0" leven "^3.1.0" lodash "^4.17.21" - mini-css-extract-plugin "^2.6.0" + mini-css-extract-plugin "^2.6.1" postcss "^8.4.14" postcss-loader "^7.0.0" prompts "^2.4.2" @@ -1935,49 +2190,48 @@ react-router "^5.3.3" react-router-config "^5.1.1" react-router-dom "^5.3.3" - remark-admonitions "^1.2.1" rtl-detect "^1.0.4" semver "^7.3.7" serve-handler "^6.1.3" shelljs "^0.8.5" - terser-webpack-plugin "^5.3.1" + terser-webpack-plugin "^5.3.3" tslib "^2.4.0" update-notifier "^5.1.0" url-loader "^4.1.1" wait-on "^6.0.1" - webpack "^5.72.1" + webpack "^5.73.0" webpack-bundle-analyzer "^4.5.0" - webpack-dev-server "^4.9.0" + webpack-dev-server "^4.9.3" webpack-merge "^5.8.0" webpackbar "^5.0.2" -"@docusaurus/cssnano-preset@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.0.0-beta.21.tgz#38113877a5857c3f9d493522085d20909dcec474" - integrity sha512-fhTZrg1vc6zYYZIIMXpe1TnEVGEjqscBo0s1uomSwKjjtMgu7wkzc1KKJYY7BndsSA+fVVkZ+OmL/kAsmK7xxw== +"@docusaurus/cssnano-preset@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.0.0-rc.1.tgz#76bbd7f6912779a0667f8f2fd8fc1a05618a6148" + integrity sha512-9/KmQvF+eTlMqUqG6UcXbRgxbGed/8bQInXuKEs+95/jI6jO/3xSzuRwuHHHP0naUvSVWjnNI9jngPrQerXE5w== dependencies: - cssnano-preset-advanced "^5.3.5" + cssnano-preset-advanced "^5.3.8" postcss "^8.4.14" postcss-sort-media-queries "^4.2.1" tslib "^2.4.0" -"@docusaurus/logger@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-2.0.0-beta.21.tgz#f6ab4133917965349ae03fd9111a940b24d4fd12" - integrity sha512-HTFp8FsSMrAj7Uxl5p72U+P7rjYU/LRRBazEoJbs9RaqoKEdtZuhv8MYPOCh46K9TekaoquRYqag2o23Qt4ggA== +"@docusaurus/logger@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-2.0.0-rc.1.tgz#db95e9b15bc243695830a5b791c0eff705ef1b54" + integrity sha512-daa3g+SXuO9K60PVMiSUmDEK9Vro+Ed7i7uF8CH6QQJLcNZy/zJc0Xz62eH7ip1x77fmeb6Rg4Us1TqTFc9AbQ== dependencies: chalk "^4.1.2" tslib "^2.4.0" -"@docusaurus/mdx-loader@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-beta.21.tgz#52af341e21f22be882d2155a7349bea10f5d77a3" - integrity sha512-AI+4obJnpOaBOAYV6df2ux5Y1YJCBS+MhXFf0yhED12sVLJi2vffZgdamYd/d/FwvWDw6QLs/VD2jebd7P50yQ== +"@docusaurus/mdx-loader@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-rc.1.tgz#e78d7d416aacc289f2427c5ccdb9145820acb0cb" + integrity sha512-8Fg0c/ceu39knmr7w0dutm7gq3YxKYCqWVS2cB/cPATzChCCNH/AGLfBT6sz/Z4tjVXE+NyREq2pfOFvkhjVXg== dependencies: - "@babel/parser" "^7.18.3" - "@babel/traverse" "^7.18.2" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" + "@babel/parser" "^7.18.8" + "@babel/traverse" "^7.18.8" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" "@mdx-js/mdx" "^1.6.22" escape-html "^1.0.3" file-loader "^6.2.0" @@ -1987,151 +2241,162 @@ remark-emoji "^2.2.0" stringify-object "^3.3.0" tslib "^2.4.0" + unified "^9.2.2" unist-util-visit "^2.0.3" url-loader "^4.1.1" - webpack "^5.72.1" + webpack "^5.73.0" -"@docusaurus/module-type-aliases@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-beta.21.tgz#345f1c1a99407775d1d3ffc1a90c2df93d50a9b8" - integrity sha512-gRkWICgQZiqSJgrwRKWjXm5gAB+9IcfYdUbCG0PRPP/G8sNs9zBIOY4uT4Z5ox2CWFEm44U3RTTxj7BiLVMBXw== +"@docusaurus/module-type-aliases@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-rc.1.tgz#c7839ac15b7712a8d86353a3253918f63ffbea09" + integrity sha512-la7D8ggFP8I5nOp/Epl6NqTeDWcbofPVMOaVisRxQbx5iuF9Al+AITbaDgm4CXpFLJACsqhsXD5W4BnKX8ZxfA== dependencies: - "@docusaurus/types" "2.0.0-beta.21" + "@docusaurus/react-loadable" "5.5.2" + "@docusaurus/types" "2.0.0-rc.1" + "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" "@types/react-router-dom" "*" react-helmet-async "*" + react-loadable "npm:@docusaurus/react-loadable@5.5.2" -"@docusaurus/plugin-client-redirects@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.0.0-beta.21.tgz#bf0c3e94d89c7bd15933dacdfefc17fec22c5d76" - integrity sha512-4xzrti0au7SaQT/cxr+FM9b+R5gfOSFODwQJ2QeTXbkdiz1+9DV3bp8nB/2CmzZ9ApY5lsueXNpa4n7+UAngrA== +"@docusaurus/plugin-client-redirects@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.0.0-rc.1.tgz#ce71d9f73bfbb4b2e159ee3a22f5517b3480c83c" + integrity sha512-uGiK7kzQeJ+gChzIgazKMlHEonOwlmK6NEJvr44aWS6DbauVXOs/aolXZCHx8ZdKPETOpZEzSRYjU5e+QIN+HA== dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-common" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-common" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" eta "^1.12.3" fs-extra "^10.1.0" lodash "^4.17.21" tslib "^2.4.0" -"@docusaurus/plugin-content-blog@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.21.tgz#86211deeea901ddcd77ca387778e121e93ee8d01" - integrity sha512-IP21yJViP3oBmgsWBU5LhrG1MZXV4mYCQSoCAboimESmy1Z11RCNP2tXaqizE3iTmXOwZZL+SNBk06ajKCEzWg== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/mdx-loader" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-common" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" - cheerio "^1.0.0-rc.11" +"@docusaurus/plugin-content-blog@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-rc.1.tgz#8ae5d5ec2da08c583a057bf2754a5b9278b3eb08" + integrity sha512-BVVrAGZujpjS/0rarY2o24rlylRRh2NZuM65kg0JNkkViF79SeEHsepog7IuHyoqGWPm1N/I7LpEp7k+gowZzQ== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/mdx-loader" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-common" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" + cheerio "^1.0.0-rc.12" feed "^4.2.2" fs-extra "^10.1.0" lodash "^4.17.21" reading-time "^1.5.0" - remark-admonitions "^1.2.1" tslib "^2.4.0" unist-util-visit "^2.0.3" utility-types "^3.10.0" - webpack "^5.72.1" - -"@docusaurus/plugin-content-docs@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-beta.21.tgz#b3171fa9aed99e367b6eb7111187bd0e3dcf2949" - integrity sha512-aa4vrzJy4xRy81wNskyhE3wzRf3AgcESZ1nfKh8xgHUkT7fDTZ1UWlg50Jb3LBCQFFyQG2XQB9N6llskI/KUnw== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/mdx-loader" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" + webpack "^5.73.0" + +"@docusaurus/plugin-content-docs@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-rc.1.tgz#2dda88166bf21b0eeb3821ef748059b20c8c49f7" + integrity sha512-Yk5Hu6uaw3tRplzJnbDygwRhmZ3PCzEXD4SJpBA6cPC73ylfqOEh6qhiU+BWhMTtDXNhY+athk5Kycfk3DW1aQ== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/mdx-loader" "2.0.0-rc.1" + "@docusaurus/module-type-aliases" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" + "@types/react-router-config" "^5.0.6" combine-promises "^1.1.0" fs-extra "^10.1.0" import-fresh "^3.3.0" js-yaml "^4.1.0" lodash "^4.17.21" - remark-admonitions "^1.2.1" tslib "^2.4.0" utility-types "^3.10.0" - webpack "^5.72.1" - -"@docusaurus/plugin-content-pages@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-beta.21.tgz#df6b4c5c4cde8a0ea491a30002e84941ca7bf0cf" - integrity sha512-DmXOXjqNI+7X5hISzCvt54QIK6XBugu2MOxjxzuqI7q92Lk/EVdraEj5mthlH8IaEH/VlpWYJ1O9TzLqX5vH2g== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/mdx-loader" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" + webpack "^5.73.0" + +"@docusaurus/plugin-content-pages@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-rc.1.tgz#2be82f53d6c77e6aa66787726c30dc60b210e6f8" + integrity sha512-FdO79WC5hfWDQu3/CTFLRQzTNc0e5n+HNzavm2MNkSzGV08BFJ6RAkbPbtra5CWef+6iXZav6D/tzv2jDPvLzA== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/mdx-loader" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" fs-extra "^10.1.0" - remark-admonitions "^1.2.1" tslib "^2.4.0" - webpack "^5.72.1" + webpack "^5.73.0" -"@docusaurus/plugin-debug@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-beta.21.tgz#dfa212fd90fe2f54439aacdc8c143e8ce96b0d27" - integrity sha512-P54J4q4ecsyWW0Jy4zbimSIHna999AfbxpXGmF1IjyHrjoA3PtuakV1Ai51XrGEAaIq9q6qMQkEhbUd3CffGAw== +"@docusaurus/plugin-debug@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-rc.1.tgz#73c06ad08d66810941e456d50b07be008f5235cb" + integrity sha512-aOsyYrPMbnsyqHwsVZ+0frrMRtnYqm4eaJpG4sC/6LYAJ07IDRQ9j3GOku2dKr5GsFK1Vx7VlE6ZLwe0MaGstg== dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" fs-extra "^10.1.0" react-json-view "^1.21.3" tslib "^2.4.0" -"@docusaurus/plugin-google-analytics@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-beta.21.tgz#5475c58fb23603badf41d84298569f6c46b4e6b2" - integrity sha512-+5MS0PeGaJRgPuNZlbd/WMdQSpOACaxEz7A81HAxm6kE+tIASTW3l8jgj1eWFy/PGPzaLnQrEjxI1McAfnYmQw== +"@docusaurus/plugin-google-analytics@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-rc.1.tgz#0136cc7534573ca56e023178ec2bda5c1e89ce71" + integrity sha512-f+G8z5OJWfg5QqWDLIdcN2SDoK5J5Gg8HMrqCI6Pfl+rxPb5I1niA+/UkAM+kMCpnekvhSt5AWz2fgkRenkPLA== dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" tslib "^2.4.0" -"@docusaurus/plugin-google-gtag@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-beta.21.tgz#a4a101089994a7103c1cc7cddb15170427b185d6" - integrity sha512-4zxKZOnf0rfh6myXLG7a6YZfQcxYDMBsWqANEjCX77H5gPdK+GHZuDrxK6sjFvRBv4liYCrNjo7HJ4DpPoT0zA== +"@docusaurus/plugin-google-gtag@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-rc.1.tgz#61698fdc41a4ace912fb8f6c834efd288edad3c0" + integrity sha512-yE1Et9hhhX9qMRnMJzpNq0854qIYiSEc2dZaXNk537HN7Q0rKkr/YONUHz2iqNYwPX2hGOY4LdpTxlMP88uVhA== dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" tslib "^2.4.0" -"@docusaurus/plugin-sitemap@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-beta.21.tgz#8bfa695eada2ec95c9376a884641237ffca5dd3d" - integrity sha512-/ynWbcXZXcYZ6sT2X6vAJbnfqcPxwdGEybd0rcRZi4gBHq6adMofYI25AqELmnbBDxt0If+vlAeUHFRG5ueP7Q== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-common" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" +"@docusaurus/plugin-sitemap@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.1.tgz#0b638e774b253d90e9f2d11663e961250f557bc4" + integrity sha512-5JmbNpssUF03odFM4ArvIsrO9bv7HnAJ0VtefXhh0WBpaFs8NgI3rTkCTFimvtRQjDR9U2bh23fXz2vjQQz6oA== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-common" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" fs-extra "^10.1.0" sitemap "^7.1.1" tslib "^2.4.0" -"@docusaurus/preset-classic@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-beta.21.tgz#1362d8650ebed22633db411caaba80075f7c86ce" - integrity sha512-KvBnIUu7y69pNTJ9UhX6SdNlK6prR//J3L4rhN897tb8xx04xHHILlPXko2Il+C3Xzgh3OCgyvkoz9K6YlFTDw== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/plugin-content-blog" "2.0.0-beta.21" - "@docusaurus/plugin-content-docs" "2.0.0-beta.21" - "@docusaurus/plugin-content-pages" "2.0.0-beta.21" - "@docusaurus/plugin-debug" "2.0.0-beta.21" - "@docusaurus/plugin-google-analytics" "2.0.0-beta.21" - "@docusaurus/plugin-google-gtag" "2.0.0-beta.21" - "@docusaurus/plugin-sitemap" "2.0.0-beta.21" - "@docusaurus/theme-classic" "2.0.0-beta.21" - "@docusaurus/theme-common" "2.0.0-beta.21" - "@docusaurus/theme-search-algolia" "2.0.0-beta.21" +"@docusaurus/preset-classic@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-rc.1.tgz#5e5b1cf80b3dd4e2c3f824c78a111f105858d853" + integrity sha512-5jjTVZkhArjyoNHwCI9x4PSG0zPmBJILjZLVrxPcHpm/K0ltkYcp6J3GxYpf5EbMuOh5+yCWM63cSshGcNOo3Q== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/plugin-content-blog" "2.0.0-rc.1" + "@docusaurus/plugin-content-docs" "2.0.0-rc.1" + "@docusaurus/plugin-content-pages" "2.0.0-rc.1" + "@docusaurus/plugin-debug" "2.0.0-rc.1" + "@docusaurus/plugin-google-analytics" "2.0.0-rc.1" + "@docusaurus/plugin-google-gtag" "2.0.0-rc.1" + "@docusaurus/plugin-sitemap" "2.0.0-rc.1" + "@docusaurus/theme-classic" "2.0.0-rc.1" + "@docusaurus/theme-common" "2.0.0-rc.1" + "@docusaurus/theme-search-algolia" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" "@docusaurus/react-loadable@5.5.2", "react-loadable@npm:@docusaurus/react-loadable@5.5.2": version "5.5.2" @@ -2141,115 +2406,125 @@ "@types/react" "*" prop-types "^15.6.2" -"@docusaurus/theme-classic@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-beta.21.tgz#6df5b9ea2d389dafb6f59badeabb3eda060b5017" - integrity sha512-Ge0WNdTefD0VDQfaIMRRWa8tWMG9+8/OlBRd5MK88/TZfqdBq7b/gnCSaalQlvZwwkj6notkKhHx72+MKwWUJA== - dependencies: - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/plugin-content-blog" "2.0.0-beta.21" - "@docusaurus/plugin-content-docs" "2.0.0-beta.21" - "@docusaurus/plugin-content-pages" "2.0.0-beta.21" - "@docusaurus/theme-common" "2.0.0-beta.21" - "@docusaurus/theme-translations" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-common" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" +"@docusaurus/theme-classic@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-rc.1.tgz#4ab30745e6b03b0f277837debae786a0a83aee6a" + integrity sha512-qNiz7ieeq3AC+V8TbW6S63pWLJph1CbzWDDPTqxDLHgA8VQaNaSmJM8S92pH+yKALRb9u14ogjjYYc75Nj2JmQ== + dependencies: + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/mdx-loader" "2.0.0-rc.1" + "@docusaurus/module-type-aliases" "2.0.0-rc.1" + "@docusaurus/plugin-content-blog" "2.0.0-rc.1" + "@docusaurus/plugin-content-docs" "2.0.0-rc.1" + "@docusaurus/plugin-content-pages" "2.0.0-rc.1" + "@docusaurus/theme-common" "2.0.0-rc.1" + "@docusaurus/theme-translations" "2.0.0-rc.1" + "@docusaurus/types" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-common" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" "@mdx-js/react" "^1.6.22" - clsx "^1.1.1" + clsx "^1.2.1" copy-text-to-clipboard "^3.0.1" - infima "0.2.0-alpha.39" + infima "0.2.0-alpha.42" lodash "^4.17.21" nprogress "^0.2.0" postcss "^8.4.14" - prism-react-renderer "^1.3.3" + prism-react-renderer "^1.3.5" prismjs "^1.28.0" react-router-dom "^5.3.3" rtlcss "^3.5.0" tslib "^2.4.0" + utility-types "^3.10.0" -"@docusaurus/theme-common@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.0.0-beta.21.tgz#508478251982d01655ef505ccb2420db38623db8" - integrity sha512-fTKoTLRfjuFG6c3iwnVjIIOensxWMgdBKLfyE5iih3Lq7tQgkE7NyTGG9BKLrnTJ7cAD2UXdXM9xbB7tBf1qzg== - dependencies: - "@docusaurus/module-type-aliases" "2.0.0-beta.21" - "@docusaurus/plugin-content-blog" "2.0.0-beta.21" - "@docusaurus/plugin-content-docs" "2.0.0-beta.21" - "@docusaurus/plugin-content-pages" "2.0.0-beta.21" - clsx "^1.1.1" +"@docusaurus/theme-common@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.0.0-rc.1.tgz#ea5d9732a16b03b488555e50107161bfa2abad98" + integrity sha512-1r9ZLKD9SeoCYVzWzcdR79Dia4ANlrlRjNl6uzETOEybjK6FF7yEa9Yra8EJcOCbi3coyYz5xFh/r1YHFTFHug== + dependencies: + "@docusaurus/mdx-loader" "2.0.0-rc.1" + "@docusaurus/module-type-aliases" "2.0.0-rc.1" + "@docusaurus/plugin-content-blog" "2.0.0-rc.1" + "@docusaurus/plugin-content-docs" "2.0.0-rc.1" + "@docusaurus/plugin-content-pages" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router-config" "*" + clsx "^1.2.1" parse-numeric-range "^1.3.0" - prism-react-renderer "^1.3.3" + prism-react-renderer "^1.3.5" tslib "^2.4.0" utility-types "^3.10.0" -"@docusaurus/theme-search-algolia@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-beta.21.tgz#2891f11372e2542e4e1426c3100b72c2d30d4d68" - integrity sha512-T1jKT8MVSSfnztSqeebUOpWHPoHKtwDXtKYE0xC99JWoZ+mMfv8AFhVSoSddn54jLJjV36mxg841eHQIySMCpQ== - dependencies: - "@docsearch/react" "^3.1.0" - "@docusaurus/core" "2.0.0-beta.21" - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/plugin-content-docs" "2.0.0-beta.21" - "@docusaurus/theme-common" "2.0.0-beta.21" - "@docusaurus/theme-translations" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" - "@docusaurus/utils-validation" "2.0.0-beta.21" +"@docusaurus/theme-search-algolia@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-rc.1.tgz#e78c0aeaea6a3717ae3a6ecd75a8652bd7c8e974" + integrity sha512-H5yq6V/B4qo6GZrDKMbeSpk3T9e9K2MliDzLonRu0w3QHW9orVGe0c/lZvRbGlDZjnsOo7XGddhXXIDWGwnpaA== + dependencies: + "@docsearch/react" "^3.1.1" + "@docusaurus/core" "2.0.0-rc.1" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/plugin-content-docs" "2.0.0-rc.1" + "@docusaurus/theme-common" "2.0.0-rc.1" + "@docusaurus/theme-translations" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" + "@docusaurus/utils-validation" "2.0.0-rc.1" algoliasearch "^4.13.1" - algoliasearch-helper "^3.8.2" - clsx "^1.1.1" + algoliasearch-helper "^3.10.0" + clsx "^1.2.1" eta "^1.12.3" fs-extra "^10.1.0" lodash "^4.17.21" tslib "^2.4.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-2.0.0-beta.21.tgz#5da60ffc58de256b96316c5e0fe2733c1e83f22c" - integrity sha512-dLVT9OIIBs6MpzMb1bAy+C0DPJK3e3DNctG+ES0EP45gzEqQxzs4IsghpT+QDaOsuhNnAlosgJpFWX3rqxF9xA== +"@docusaurus/theme-translations@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-2.0.0-rc.1.tgz#bd647f78c741ee7f6c6d2cbbd3e3f282ef2f89ad" + integrity sha512-JLhNdlnbQhxVQzOnLyiCaTzKFa1lpVrM3nCrkGQKscoG2rY6ARGYMgMN2DkoH6hm7TflQ8+PE1S5MzzASeLs4Q== dependencies: fs-extra "^10.1.0" tslib "^2.4.0" -"@docusaurus/types@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-beta.21.tgz#36659c6c012663040dcd4cbc97b5d7a555dae229" - integrity sha512-/GH6Npmq81eQfMC/ikS00QSv9jNyO1RXEpNSx5GLA3sFX8Iib26g2YI2zqNplM8nyxzZ2jVBuvUoeODTIbTchQ== +"@docusaurus/types@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-rc.1.tgz#032f8afde6b4878e37f984b9949a96b150103c21" + integrity sha512-wX25FOZa/aKnCGA5ljWPaDpMW3TuTbs0BtjQ8WTC557p8zDvuz4r+g2/FPHsgWE0TKwUMf4usQU1m3XpJLPN+g== dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" commander "^5.1.0" - history "^4.9.0" joi "^17.6.0" react-helmet-async "^1.3.0" utility-types "^3.10.0" - webpack "^5.72.1" + webpack "^5.73.0" webpack-merge "^5.8.0" -"@docusaurus/utils-common@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-2.0.0-beta.21.tgz#81e86ed04ad62b75e9ba6a5e7689dc23d5f36a0a" - integrity sha512-5w+6KQuJb6pUR2M8xyVuTMvO5NFQm/p8TOTDFTx60wt3p0P1rRX00v6FYsD4PK6pgmuoKjt2+Ls8dtSXc4qFpQ== +"@docusaurus/utils-common@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-2.0.0-rc.1.tgz#3e233a28794325d5d9d3af3f7b1c22b59aa8b847" + integrity sha512-+iZICpeFPZJ9oGJXuG92WTWee6WRnVx5BdzlcfuKf/f5KQX8PvwXR2tDME78FGGhShB8zr+vjuNEXuLvXT7j2A== dependencies: tslib "^2.4.0" -"@docusaurus/utils-validation@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.0.0-beta.21.tgz#10169661be5f8a233f4c12202ee5802ccb77400f" - integrity sha512-6NG1FHTRjv1MFzqW//292z7uCs77vntpWEbZBHk3n67aB1HoMn5SOwjLPtRDjbCgn6HCHFmdiJr6euCbjhYolg== +"@docusaurus/utils-validation@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.0.0-rc.1.tgz#dded12f036cda8a54a19e01694b35859fe0cf1d5" + integrity sha512-lj36gm9Ksu4tt/EUeLDWoMbXe3sfBxeIPIUUdqYcBYkF/rpQkh+uL/dncjNGiw6uvBOqXhOfsFVP045HtgShVw== dependencies: - "@docusaurus/logger" "2.0.0-beta.21" - "@docusaurus/utils" "2.0.0-beta.21" + "@docusaurus/logger" "2.0.0-rc.1" + "@docusaurus/utils" "2.0.0-rc.1" joi "^17.6.0" js-yaml "^4.1.0" tslib "^2.4.0" -"@docusaurus/utils@2.0.0-beta.21": - version "2.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-beta.21.tgz#8fc4499c4cfedd29805025d930f8008cad255044" - integrity sha512-M/BrVCDmmUPZLxtiStBgzpQ4I5hqkggcpnQmEN+LbvbohjbtVnnnZQ0vptIziv1w8jry/woY+ePsyOO7O/yeLQ== +"@docusaurus/utils@2.0.0-rc.1": + version "2.0.0-rc.1" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-rc.1.tgz#53584b800df9e13864d5ef1a76aa7655a90ec86e" + integrity sha512-ym9I1OwIYbKs1LGaUajaA/vDG8VweJj/6YoZjHp+eDQHhTRIrHXiYoGDqorafRhftKwnA1EnyomuXpNd9bq8Gg== dependencies: - "@docusaurus/logger" "2.0.0-beta.21" + "@docusaurus/logger" "2.0.0-rc.1" "@svgr/webpack" "^6.2.1" file-loader "^6.2.0" fs-extra "^10.1.0" @@ -2263,7 +2538,7 @@ shelljs "^0.8.5" tslib "^2.4.0" url-loader "^4.1.1" - webpack "^5.72.1" + webpack "^5.73.0" "@hapi/hoek@^9.0.0": version "9.2.1" @@ -2277,12 +2552,12 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" - integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" @@ -2291,10 +2566,10 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz#4ac237f4dabc8dd93330386907b97591801f7352" integrity sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw== -"@jridgewell/set-array@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.0.tgz#1179863356ac8fbea64a5a4bcde93a4871012c01" - integrity sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" @@ -2309,6 +2584,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.7": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.13" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" @@ -2405,15 +2688,14 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== -"@slorber/static-site-generator-webpack-plugin@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.4.tgz#2bf4a2545e027830d2aa5eb950437c26a289b0f1" - integrity sha512-FvMavoWEIePps6/JwGCOLYKCRhuwIHhMtmbKpBFgzNkxwpa/569LfTkrbRk1m1I3n+ezJK4on9E1A6cjuZmD9g== +"@slorber/static-site-generator-webpack-plugin@^4.0.7": + version "4.0.7" + resolved "https://registry.yarnpkg.com/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz#fc1678bddefab014e2145cbe25b3ce4e1cfc36f3" + integrity sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA== dependencies: - bluebird "^3.7.1" - cheerio "^0.22.0" eval "^0.1.8" - webpack-sources "^1.4.3" + p-map "^4.0.0" + webpack-sources "^3.2.2" "@svgr/babel-plugin-add-jsx-attribute@^6.0.0": version "6.0.0" @@ -2672,7 +2954,7 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-router-config@*": +"@types/react-router-config@*", "@types/react-router-config@^5.0.6": version "5.0.6" resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.6.tgz#87c5c57e72d241db900d9734512c50ccec062451" integrity sha512-db1mx37a1EJDf1XeX8jJN7R3PZABmJQXR8r28yUjVMFSjkmnQo6X6pOEEmNl+Tp2gYQOGPdYbFIipBtdElZ3Yg== @@ -2731,7 +3013,7 @@ dependencies: "@types/express" "*" -"@types/serve-static@*": +"@types/serve-static@*", "@types/serve-static@^1.13.10": version "1.13.10" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== @@ -2964,10 +3246,10 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" -algoliasearch-helper@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.8.2.tgz#35726dc6d211f49dbab0bf6d37b4658165539523" - integrity sha512-AXxiF0zT9oYwl8ZBgU/eRXvfYhz7cBA5YrLPlw9inZHdaYF0QEya/f1Zp1mPYMXc1v6VkHwBq4pk6/vayBLICg== +algoliasearch-helper@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.10.0.tgz#59a0f645dd3c7e55cf01faa568d1af50c49d36f6" + integrity sha512-4E4od8qWWDMVvQ3jaRX6Oks/k35ywD011wAA4LbYMMjOtaZV6VWaTjRr4iN2bdaXP2o1BP7SLFMBf3wvnHmd8Q== dependencies: "@algolia/events" "^4.0.1" @@ -3165,7 +3447,7 @@ babel-plugin-extract-import-names@1.6.22: dependencies: "@babel/helper-plugin-utils" "7.10.4" -babel-plugin-polyfill-corejs2@^0.3.0: +babel-plugin-polyfill-corejs2@^0.3.0, babel-plugin-polyfill-corejs2@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== @@ -3174,7 +3456,7 @@ babel-plugin-polyfill-corejs2@^0.3.0: "@babel/helper-define-polyfill-provider" "^0.3.1" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.5.0: +babel-plugin-polyfill-corejs3@^0.5.0, babel-plugin-polyfill-corejs3@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== @@ -3182,7 +3464,7 @@ babel-plugin-polyfill-corejs3@^0.5.0: "@babel/helper-define-polyfill-provider" "^0.3.1" core-js-compat "^3.21.0" -babel-plugin-polyfill-regenerator@^0.3.0: +babel-plugin-polyfill-regenerator@^0.3.0, babel-plugin-polyfill-regenerator@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== @@ -3219,11 +3501,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bluebird@^3.7.1: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - body-parser@1.19.2: version "1.19.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" @@ -3250,7 +3527,7 @@ bonjour-service@^1.0.11: fast-deep-equal "^3.1.3" multicast-dns "^7.2.4" -boolbase@^1.0.0, boolbase@~1.0.0: +boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -3399,7 +3676,7 @@ caniuse-lite@^1.0.30001335: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz#a9eb13edd2613f418ebc632c8d6c9ab9fde7ccc4" integrity sha512-/YxSlBmL7iKXTbIJ48IQTnAOBk7XmWsxhBF1PZLOko5Dt9qc4Pl+84lfqG3Tc4EuavurRn1QLoVJGxY2iSycfw== -ccount@^1.0.0, ccount@^1.0.3: +ccount@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== @@ -3448,32 +3725,10 @@ cheerio-select@^2.1.0: domhandler "^5.0.3" domutils "^3.0.1" -cheerio@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" - integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" - -cheerio@^1.0.0-rc.11: - version "1.0.0-rc.11" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.11.tgz#1be84be1a126958366bcc57a11648cd9b30a60c2" - integrity sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag== +cheerio@^1.0.0-rc.12: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== dependencies: cheerio-select "^2.1.0" dom-serializer "^2.0.0" @@ -3482,7 +3737,6 @@ cheerio@^1.0.0-rc.11: htmlparser2 "^8.0.1" parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" - tslib "^2.4.0" chokidar@^3.4.2, chokidar@^3.5.3: version "3.5.3" @@ -3556,10 +3810,10 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" -clsx@1.1.1, clsx@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" - integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== +clsx@1.2.1, clsx@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== collapse-white-space@^1.0.2: version "1.0.6" @@ -3672,10 +3926,10 @@ configstore@^5.0.1: write-file-atomic "^3.0.0" xdg-basedir "^4.0.0" -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== consola@^2.15.3: version "2.15.3" @@ -3754,10 +4008,10 @@ core-js-pure@^3.20.2: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.2.tgz#c10bffdc3028d25c2aae505819a05543db61544f" integrity sha512-Lb+/XT4WC4PaCWWtZpNPaXmjiNDUe5CJuUtbkMrIM1kb1T/jJoAIp+bkVP/r5lHzMr+ZAAF8XHp7+my6Ol0ysQ== -core-js@^3.22.7: - version "3.22.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.7.tgz#8d6c37f630f6139b8732d10f2c114c3f1d00024f" - integrity sha512-Jt8SReuDKVNZnZEzyEQT5eK6T2RRCXkfTq7Lo09kpm+fHjgGewSbNjV+Wt4yZMhPDdzz2x1ulI5z/w4nxpBseg== +core-js@^3.23.3: + version "3.23.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.23.3.tgz#3b977612b15da6da0c9cc4aec487e8d24f371112" + integrity sha512-oAKwkj9xcWNBAvGbT//WiCdOMpb9XQG92/Fe3ABFM/R16BsHgePG00mFOgKf7IsCtfj8tA1kHtf/VwErhriz5Q== core-util-is@~1.0.0: version "1.0.3" @@ -3812,6 +4066,11 @@ css-declaration-sorter@^6.2.2: resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz#bfd2f6f50002d6a3ae779a87d3a0c5d5b10e0f02" integrity sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg== +css-declaration-sorter@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.0.tgz#72ebd995c8f4532ff0036631f7365cce9759df14" + integrity sha512-OGT677UGHJTAVMRhPO+HJ4oKln3wkBTwtDFH0ojbqm+MJm6xuDMHp2nkhh/ThaBqq20IbraBQSWKfSLNHQO9Og== + css-loader@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" @@ -3860,16 +4119,6 @@ css-select@^5.1.0: domutils "^3.0.1" nth-check "^2.0.1" -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" @@ -3878,11 +4127,6 @@ css-tree@^1.1.2, css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - css-what@^6.0.1, css-what@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" @@ -3893,13 +4137,13 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-advanced@^5.3.5: - version "5.3.6" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.6.tgz#6c995a86cecc9e6472bf6d120e5517231ed527dc" - integrity sha512-OZHsytu16eStRVrIY3wmPQqhJMaI0+O3raU4JHoKV3uuQYEeQek/FJVUIvYXD55hWR6OjCMyKYNRDw+k3/xgUw== +cssnano-preset-advanced@^5.3.8: + version "5.3.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.8.tgz#027b1d05ef896d908178c483f0ec4190cb50ef9a" + integrity sha512-xUlLLnEB1LjpEik+zgRNlk8Y/koBPPtONZjp7JKbXigeAmCrFvq9H0pXW5jJV45bQWAlmJ0sKy+IMr0XxLYQZg== dependencies: autoprefixer "^10.3.7" - cssnano-preset-default "^5.2.10" + cssnano-preset-default "^5.2.12" postcss-discard-unused "^5.1.0" postcss-merge-idents "^5.1.1" postcss-reduce-idents "^5.2.0" @@ -3940,12 +4184,56 @@ cssnano-preset-default@^5.2.10: postcss-svgo "^5.1.0" postcss-unique-selectors "^5.1.1" +cssnano-preset-default@^5.2.12: + version "5.2.12" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" + integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== + dependencies: + css-declaration-sorter "^6.3.0" + cssnano-utils "^3.1.0" + postcss-calc "^8.2.3" + postcss-colormin "^5.3.0" + postcss-convert-values "^5.1.2" + postcss-discard-comments "^5.1.2" + postcss-discard-duplicates "^5.1.0" + postcss-discard-empty "^5.1.1" + postcss-discard-overridden "^5.1.0" + postcss-merge-longhand "^5.1.6" + postcss-merge-rules "^5.1.2" + postcss-minify-font-values "^5.1.0" + postcss-minify-gradients "^5.1.1" + postcss-minify-params "^5.1.3" + postcss-minify-selectors "^5.2.1" + postcss-normalize-charset "^5.1.0" + postcss-normalize-display-values "^5.1.0" + postcss-normalize-positions "^5.1.1" + postcss-normalize-repeat-style "^5.1.1" + postcss-normalize-string "^5.1.0" + postcss-normalize-timing-functions "^5.1.0" + postcss-normalize-unicode "^5.1.0" + postcss-normalize-url "^5.1.0" + postcss-normalize-whitespace "^5.1.1" + postcss-ordered-values "^5.1.3" + postcss-reduce-initial "^5.1.0" + postcss-reduce-transforms "^5.1.0" + postcss-svgo "^5.1.0" + postcss-unique-selectors "^5.1.1" + cssnano-utils@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== -cssnano@^5.1.8, cssnano@^5.1.9: +cssnano@^5.1.12: + version "5.1.12" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.12.tgz#bcd0b64d6be8692de79332c501daa7ece969816c" + integrity sha512-TgvArbEZu0lk/dvg2ja+B7kYoD7BBCmn3+k58xD0qjrGHsFzXY/wKTo9M5egcUCabPol05e/PVoIu79s2JN4WQ== + dependencies: + cssnano-preset-default "^5.2.12" + lilconfig "^2.0.3" + yaml "^1.10.2" + +cssnano@^5.1.8: version "5.1.10" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.10.tgz#fc6ddd9a4d7d238f320634326ed814cf0abf6e1c" integrity sha512-ACpnRgDg4m6CZD/+8SgnLcGCgy6DDGdkMbOawwdvVxNietTNLe/MtWcenp6qT0PRt5wzhGl6/cjMWCdhKXC9QA== @@ -4100,14 +4388,6 @@ dom-converter@^0.2.0: dependencies: utila "~0.4" -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - dom-serializer@^1.0.1: version "1.4.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" @@ -4126,31 +4406,11 @@ dom-serializer@^2.0.0: domhandler "^5.0.2" entities "^4.2.0" -dom-serializer@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" @@ -4165,22 +4425,6 @@ domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" @@ -4284,11 +4528,6 @@ enhanced-resolve@^5.9.3: graceful-fs "^4.2.4" tapable "^2.2.0" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -4908,17 +5147,6 @@ hast-to-hyperscript@^9.0.0: unist-util-is "^4.0.0" web-namespaces "^1.0.0" -hast-util-from-parse5@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz#3089dc0ee2ccf6ec8bc416919b51a54a589e097c" - integrity sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" - hast-util-from-parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" @@ -4963,16 +5191,6 @@ hast-util-to-parse5@^6.0.0: xtend "^4.0.0" zwitch "^1.0.0" -hastscript@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" - integrity sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ== - dependencies: - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -5057,18 +5275,6 @@ html-webpack-plugin@^5.5.0: pretty-error "^4.0.0" tapable "^2.0.0" -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - htmlparser2@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" @@ -5202,10 +5408,10 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infima@0.2.0-alpha.39: - version "0.2.0-alpha.39" - resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.39.tgz#054b13ac44f3e9a42bc083988f1a1586add2f59c" - integrity sha512-UyYiwD3nwHakGhuOUfpe3baJ8gkiPpRVx4a4sE/Ag+932+Y6swtLsdPoRR8ezhwqGnduzxmFkjumV9roz6QoLw== +infima@0.2.0-alpha.42: + version "0.2.0-alpha.42" + resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.42.tgz#f6e86a655ad40877c6b4d11b2ede681eb5470aa5" + integrity sha512-ift8OXNbQQwtbIt6z16KnSWP7uJ/SysSMFI4F87MNRTicypfl4Pv3E2OGVv6N3nSZFJvA8imYulCBS64iyHYww== inflight@^1.0.4: version "1.0.6" @@ -5629,16 +5835,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= - lodash.curry@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" @@ -5649,66 +5845,16 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= - -lodash.flatten@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - lodash.flow@^3.3.0: version "3.5.0" resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= - -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.merge@^4.4.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= - -lodash.some@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= - lodash.uniq@4.5.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" @@ -5892,10 +6038,10 @@ mini-create-react-context@^0.4.0: "@babel/runtime" "^7.12.1" tiny-warning "^1.0.3" -mini-css-extract-plugin@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz#578aebc7fc14d32c0ad304c2c34f08af44673f5e" - integrity sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w== +mini-css-extract-plugin@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" + integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== dependencies: schema-utils "^4.0.0" @@ -6047,13 +6193,6 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6239,11 +6378,6 @@ parse5-htmlparser2-tree-adapter@^7.0.0: domhandler "^5.0.2" parse5 "^7.0.0" -parse5@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -6423,6 +6557,14 @@ postcss-merge-longhand@^5.1.5: postcss-value-parser "^4.2.0" stylehacks "^5.1.0" +postcss-merge-longhand@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" + integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^5.1.0" + postcss-merge-rules@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" @@ -6512,6 +6654,13 @@ postcss-normalize-positions@^5.1.0: dependencies: postcss-value-parser "^4.2.0" +postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-repeat-style@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz#f6d6fd5a54f51a741cc84a37f7459e60ef7a6398" @@ -6519,6 +6668,13 @@ postcss-normalize-repeat-style@^5.1.0: dependencies: postcss-value-parser "^4.2.0" +postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-string@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" @@ -6564,6 +6720,14 @@ postcss-ordered-values@^5.1.1: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" +postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + postcss-reduce-idents@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz#c89c11336c432ac4b28792f24778859a67dfba95" @@ -6671,10 +6835,10 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@1.3.3, prism-react-renderer@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.3.tgz#9b5a4211a6756eee3c96fee9a05733abc0b0805c" - integrity sha512-Viur/7tBTCH2HmYzwCHmt2rEFn+rdIWNIINXyg0StiISbDiIhHKhrFuEK8eMkKgvsIYSjgGqy/hNyucHp6FpoQ== +prism-react-renderer@1.3.5, prism-react-renderer@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz#786bb69aa6f73c32ba1ee813fbe17a0115435085" + integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg== prismjs@^1.28.0: version "1.28.0" @@ -6849,13 +7013,13 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f" - integrity sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w== +react-dom@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" - scheduler "^0.22.0" + scheduler "^0.23.0" react-error-overlay@^6.0.11: version "6.0.11" @@ -6950,10 +7114,10 @@ react-textarea-autosize@^8.3.2: use-composed-ref "^1.0.0" use-latest "^1.0.0" -react@18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" - integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== +react@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" @@ -6970,7 +7134,7 @@ readable-stream@^2.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1: +readable-stream@^3.0.6: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -7041,6 +7205,18 @@ regexpu-core@^5.0.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + registry-auth-token@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" @@ -7067,29 +7243,11 @@ regjsparser@^0.8.2: dependencies: jsesc "~0.5.0" -rehype-parse@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.2.tgz#aeb3fdd68085f9f796f1d3137ae2b85a98406964" - integrity sha512-0S3CpvpTAgGmnz8kiCyFLGuW5yA4OQhyNTm/nwPopZ7+PI11WnGl1TTWTGv/2hPEe/g2jRLlhVVSsoDH8waRug== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.0" - relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= -remark-admonitions@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/remark-admonitions/-/remark-admonitions-1.2.1.tgz#87caa1a442aa7b4c0cafa04798ed58a342307870" - integrity sha512-Ji6p68VDvD+H1oS95Fdx9Ar5WA2wcDA4kwrrhVU7fGctC6+d3uiMICu7w7/2Xld+lnU7/gi+432+rRbup5S8ow== - dependencies: - rehype-parse "^6.0.2" - unified "^8.4.2" - unist-util-visit "^2.0.1" - remark-emoji@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" @@ -7270,10 +7428,10 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.22.0.tgz#83a5d63594edf074add9a7198b1bae76c3db01b8" - integrity sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" @@ -7532,11 +7690,6 @@ sort-css-media-queries@2.0.4: resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-2.0.4.tgz#b2badfa519cb4a938acbc6d3aaa913d4949dc908" integrity sha512-PAIsEK/XupCQwitjv7XxoMvYhT7EAfyzI3hsy/MyDgTvc+Ft55ctdkctJLOy6cQejaIC+zjpUL4djFVm2ivOOw== -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -7555,7 +7708,7 @@ source-map@^0.5.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -7762,7 +7915,7 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.1: +terser-webpack-plugin@^5.1.3: version "5.3.1" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54" integrity sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g== @@ -7773,6 +7926,17 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.1: source-map "^0.6.1" terser "^5.7.2" +terser-webpack-plugin@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" + integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.7.2" + terser@^5.10.0, terser@^5.7.2: version "5.12.1" resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" @@ -7928,13 +8092,14 @@ unified@9.2.0: trough "^1.0.0" vfile "^4.0.0" -unified@^8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" - integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== +unified@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" + integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== dependencies: bail "^1.0.0" extend "^3.0.0" + is-buffer "^2.0.0" is-plain-obj "^2.0.0" trough "^1.0.0" vfile "^4.0.0" @@ -7995,7 +8160,7 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.3: +unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== @@ -8158,7 +8323,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -web-namespaces@^1.0.0, web-namespaces@^1.1.2: +web-namespaces@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== @@ -8194,15 +8359,16 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.9.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.1.tgz#184607b0287c791aeaa45e58e8fe75fcb4d7e2a8" - integrity sha512-CTMfu2UMdR/4OOZVHRpdy84pNopOuigVIsRbGX3LVDMWNP8EUgC5mUBMErbwBlHTEX99ejZJpVqrir6EXAEajA== +webpack-dev-server@^4.9.3: + version "4.9.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" + integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" "@types/express" "^4.17.13" "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" "@types/sockjs" "^0.3.33" "@types/ws" "^8.5.1" ansi-html-community "^0.0.8" @@ -8210,7 +8376,7 @@ webpack-dev-server@^4.9.0: chokidar "^3.5.3" colorette "^2.0.10" compression "^1.7.4" - connect-history-api-fallback "^1.6.0" + connect-history-api-fallback "^2.0.0" default-gateway "^6.0.3" express "^4.17.3" graceful-fs "^4.2.6" @@ -8236,23 +8402,15 @@ webpack-merge@^5.8.0: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack-sources@^3.2.3: +webpack-sources@^3.2.2, webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.72.1: - version "5.72.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.1.tgz#3500fc834b4e9ba573b9f430b2c0a61e1bb57d13" - integrity sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung== +webpack@^5.73.0: + version "5.73.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" + integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51"