diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e5858b4..5fc6da6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,46 +9,407 @@ name: Continuous Integration on: pull_request: - branches: ['**'] + branches: ['**', '!update/**', '!pr/**'] push: - branches: ['**'] + branches: ['**', '!update/**', '!pr/**'] + tags: [v*] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +concurrency: + group: ${{ github.workflow }} @ ${{ github.ref }} + cancel-in-progress: true + jobs: build: - name: Build and Test + name: Test strategy: matrix: - os: [ubuntu-latest] - scala: [2.12.15, 2.13.16] - java: [adopt@1.8] + os: [ubuntu-22.04] + scala: [2.12, 2.13] + java: [temurin@8, temurin@11, temurin@17] + project: [rootJS, rootJVM] + exclude: + - scala: 2.12 + java: temurin@11 + - scala: 2.12 + java: temurin@17 + - project: rootJS + java: temurin@11 + - project: rootJS + java: temurin@17 runs-on: ${{ matrix.os }} + timeout-minutes: 60 steps: - name: Checkout current branch (full) - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Setup Java and Scala - uses: olafurpg/setup-scala@v13 + - name: Setup sbt + uses: sbt/setup-sbt@v1 + + - name: Setup Java (temurin@8) + id: setup-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v4 with: - java-version: ${{ matrix.java }} + distribution: temurin + java-version: 8 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@8' && steps.setup-java-temurin-8.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@11) + id: setup-java-temurin-11 + if: matrix.java == 'temurin@11' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 11 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false' + run: sbt +update - - name: Cache sbt - uses: actions/cache@v2 + - name: Setup Java (temurin@17) + id: setup-java-temurin-17 + if: matrix.java == 'temurin@17' + uses: actions/setup-java@v4 with: - path: | - ~/.sbt - ~/.ivy2/cache - ~/.coursier/cache/v1 - ~/.cache/coursier/v1 - ~/AppData/Local/Coursier/Cache/v1 - ~/Library/Caches/Coursier/v1 - key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + distribution: temurin + java-version: 17 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' + run: sbt +update - name: Check that workflows are up to date - run: sbt ++${{ matrix.scala }} githubWorkflowCheck + run: sbt githubWorkflowCheck + + - name: Check headers and formatting + if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' headerCheckAll scalafmtCheckAll 'project /' scalafmtSbtCheck + + - name: Check scalafix lints + if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' 'scalafixAll --check' + + - name: scalaJSLink + if: matrix.project == 'rootJS' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' Test/scalaJSLinkerResult + + - name: Test + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' test + + - name: Check binary compatibility + if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' mimaReportBinaryIssues + + - name: Generate API documentation + if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' doc + + - name: Make target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') + run: mkdir -p modules/derivation/js/target modules/annotations/jvm/target modules/derivation/jvm/target modules/annotations/js/target project/target + + - name: Compress target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') + run: tar cf targets.tar modules/derivation/js/target modules/annotations/jvm/target modules/derivation/jvm/target modules/annotations/js/target project/target + + - name: Upload target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') + uses: actions/upload-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-${{ matrix.scala }}-${{ matrix.project }} + path: targets.tar + + publish: + name: Publish Artifacts + needs: [build] + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') + strategy: + matrix: + os: [ubuntu-22.04] + java: [temurin@8] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v4 + with: + fetch-depth: 0 - - uses: codecov/codecov-action@v1 + - name: Setup sbt + uses: sbt/setup-sbt@v1 + + - name: Setup Java (temurin@8) + id: setup-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 8 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@8' && steps.setup-java-temurin-8.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@11) + id: setup-java-temurin-11 + if: matrix.java == 'temurin@11' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 11 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@17) + id: setup-java-temurin-17 + if: matrix.java == 'temurin@17' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' + run: sbt +update + + - name: Download target directories (2.12, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJS + + - name: Inflate target directories (2.12, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12, rootJVM) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJVM + + - name: Inflate target directories (2.12, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13-rootJS + + - name: Inflate target directories (2.13, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13, rootJVM) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13-rootJVM + + - name: Inflate target directories (2.13, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Import signing key + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' + env: + PGP_SECRET: ${{ secrets.PGP_SECRET }} + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + run: echo $PGP_SECRET | base64 -d -i - | gpg --import + + - name: Import signing key and strip passphrase + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != '' + env: + PGP_SECRET: ${{ secrets.PGP_SECRET }} + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + run: | + echo "$PGP_SECRET" | base64 -d -i - > /tmp/signing-key.gpg + echo "$PGP_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg + (echo "$PGP_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1) + + - name: Publish + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_CREDENTIAL_HOST: ${{ secrets.SONATYPE_CREDENTIAL_HOST }} + run: sbt tlCiRelease + + dependency-submission: + name: Submit Dependencies + if: github.event.repository.fork == false && github.event_name != 'pull_request' + strategy: + matrix: + os: [ubuntu-22.04] + java: [temurin@8] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup sbt + uses: sbt/setup-sbt@v1 + + - name: Setup Java (temurin@8) + id: setup-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 8 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@8' && steps.setup-java-temurin-8.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@11) + id: setup-java-temurin-11 + if: matrix.java == 'temurin@11' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 11 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@17) + id: setup-java-temurin-17 + if: matrix.java == 'temurin@17' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' + run: sbt +update + + - name: Submit Dependencies + uses: scalacenter/sbt-dependency-submission@v2 + with: + modules-ignore: examples_2.12 examples_2.13 examplesderivation_2.12 examplesderivation_2.13 examplesgeneric_2.12 examplesgeneric_2.13 rootjs_2.12 rootjs_2.13 docs_2.12 docs_2.13 examplesscrooge_2.12 examplesscrooge_2.13 examples_sjs1_2.12 examples_sjs1_2.13 rootjvm_2.12 rootjvm_2.13 rootnative_2.12 rootnative_2.13 examplesderivation_sjs1_2.12 examplesderivation_sjs1_2.13 examplesgeneric_sjs1_2.12 examplesgeneric_sjs1_2.13 + configs-ignore: test scala-tool scala-doc-tool test-internal + + coverage: + name: Generate coverage report + strategy: + matrix: + os: [ubuntu-22.04] + scala: [2.12, 2.13] + java: [temurin@11] + runs-on: ${{ matrix.os }} + steps: + - name: Install sbt + uses: sbt/setup-sbt@v1 + + - name: Checkout current branch (fast) + uses: actions/checkout@v4 + + - name: Setup Java (temurin@17) + id: setup-java-temurin-17 + if: matrix.java == 'temurin@17' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' + run: sbt +update + + - run: sbt '++ ${{ matrix.scala }}' coverage rootJVM/test coverageAggregate + + - uses: codecov/codecov-action@v4 + with: + flags: ${{matrix.scala}} + + site: + name: Generate Site + strategy: + matrix: + os: [ubuntu-22.04] + java: [temurin@11] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup sbt + uses: sbt/setup-sbt@v1 + + - name: Setup Java (temurin@8) + id: setup-java-temurin-8 + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 8 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@8' && steps.setup-java-temurin-8.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@11) + id: setup-java-temurin-11 + if: matrix.java == 'temurin@11' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 11 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@11' && steps.setup-java-temurin-11.outputs.cache-hit == 'false' + run: sbt +update + + - name: Setup Java (temurin@17) + id: setup-java-temurin-17 + if: matrix.java == 'temurin@17' + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + cache: sbt + + - name: sbt update + if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' + run: sbt +update + + - name: Generate site + run: sbt docs/tlSite + + - name: Publish site + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + uses: peaceiris/actions-gh-pages@v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: site/target/docs/site + keep_files: true diff --git a/.gitignore b/.gitignore index 8268d15a..f6a02ecf 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,6 @@ target/ tmp/ .bloop .metals +.vscode +project/project +project/metals.sbt diff --git a/.scalafix.conf b/.scalafix.conf new file mode 100644 index 00000000..edf55aee --- /dev/null +++ b/.scalafix.conf @@ -0,0 +1,3 @@ +rules = [ + OrganizeImports +] diff --git a/.scalafmt.conf b/.scalafmt.conf index 21a59f8c..70a50e69 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,6 +1,10 @@ version = 3.5.0 +project.git = true +runner.dialect = scala213 +project.layout = StandardConvention continuationIndent.defnSite = 2 -docstrings = JavaDoc +docstrings.style = Asterisk +docstrings.wrap = no includeCurlyBraceInSelectChains = false maxColumn = 120 newlines.alwaysBeforeElseAfterCurlyIf = false @@ -13,3 +17,5 @@ rewrite.rules = [ AsciiSortImports, PreferCurlyFors ] +newlines.afterCurlyLambda = preserve +newlines.beforeCurlyLambdaParams = multilineWithCaseOnly \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..9aa0a58a --- /dev/null +++ b/LICENSE @@ -0,0 +1,67 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md index 9a909f3a..8d97fb24 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ [![Gitter](https://img.shields.io/badge/gitter-join%20chat-green.svg)](https://gitter.im/circe/circe) [![Maven Central](https://img.shields.io/maven-central/v/io.circe/circe-derivation_2.12.svg)](https://maven-badges.herokuapp.com/maven-central/io.circe/circe-derivation_2.12) +## Using + +```scala +libraryDependencies += "io.circe" % "circe-derivation" %% "@VERSION@" +``` + +## Description + This library provides macro-supported derivation of circe's type class instances. It differs from circe-generic in that this derivation is not based on Shapeless's generic representation of case classes and ADTs, and it is not intended to be as fully featured as `io.circe.generic`. Notably fully diff --git a/build.sbt b/build.sbt index 1afb733d..5e18f22a 100644 --- a/build.sbt +++ b/build.sbt @@ -1,38 +1,27 @@ import sbtcrossproject.{ CrossType, crossProject } -import scala.xml.{ Elem, Node => XmlNode, NodeSeq => XmlNodeSeq } -import scala.xml.transform.{ RewriteRule, RuleTransformer } -ThisBuild / organization := "io.circe" -ThisBuild / crossScalaVersions := Seq("2.12.15", "2.13.16") -ThisBuild / githubWorkflowPublishTargetBranches := Nil -ThisBuild / githubWorkflowBuild := Seq( - WorkflowStep.Use( - UseRef.Public( - "codecov", - "codecov-action", - "v1" - ) - ) -) +val Scala212V: String = "2.12.20" +val Scala213V: String = "2.13.16" +// val Scala3V: String = "3.1.3" - unsupported yet -val compilerOptions = Seq( - "-deprecation", - "-encoding", - "UTF-8", - "-feature", - "-language:existentials", - "-language:higherKinds", - "-unchecked", - "-Ywarn-dead-code", - "-Ywarn-numeric-widen" -) +ThisBuild / circeRootOfCodeCoverage := Some("rootJVM") +ThisBuild / tlBaseVersion := "0.13" +ThisBuild / tlCiReleaseTags := true +ThisBuild / tlFatalWarnings := false //TODO: ... fix this someday + +ThisBuild / licenses := Seq(License.Apache2) +ThisBuild / startYear := Some(2017) +ThisBuild / crossScalaVersions := List(Scala212V, Scala213V) // List(Scala3V, Scala212V, Scala213V) +ThisBuild / scalaVersion := Scala213V + +ThisBuild / githubWorkflowJavaVersions := Seq("8", "11", "17").map(JavaSpec.temurin) val catsVersion = "2.13.0" -val circeVersion = "0.14.1" +val circeVersion = "0.14.14" val paradiseVersion = "2.1.1" val previousCirceDerivationVersion = "0.13.0-M5" val scalaCheckVersion = "1.18.1" -val scalaJavaTimeVersion = "2.3.0" +val scalaJavaTimeVersion = "2.6.0" def priorTo2_13(scalaVersion: String): Boolean = CrossVersion.partialVersion(scalaVersion) match { @@ -41,37 +30,14 @@ def priorTo2_13(scalaVersion: String): Boolean = } val baseSettings = Seq( - scalacOptions ++= compilerOptions, - scalacOptions ++= ( - if (priorTo2_13(scalaVersion.value)) - Seq( - "-Xfuture", - "-Yno-adapted-args", - "-Ywarn-unused-import" - ) - else - Seq( - "-Ywarn-unused:imports" - ) - ), - Compile / console / scalacOptions ~= { - _.filterNot(Set("-Ywarn-unused-import")) - }, - Test / console / scalacOptions ~= { - _.filterNot(Set("-Ywarn-unused-import")) - }, - coverageHighlighting := true, - (Compile / scalastyleSources) ++= (Compile / unmanagedSourceDirectories).value + coverageHighlighting := true ) -val allSettings = baseSettings ++ publishSettings - -val docMappingsApiDir = settingKey[String]("Subdirectory in site target directory for API docs") +val allSettings = baseSettings -val root = project - .in(file(".")) +val root = tlCrossRootProject + .enablePlugins(NoPublishPlugin) .settings(allSettings) - .settings(noPublishSettings) .settings( libraryDependencies ++= Seq( "io.circe" %% "circe-jawn" % circeVersion, @@ -79,17 +45,18 @@ val root = project ) ) .aggregate( - derivationJVM, - derivationJS, - annotationsJVM, - annotationsJS, + derivation.jvm, + derivation.js, + annotations.jvm, + annotations.js, examplesScrooge, - examplesDerivationJVM, - examplesDerivationJS, - examplesGenericJVM, - examplesGenericJS + examplesDerivation.jvm, + examplesDerivation.js, + examplesGeneric.jvm, + examplesGeneric.js ) - .dependsOn(derivationJVM) + +lazy val docs = project.in(file("site")).enablePlugins(CirceOrgSitePlugin) lazy val derivation = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) @@ -108,10 +75,8 @@ lazy val derivation = crossProject(JSPlatform, JVMPlatform) "io.circe" %%% "circe-parser" % circeVersion % Test, "io.circe" %%% "circe-testing" % circeVersion % Test, "org.scalatestplus" %%% "scalacheck-1-14" % "3.2.2.0" % Test, - "org.typelevel" %%% "discipline-scalatest" % "2.1.5" % Test - ), - ghpagesNoJekyll := true, - docMappingsApiDir := "api" + "org.typelevel" %%% "discipline-scalatest" % "2.3.0" % Test + ) ) .dependsOn(examples % Test) .jvmSettings( @@ -121,20 +86,13 @@ lazy val derivation = crossProject(JSPlatform, JVMPlatform) "com.stripe" %% "scrooge-shapes" % "0.1.0" % Test ) else Nil - ), - mimaPreviousArtifacts := Set("io.circe" %% "circe-derivation" % previousCirceDerivationVersion), - addMappingsToSiteDir(Compile / packageDoc / mappings, docMappingsApiDir) + ) ) .jsSettings( - coverageEnabled := false, - coverageExcludedPackages := "io.circe.derivation.*", libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) .jvmConfigure(_.dependsOn(examplesScrooge % Test)) -lazy val derivationJVM = derivation.jvm -lazy val derivationJS = derivation.js - lazy val annotations = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Full) @@ -144,8 +102,6 @@ lazy val annotations = crossProject(JSPlatform, JVMPlatform) name := "Circe derivation", moduleName := "circe-derivation-annotations", description := "circe derivation annotations", - ghpagesNoJekyll := true, - docMappingsApiDir := "api", libraryDependencies ++= Seq( scalaOrganization.value % "scala-compiler" % scalaVersion.value % Provided, scalaOrganization.value % "scala-reflect" % scalaVersion.value % Provided @@ -163,26 +119,17 @@ lazy val annotations = crossProject(JSPlatform, JVMPlatform) ) ) .dependsOn(derivation, derivation % "test->test") - .jvmSettings( - mimaPreviousArtifacts := Set("io.circe" %% "circe-derivation-annotations" % previousCirceDerivationVersion), - addMappingsToSiteDir(Compile / packageDoc / mappings, docMappingsApiDir) - ) .jsSettings( - coverageEnabled := false, - coverageExcludedPackages := "io.circe.derivation.*", libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % scalaJavaTimeVersion ) .jvmConfigure(_.dependsOn(examplesScrooge % Test)) -lazy val annotationsJVM = annotations.jvm -lazy val annotationsJS = annotations.js - lazy val examples = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Pure) .in(file("examples")) .settings(allSettings) - .settings(noPublishSettings) + .enablePlugins(NoPublishPlugin) .settings( libraryDependencies ++= Seq( "io.circe" %%% "circe-testing" % circeVersion, @@ -190,17 +137,11 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform) "org.typelevel" %%% "cats-core" % catsVersion ) ) - .jsSettings( - coverageEnabled := false - ) - -lazy val examplesJVM = examples.jvm -lazy val examplesJS = examples.js lazy val examplesScrooge = project .in(file("examples/scrooge")) .settings(allSettings) - .settings(noPublishSettings) + .enablePlugins(NoPublishPlugin) .settings( libraryDependencies ++= Seq( "org.scalacheck" %% "scalacheck" % scalaCheckVersion, @@ -232,29 +173,16 @@ lazy val examplesDerivation = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Full) .in(file("examples/derivation")) .settings(allSettings) - .settings(noPublishSettings) - .settings( - coverageExcludedPackages := "io.circe.examples.*", - wartremoverErrors ++= Warts.unsafe - ) - .jsSettings( - coverageEnabled := false - ) + .enablePlugins(NoPublishPlugin) .jvmConfigure(_.dependsOn(examplesScrooge)) .dependsOn(derivation, examples) -lazy val examplesDerivationJVM = examplesDerivation.jvm -lazy val examplesDerivationJS = examplesDerivation.js - lazy val examplesGeneric = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Full) .in(file("examples/generic")) .settings(allSettings) - .settings(noPublishSettings) - .settings( - coverageExcludedPackages := "io.circe.examples.*" - ) + .enablePlugins(NoPublishPlugin) .settings(libraryDependencies += "io.circe" %%% "circe-generic" % circeVersion) .jvmSettings( libraryDependencies ++= ( @@ -265,76 +193,5 @@ lazy val examplesGeneric = crossProject(JSPlatform, JVMPlatform) else Nil ) ) - .jsSettings( - coverageEnabled := false - ) .jvmConfigure(_.dependsOn(examplesScrooge)) .dependsOn(examples) - -lazy val examplesGenericJVM = examplesGeneric.jvm -lazy val examplesGenericJS = examplesGeneric.js - -lazy val noPublishSettings = Seq( - publish := {}, - publishLocal := {}, - publishArtifact := false -) - -lazy val publishSettings = Seq( - releaseCrossBuild := true, - releasePublishArtifactsAction := PgpKeys.publishSigned.value, - releaseVcsSign := true, - homepage := Some(url("https://github.com/circe/circe-derivation")), - licenses := Seq("Apache 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), - publishMavenStyle := true, - Test / publishArtifact := false, - pomIncludeRepository := { _ => false }, - publishTo := { - val nexus = "https://oss.sonatype.org/" - if (isSnapshot.value) - Some("snapshots".at(nexus + "content/repositories/snapshots")) - else - Some("releases".at(nexus + "service/local/staging/deploy/maven2")) - }, - autoAPIMappings := true, - apiURL := Some(url("https://circe.github.io/circe-derivation/api/")), - scmInfo := Some( - ScmInfo( - url("https://github.com/circe/circe-derivation"), - "scm:git:git@github.com:circe/circe-derivation.git" - ) - ), - developers := List( - Developer( - "travisbrown", - "Travis Brown", - "travisrobertbrown@gmail.com", - url("https://twitter.com/travisbrown") - ) - ), - pomPostProcess := { (node: XmlNode) => - new RuleTransformer( - new RewriteRule { - private def isTestScope(elem: Elem): Boolean = - elem.label == "dependency" && elem.child.exists(child => child.label == "scope" && child.text == "test") - - override def transform(node: XmlNode): XmlNodeSeq = node match { - case elem: Elem if isTestScope(elem) => Nil - case _ => node - } - } - ).transform(node).head - } -) - -credentials ++= ( - for { - username <- Option(System.getenv().get("SONATYPE_USERNAME")) - password <- Option(System.getenv().get("SONATYPE_PASSWORD")) - } yield Credentials( - "Sonatype Nexus Repository Manager", - "oss.sonatype.org", - username, - password - ) -).toSeq diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..8d97fb24 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,71 @@ +# circe-derivation + +[![Build status](https://img.shields.io/github/workflow/status/circe/circe-derivation/Continuous%20Integration.svg)](https://github.com/circe/circe-derivation/actions) +[![Coverage status](https://img.shields.io/codecov/c/github/circe/circe-derivation/master.svg)](https://codecov.io/github/circe/circe-derivation) +[![Gitter](https://img.shields.io/badge/gitter-join%20chat-green.svg)](https://gitter.im/circe/circe) +[![Maven Central](https://img.shields.io/maven-central/v/io.circe/circe-derivation_2.12.svg)](https://maven-badges.herokuapp.com/maven-central/io.circe/circe-derivation_2.12) + +## Using + +```scala +libraryDependencies += "io.circe" % "circe-derivation" %% "@VERSION@" +``` + +## Description + +This library provides macro-supported derivation of circe's type class instances. It differs from +circe-generic in that this derivation is not based on Shapeless's generic representation of case +classes and ADTs, and it is not intended to be as fully featured as `io.circe.generic`. Notably fully +automatic derivation is a non-goal. The only targeted remaining feature for parity is constructor renaming. + +In return for losing automatic derivation you get a library that has no dependencies apart from circe-core, +should compile much more quickly in most cases, and supports some classes that circe-generic doesn't +(e.g. Scrooge-generated representations of Thrift structs). + +## Who is this for? + +There are already a lot of ways to define encoders and decoders in circe (or to avoid defining +them using fully-automatic derivation). In general users who want to use generic derivation should +stick to circe-generic, which is well-tested, robust, and provides a clear path from automatic +generic derivation (which can be useful for initial exploration or in relatively simple +applications) to semi-automatic derivation (which has some syntactic overhead but tends to compile +much more quickly and to be easier to reason about). + +Users who want the generic derivation experience but need particular functionality that isn't +provided in circe-generic may be interested in circe-generic-extras, which supports transforming +member names, using default values, etc. (at the expense of even slower compile times). + +This library is for people who don't care about the full generic derivation experience but just +want fast builds and instances that stay in sync with their definitions, and who don't mind a bit +of boilerplate (a couple of lines per case class). + +Note that the `io.circe.derivation` API is almost identical to `io.circe.generic.semiauto`, and in +many situations it can be used as a drop-in replacement. If you're currently using circe-generic's +`deriveEncoder` and `deriveDecoder` for case classes, but are still suffering from slow compilation, +adding a circe-derivation dependency and switching the imports is probably worth a try. + +## Contributors and participation + +This project supports the Scala [code of conduct][code-of-conduct] and we want +all of its channels (Gitter, GitHub, etc.) to be welcoming environments for everyone. + +Please see the [circe contributors' guide][contributing] for details on how to submit a pull +request. + +## License + +circe-derivation is licensed under the **[Apache License, Version 2.0][apache]** +(the "License"); you may not use this software except in compliance with the +License. + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +[apache]: http://www.apache.org/licenses/LICENSE-2.0 +[api-docs]: https://circe.github.io/circe-derivation/api/io/circe/ +[circe]: https://github.com/circe/circe +[code-of-conduct]: https://www.scala-lang.org/conduct.html +[contributing]: https://circe.github.io/circe/contributing.html diff --git a/examples/derivation/jvm/src/main/scala/io/circe/examples/derivation/ScroogeInstances.scala b/examples/derivation/jvm/src/main/scala/io/circe/examples/derivation/ScroogeInstances.scala index 2a8a2ba6..057a396d 100644 --- a/examples/derivation/jvm/src/main/scala/io/circe/examples/derivation/ScroogeInstances.scala +++ b/examples/derivation/jvm/src/main/scala/io/circe/examples/derivation/ScroogeInstances.scala @@ -1,8 +1,27 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.derivation -import io.circe.{ Decoder, Encoder } -import io.circe.derivation.{ deriveDecoder, deriveEncoder } -import io.circe.examples.scrooge.{ BiggerStruct, SomethingStruct } +import io.circe.Decoder +import io.circe.Encoder +import io.circe.derivation.deriveDecoder +import io.circe.derivation.deriveEncoder +import io.circe.examples.scrooge.BiggerStruct +import io.circe.examples.scrooge.SomethingStruct object ScroogeInstances { implicit val decodeSomethingStruct: Decoder[SomethingStruct] = deriveDecoder diff --git a/examples/derivation/shared/src/main/scala/io/circe/examples/derivation/Instances.scala b/examples/derivation/shared/src/main/scala/io/circe/examples/derivation/Instances.scala index 7f22ffea..1e0022aa 100644 --- a/examples/derivation/shared/src/main/scala/io/circe/examples/derivation/Instances.scala +++ b/examples/derivation/shared/src/main/scala/io/circe/examples/derivation/Instances.scala @@ -1,8 +1,29 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.derivation -import io.circe.{ Decoder, Encoder } -import io.circe.derivation.{ deriveDecoder, deriveEncoder } -import io.circe.examples.{ Bar, Baz, Foo, Qux } +import io.circe.Decoder +import io.circe.Encoder +import io.circe.derivation.deriveDecoder +import io.circe.derivation.deriveEncoder +import io.circe.examples.Bar +import io.circe.examples.Baz +import io.circe.examples.Foo +import io.circe.examples.Qux object Instances { implicit val decodeFoo0: Decoder[Foo] = deriveDecoder diff --git a/examples/generic/jvm/src/main/scala-2.13/com/stripe/scrooge/package.scala b/examples/generic/jvm/src/main/scala-2.13/com/stripe/scrooge/package.scala index e38cbbd7..e49bd78c 100644 --- a/examples/generic/jvm/src/main/scala-2.13/com/stripe/scrooge/package.scala +++ b/examples/generic/jvm/src/main/scala-2.13/com/stripe/scrooge/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.stripe.scrooge // A terrible hack to fix things until Scrooge is published for 2.13. diff --git a/examples/generic/jvm/src/main/scala/io/circe/examples/generic/ScroogeInstances.scala b/examples/generic/jvm/src/main/scala/io/circe/examples/generic/ScroogeInstances.scala index 6941d32c..d058405e 100644 --- a/examples/generic/jvm/src/main/scala/io/circe/examples/generic/ScroogeInstances.scala +++ b/examples/generic/jvm/src/main/scala/io/circe/examples/generic/ScroogeInstances.scala @@ -1,9 +1,28 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.generic -import com.stripe.scrooge.shapes._ -import io.circe.{ Decoder, Encoder } -import io.circe.examples.scrooge.{ BiggerStruct, SomethingStruct } -import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } +import com.stripe.scrooge.shapes._ // scalafix:ok +import io.circe.Decoder +import io.circe.Encoder +import io.circe.examples.scrooge.BiggerStruct +import io.circe.examples.scrooge.SomethingStruct +import io.circe.generic.semiauto.deriveDecoder +import io.circe.generic.semiauto.deriveEncoder object ScroogeInstances { implicit val decodeSomethingStruct: Decoder[SomethingStruct] = deriveDecoder diff --git a/examples/generic/shared/src/main/scala/io/circe/examples/generic/Instances.scala b/examples/generic/shared/src/main/scala/io/circe/examples/generic/Instances.scala index 6163ea76..06ff12df 100644 --- a/examples/generic/shared/src/main/scala/io/circe/examples/generic/Instances.scala +++ b/examples/generic/shared/src/main/scala/io/circe/examples/generic/Instances.scala @@ -1,8 +1,29 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.generic -import io.circe.{ Decoder, Encoder } -import io.circe.examples.{ Bar, Baz, Foo, Qux } -import io.circe.generic.semiauto.{ deriveDecoder, deriveEncoder } +import io.circe.Decoder +import io.circe.Encoder +import io.circe.examples.Bar +import io.circe.examples.Baz +import io.circe.examples.Foo +import io.circe.examples.Qux +import io.circe.generic.semiauto.deriveDecoder +import io.circe.generic.semiauto.deriveEncoder object Instances { implicit val decodeFoo0: Decoder[Foo] = deriveDecoder diff --git a/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/BiggerStruct.scala b/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/BiggerStruct.scala index 3920e0da..793a9744 100644 --- a/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/BiggerStruct.scala +++ b/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/BiggerStruct.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.scrooge case class BiggerStruct(c: SomethingStruct, d: Option[String]) diff --git a/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/SomethingStruct.scala b/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/SomethingStruct.scala index 05b5dafd..630e12a2 100644 --- a/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/SomethingStruct.scala +++ b/examples/scrooge/src/main/scala-2.13/io/circe/examples/scrooge/SomethingStruct.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples.scrooge case class SomethingStruct(a: String, b: Option[Long], c: List[String]) diff --git a/examples/scrooge/src/main/scala/io/circe/examples/scrooge/package.scala b/examples/scrooge/src/main/scala/io/circe/examples/scrooge/package.scala index b06baca0..5ed903c4 100644 --- a/examples/scrooge/src/main/scala/io/circe/examples/scrooge/package.scala +++ b/examples/scrooge/src/main/scala/io/circe/examples/scrooge/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.examples import cats.kernel.Eq diff --git a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/Configuration.scala b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/Configuration.scala index 86a03f2d..2bf243d9 100644 --- a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/Configuration.scala +++ b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/Configuration.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations import io.circe.derivation.renaming diff --git a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonCodec.scala b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonCodec.scala index 39c591e7..9d7cec54 100644 --- a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonCodec.scala +++ b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonCodec.scala @@ -1,7 +1,25 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations -import io.circe.{ Codec, Decoder, Encoder } -import scala.language.experimental.macros +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder + import scala.reflect.macros.blackbox class JsonCodec( @@ -37,9 +55,9 @@ private[derivation] final class GenericJsonCodecMacros(val c: blackbox.Context) } """ case List( - clsDef: ClassDef, - q"object $objName extends { ..$objEarlyDefs } with ..$objParents { $objSelf => ..$objDefs }" - ) if isCaseClassOrSealed(clsDef) => + clsDef: ClassDef, + q"object $objName extends { ..$objEarlyDefs } with ..$objParents { $objSelf => ..$objDefs }" + ) if isCaseClassOrSealed(clsDef) => q""" $clsDef object $objName extends { ..$objEarlyDefs } with ..$objParents { $objSelf => @@ -112,7 +130,7 @@ private[derivation] final class GenericJsonCodecMacros(val c: blackbox.Context) case q"new ${`macroName`}()" => (JsonCodecType.Both, defaultCfg) case q"new ${`macroName`}(config = $cfg)" => (codecFrom(c.typecheck(cfg)), cfg) case q"new ${`macroName`}($cfg)" => (codecFrom(c.typecheck(cfg)), cfg) - case _ => c.abort(c.enclosingPosition, s"Unsupported arguments supplied to @$macroName") + case _ => c.abort(c.enclosingPosition, s"Unsupported arguments supplied to @$macroName") } } } @@ -162,10 +180,11 @@ private[derivation] final class GenericJsonCodecMacros(val c: blackbox.Context) } else { val tparamNames = tparams.map(_.name) def mkImplicitParams(prefix: String, typeSymbol: TypeSymbol) = - tparamNames.zipWithIndex.map { case (tparamName, i) => - val paramName = TermName(s"$prefix$i") - val paramType = tq"$typeSymbol[$tparamName]" - q"$paramName: $paramType" + tparamNames.zipWithIndex.map { + case (tparamName, i) => + val paramName = TermName(s"$prefix$i") + val paramType = tq"$typeSymbol[$tparamName]" + q"$paramName: $paramType" } val decodeParams = mkImplicitParams("decode", DecoderClass) val encodeParams = mkImplicitParams("encode", EncoderClass) diff --git a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonKey.scala b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonKey.scala index 3fd1aa3e..6de06137 100644 --- a/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonKey.scala +++ b/modules/annotations/shared/src/main/scala/io/circe/derivation/annotations/JsonKey.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations import scala.annotation.StaticAnnotation diff --git a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecADTSpec.scala b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecADTSpec.scala index 53c3fd95..1eb2cf7a 100644 --- a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecADTSpec.scala +++ b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecADTSpec.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations import io.circe._ diff --git a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecCustomSpec.scala b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecCustomSpec.scala index 7bfb4b35..6044fe84 100644 --- a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecCustomSpec.scala +++ b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecCustomSpec.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations import io.circe._ diff --git a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecMacrosSuite.scala b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecMacrosSuite.scala index 340084e6..e96dc67e 100644 --- a/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecMacrosSuite.scala +++ b/modules/annotations/shared/src/test/scala/io/circe/derivation/annotations/JsonCodecMacrosSuite.scala @@ -1,11 +1,30 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation.annotations import cats.instances.AllInstances import cats.kernel.Eq -import io.circe.{ Decoder, Encoder } +import io.circe.Decoder +import io.circe.Encoder import io.circe.derivation.CirceSuite -import io.circe.testing.{ ArbitraryInstances, CodecTests } -import org.scalacheck.{ Arbitrary, Gen } +import io.circe.testing.ArbitraryInstances +import io.circe.testing.CodecTests +import org.scalacheck.Arbitrary +import org.scalacheck.Gen package object jsoncodecmacrossuiteaux extends AnyRef with AllInstances with ArbitraryInstances diff --git a/modules/derivation/jvm/src/test/scala-2.13/com/stripe/scrooge/package.scala b/modules/derivation/jvm/src/test/scala-2.13/com/stripe/scrooge/package.scala index e38cbbd7..e49bd78c 100644 --- a/modules/derivation/jvm/src/test/scala-2.13/com/stripe/scrooge/package.scala +++ b/modules/derivation/jvm/src/test/scala-2.13/com/stripe/scrooge/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.stripe.scrooge // A terrible hack to fix things until Scrooge is published for 2.13. diff --git a/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeDerivationSuite.scala b/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeDerivationSuite.scala index a6bac48b..d8a8e4aa 100644 --- a/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeDerivationSuite.scala +++ b/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeDerivationSuite.scala @@ -1,6 +1,24 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import io.circe.{ Codec, Decoder, Encoder } +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder import io.circe.examples.scrooge._ import io.circe.testing.CodecTests diff --git a/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeGenericAutoCodecs.scala b/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeGenericAutoCodecs.scala index ede594fb..a5eea16f 100644 --- a/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeGenericAutoCodecs.scala +++ b/modules/derivation/jvm/src/test/scala/io/circe/derivation/ScroogeGenericAutoCodecs.scala @@ -1,9 +1,27 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import com.stripe.scrooge.shapes._ -import io.circe.{ Decoder, Encoder } +import com.stripe.scrooge.shapes._ // scalafix:ok +import io.circe.Decoder +import io.circe.Encoder import io.circe.examples.scrooge._ -import io.circe.generic.semiauto.{ deriveDecoder => genericDeriveDecoder, deriveEncoder => genericDeriveEncoder } +import io.circe.generic.semiauto.{ deriveDecoder => genericDeriveDecoder } +import io.circe.generic.semiauto.{ deriveEncoder => genericDeriveEncoder } object ScroogeGenericAutoCodecs { implicit val decodeSomethingStruct: Decoder[SomethingStruct] = genericDeriveDecoder diff --git a/modules/derivation/shared/src/main/scala-2.12/io/circe/derivation/ScalaVersionCompat.scala b/modules/derivation/shared/src/main/scala-2.12/io/circe/derivation/ScalaVersionCompat.scala index 652958f8..21a23f4b 100644 --- a/modules/derivation/shared/src/main/scala-2.12/io/circe/derivation/ScalaVersionCompat.scala +++ b/modules/derivation/shared/src/main/scala-2.12/io/circe/derivation/ScalaVersionCompat.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import scala.reflect.macros.blackbox diff --git a/modules/derivation/shared/src/main/scala-2.13/io/circe/derivation/ScalaVersionCompat.scala b/modules/derivation/shared/src/main/scala-2.13/io/circe/derivation/ScalaVersionCompat.scala index 652958f8..21a23f4b 100644 --- a/modules/derivation/shared/src/main/scala-2.13/io/circe/derivation/ScalaVersionCompat.scala +++ b/modules/derivation/shared/src/main/scala-2.13/io/circe/derivation/ScalaVersionCompat.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import scala.reflect.macros.blackbox diff --git a/modules/derivation/shared/src/main/scala/io/circe/derivation/DerivationMacros.scala b/modules/derivation/shared/src/main/scala/io/circe/derivation/DerivationMacros.scala index 3b52ceeb..1bb1959a 100644 --- a/modules/derivation/shared/src/main/scala/io/circe/derivation/DerivationMacros.scala +++ b/modules/derivation/shared/src/main/scala/io/circe/derivation/DerivationMacros.scala @@ -1,6 +1,25 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import io.circe.{ Codec, Decoder, Encoder } +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder + import scala.collection.immutable.ListMap import scala.reflect.macros.blackbox import scala.util.control.TailCalls._ @@ -54,7 +73,7 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { s"No method $memberName in $tpe (this is probably because a constructor parameter isn't a val)" ) - //we extract annotation names + // we extract annotation names var keyName: Option[Tree] = None var noDefault = false @@ -104,8 +123,9 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { def instantiate: Tree = instantiate(paramListsWithNames.map(_.map(p => q"${p._2}"))) def instantiateAccumulating: Tree = instantiate( paramListsWithNames.map( - _.map { case (Member(_, _, tpe, _, _, _), name) => - extractFromValid(name, tpe) + _.map { + case (Member(_, _, tpe, _, _, _), name) => + extractFromValid(name, tpe) } ) ) @@ -115,12 +135,14 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { val paramListsWithNames: List[List[(Member, TermName)]] = paramLists - .foldLeft((List.empty[List[(Member, TermName)]], 1)) { case ((acc, i), paramList) => - val nextParamList = paramList.zipWithIndex.map { case (member, j) => - (member, TermName(s"res${i + j}")) - } + .foldLeft((List.empty[List[(Member, TermName)]], 1)) { + case ((acc, i), paramList) => + val nextParamList = paramList.zipWithIndex.map { + case (member, j) => + (member, TermName(s"res${i + j}")) + } - (nextParamList :: acc, i + nextParamList.size) + (nextParamList :: acc, i + nextParamList.size) } ._1 .reverse @@ -169,10 +191,11 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { case NoSymbol => None case s => val defaults = caseClassFieldsDefaults(tpe) - s.alternatives.collect { case m: MethodSymbol => - m.paramLists + s.alternatives.collect { + case m: MethodSymbol => + m.paramLists }.sortBy(-_.map(_.size).sum).headOption.map { applyParams => - //We use zipwithIndex for gathering default field value if available + // We use zipwithIndex for gathering default field value if available ProductReprWithApply( tpe, applyParams.map(_.zipWithIndex.map(Member.fromSymbol(tpe, defaults))) @@ -371,8 +394,9 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { val discriminatorCases: List[Tree] = subclassList .zip(transformedNameNames) - .map { case (s, value) => - cq"""nme if nme.equals($value) => _root_.io.circe.Decoder[${s.asType}].map[$tpe](_root_.scala.Predef.identity)""" + .map { + case (s, value) => + cq"""nme if nme.equals($value) => _root_.io.circe.Decoder[${s.asType}].map[$tpe](_root_.scala.Predef.identity)""" } .toList @@ -446,14 +470,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } else { val instanceDefs: List[Tree] = - repr.instances.map(_.decoder).map { case instance @ Instance(_, instanceType, name) => - val resolved = instance.resolve() - - if (checkDecoderValSafety(resolved)) { - q"private[this] val $name: _root_.io.circe.Decoder[$instanceType] = $resolved" - } else { - q"private[this] def $name: _root_.io.circe.Decoder[$instanceType] = $resolved" - } + repr.instances.map(_.decoder).map { + case instance @ Instance(_, instanceType, name) => + val resolved = instance.resolve() + + if (checkDecoderValSafety(resolved)) { + q"private[this] val $name: _root_.io.circe.Decoder[$instanceType] = $resolved" + } else { + q"private[this] def $name: _root_.io.circe.Decoder[$instanceType] = $resolved" + } } val reversed = repr.paramListsWithNames.flatten.reverse @@ -479,11 +504,11 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { q""" { val $resName: _root_.io.circe.Decoder.Result[$memberType] = ${productMemberDecoding( - repr, - member, - useDefaults, - transformName - )} + repr, + member, + useDefaults, + transformName + )} if ($resName.isRight) { val $resultName: $memberType = ${extractFromRight(resName, memberType)} @@ -495,14 +520,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } val (results: List[Tree], resultNames: List[TermName]) = - reversed.reverse.map { case (member, resultName) => - ( - q""" + reversed.reverse.map { + case (member, resultName) => + ( + q""" val $resultName: _root_.io.circe.Decoder.AccumulatingResult[${member.tpe}] = ${productMemberAccumulatingDecoding(repr, member, useDefaults, transformName)} """, - resultName - ) + resultName + ) }.unzip val resultErrors: List[Tree] = resultNames.map(resultName => q"errors($resultName)") @@ -561,14 +587,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { productRepr(tpe).fold(fail(tpe)) { repr => val instanceDefs: List[Tree] = - repr.instances.map(_.encoder).map { case instance @ Instance(_, instanceType, name) => - val resolved = instance.resolve() + repr.instances.map(_.encoder).map { + case instance @ Instance(_, instanceType, name) => + val resolved = instance.resolve() - if (checkEncoderValSafety(resolved)) { - q"private[this] val $name: _root_.io.circe.Encoder[$instanceType] = $resolved" - } else { - q"private[this] def $name: _root_.io.circe.Encoder[$instanceType] = $resolved" - } + if (checkEncoderValSafety(resolved)) { + q"private[this] val $name: _root_.io.circe.Encoder[$instanceType] = $resolved" + } else { + q"private[this] def $name: _root_.io.circe.Encoder[$instanceType] = $resolved" + } } // we check if we want to serialize no defaults @@ -618,17 +645,18 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } else { // we manage without default serialization - common case - val fields: List[Tree] = repr.paramLists.flatten.map { case Member(name, decodedName, tpe, keyName, _, _) => - repr.encoder(tpe) match { - case Instance(_, _, instanceName) => - val realName = keyName.getOrElse(transformName(decodedName)) - q""" + val fields: List[Tree] = repr.paramLists.flatten.map { + case Member(name, decodedName, tpe, keyName, _, _) => + repr.encoder(tpe) match { + case Instance(_, _, instanceName) => + val realName = keyName.getOrElse(transformName(decodedName)) + q""" _root_.scala.Tuple2.apply[_root_.java.lang.String, _root_.io.circe.Json]( ${transformName(decodedName)}, this.$instanceName.apply(a.$name) ) """ - } + } } c.Expr[Encoder.AsObject[T]]( @@ -714,16 +742,17 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { case None => ListMap() case Some(syntatic) => ListMap( - syntatic.asMethod.paramLists.flatten.zipWithIndex.map { case (field, i) => - ( - field.name.toTermName.decodedName.toString, { - val method = TermName(s"apply$$default$$${i + 1}") - tpe.typeSymbol.companion.typeSignature.member(method) match { - case NoSymbol => None - case _ => Some(q"${tpe.typeSymbol.companion}.$method") + syntatic.asMethod.paramLists.flatten.zipWithIndex.map { + case (field, i) => + ( + field.name.toTermName.decodedName.toString, { + val method = TermName(s"apply$$default$$${i + 1}") + tpe.typeSymbol.companion.typeSignature.member(method) match { + case NoSymbol => None + case _ => Some(q"${tpe.typeSymbol.companion}.$method") + } } - } - ) + ) }: _* ) } @@ -756,8 +785,9 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { val discriminatorCases: List[Tree] = subclassList .zip(transformedNameNames) - .map { case (s, value) => - cq"""nme if nme.equals($value) => _root_.io.circe.Decoder[${s.asType}].map[$tpe](_root_.scala.Predef.identity)""" + .map { + case (s, value) => + cq"""nme if nme.equals($value) => _root_.io.circe.Decoder[${s.asType}].map[$tpe](_root_.scala.Predef.identity)""" } .toList @@ -908,14 +938,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } else { val encoderInstanceDefs: List[Tree] = - repr.instances.map(_.encoder).map { case instance @ Instance(_, instanceType, name) => - val resolved = instance.resolve() - - if (checkEncoderValSafety(resolved)) { - q"private[this] val $name: _root_.io.circe.Encoder[$instanceType] = $resolved" - } else { - q"private[this] def $name: _root_.io.circe.Encoder[$instanceType] = $resolved" - } + repr.instances.map(_.encoder).map { + case instance @ Instance(_, instanceType, name) => + val resolved = instance.resolve() + + if (checkEncoderValSafety(resolved)) { + q"private[this] val $name: _root_.io.circe.Encoder[$instanceType] = $resolved" + } else { + q"private[this] def $name: _root_.io.circe.Encoder[$instanceType] = $resolved" + } } // we manage default serialization @@ -949,14 +980,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } val decoderInstanceDefs: List[Tree] = - repr.instances.map(_.decoder).map { case instance @ Instance(_, instanceType, name) => - val resolved = instance.resolve() - - if (checkDecoderValSafety(resolved)) { - q"private[this] val $name: _root_.io.circe.Decoder[$instanceType] = $resolved" - } else { - q"private[this] def $name: _root_.io.circe.Decoder[$instanceType] = $resolved" - } + repr.instances.map(_.decoder).map { + case instance @ Instance(_, instanceType, name) => + val resolved = instance.resolve() + + if (checkDecoderValSafety(resolved)) { + q"private[this] val $name: _root_.io.circe.Decoder[$instanceType] = $resolved" + } else { + q"private[this] def $name: _root_.io.circe.Decoder[$instanceType] = $resolved" + } } val reversed = repr.paramListsWithNames.flatten.reverse @@ -982,11 +1014,11 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { q""" { val $resName: _root_.io.circe.Decoder.Result[$memberType] = ${productMemberDecoding( - repr, - member, - useDefaults, - transformName - )} + repr, + member, + useDefaults, + transformName + )} if ($resName.isRight) { val $resultName: $memberType = ${extractFromRight(resName, memberType)} @@ -998,14 +1030,15 @@ class DerivationMacros(val c: blackbox.Context) extends ScalaVersionCompat { } val (results: List[Tree], resultNames: List[TermName]) = - reversed.reverse.map { case (member, resultName) => - ( - q""" + reversed.reverse.map { + case (member, resultName) => + ( + q""" val $resultName: _root_.io.circe.Decoder.AccumulatingResult[${member.tpe}] = ${productMemberAccumulatingDecoding(repr, member, useDefaults, transformName)} """, - resultName - ) + resultName + ) }.unzip val resultErrors: List[Tree] = resultNames.map(resultName => q"errors($resultName)") diff --git a/modules/derivation/shared/src/main/scala/io/circe/derivation/package.scala b/modules/derivation/shared/src/main/scala/io/circe/derivation/package.scala index e0369935..4ff080b6 100644 --- a/modules/derivation/shared/src/main/scala/io/circe/derivation/package.scala +++ b/modules/derivation/shared/src/main/scala/io/circe/derivation/package.scala @@ -1,6 +1,20 @@ -package io.circe +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import scala.language.experimental.macros +package io.circe package object derivation { final def deriveDecoder[A]: Decoder[A] = macro DerivationMacros.materializeDecoder[A] diff --git a/modules/derivation/shared/src/main/scala/io/circe/derivation/renaming.scala b/modules/derivation/shared/src/main/scala/io/circe/derivation/renaming.scala index c357bc3d..6b7d1ccb 100644 --- a/modules/derivation/shared/src/main/scala/io/circe/derivation/renaming.scala +++ b/modules/derivation/shared/src/main/scala/io/circe/derivation/renaming.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation package object renaming { diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/CirceSuite.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/CirceSuite.scala index 3e97b4a8..7c46bcdb 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/CirceSuite.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/CirceSuite.scala @@ -1,13 +1,30 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import cats.Eq import cats.instances.AllInstances -import cats.syntax.{ AllSyntax, EitherOps } -import io.circe.testing.{ ArbitraryInstances, EqInstances } +import cats.syntax.AllSyntax +import cats.syntax.EitherOps +import io.circe.testing.ArbitraryInstances +import io.circe.testing.EqInstances import org.scalatest.flatspec.AnyFlatSpec import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import org.typelevel.discipline.scalatest.FlatSpecDiscipline -import scala.language.implicitConversions /** * An opinionated stack of traits to improve consistency and reduce boilerplate in circe tests. diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/CodecAgreementTests.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/CodecAgreementTests.scala index 1be583d7..b4e2a584 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/CodecAgreementTests.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/CodecAgreementTests.scala @@ -1,9 +1,29 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import cats.kernel.Eq import cats.laws._ import cats.laws.discipline._ -import io.circe.{ Decoder, Encoder, Json } -import org.scalacheck.{ Arbitrary, Prop, Shrink } +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Json +import org.scalacheck.Arbitrary +import org.scalacheck.Prop +import org.scalacheck.Shrink import org.typelevel.discipline.Laws trait CodecAgreementLaws[A] { diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/DerivationSuite.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/DerivationSuite.scala index 7dd3c8c4..aeb3e003 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/DerivationSuite.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/DerivationSuite.scala @@ -1,7 +1,28 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import cats.data.{ NonEmptyList, Validated } -import io.circe.{ Codec, CursorOp, Decoder, Encoder, Json } +import cats.data.NonEmptyList +import cats.data.Validated +import io.circe.Codec +import io.circe.CursorOp +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Json import io.circe.examples._ import io.circe.syntax._ import io.circe.testing.CodecTests diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/GenericAutoCodecs.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/GenericAutoCodecs.scala index 0f7092d4..c2f6f4ae 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/GenericAutoCodecs.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/GenericAutoCodecs.scala @@ -1,8 +1,26 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import io.circe.{ Decoder, Encoder } +import io.circe.Decoder +import io.circe.Encoder import io.circe.examples._ -import io.circe.generic.semiauto.{ deriveDecoder => genericDeriveDecoder, deriveEncoder => genericDeriveEncoder } +import io.circe.generic.semiauto.{ deriveDecoder => genericDeriveDecoder } +import io.circe.generic.semiauto.{ deriveEncoder => genericDeriveEncoder } object GenericAutoCodecs { implicit val decodeFoo: Decoder[Foo] = genericDeriveDecoder diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformConstructorNamesSuite.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformConstructorNamesSuite.scala index 27ba1da0..de89438c 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformConstructorNamesSuite.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformConstructorNamesSuite.scala @@ -1,7 +1,33 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import io.circe.{ Codec, Decoder, Encoder, Json } -import io.circe.examples.{ Adt, AdtBar, AdtFoo, AdtQux, NestedAdt, NestedAdtBar, NestedAdtFoo, NestedAdtQux } +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Json +import io.circe.examples.Adt +import io.circe.examples.AdtBar +import io.circe.examples.AdtFoo +import io.circe.examples.AdtQux +import io.circe.examples.NestedAdt +import io.circe.examples.NestedAdtBar +import io.circe.examples.NestedAdtFoo +import io.circe.examples.NestedAdtQux import io.circe.syntax._ import io.circe.testing.CodecTests diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesExample.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesExample.scala index 03ee72e2..ee6c3f8a 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesExample.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesExample.scala @@ -1,7 +1,25 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import cats.kernel.Eq -import io.circe.{ Codec, Decoder, Encoder } +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder import org.scalacheck.Arbitrary object TransformMemberNamesExample { diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesSuite.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesSuite.scala index 4983c12a..88947779 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesSuite.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesSuite.scala @@ -1,7 +1,29 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation -import io.circe.{ Codec, Decoder, Encoder, Json } -import io.circe.examples.{ Bar, Baz, Foo, Qux } +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Json +import io.circe.examples.Bar +import io.circe.examples.Baz +import io.circe.examples.Foo +import io.circe.examples.Qux import io.circe.parser.decode import io.circe.syntax._ import io.circe.testing.CodecTests diff --git a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesWithDefaultsSuite.scala b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesWithDefaultsSuite.scala index f5a1a7e2..16f0aa9f 100644 --- a/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesWithDefaultsSuite.scala +++ b/modules/derivation/shared/src/test/scala/io/circe/derivation/TransformMemberNamesWithDefaultsSuite.scala @@ -1,10 +1,32 @@ +/* + * Copyright 2017 circe + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package io.circe.derivation import cats.data.Validated -import io.circe.{ Codec, Decoder, Encoder, Json } -import io.circe.examples.{ Bar, Baz, Foo, Qux } -import io.circe.syntax._ +import io.circe.Codec +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Json +import io.circe.examples.Bar +import io.circe.examples.Baz +import io.circe.examples.Foo +import io.circe.examples.Qux import io.circe.examples._ +import io.circe.syntax._ import io.circe.testing.CodecTests object TransformMemberNamesWithDefaultsSuiteCodecs extends Serializable { diff --git a/project/build.properties b/project/build.properties index 46e43a97..bbb0b608 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.8.2 +sbt.version=1.11.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index bb4e2ccc..8da281ee 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,15 +1,7 @@ -addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.13.0") -addSbtPlugin("com.github.sbt" % "sbt-release" % "1.1.0") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.8") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.7") +addSbtPlugin("io.circe" % "sbt-circe-org" % "0.4.8") // Only needed for testing. -addSbtPlugin("com.twitter" % "scrooge-sbt-plugin" % "20.4.1") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.0.1") -addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.3") -addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.2") -addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.4.1") -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.8.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.4") -addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3") -addSbtPlugin("org.wartremover" % "sbt-wartremover" % "2.4.19") +addSbtPlugin("com.twitter" % "scrooge-sbt-plugin" % "24.2.0") diff --git a/scalastyle-config.xml b/scalastyle-config.xml deleted file mode 100644 index ee8b24d7..00000000 --- a/scalastyle-config.xml +++ /dev/null @@ -1,85 +0,0 @@ - - Circe Configuration - - - FOR - IF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - all - .+ - - - diff --git a/version.sbt b/version.sbt deleted file mode 100644 index f9df5561..00000000 --- a/version.sbt +++ /dev/null @@ -1 +0,0 @@ -ThisBuild / version := "0.13.0-SNAPSHOT"