From 1c021f8d02ce7c0445a022fd13b9e2423fa4b371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 24 May 2017 23:03:48 +0200 Subject: [PATCH 01/14] Use EPFL Artifactory for resolution. Also, it always bugged me that misformatted file errors blocked tests. This change makes it so that scalafmt is only run on a single entry in the build matrix --- .drone.yml | 4 ++-- .drone.yml.sig | 2 +- bin/runci.sh | 16 ++++++++++++++++ build.sbt | 11 ++++++++++- scalafmt | Bin 12534 -> 12226 bytes 5 files changed, 29 insertions(+), 4 deletions(-) create mode 100755 bin/runci.sh diff --git a/.drone.yml b/.drone.yml index 037f2a7ec..d3fd81290 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,8 +7,7 @@ pipeline: pull: true commands: - git fetch --tags && git log | head -n 20 - - ./scalafmt --test - - /usr/bin/sbt $CI_TEST + - ./bin/runci.sh $CI_TEST publish: image: olafurpg/scalafix:0.3.0 @@ -30,3 +29,4 @@ matrix: CI_SCALA_VERSION: 2.12.2 - CI_TEST: ci-slow CI_SCALA_VERSION: 2.11.11 + - CI_TEST: scalafmt diff --git a/.drone.yml.sig b/.drone.yml.sig index a643c565f..982c596e0 100644 --- a/.drone.yml.sig +++ b/.drone.yml.sig @@ -1 +1 @@ -eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgdGVzdHM6CiAgICBpbWFnZTogc2NhbGFwbGF0Zm9ybS9zY2FsYToxLjIKICAgIGVudmlyb25tZW50OgogICAgICAtIEJJTlRSQVlfVVNFUk5BTUU9Zm9vX3VzZXIKICAgICAgLSBCSU5UUkFZX1BBU1NXT1JEPWZvb19wYXNzd29yZAogICAgcHVsbDogdHJ1ZQogICAgY29tbWFuZHM6CiAgICAgIC0gZ2l0IGZldGNoIC0tdGFncyAmJiBnaXQgbG9nIHwgaGVhZCAtbiAyMAogICAgICAtIC4vc2NhbGFmbXQgLS10ZXN0CiAgICAgIC0gL3Vzci9iaW4vc2J0ICRDSV9URVNUCgogIHB1Ymxpc2g6CiAgICBpbWFnZTogb2xhZnVycGcvc2NhbGFmaXg6MC4zLjAKICAgIHB1bGw6IHRydWUKICAgIHZvbHVtZXM6CiAgICAgIC0gL3BsYXRmb3JtOi9rZXlzCiAgICBjb21tYW5kczoKICAgICAgLSAuL2Jpbi9wdWJsaXNoLnNoCiAgICB3aGVuOgogICAgICBldmVudDogW3B1c2gsIHRhZ10KICAgICAgYnJhbmNoOiBbbWFzdGVyXQoKbWF0cml4OgogIGluY2x1ZGU6CiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQogICAgICBDSV9QVUJMSVNIOiB0cnVlCiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMi4yCiAgICAtIENJX1RFU1Q6IGNpLXNsb3cKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQo.CAw7B_peQuTMacKIPeaUMHKi4cjPPs-8TNi9oQ7OOEU \ No newline at end of file +eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgdGVzdHM6CiAgICBpbWFnZTogc2NhbGFwbGF0Zm9ybS9zY2FsYToxLjIKICAgIGVudmlyb25tZW50OgogICAgICAtIEJJTlRSQVlfVVNFUk5BTUU9Zm9vX3VzZXIKICAgICAgLSBCSU5UUkFZX1BBU1NXT1JEPWZvb19wYXNzd29yZAogICAgcHVsbDogdHJ1ZQogICAgY29tbWFuZHM6CiAgICAgIC0gZ2l0IGZldGNoIC0tdGFncyAmJiBnaXQgbG9nIHwgaGVhZCAtbiAyMAogICAgICAtIC4vYmluL3J1bmNpLnNoICRDSV9URVNUCgogIHB1Ymxpc2g6CiAgICBpbWFnZTogb2xhZnVycGcvc2NhbGFmaXg6MC4zLjAKICAgIHB1bGw6IHRydWUKICAgIHZvbHVtZXM6CiAgICAgIC0gL3BsYXRmb3JtOi9rZXlzCiAgICBjb21tYW5kczoKICAgICAgLSAuL2Jpbi9wdWJsaXNoLnNoCiAgICB3aGVuOgogICAgICBldmVudDogW3B1c2gsIHRhZ10KICAgICAgYnJhbmNoOiBbbWFzdGVyXQoKbWF0cml4OgogIGluY2x1ZGU6CiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQogICAgICBDSV9QVUJMSVNIOiB0cnVlCiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMi4yCiAgICAtIENJX1RFU1Q6IGNpLXNsb3cKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQogICAgLSBDSV9URVNUOiBzY2FsYWZtdAo.DjLtSc3Q6xjSArP59XYTtwDxEPy685nloNsUL5LuT_s \ No newline at end of file diff --git a/bin/runci.sh b/bin/runci.sh new file mode 100755 index 000000000..e3848e02d --- /dev/null +++ b/bin/runci.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -eux +TEST=${1} + +case "$TEST" in + "scalafmt" ) + ./scalafmt --test + ;; + * ) + sbt $TEST + ;; +esac + + + + diff --git a/build.sbt b/build.sbt index ac6e1100e..317ad4021 100644 --- a/build.sbt +++ b/build.sbt @@ -84,6 +84,12 @@ lazy val allSettings = List( version := sys.props.getOrElse("scalafix.version", version.value), resolvers += Resolver.bintrayRepo("scalameta", "maven"), resolvers += Resolver.sonatypeRepo("releases"), + resolvers ~= { old => + if (isDroneCI) { + println(s"Using resolver: $epflArtifactory") + epflArtifactory +: old + } else old + }, triggeredMessage in ThisBuild := Watched.clearWhenTriggered, scalacOptions := compilerOptions, scalacOptions in (Compile, console) := compilerOptions :+ "-Yrepl-class-based", @@ -331,5 +337,8 @@ def setId(project: Project): Project = { val newId = "scalafix-" + project.id project.copy(base = file(newId)).settings(moduleName := newId) } - def customScalafixVersion = sys.props.get("scalafix.version") +def isDroneCI = sys.env("CI") == "DRONE" +def epflArtifactory = + MavenRepository("epfl-artifactory", + "http://scala-webapps.epfl.ch:8081/artifactory/dbuild/") diff --git a/scalafmt b/scalafmt index fde05c864a9dbb7c0779cb78cb8351fa1f1d2eb0..17107ef9c95954ee682b12ba8a9917a8537a928d 100755 GIT binary patch delta 10035 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 M_MSt2hQB}mADQZ^sQ>@~ delta 10377 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 Date: Thu, 25 May 2017 15:18:57 +0200 Subject: [PATCH 02/14] Use olafurpg/scala docker image with sbt cached. --- .drone.yml | 2 +- .drone.yml.sig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index d3fd81290..24d10ec7e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,6 +1,6 @@ pipeline: tests: - image: scalaplatform/scala:1.2 + image: olafurpg/scala:0.1 environment: - BINTRAY_USERNAME=foo_user - BINTRAY_PASSWORD=foo_password diff --git a/.drone.yml.sig b/.drone.yml.sig index 982c596e0..a07764419 100644 --- a/.drone.yml.sig +++ b/.drone.yml.sig @@ -1 +1 @@ -eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgdGVzdHM6CiAgICBpbWFnZTogc2NhbGFwbGF0Zm9ybS9zY2FsYToxLjIKICAgIGVudmlyb25tZW50OgogICAgICAtIEJJTlRSQVlfVVNFUk5BTUU9Zm9vX3VzZXIKICAgICAgLSBCSU5UUkFZX1BBU1NXT1JEPWZvb19wYXNzd29yZAogICAgcHVsbDogdHJ1ZQogICAgY29tbWFuZHM6CiAgICAgIC0gZ2l0IGZldGNoIC0tdGFncyAmJiBnaXQgbG9nIHwgaGVhZCAtbiAyMAogICAgICAtIC4vYmluL3J1bmNpLnNoICRDSV9URVNUCgogIHB1Ymxpc2g6CiAgICBpbWFnZTogb2xhZnVycGcvc2NhbGFmaXg6MC4zLjAKICAgIHB1bGw6IHRydWUKICAgIHZvbHVtZXM6CiAgICAgIC0gL3BsYXRmb3JtOi9rZXlzCiAgICBjb21tYW5kczoKICAgICAgLSAuL2Jpbi9wdWJsaXNoLnNoCiAgICB3aGVuOgogICAgICBldmVudDogW3B1c2gsIHRhZ10KICAgICAgYnJhbmNoOiBbbWFzdGVyXQoKbWF0cml4OgogIGluY2x1ZGU6CiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQogICAgICBDSV9QVUJMSVNIOiB0cnVlCiAgICAtIENJX1RFU1Q6IGNpLWZhc3QKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMi4yCiAgICAtIENJX1RFU1Q6IGNpLXNsb3cKICAgICAgQ0lfU0NBTEFfVkVSU0lPTjogMi4xMS4xMQogICAgLSBDSV9URVNUOiBzY2FsYWZtdAo.DjLtSc3Q6xjSArP59XYTtwDxEPy685nloNsUL5LuT_s \ No newline at end of file +eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgdGVzdHM6CiAgICBpbWFnZTogb2xhZnVycGcvc2NhbGE6MC4xCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBCSU5UUkFZX1VTRVJOQU1FPWZvb191c2VyCiAgICAgIC0gQklOVFJBWV9QQVNTV09SRD1mb29fcGFzc3dvcmQKICAgIHB1bGw6IHRydWUKICAgIGNvbW1hbmRzOgogICAgICAtIGdpdCBmZXRjaCAtLXRhZ3MgJiYgZ2l0IGxvZyB8IGhlYWQgLW4gMjAKICAgICAgLSAuL2Jpbi9ydW5jaS5zaCAkQ0lfVEVTVAoKICBwdWJsaXNoOgogICAgaW1hZ2U6IG9sYWZ1cnBnL3NjYWxhZml4OjAuMy4wCiAgICBwdWxsOiB0cnVlCiAgICB2b2x1bWVzOgogICAgICAtIC9wbGF0Zm9ybTova2V5cwogICAgY29tbWFuZHM6CiAgICAgIC0gLi9iaW4vcHVibGlzaC5zaAogICAgd2hlbjoKICAgICAgZXZlbnQ6IFtwdXNoLCB0YWddCiAgICAgIGJyYW5jaDogW21hc3Rlcl0KCm1hdHJpeDoKICBpbmNsdWRlOgogICAgLSBDSV9URVNUOiBjaS1mYXN0CiAgICAgIENJX1NDQUxBX1ZFUlNJT046IDIuMTEuMTEKICAgICAgQ0lfUFVCTElTSDogdHJ1ZQogICAgLSBDSV9URVNUOiBjaS1mYXN0CiAgICAgIENJX1NDQUxBX1ZFUlNJT046IDIuMTIuMgogICAgLSBDSV9URVNUOiBjaS1zbG93CiAgICAgIENJX1NDQUxBX1ZFUlNJT046IDIuMTEuMTEKICAgIC0gQ0lfVEVTVDogc2NhbGFmbXQK.SxfxsZ9QYuIR2jIvU5VUhC-R6Et1O3zQ3Vtf3MjWjjQ \ No newline at end of file From 9beff13d4bb390f4f82c4459ba97a75882cff907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 25 May 2017 17:18:55 +0200 Subject: [PATCH 03/14] More project cleanup. - scalafix-testkit no longer interfaces with the ScalahostPipeline API. Instead, we use sbt-scalahost to build a mirror and buildinfo to generate the necessary mappings between original and expected code. This results in a cleaner test setup: - no more .source files without syntax highlighting and auto-completion. - less duplication wrapping every unit test in `object a { }` - cleaner compiler errors in input/output projects - easier to use custom classpath for single test suite, just add a new project! - Remove old organize imports. OrganizeImports was implemented before Symbols came and the current implementation is weird adaptation from the old ScalafixMirror that no longer exists. Instead of keeping this cruft, this commit removes the import patches with less ambitious patch implementation that are still somewhat useful. --- .scalafmt.conf | 3 + build.sbt | 110 +++++-- project/plugins.sbt | 7 +- project/project/plugins.sbt | 1 + readme/ImplementingRewrites.scalatex | 75 ----- .../src/test/scala/scalafix/cli/CliTest.scala | 4 +- .../config/ExplicitReturnTypesConfig.scala | 29 ++ .../scalafix/config/ScalafixConfig.scala | 1 + .../config/ScalafixMetaconfigReaders.scala | 12 +- .../src/main/scala/scalafix/package.scala | 4 +- .../scala/scalafix/patch/ImportPatchOps.scala | 89 ++++++ .../scalafix/patch/OrganizeImports.scala | 219 -------------- .../src/main/scala/scalafix/patch/Patch.scala | 84 ++++-- ...plicit.scala => ExplicitReturnTypes.scala} | 2 +- .../scala/scalafix/rewrite/RewriteCtx.scala | 1 + .../scalafix/rewrite/ScalaJsRewrites.scala | 81 ------ .../scalafix/rewrite/ScalafixRewrites.scala | 3 +- .../scalafix/rewrite/SemanticPatchOps.scala | 12 +- .../scala/scalafix/rewrite/Xor2Either.scala | 4 +- .../main/scala/scalafix/syntax/package.scala | 13 + .../main/scala/scalafix/util/TokenList.scala | 6 + .../testkit/SemanticRewriteSuite.scala | 275 +++--------------- .../main}/resources/rewrites/MyRewrite.scala | 0 .../main}/resources/rewrites/MyRewrite2.scala | 0 .../main/scala/test/ExplicitReturnTypes.scala | 69 +++++ .../src/main/scala/test/ExplicitUnit.scala | 25 ++ .../src/main/scala/test/FileRewrite.scala | 8 + .../src/main/scala/test/FileRewrite2.scala | 8 + .../src/main/scala/test/FlipEither.scala} | 12 +- .../src/main/scala/test/FqnRewrite.scala} | 11 +- .../src/main/scala/test/NoAutoTupling.scala | 62 ++++ .../scala/test/PatchWithEmptyRange.scala} | 11 +- .../src/main/scala/test/ProcedureSyntax.scala | 21 ++ .../main/scala/test/RemoveXmlLiterals.scala | 59 ++++ .../src/main/scala/test/VolatileLazyVal.scala | 17 ++ .../src/main/scala/test/Xor2Either.scala | 15 + .../main/scala/test/ExplicitReturnTypes.scala | 66 +++++ .../src/main/scala/test/ExplicitUnit.scala | 22 ++ .../src/main/scala/test/FileRewrite.scala | 4 + .../src/main/scala/test/FileRewrite2.scala | 4 + .../src/main/scala/test/FlipEither.scala | 6 + .../src/main/scala/test/FqnRewrite.scala | 7 + .../src/main/scala/test/NoAutoTupling.scala | 60 ++++ .../main/scala/test/PatchWithEmptyRange.scala | 6 + .../src/main/scala/test/ProcedureSyntax.scala | 18 ++ .../main/scala/test/RemoveXmlLiterals.scala | 58 ++++ .../src/main/scala/test/VolatileLazyVal.scala | 14 + .../src/main/scala/test/Xor2Either.scala | 14 + .../src/main/scala/cats/data/Xor.scala | 0 .../src/main/scala/cats/implicits.scala | 0 .../ExplicitImplicit/ExplicitImplicit.source | 215 -------------- .../checkSyntax/DemandJsGlobal.source | 115 -------- .../resources/checkSyntax/ExplicitUnit.source | 49 ---- .../resources/checkSyntax/FileRewrite.source | 9 - .../resources/checkSyntax/FileRewrite2.source | 8 - .../test/resources/checkSyntax/LazyVal.source | 32 -- .../checkSyntax/NoAutoTupling.source | 115 -------- .../checkSyntax/OrganizeImportsBase.source | 84 ------ .../OrganizeImportsExpandRelative.source | 50 ---- .../OrganizeImportsGroupByPrefix.source | 16 - .../OrganizeImportsNoGroups.source | 9 - .../OrganizeImportsNoPreviousImport.source | 11 - .../OrganizeImportsRemoveUnused.source | 146 ---------- .../checkSyntax/ProcedureSyntax.source | 45 --- .../checkSyntax/RemoveXmlLiterals.source | 132 --------- .../resources/checkSyntax/Xor2Either.source | 44 --- .../scala/scalafix/tests/SemanticTests.scala | 10 - .../scala/scalafix/tests/ProjectTests.scala | 0 .../scalafix/tests/URLConfiguration.scala | 0 .../src/main/scala/scala/scalajs/js.scala | 0 .../scala/scala/scalajs/js/GlobalScope.scala | 0 .../main/scala/scala/scalajs/js/Object.scala | 0 .../scalajs/js/annotation/JSGlobal.scala | 0 .../scala/scalajs/js/annotation/JSName.scala | 0 .../scalajs/js/annotation/falsealarm/js.scala | 0 .../main/scala/scalafix/test/FqnRewrite.scala | 4 +- .../main/scala/scalafix/test/Generic.scala | 0 .../scala/scalafix/tests/ErrorSuite.scala | 0 .../tests/GitHubUrlRewriteSuite.scala | 0 .../scala/scalafix/tests/SemanticTests.scala | 21 ++ 80 files changed, 948 insertions(+), 1799 deletions(-) create mode 100644 scalafix-core/src/main/scala/scalafix/config/ExplicitReturnTypesConfig.scala create mode 100644 scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala delete mode 100644 scalafix-core/src/main/scala/scalafix/patch/OrganizeImports.scala rename scalafix-core/src/main/scala/scalafix/rewrite/{ExplicitImplicit.scala => ExplicitReturnTypes.scala} (96%) delete mode 100644 scalafix-core/src/main/scala/scalafix/rewrite/ScalaJsRewrites.scala rename scalafix-tests/{src/test => input/src/main}/resources/rewrites/MyRewrite.scala (100%) rename scalafix-tests/{src/test => input/src/main}/resources/rewrites/MyRewrite2.scala (100%) create mode 100644 scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala create mode 100644 scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala create mode 100644 scalafix-tests/input/src/main/scala/test/FileRewrite.scala create mode 100644 scalafix-tests/input/src/main/scala/test/FileRewrite2.scala rename scalafix-tests/{src/test/resources/checkSyntax/FlipEither.source => input/src/main/scala/test/FlipEither.scala} (74%) rename scalafix-tests/{src/test/resources/checkSyntax/FqnRewrite.source => input/src/main/scala/test/FqnRewrite.scala} (66%) create mode 100644 scalafix-tests/input/src/main/scala/test/NoAutoTupling.scala rename scalafix-tests/{src/test/resources/checkSyntax/PatchTokenWithEmptyRange.source => input/src/main/scala/test/PatchWithEmptyRange.scala} (51%) create mode 100644 scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala create mode 100644 scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala create mode 100644 scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala create mode 100644 scalafix-tests/input/src/main/scala/test/Xor2Either.scala create mode 100644 scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala create mode 100644 scalafix-tests/output/src/main/scala/test/ExplicitUnit.scala create mode 100644 scalafix-tests/output/src/main/scala/test/FileRewrite.scala create mode 100644 scalafix-tests/output/src/main/scala/test/FileRewrite2.scala create mode 100644 scalafix-tests/output/src/main/scala/test/FlipEither.scala create mode 100644 scalafix-tests/output/src/main/scala/test/FqnRewrite.scala create mode 100644 scalafix-tests/output/src/main/scala/test/NoAutoTupling.scala create mode 100644 scalafix-tests/output/src/main/scala/test/PatchWithEmptyRange.scala create mode 100644 scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala create mode 100644 scalafix-tests/output/src/main/scala/test/RemoveXmlLiterals.scala create mode 100644 scalafix-tests/output/src/main/scala/test/VolatileLazyVal.scala create mode 100644 scalafix-tests/output/src/main/scala/test/Xor2Either.scala rename scalafix-tests/{ => shared}/src/main/scala/cats/data/Xor.scala (100%) rename scalafix-tests/{ => shared}/src/main/scala/cats/implicits.scala (100%) delete mode 100644 scalafix-tests/src/test/resources/ExplicitImplicit/ExplicitImplicit.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/DemandJsGlobal.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/ExplicitUnit.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/FileRewrite.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/FileRewrite2.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/LazyVal.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/NoAutoTupling.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsBase.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsExpandRelative.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsGroupByPrefix.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoGroups.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoPreviousImport.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsRemoveUnused.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/ProcedureSyntax.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/RemoveXmlLiterals.source delete mode 100644 scalafix-tests/src/test/resources/checkSyntax/Xor2Either.source delete mode 100644 scalafix-tests/src/test/scala/scalafix/tests/SemanticTests.scala rename scalafix-tests/{ => unit}/src/it/scala/scalafix/tests/ProjectTests.scala (100%) rename scalafix-tests/{ => unit}/src/it/scala/scalafix/tests/URLConfiguration.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js/GlobalScope.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js/Object.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js/annotation/JSName.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scala/scalajs/js/annotation/falsealarm/js.scala (100%) rename scalafix-tests/{ => unit}/src/main/scala/scalafix/test/FqnRewrite.scala (88%) rename scalafix-tests/{ => unit}/src/main/scala/scalafix/test/Generic.scala (100%) rename scalafix-tests/{ => unit}/src/test/scala/scalafix/tests/ErrorSuite.scala (100%) rename scalafix-tests/{ => unit}/src/test/scala/scalafix/tests/GitHubUrlRewriteSuite.scala (100%) create mode 100644 scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 214e2853e..9e24de54e 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -7,3 +7,6 @@ align.tokens = [ ] onTestFailure = "To fix this, run `./scalafmt` from the project base directory" optIn.annotationNewlines = true +project.excludeFilters = [ + scalafix-tests/output +] diff --git a/build.sbt b/build.sbt index 317ad4021..2260b8935 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,9 @@ import sbt.ScriptedPlugin import sbt.ScriptedPlugin._ - import Dependencies._ +import xsbti.Position +import xsbti.Reporter +import xsbti.Severity organization in ThisBuild := "ch.epfl.scala" version in ThisBuild := customScalafixVersion.getOrElse( version.in(ThisBuild).value) @@ -91,12 +93,13 @@ lazy val allSettings = List( } else old }, triggeredMessage in ThisBuild := Watched.clearWhenTriggered, - scalacOptions := compilerOptions, + scalacOptions ++= compilerOptions, scalacOptions in (Compile, console) := compilerOptions :+ "-Yrepl-class-based", libraryDependencies += scalatest % Test, testOptions in Test += Tests.Argument("-oD"), scalaVersion := ciScalaVersion.getOrElse(scala212), crossScalaVersions := crossVersions, + scalametaSemanticdb := ScalametaSemanticdb.Disabled, updateOptions := updateOptions.value.withCachedResolution(true) ) @@ -221,8 +224,82 @@ lazy val testkit = project reflect ) -lazy val tests = project - .configure(setId) +lazy val testsDeps = List( + // integration property tests + "org.renucci" %% "scala-xml-quote" % "0.1.3", + "org.typelevel" %% "catalysts-platform" % "0.0.5", + "com.typesafe.slick" %% "slick" % "3.2.0-M2", + "com.chuusai" %% "shapeless" % "2.3.2", + "org.scalacheck" %% "scalacheck" % "1.13.4" +) + +lazy val testsShared = project + .in(file("scalafix-tests/shared")) + .settings( + allSettings, + noPublish + ) + +lazy val testsInput = project + .in(file("scalafix-tests/input")) + .settings( + allSettings, + noPublish, + scalametaSourceroot := sourceDirectory.in(Compile).value, + scalametaSemanticdb := ScalametaSemanticdb.Fat, + scalacOptions ~= (_.filterNot(_ == "-Yno-adapted-args")), + // TODO: Remove once scala-xml-quote is merged into scala-xml + resolvers += Resolver.bintrayRepo("allanrenucci", "maven"), + libraryDependencies ++= testsDeps + ) + .dependsOn(testsShared) + +lazy val testsOutput = project + .in(file("scalafix-tests/output")) + .settings( + allSettings, + noPublish, + resolvers := resolvers.in(testsInput).value, + libraryDependencies := libraryDependencies.in(testsInput).value + ) + .dependsOn(testsShared) + +lazy val unit = project + .in(file("scalafix-tests/unit")) + .settings( + allSettings, + noPublish, + fork := false, + javaOptions := Nil, + buildInfoPackage := "scalafix.tests", + buildInfoObject := "BuildInfo", + compileInputs.in(Compile, compile) := + compileInputs + .in(Compile, compile) + .dependsOn( + compile.in(testsInput, Compile), + compile.in(testsOutput, Compile) + ) + .value, + buildInfoKeys := Seq[BuildInfoKey]( + "inputSourceroot" -> + sourceDirectory.in(testsInput, Compile).value, + "outputSourceroot" -> + sourceDirectory.in(testsOutput, Compile).value, + "testsInputResources" -> resourceDirectory.in(testsInput, Compile).value, + "mirrorClasspath" -> classDirectory.in(testsInput, Compile).value + ), + libraryDependencies ++= testsDeps + ) + .enablePlugins(BuildInfoPlugin) + .dependsOn( + testsInput % Scalameta, + cli, + testkit + ) + +lazy val integration = project + .in(file("scalafix-tests/integration")) .configs(IntegrationTest) .settings( allSettings, @@ -233,21 +310,10 @@ lazy val tests = project s"; plz $scala212 publishLocal " + s"; such scalafix-sbt/publishLocal " + "; tests/it:testQuick" // hack to workaround cyclic dependencies in test. - )(state.value), - parallelExecution in Test := true, - // TODO: Remove once scala-xml-quote is merged into scala-xml - resolvers += Resolver.bintrayRepo("allanrenucci", "maven"), - libraryDependencies ++= Seq( - scalahost % Test, - // integration property tests - "org.renucci" %% "scala-xml-quote" % "0.1.3" % Test, - "org.typelevel" %% "catalysts-platform" % "0.0.5" % Test, - "com.typesafe.slick" %% "slick" % "3.2.0-M2" % Test, - "com.chuusai" %% "shapeless" % "2.3.2" % Test, - "org.scalacheck" %% "scalacheck" % "1.13.4" % Test - ) + )(state.value) ) .dependsOn( + testsInput % Scalameta, core, reflect, testkit @@ -291,8 +357,7 @@ def exposePaths(projectName: String, fullClasspath in config := { val defaultValue = (fullClasspath in config).value val classpath = defaultValue.files.map(_.getAbsolutePath) - val scalaLibrary = - classpath.map(_.toString).find(_.contains("scala-library")).get + val scalaLibrary = classpath.find(_.contains("scala-library")).get System.setProperty("sbt.paths.scalalibrary.classes", scalaLibrary) System.setProperty(prefix + "classes", classpath.mkString(java.io.File.pathSeparator)) @@ -335,10 +400,13 @@ lazy val gitPushTag = taskKey[Unit]("Push to git tag") def setId(project: Project): Project = { val newId = "scalafix-" + project.id - project.copy(base = file(newId)).settings(moduleName := newId) + project + .copy(base = file(newId)) + .settings(moduleName := newId) + .disablePlugins(ScalahostSbtPlugin) } def customScalafixVersion = sys.props.get("scalafix.version") -def isDroneCI = sys.env("CI") == "DRONE" +def isDroneCI = sys.env.get("CI").exists(_ == "DRONE") def epflArtifactory = MavenRepository("epfl-artifactory", "http://scala-webapps.epfl.ch:8081/artifactory/dbuild/") diff --git a/project/plugins.sbt b/project/plugins.sbt index 486ba0018..e260afcd3 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -8,8 +8,9 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1") addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "1.2.0") +addSbtPlugin("org.scalameta" % "sbt-scalahost" % Dependencies.scalametaV) + +resolvers += Resolver.bintrayIvyRepo("duhemm", "sbt-plugins") +addSbtPlugin("org.duhemm" % "sbt-errors-summary" % "0.2.0") -// TODO(olafur) re-enable scoverage. -// scoverage is disabled because it messes up with scalafix-nsc -//addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.0.1") libraryDependencies += "org.scala-sbt" % "scripted-plugin" % sbtVersion.value diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt index 5b48d85fb..ae8cb7d8d 100644 --- a/project/project/plugins.sbt +++ b/project/project/plugins.sbt @@ -1 +1,2 @@ addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-M15") +unmanagedSources.in(Compile) += baseDirectory.value / ".." / "Dependencies.scala" diff --git a/readme/ImplementingRewrites.scalatex b/readme/ImplementingRewrites.scalatex index e7ef0b59a..db6e574fe 100644 --- a/readme/ImplementingRewrites.scalatex +++ b/readme/ImplementingRewrites.scalatex @@ -18,78 +18,3 @@ @bintrayRepo libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "@V.nightly" % Test cross CrossVersion.full - @p - Tests are written in @code{.source} text files in some directory - of your project. A good place to put the tests is under @code{src/test/resources} - so that tests re-run on file save when using @code{~test}. - - @p - Unit tests are written in the following format: - @hl.scala - <<< This is a test name - object OriginalCode - >>> - object ExpectedCode - <<< This is another test file - object OriginalCode - >>> - object ExpectedCode - @p - To setup a test suite with scalafix-testkit: - - @hl.ref(wd/"scalafix-tests"/"src"/"test"/"scala"/"scalafix"/"tests"/"SemanticTests.scala") - - @p - Define @code{.scalafix.conf} configuration at the top of a @code{.source} file: - - @hl.scala - $ cat MyTest.source - rewrites = [ProcedureSyntax] - <<< basic main function - object Main { def main(args: Seq[String]) { println(args) } } - >>> - object Main { def main(args: Seq[String]): Unit = { println(args) } } - - @p - When a test fails, a failure report shows a diff between the expected - and obtained output of the rewrite. - - @hl.scala - =========== - => Obtained - =========== - object Main { def main(args: Seq[String]) { println(args) } } - - ======= - => Diff - ======= - - object Main { def main(args: Seq[String]) { println(args) } } - + object Main { def main(args: Seq[String]): Unit = { println(args) } } - - @p - To run only a single test, prefix the test name with @code{ONLY} - @hl.scala - <<< ONLY This test will run - object OriginalCode - >>> - object ExpectedCode - <<< This test is skipped - object OriginalCode - >>> - object ExpectedCode - - @p - To skip a single test, prefix the test name with @code{SKIP} - @hl.scala - <<< SKIP This test will NOT run - object OriginalCode - >>> - object ExpectedCode - <<< This test will run - object OriginalCode - >>> - object ExpectedCode - - @p - For more resources on scalafix-testkit, clone the scalafix repo and - look at the sources in the @code{scalafix-tests} module. diff --git a/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala b/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala index f3ba6dffb..362a17160 100644 --- a/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala +++ b/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala @@ -1,7 +1,7 @@ package scalafix.cli import scala.collection.immutable.Seq -import scalafix.rewrite.ExplicitImplicit +import scalafix.rewrite.ExplicitReturnTypes import scalafix.rewrite.ProcedureSyntax import scalafix.testkit.DiffAssertions import scalafix.util.FileOps @@ -146,7 +146,7 @@ class CliTest extends FunSuite with DiffAssertions { val file = File.createTempFile("prefix", ".scala") FileOps.writeFile(file, "object a { implicit val x = ??? }") val code = Cli.runOn( - ScalafixOptions(rewrites = List(ExplicitImplicit.toString), + ScalafixOptions(rewrites = List(ExplicitReturnTypes.toString), files = List(file.getAbsolutePath), common = devNull)) assert(code == ExitStatus.InvalidCommandLineOption) diff --git a/scalafix-core/src/main/scala/scalafix/config/ExplicitReturnTypesConfig.scala b/scalafix-core/src/main/scala/scalafix/config/ExplicitReturnTypesConfig.scala new file mode 100644 index 000000000..05d11be76 --- /dev/null +++ b/scalafix-core/src/main/scala/scalafix/config/ExplicitReturnTypesConfig.scala @@ -0,0 +1,29 @@ +package scalafix.config + +import metaconfig._ + +@DeriveConfDecoder +case class ExplicitReturnTypesConfig( + memberKind: Seq[MemberKind] = Nil, + memberVisibility: Seq[MemberVisibility] = Nil +) + +sealed trait MemberVisibility +object MemberVisibility { + case object Public extends MemberVisibility + case object Protected extends MemberVisibility + case object Private extends MemberVisibility + def all = List(Public, Protected, Private) + implicit val readerMemberVisibility: ConfDecoder[MemberVisibility] = + ReaderUtil.fromMap(all.map(x => x.toString -> x).toMap) +} + +sealed trait MemberKind +object MemberKind { + case object Def extends MemberKind + case object Val extends MemberKind + case object Var extends MemberKind + def all = List(Def, Val, Var) + implicit val readerMemberKind: ConfDecoder[MemberKind] = + ReaderUtil.fromMap(all.map(x => x.toString -> x).toMap) +} diff --git a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala index 2940d4e19..7fb6bef99 100644 --- a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala +++ b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala @@ -13,6 +13,7 @@ import metaconfig.typesafeconfig.typesafeConfigMetaconfigParser @DeriveConfDecoder case class ScalafixConfig( parser: Parse[_ <: Tree] = Parse.parseSource, + @Recurse explicitReturnTypes: ExplicitReturnTypesConfig = ExplicitReturnTypesConfig(), @Recurse imports: ImportsConfig = ImportsConfig(), @Recurse patches: PatchConfig = PatchConfig(), @Recurse debug: DebugConfig = DebugConfig(), diff --git a/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala b/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala index 27c135428..c4a834529 100644 --- a/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala +++ b/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala @@ -11,11 +11,10 @@ import scala.util.matching.Regex import scalafix.patch.TreePatch._ import scalafix.rewrite.ScalafixRewrites import scalafix.util.ClassloadRewrite - import java.io.OutputStream import java.io.PrintStream import java.net.URI - +import java.util.regex.Pattern import metaconfig.Conf import metaconfig.ConfDecoder import metaconfig.ConfError @@ -49,10 +48,13 @@ trait ScalafixMetaconfigReaders { } yield scheme -> uri } + private val rewriteReges = Pattern.compile("rewrites?") + private def isRewriteKey(key: (String, Conf)) = + rewriteReges.matcher(key._1).matches() def scalafixConfigEmptyRewriteReader: ConfDecoder[(Conf, ScalafixConfig)] = ConfDecoder.instance[(Conf, ScalafixConfig)] { case Conf.Obj(values) => - val (rewrites, noRewrites) = values.partition(_._1 == "rewrites") + val (rewrites, noRewrites) = values.partition(isRewriteKey) val rewriteConf = Configured.Ok(rewrites.lastOption.map(_._2).getOrElse(Conf.Lst())) val config = @@ -141,6 +143,8 @@ trait ScalafixMetaconfigReaders { } implicit lazy val importerReader: ConfDecoder[Importer] = parseReader[Importer] + implicit lazy val importeeReader: ConfDecoder[Importee] = + parseReader[Importee] implicit lazy val refReader: ConfDecoder[Ref] = castReader[Stat, Ref](parseReader[Stat]) implicit lazy val termRefReader: ConfDecoder[Term.Ref] = @@ -153,7 +157,7 @@ trait ScalafixMetaconfigReaders { implicit lazy val AddGlobalImportReader: ConfDecoder[AddGlobalImport] = importerReader.map(AddGlobalImport.apply) implicit lazy val RemoveGlobalImportReader: ConfDecoder[RemoveGlobalImport] = - importerReader.map(RemoveGlobalImport.apply) + symbolReader.map(RemoveGlobalImport.apply) implicit lazy val PrintStreamReader: ConfDecoder[PrintStream] = { val empty = new PrintStream(new OutputStream { diff --git a/scalafix-core/src/main/scala/scalafix/package.scala b/scalafix-core/src/main/scala/scalafix/package.scala index 6c6b4cc07..bd3dff9ea 100644 --- a/scalafix-core/src/main/scala/scalafix/package.scala +++ b/scalafix-core/src/main/scala/scalafix/package.scala @@ -26,8 +26,8 @@ package object scalafix { extends SyntacticPatchOps(ctx) { def semanticOps: SyntacticPatchOps = this } - implicit class XtensionSeqPatch(patches: Seq[Patch]) { - def asPatch: Patch = Patch.fromSeq(patches) + implicit class XtensionSeqPatch(patches: Iterable[Patch]) { + def asPatch: Patch = Patch.fromIterable(patches) } implicit class XtensionOptionPatch(patch: Option[Patch]) { def asPatch: Patch = patch.getOrElse(Patch.empty) diff --git a/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala b/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala new file mode 100644 index 000000000..9f1e8faff --- /dev/null +++ b/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala @@ -0,0 +1,89 @@ +package scalafix.patch + +import scala.collection.immutable.Seq +import scala.collection.mutable +import scalafix.syntax._ +import scala.meta._ +import scala.meta.tokens.Token.Comment +import scala.meta.tokens.Token.KwImport +import scalafix.Failure +import scalafix.config.FilterMatcher +import scalafix.patch.TreePatch.ImportPatch +import scalafix.rewrite.RewriteCtx +import scalafix.util.Whitespace +import org.scalameta.logger + +object ImportPatchOps { + + // NOTE(olafur): This method is the simplest/dummest thing I can think of + // to convert + private[scalafix] def superNaiveImportPatchToTokenPatchConverter( + ctx: RewriteCtx, + importPatches: Seq[ImportPatch])( + implicit mirror: Mirror): Iterable[Patch] = { + val allImports = getGlobalImports(ctx.tree) + val allImporters = allImports.flatMap(_.importers) + val allImportees = allImporters.flatMap(_.importees) + val allImporteeSymbols = allImportees.flatMap { importee => + importee.symbolOpt.map(_.normalized -> importee) + } + def fallbackToken(tree: Tree): Token = tree match { + case Source(stat :: _) => fallbackToken(stat) + case Pkg(_, stat :: _) => fallbackToken(stat) + case els => ctx.toks(els).head + } + val editToken = fallbackToken(ctx.tree) + val isRemovedImportee = mutable.LinkedHashSet.empty[Importee] + importPatches.foreach { + case TreePatch.RemoveGlobalImport(sym) => + allImporteeSymbols + .withFilter(_._1 == sym.normalized) + .foreach { case (_, x) => isRemovedImportee += x } + case x: TreePatch.RemoveImportee => isRemovedImportee += x.importee + case _ => + } + val extraPatches = importPatches.collect { + case TreePatch.AddGlobalImport(importer) + if !allImporters.exists(_.syntax == importer.syntax) => + ctx.addLeft(editToken, s"import $importer\n") + } + val isRemovedImporter = + allImporters.filter(_.importees.forall(isRemovedImportee)).toSet + val isRemovedImport = + allImports.filter(_.importers.forall(isRemovedImporter)) + def remove(toRemove: Tree) = { + val tokens = ctx.toks(toRemove) + def removeFirstComma(lst: Iterable[Token]) = + lst.find(!_.is[Whitespace]) match { + case Some(tok @ Token.Comma()) => TokenPatch.Remove(tok) + case _ => Patch.empty + } + val trailingComma = + removeFirstComma(ctx.tokenList.from(tokens.last)) + val leadingComma = + removeFirstComma(ctx.tokenList.to(tokens.head).reverse) + trailingComma + leadingComma + PatchOps.removeTokens(tokens) + } + + extraPatches ++ + (isRemovedImportee ++ + isRemovedImporter ++ + isRemovedImport).map(remove) + } + + private def extractImports(stats: Seq[Stat]): Seq[Import] = { + stats + .takeWhile(_.is[Import]) + .collect { case i: Import => i } + } + + def getGlobalImports(ast: Tree): Seq[Import] = + ast match { + case Pkg(_, Seq(pkg: Pkg)) => getGlobalImports(pkg) + case Source(Seq(pkg: Pkg)) => getGlobalImports(pkg) + case Pkg(_, stats) => extractImports(stats) + case Source(stats) => extractImports(stats) + case _ => Nil + } + +} diff --git a/scalafix-core/src/main/scala/scalafix/patch/OrganizeImports.scala b/scalafix-core/src/main/scala/scalafix/patch/OrganizeImports.scala deleted file mode 100644 index 80260914e..000000000 --- a/scalafix-core/src/main/scala/scalafix/patch/OrganizeImports.scala +++ /dev/null @@ -1,219 +0,0 @@ -package scalafix.patch - -import scala.collection.immutable.Seq -import scala.meta._ -import scala.meta.tokens.Token.Comment -import scala.meta.tokens.Token.KwImport -import scalafix.config.FilterMatcher -import scalafix.patch.TreePatch.AddGlobalImport -import scalafix.patch.TreePatch.RemoveGlobalImport -import scalafix.rewrite.RewriteCtx -import scalafix.syntax._ -import scalafix.syntax.XtensionRefSymbolOpt -import scalafix.util.CanonicalImport - -private[this] class OrganizeImports[T] private (implicit ctx: RewriteCtx, - mirror: Mirror) { - lazy val fallbackToken: Token = { - def loop(tree: Tree): Token = tree match { - case Source(stat :: _) => loop(stat) - case Pkg(_, stat :: _) => loop(stat) - case els => els.tokens(ctx.config.dialect).head - } - - loop(ctx.tree) - } - - def fullyQualifiedName(ref: Ref): Option[Ref] = - for { - sym <- ref.symbolOpt - name <- sym.to[Ref].toOption - strippedRoot = name.transform { - case q"_root_.$nme" => nme - } - if strippedRoot.is[Ref] - } yield strippedRoot.asInstanceOf[Ref] - - def extractImports(stats: Seq[Stat]): Seq[Import] = { - stats - .takeWhile(_.is[Import]) - .collect { case i: Import => i } - } - - def getCanonicalImports(imp: Import): Seq[CanonicalImport] = { - implicit val currentImport = imp - imp.importers.flatMap { importer => - val wildcard = importer.importees.lastOption.collectFirst { - case wildcard: Importee.Wildcard => wildcard - } - wildcard.fold( - importer.importees.map(i => - CanonicalImport.fromImportee(importer.ref, i)) - ) { wildcard => - List( - CanonicalImport.fromWildcard( - importer.ref, - wildcard, - importer.importees.init - )) - } - } - } - - def getLastTopLevelPkg(potPkg: Stat): Stat = potPkg match { - case Pkg(_, head +: Nil) => getLastTopLevelPkg(head) - case Pkg(_, head +: _) => head - case _ => potPkg - } - - def getGlobalImports(ast: Tree): Seq[Import] = - ast match { - case Pkg(_, Seq(pkg: Pkg)) => getGlobalImports(pkg) - case Source(Seq(pkg: Pkg)) => getGlobalImports(pkg) - case Pkg(_, stats) => extractImports(stats) - case Source(stats) => extractImports(stats) - case _ => Nil - } - - def removeDuplicates(imports: Seq[CanonicalImport]): Seq[CanonicalImport] = - imports.distinctBy(_.importerSyntax) - - def rootPkgName(ref: Ref): String = ref match { - case name: Term.Name => name.value - case _ => - ref.collect { - case Term.Select(name: Term.Name, _) => name.value - }.head - } - - def fullyQualify(imp: CanonicalImport): Option[Term.Ref] = - for { - fqnRef <- fullyQualifiedName(imp.ref) - // Avoid inserting unneeded `package` - if rootPkgName(fqnRef) != rootPkgName(imp.ref) - } yield fqnRef.asInstanceOf[Term.Ref] - - def groupImports(imports0: Seq[CanonicalImport]): Seq[Seq[Import]] = { - val config = ctx.config.imports - val rootImports = imports0.filter(_.isRootImport) - val imports = - imports0.map(imp => - imp.withFullyQualifiedRef(fullyQualify(imp), rootImports)) - val (fullyQualifiedImports, relativeImports) = - imports.partition { imp => - ctx.config.imports.expandRelative || - fullyQualify(imp).forall(_.syntax == imp.ref.syntax) - } - val groupById = - config.groups.zipWithIndex.toMap - .withDefaultValue(config.groups.length) - val grouped: Map[FilterMatcher, Seq[CanonicalImport]] = - fullyQualifiedImports - .groupBy { imp => - config.groups - .find(_.matches(imp.refSyntax)) - .getOrElse(FilterMatcher.matchEverything) - } + (FilterMatcher("relative") -> relativeImports) - val inOrder = - grouped - .mapValues(_.sorted) - .to[Seq] - .filter(_._2.nonEmpty) - .sortBy(x => groupById(x._1)) - .collect { case (_, s) => s } - val asImports = inOrder.map { is => - if (config.groupByPrefix) { - is.groupBy(_.ref.syntax) - .to[Seq] - .map { - case (_, importers) => - Import(Seq( - Importer(importers.head.actualRef, importers.map(_.importee)))) - - } - } else { - var usedLeadingComment = Set.empty[Comment] - is.map { i => - val result = i - .withoutLeading(usedLeadingComment) - .syntax - .parse[Stat] - .get - .asInstanceOf[Import] - usedLeadingComment = usedLeadingComment ++ i.leadingComments - result - } - } - } - asImports - } - - def prettyPrint(imports: Seq[CanonicalImport]): String = { - groupImports(imports) - .map(_.map(_.syntax).mkString("\n")) - .mkString("\n\n") - } - - def getRemovePatches(oldImports: Seq[Import]): Seq[TokenPatch.Remove] = { - val toRemove = for { - firstImport <- oldImports.headOption - first <- firstImport.tokens.headOption - lastImport <- oldImports.lastOption - last <- lastImport.tokens.lastOption - } yield { - ctx.tokens.toIterator - .dropWhile(_.start < first.start) - .takeWhile { x => - x.end <= last.end - } - .map(TokenPatch.Remove) - .toList - } - toRemove.getOrElse(Nil) - } - - def cleanUpImports(globalImports: Seq[CanonicalImport], - patches: Seq[ImportPatch]): Seq[CanonicalImport] = { - def combine(is: Seq[CanonicalImport], - patch: ImportPatch): Seq[CanonicalImport] = - patch match { - case _: AddGlobalImport => - is ++ getCanonicalImports(patch.toImport) - case remove: RemoveGlobalImport => - is.filterNot(_.structure == remove.importer.structure) - } - - patches.foldLeft(globalImports)(combine) - } - - def organizeImports(patches: Seq[ImportPatch]): Seq[TokenPatch] = { - if (!ctx.config.imports.organize && patches.isEmpty) { - Nil - } else { - val oldImports = getGlobalImports(ctx.tree) - val globalImports = oldImports.flatMap(getCanonicalImports) - val cleanedUpImports = cleanUpImports(globalImports, patches) - val tokenToEdit = - oldImports.headOption - .map(_.tokens.head) - .getOrElse(fallbackToken) - val suffix = - if (!tokenToEdit.is[KwImport] && tokenToEdit.eq(fallbackToken)) "\n" - else "" - val toInsert = prettyPrint(cleanedUpImports) ++ suffix - TokenPatch.Add(tokenToEdit, toInsert, "") +: - getRemovePatches(oldImports) - } - } -} - -object OrganizeImports { - def organizeImports(patches: Seq[ImportPatch])( - implicit ctx: RewriteCtx, - mirror: Mirror): Seq[TokenPatch] = - new OrganizeImports().organizeImports( - patches ++ ctx.config.patches.all.collect { - case i: ImportPatch => i - } - ) -} diff --git a/scalafix-core/src/main/scala/scalafix/patch/Patch.scala b/scalafix-core/src/main/scala/scalafix/patch/Patch.scala index 7b02fbf92..7b1a870de 100644 --- a/scalafix-core/src/main/scala/scalafix/patch/Patch.scala +++ b/scalafix-core/src/main/scala/scalafix/patch/Patch.scala @@ -12,10 +12,11 @@ import scalafix.config._ import scalafix.syntax._ import scalafix.patch.TokenPatch.Add import scalafix.patch.TokenPatch.Remove +import scalafix.patch.TreePatch.ImportPatch import scalafix.patch.TreePatch.RenamePatch import scalafix.patch.TreePatch.Replace - import difflib.DiffUtils +import org.scalameta.logger /** A data structure that can produce a .patch file. * @@ -46,19 +47,31 @@ sealed abstract class Patch { def nonEmpty: Boolean = !isEmpty } -private[scalafix] case class Concat(a: Patch, b: Patch) extends Patch -private[scalafix] case object EmptyPatch extends Patch -abstract class TreePatch extends Patch -abstract class TokenPatch(val tok: Token, val newTok: String) extends Patch { +////////////////////////////// +// Low-level patches +////////////////////////////// +trait LowLevelPatch +abstract class TokenPatch(val tok: Token, val newTok: String) + extends Patch + with LowLevelPatch { override def toString: String = - s"TokenPatch(${tok.syntax.revealWhiteSpace}, ${tok.structure}, $newTok)" + s"TokenPatch.${this.getClass.getSimpleName}(${tok.syntax.revealWhiteSpace}, ${tok.structure}, $newTok)" } +private[scalafix] object TokenPatch { + case class Remove(override val tok: Token) extends TokenPatch(tok, "") + case class Add(override val tok: Token, + addLeft: String, + addRight: String, + keepTok: Boolean = true) + extends TokenPatch(tok, + s"""$addLeft${if (keepTok) tok else ""}$addRight""") -abstract class ImportPatch(val importer: Importer) extends TreePatch { - def importee: Importee = importer.importees.head - def toImport: Import = Import(Seq(importer)) } +////////////////////////////// +// High-level patches +////////////////////////////// +abstract class TreePatch extends Patch private[scalafix] object TreePatch { trait RenamePatch case class Rename(from: Name, to: Name) extends TreePatch with RenamePatch @@ -79,26 +92,23 @@ private[scalafix] object TreePatch { extends TreePatch { require(to.isStableId) } - case class RemoveGlobalImport(override val importer: Importer) - extends ImportPatch(importer) - case class AddGlobalImport(override val importer: Importer) - extends ImportPatch(importer) + abstract class ImportPatch extends TreePatch + @DeriveConfDecoder + case class RemoveGlobalImport(symbol: Symbol) extends ImportPatch + @DeriveConfDecoder + case class RemoveImportee(importee: Importee) extends ImportPatch + @DeriveConfDecoder + case class AddGlobalImport(importer: Importer) extends ImportPatch } -private[scalafix] object TokenPatch { - case class Remove(override val tok: Token) extends TokenPatch(tok, "") - case class Add(override val tok: Token, - addLeft: String, - addRight: String, - keepTok: Boolean = true) - extends TokenPatch(tok, - s"""$addLeft${if (keepTok) tok else ""}$addRight""") +// implementation detail +private[scalafix] case class Concat(a: Patch, b: Patch) extends Patch +private[scalafix] case object EmptyPatch extends Patch with LowLevelPatch -} object Patch { /** Combine a sequence of patches into a single patch */ - def fromSeq(seq: scala.Seq[Patch]): Patch = + def fromIterable(seq: Iterable[Patch]): Patch = seq.foldLeft(empty)(_ + _) /** A patch that does no diff/rewrite */ @@ -112,7 +122,7 @@ object Patch { add1.keepTok && add2.keepTok) case (_: Remove, add: Add) => add.copy(keepTok = false) case (add: Add, _: Remove) => add.copy(keepTok = false) - case (rem: Remove, _: Remove) => rem + case (rem: Remove, rem2: Remove) => rem case _ => throw Failure.TokenPatchMergeError(a, b) } private[scalafix] def apply(p: Patch, @@ -133,11 +143,11 @@ object Patch { } } - private def syntaxApply(ctx: RewriteCtx, patches: Seq[TokenPatch]): String = { + private def syntaxApply(ctx: RewriteCtx, + patches: Iterable[TokenPatch]): String = { val patchMap = patches .groupBy(_.tok.hash) .mapValues(_.reduce(merge).newTok) - ctx.tokens.toIterator .map(tok => patchMap.getOrElse(tok.hash, tok.syntax)) .mkString @@ -153,16 +163,29 @@ object Patch { val replacePatches = Replacer.toTokenPatches(ast, patches.collect { case e: Replace => e }) - val importPatches = OrganizeImports.organizeImports( + val importPatches = patches.collect { case e: ImportPatch => e } ++ - replacePatches.collect { case e: ImportPatch => e } - ) + replacePatches.collect { case e: ImportPatch => e } ++ + ctx.config.patches.all.collect { case e: ImportPatch => e } + val importTokenPatches = { + val result = ImportPatchOps.superNaiveImportPatchToTokenPatchConverter( + ctx, + importPatches) + Patch + .underlying(result.asPatch) + .collect { + case x: TokenPatch => x + case els => + throw Failure.InvariantFailedException( + s"Expected TokenPatch, got $els") + } + } val replaceTokenPatches = replacePatches.collect { case t: TokenPatch => t } syntaxApply( ctx, - importPatches ++ + importTokenPatches ++ tokenPatches ++ replaceTokenPatches ++ renamePatches @@ -175,6 +198,7 @@ object Patch { case Concat(a, b) => loop(a) loop(b) + case EmptyPatch => // do nothing case els => builder += els } diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitImplicit.scala b/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala similarity index 96% rename from scalafix-core/src/main/scala/scalafix/rewrite/ExplicitImplicit.scala rename to scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala index 6acc23855..6cd95d751 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitImplicit.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala @@ -7,7 +7,7 @@ import scalafix.util.Whitespace import scala.collection.immutable.Seq import org.scalameta.logger -case class ExplicitImplicit(mirror: Mirror) extends SemanticRewrite(mirror) { +case class ExplicitReturnTypes(mirror: Mirror) extends SemanticRewrite(mirror) { // Don't explicitly annotate vals when the right-hand body is a single call // to `implicitly`. Prevents ambiguous implicit. Not annotating in such cases, // this a common trick employed implicit-heavy code to workaround SI-2712. diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala b/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala index 4768fade1..acc849ccc 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala @@ -12,6 +12,7 @@ import scalafix.util.TokenList /** Bundle of useful things when implementing [[Rewrite]]. */ case class RewriteCtx(tree: Tree, config: ScalafixConfig) { + def toks(t: Tree): Tokens = t.tokens(config.dialect) implicit lazy val tokens: Tokens = tree.tokens(config.dialect) lazy val tokenList: TokenList = new TokenList(tokens) lazy val comments: AssociatedComments = AssociatedComments(tokens) diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/ScalaJsRewrites.scala b/scalafix-core/src/main/scala/scalafix/rewrite/ScalaJsRewrites.scala deleted file mode 100644 index b27eb103c..000000000 --- a/scalafix-core/src/main/scala/scalafix/rewrite/ScalaJsRewrites.scala +++ /dev/null @@ -1,81 +0,0 @@ -package scalafix -package rewrite -import scala.collection.immutable.Seq -import scala.meta._ -import scala.meta.contrib._ - -object ScalaJsRewrites { - // Symbols copy pasted from mirror.database - val nativeSymbol = Symbol("_root_.scala.scalajs.js.package.native#") - val globalScopeSymbol = - Symbol("_root_.scala.scalajs.js.annotation.JSGlobalScope#``()V.") - val globalScopeParentSymbol = - Symbol("_root_.scala.scalajs.js.GlobalScope#") - val jsImportSymbol = Symbol( - "_root_.scala.scalajs.js.annotation.JSImport#``(Ljava/lang/String;Ljava/lang/String;)V.") - - private object ClassOrObject { - def unapply(arg: Tree): Option[(Seq[Mod], Seq[Ctor.Call])] = arg match { - case Defn.Class(mods, _, _, _, Template(_, parents, _, _)) => - Option(mods -> parents) - case Defn.Object(mods, _, Template(_, parents, _, _)) => - Option(mods -> parents) - case _ => None - } - } - - val DemandJSGlobal = Rewrite.semantic { implicit mirror => ctx => - import ctx._ - object JsNative { - def unapply(mods: Seq[Mod]): Option[(Mod, Option[Name])] = - mods.collectFirst { - case native @ Mod.Annot(ref: Ref) if ref.symbol == nativeSymbol => - native -> mods.collectFirst { - case Mod.Annot( - Term.Apply(jsName @ Ctor.Ref.Name("JSName"), _)) => - jsName - } - } - } - // https://github.com/scala-js/scala-js/pull/2794#issuecomment-284982025 - def skipRewrite(mods: Seq[Mod], parents: Seq[Ctor.Call]): Boolean = { - def hasInvalidAnnot: Boolean = - mods.exists(_.exists { - case ref: Ref => - ref.symbol == jsImportSymbol || - ref.symbol == globalScopeSymbol - case _ => false - }) - def hasGlobalScopeParent: Boolean = - parents.exists(_.exists { - case ref: Ref => ref.symbol == globalScopeParentSymbol - case _ => false - }) - hasInvalidAnnot || hasGlobalScopeParent - } - val patchB = Seq.newBuilder[Patch] - new Traverser { - override def apply(tree: Tree): Unit = tree match { - case ClassOrObject(mods, parents) => - if (skipRewrite(mods, parents)) Unit // do nothing - else { - mods match { - case JsNative(_, Some(jsName)) => - patchB += ctx.rename(jsName, q"JSGlobal") - case JsNative(native, None) => - patchB += ctx.addRight(native.tokens.last, " @JSGlobal") - case _ => - } - } - case _ => super.apply(tree) - } - }.apply(tree) - val patches = patchB.result() - - if (patches.nonEmpty && config.imports.organize) { - ctx.addGlobalImport(importer"scala.scalajs.js.annotation.JSGlobal") ++ patches - } else { - patches.asPatch - } - } -} diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala b/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala index e65a74642..3e2a88dfa 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala @@ -10,8 +10,7 @@ object ScalafixRewrites { ExplicitUnit ) def semantic(mirror: Mirror): List[Rewrite] = List( - ScalaJsRewrites.DemandJSGlobal(mirror), - ExplicitImplicit(mirror), + ExplicitReturnTypes(mirror), Xor2Either(mirror), NoAutoTupling(mirror) ) diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/SemanticPatchOps.scala b/scalafix-core/src/main/scala/scalafix/rewrite/SemanticPatchOps.scala index c248ce128..1a4b1401c 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/SemanticPatchOps.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/SemanticPatchOps.scala @@ -6,9 +6,15 @@ import scala.meta._ import scalafix.patch.TokenPatch._ import scalafix.patch.TreePatch._ +object PatchOps { + def removeTokens(tokens: Tokens): Patch = tokens.foldLeft(Patch.empty)(_ + TokenPatch.Remove(_)) +} + class SyntacticPatchOps(ctx: RewriteCtx) { + def removeImportee(importee: Importee): Patch = TreePatch.RemoveImportee(importee) def replaceToken(token: Token, toReplace: String): Patch = Add(token, "", toReplace, keepTok = false) + def removeTokens(tokens: Tokens): Patch = PatchOps.removeTokens(tokens) def removeToken(token: Token): Patch = Add(token, "", "", keepTok = false) def rename(from: Name, to: Name): Patch = Rename(from, to) def addRight(tok: Token, toAdd: String): Patch = Add(tok, "", toAdd) @@ -16,10 +22,8 @@ class SyntacticPatchOps(ctx: RewriteCtx) { } class SemanticPatchOps(ctx: RewriteCtx, mirror: Mirror) { - def removeGlobalImport(importer: Importer): Patch = - RemoveGlobalImport(importer) - def addGlobalImport(importer: Importer): Patch = - AddGlobalImport(importer) + def removeGlobalImport(symbol: Symbol): Patch = RemoveGlobalImport(symbol) + def addGlobalImport(importer: Importer): Patch = AddGlobalImport(importer) def replace(from: Symbol, to: Term.Ref, additionalImports: List[Importer] = Nil, diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/Xor2Either.scala b/scalafix-core/src/main/scala/scalafix/rewrite/Xor2Either.scala index 40a4c1801..cbaeff1aa 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/Xor2Either.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/Xor2Either.scala @@ -25,8 +25,8 @@ case class Xor2Either(mirror: Mirror) extends SemanticRewrite(mirror) { ctx.replace(Symbol("_root_.cats.data.Xor.Right."), q"Right"), ctx.replace(Symbol("_root_.cats.data.XorFunctions.left."), q"Left"), ctx.replace(Symbol("_root_.cats.data.XorFunctions.right."), q"Right"), - ctx.removeGlobalImport(importer"cats.data.Xor"), - ctx.removeGlobalImport(importer"cats.data.XorT") + ctx.removeGlobalImport(Symbol("_root_.cats.data.Xor.")), + ctx.removeGlobalImport(Symbol("_root_.cats.data.XorT.")) ) } } diff --git a/scalafix-core/src/main/scala/scalafix/syntax/package.scala b/scalafix-core/src/main/scala/scalafix/syntax/package.scala index 188f8f1c3..958a90d5e 100644 --- a/scalafix-core/src/main/scala/scalafix/syntax/package.scala +++ b/scalafix-core/src/main/scala/scalafix/syntax/package.scala @@ -3,6 +3,7 @@ package scalafix import java.nio.charset.Charset import scala.collection.IterableLike import scala.collection.generic.CanBuildFrom +import scala.collection.immutable.Seq import scala.collection.mutable import scala.meta._ import scala.meta.semantic.Signature @@ -12,10 +13,13 @@ import scala.util.Success import scala.util.Try import org.scalameta.logger import scala.compat.Platform.EOL +import scala.meta.classifiers.Classifier import scala.meta.internal.io.PathIO import scala.meta.internal.prettyprinters.TreeSyntax import scala.meta.internal.prettyprinters.TreeToString import scala.meta.internal.scalafix.ScalafixScalametaHacks +import scalafix.patch.TokenPatch +import scalafix.util.Whitespace package object syntax { @@ -95,6 +99,15 @@ package object syntax { } implicit class XtensionSymbol(symbol: Symbol) { + def underlyingSymbols: Seq[Symbol] = symbol match { + case Symbol.Multi(symbols) => symbols + case _ => List(symbol) + } + def isSameNormalized(other: Symbol): Boolean = { + val syms = symbol.underlyingSymbols.map(_.normalized) + val otherSyms = other.underlyingSymbols.map(_.normalized) + syms.exists(otherSyms.contains) + } /** Returns simplified version of this Symbol. * diff --git a/scalafix-core/src/main/scala/scalafix/util/TokenList.scala b/scalafix-core/src/main/scala/scalafix/util/TokenList.scala index 49dc603ba..cbec5dbf6 100644 --- a/scalafix-core/src/main/scala/scalafix/util/TokenList.scala +++ b/scalafix-core/src/main/scala/scalafix/util/TokenList.scala @@ -1,10 +1,16 @@ package scalafix.util +import scala.collection.SeqView +import scala.collection.immutable.IndexedSeq import scala.meta.tokens.Token import scala.meta.tokens.Tokens /** Helper to traverse tokens as a doubly linked list. */ class TokenList(tokens: Tokens) { + def from(token: Token): SeqView[Token, IndexedSeq[Token]] = + tokens.view(tok2idx(token), tokens.length) + def to(token: Token): SeqView[Token, IndexedSeq[Token]] = + tokens.view(0, tok2idx(token)) private[this] val tok2idx = { val map = Map.newBuilder[Token, Int] var i = 0 diff --git a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala index b7d75d6fc..fb0d6f3f1 100644 --- a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala +++ b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala @@ -1,252 +1,49 @@ package scalafix package testkit -import scala.collection.immutable.Seq import scala.meta._ -import scala.meta.internal.semantic.DatabaseOps -import scala.reflect.io.AbstractFile -import scala.tools.cmd.CommandLineParser -import scala.tools.nsc.CompilerCommand -import scala.tools.nsc.Global -import scala.tools.nsc.Settings -import scala.tools.nsc.reporters.StoreReporter -import scala.util.control.NonFatal -import scala.{meta => m} -import scalafix.config.ScalafixConfig -import scalafix.rewrite.RewriteCtx -import scalafix.syntax._ - -import java.io.File -import java.io.PrintWriter -import java.net.URL -import java.net.URLClassLoader - -import metaconfig.ConfError +import scala.meta.internal.io.FileIO +import scalafix.reflect.ScalafixCompilerDecoder +import metaconfig.Configured import org.scalatest.FunSuite +import org.scalatest.exceptions.TestFailedException -/** - * - * @param classpath the classpath to use to compile rewrite unit tests. - * Defaults to the classpath of the current classloader. - * @param scalahostPluginPath the file path to the scalahost compiler plugin, - * which is passed as `-Xplugin:/path/scalahost.jar` - * to scalac in order to build a semantic DB - * when compiling .source unit test files. - */ abstract class SemanticRewriteSuite( - classpath: String = SemanticRewriteSuite.thisClasspath, - scalahostPluginPath: File = SemanticRewriteSuite.scalahostJarPath + val mirror: Database, + val inputSourceroot: AbsolutePath, + val expectedOutputSourceroot: AbsolutePath ) extends FunSuite with DiffAssertions { self => - val g: Global = { - def fail(msg: String) = - sys.error(s"ReflectToMeta initialization failed: $msg") - // TODO(olafur) hack, find a way to pass this path via buildinfo - val scalacOptions = Seq( - "-Yrangepos", - "-cp", - classpath, - "-Xplugin:" + scalahostPluginPath, - "-Xplugin-require:scalahost", - "-Ywarn-unused-import" - ).mkString(" ", " ", " ") - val args = CommandLineParser.tokenize(scalacOptions) - val emptySettings = new Settings( - error => fail(s"couldn't apply settings because $error")) - val reporter = new StoreReporter() - val command = new CompilerCommand(args, emptySettings) - val settings = command.settings - val g = new Global(settings, reporter) - val run = new g.Run - g.phase = run.parserPhase - g.globalPhase = run.parserPhase - g - } - - lazy val databaseOps: DatabaseOps { val global: self.g.type } = - new DatabaseOps { override val global: self.g.type = self.g } - import databaseOps._ - - def runDiffTest(dt: DiffTest): Unit = { - if (dt.skip) { - ignore(dt.fullName) {} - } else { - test(dt.fullName) { - check(dt.original, dt.expected, dt) - } - } - } - - def check(original: String, expectedStr: String, diffTest: DiffTest): Unit = { - def formatHeader(header: String): String = { - val line = s"=" * (header.length + 3) - s"$line\n=> $header\n$line" - } - - val fixed = fix(diffTest.wrapped(), diffTest.config) - val obtained = parse(diffTest.unwrap(fixed)) - val expected = parse(expectedStr) - try { - assertNoDiff(obtained, expected) - typeChecks(diffTest.wrapped(fixed)) - checkMismatchesModuloDesugarings(obtained, expected) - } catch { - case MismatchException(details) => - val header = s"scala -> meta converter error\n$details" - val fullDetails = - s"""${formatHeader("Expected")} - |${expected.syntax} - |${formatHeader("Obtained")} - |${obtained.syntax}""".stripMargin - fail(s"$header\n$fullDetails") - } - } - - def fix(code: String, - getConfig: Option[Mirror] => (Rewrite, ScalafixConfig)): String = { - val mirror = computeMirror(code) - val (rewrite, config) = getConfig(Some(mirror)) - val tree = mirror.sources.head - val ctx = RewriteCtx(tree, config) - rewrite.apply(ctx) - } - - def withCwd[T](f: File => T): T = { - val javaFile = File.createTempFile("paradise", ".scala") - databaseOps.config.setSourceroot(AbsolutePath(javaFile.getParentFile)) - f(javaFile) - } - - private def computeMirror(code: String): Mirror = withCwd { javaFile => - val writer = new PrintWriter(javaFile) - try writer.write(code) - finally writer.close() - val run = new g.Run - val abstractFile = AbstractFile.getFile(javaFile) - val sourceFile = g.getSourceFile(abstractFile) - val unit = new g.CompilationUnit(sourceFile) - run.compileUnits(List(unit), run.phaseNamed("terminal")) - - g.phase = run.parserPhase - g.globalPhase = run.parserPhase - val reporter = new StoreReporter() - g.reporter = reporter - unit.body = g.newUnitParser(unit).parse() - val packageobjectsPhase = run.phaseNamed("packageobjects") - val phases = List(run.parserPhase, - run.namerPhase, - packageobjectsPhase, - run.typerPhase) - reporter.reset() - - phases.foreach(phase => { - g.phase = phase - g.globalPhase = phase - phase.asInstanceOf[g.GlobalPhase].apply(unit) - val errors = reporter.infos.filter(_.severity == reporter.ERROR) - errors.foreach { - case reporter.Info(pos, msg, reporter.ERROR) => - val formattedMessage = - ConfError - .msg(msg) - .atPos( - m.Position.Range(Input.File(javaFile), pos.start, pos.end)) - .notOk - .toString - fail(formattedMessage) - case _ => // nothing - } - }) - g.phase = run.phaseNamed("patmat") - g.globalPhase = run.phaseNamed("patmat") - new Mirror { - override def database = - Database( - List( - unit.source.toInput -> unit.toAttributes - )) - } - } - - private def checkMismatchesModuloDesugarings(obtained: m.Tree, - expected: m.Tree): Unit = { - import scala.meta._ - def loop(x: Any, y: Any): Boolean = { - val ok = (x, y) match { - case (x, y) if x == null || y == null => - x == null && y == null - case (x: Some[_], y: Some[_]) => - loop(x.get, y.get) - case (x: None.type, y: None.type) => - true - case (xs: Seq[_], ys: Seq[_]) => - xs.length == ys.length && xs.zip(ys).forall { - case (x, y) => loop(x, y) + mirror.entries.foreach { + case (input @ Input.LabeledString(relpath, code), attributes) + if relpath.contains("test") => + test(relpath) { + val (rewrite, config) = input.tokenize.get + .collectFirst { + case Token.Comment(comment) => + val decoder = + ScalafixCompilerDecoder.fromMirrorOption(Some(mirror)) + ScalafixConfig + .fromInput(Input.LabeledString(relpath, comment), + Some(mirror))(decoder) + .get } - case (x: Tree, y: Tree) => - def sameStructure = - x.productPrefix == y.productPrefix && - loop(x.productIterator.toList, y.productIterator.toList) - - sameStructure - case _ => - x == y - } - if (!ok) { - val structure = (x, y) match { - case (t1: Tree, t2: Tree) => - s""" - |Diff: - |${t1.structure} - |${t2.structure} - |""".stripMargin - case _ => "" + .getOrElse(throw new TestFailedException( + s"Missing scalafix configuration inside comment at top of file $relpath", + 0)) + val obtainedWithComment = + rewrite.apply(input, config.copy(dialect = attributes.dialect)) + val obtained = { + val tokens = obtainedWithComment.tokenize.get + val comment = tokens + .find(x => x.is[Token.Comment] && x.syntax.startsWith("/*")) + .get + tokens.filterNot(_ eq comment).mkString } - throw MismatchException(s"$x != $y$structure") - } else true - } - - loop(obtained, expected) - } - - private def typeChecks(code: String): Unit = { - try { - computeMirror(code) - } catch { - case NonFatal(e) => - e.printStackTrace() - fail( - s"""Fixed source code does not typecheck! - |Message: ${e.getMessage} - |Reveal: ${code.revealWhiteSpace} - |Code: $code""".stripMargin, - e - ) - } - } - - private def parse(code: String): m.Tree = { - import scala.meta._ - code.parse[Source].get - } - - def assertNoDiff(obtained: Tree, expected: Tree): Boolean = { - assertNoDiff(obtained.tokens.mkString, - expected.tokens.mkString, - "Tree syntax mismatch") - } - - case class MismatchException(details: String) extends Exception -} - -object SemanticRewriteSuite { - def thisClasspathLst: List[URL] = this.getClass.getClassLoader match { - case u: URLClassLoader => u.getURLs.toList - case _ => Nil + val expected = + new String(expectedOutputSourceroot.resolve(relpath).readAllBytes) + assertNoDiff(obtained, expected) + } + case els => // do nothing } - def thisClasspath: String = - thisClasspathLst.mkString(java.io.File.pathSeparator) - - def scalahostJarPath: File = - new File(thisClasspathLst.find(_.toString.contains("scalahost")).get.toURI) } diff --git a/scalafix-tests/src/test/resources/rewrites/MyRewrite.scala b/scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala similarity index 100% rename from scalafix-tests/src/test/resources/rewrites/MyRewrite.scala rename to scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala diff --git a/scalafix-tests/src/test/resources/rewrites/MyRewrite2.scala b/scalafix-tests/input/src/main/resources/rewrites/MyRewrite2.scala similarity index 100% rename from scalafix-tests/src/test/resources/rewrites/MyRewrite2.scala rename to scalafix-tests/input/src/main/resources/rewrites/MyRewrite2.scala diff --git a/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala b/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala new file mode 100644 index 000000000..e522df4c6 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala @@ -0,0 +1,69 @@ +/* +rewrites = ExplicitReturnTypes + */ +package test + +object ExplicitReturnTypesInput { + implicit val L = List(1) + implicit val M = Map(1 -> "STRING") + implicit def D = 2 + implicit def tparam[T](e: T) = e + implicit def tparam2[T](e: T) = List(e) + implicit def tparam3[T](e: T) = Map(e -> e) + class Path { + class B { class C } + implicit val x = new B + implicit val y = new x.C + } + class TwoClasses[T](e: T) + class TwoClasses2 { + implicit val x = new TwoClasses(10) + } + class implicitlytrick { + implicit val s = "string" + implicit val x = implicitly[String] + } + object InnerInnerObject { + object B { + class C + object C { + implicit val x = List(new C) + } + } + } + object SiblingObject { + class B + } + object A { + class C { + implicit val x = List(new SiblingObject.B) + } + } + object slick { + case class Supplier(id: Int, name: String) + implicit val supplierGetter = (arg: (Int, String)) => + Supplier(arg._1, arg._2) + } +} + +class DeeperPackage[T](e: T) +package foo { + class B { + implicit val x = new DeeperPackage(10) + } +} + +package shallwpackage { + class A[T](e: T) +} +class shallobpackage { + implicit val x = new shallwpackage.A(10) +} + +package enclosingPackageStripIsLast { class B } +package a { + import enclosingPackageStripIsLast.B + class A { + implicit val x = new B + } +} diff --git a/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala b/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala new file mode 100644 index 000000000..99fcfeeaa --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala @@ -0,0 +1,25 @@ +/* +rewrites = ExplicitUnit +*/ +package test + +object ExplicitUnit { + trait A { + def x + } + abstract class B { + def x + } + trait C { + def x /* comment */ + } + trait D { + def x() + } + trait E { + def x(a: String, b: Boolean) + } + trait F { + def x: String // don't touch this + } +} diff --git a/scalafix-tests/input/src/main/scala/test/FileRewrite.scala b/scalafix-tests/input/src/main/scala/test/FileRewrite.scala new file mode 100644 index 000000000..8822468cc --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/FileRewrite.scala @@ -0,0 +1,8 @@ +/* +rewrites = [ + "file:scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala" +] +*/ +package test + +object FileRewrite diff --git a/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala b/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala new file mode 100644 index 000000000..fa96e79bb --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala @@ -0,0 +1,8 @@ +/* +rewrites = [ + "file:scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala" +] +*/ +package test + +object FileRewrite2 diff --git a/scalafix-tests/src/test/resources/checkSyntax/FlipEither.source b/scalafix-tests/input/src/main/scala/test/FlipEither.scala similarity index 74% rename from scalafix-tests/src/test/resources/checkSyntax/FlipEither.source rename to scalafix-tests/input/src/main/scala/test/FlipEither.scala index b6b800508..372e5c4b4 100644 --- a/scalafix-tests/src/test/resources/checkSyntax/FlipEither.source +++ b/scalafix-tests/input/src/main/scala/test/FlipEither.scala @@ -1,3 +1,4 @@ +/* patches.replacements = [ { from = _root_.scala.util.Right. @@ -28,14 +29,9 @@ patches.addGlobalImports = [ "scala.collection.immutable.Seq" ] rewrites = [] -<<< NOWRAP flip either -import scala._ +*/ +package test + object FlipEither { val x: Either[Int, String] = if (true) Left(1) else Right("msg") } ->>> -import scala._ -import scala.collection.immutable.Seq -object FlipEither { - val x: Either[String, Int] = if (true) Right(1) else Left("msg") -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/FqnRewrite.source b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala similarity index 66% rename from scalafix-tests/src/test/resources/checkSyntax/FqnRewrite.source rename to scalafix-tests/input/src/main/scala/test/FqnRewrite.scala index 6010f1214..c30930abe 100644 --- a/scalafix-tests/src/test/resources/checkSyntax/FqnRewrite.source +++ b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala @@ -1,3 +1,4 @@ +/* rewrites = [ "scala:banana.rewrite.FqnRewrite" "scala:banana.rewrite.FqnRewrite2" @@ -5,11 +6,7 @@ rewrites = [ "scala:banana.rewrite.LambdaRewrites.semantic" ] imports.removeUnused = true -<<< NOWRAP add import -object FqnMe ->>> -// comment -import scala.meta._ +*/ +package test -import hello.semantic -object FqnMe2 +object FqnRewrite diff --git a/scalafix-tests/input/src/main/scala/test/NoAutoTupling.scala b/scalafix-tests/input/src/main/scala/test/NoAutoTupling.scala new file mode 100644 index 000000000..35ae76513 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/NoAutoTupling.scala @@ -0,0 +1,62 @@ +/* +rewrites = NoAutoTupling + */ +package test + +class NoAutoTupling { +// <<< add explicit tuple + object tup { + def fooo(t: (Int, Int)): Int = ??? + fooo(1 + 1, 2) + } +// <<< multiple parameter lists, all auto-tupled + object tup1 { + def fooo(t: (Int, Int))(s: (String, String)): Int = ??? + fooo(1, 2)("a", "b") + + def baar(t: (Boolean, Int, String))(s: (Boolean, String))( + k: (Int, String)): String = ??? + baar(true, 1, "foo")(false, "42")(42, "foo") + } +// <<< multiple parameter lists, some auto-tupled + object tup2 { + def fooo(t: (Int, Int))(s: (String, String)): Int = ??? + fooo((1, 2))("a", "b") + + def baar(t: (Boolean, Int, String))(s: (Boolean, String))( + k: (Int, String)): String = ??? + baar(true, 1, "foo")((false, "42"))(42, "foo") + } +// <<< already tupled calls stay the same + object tup3 { + def fooo(t: (Int, Int)): Int = ??? + fooo((1, 2)) + } +// <<< methods not involving tuples stay the same + object tup4 { + def sum(a: Int, b: Int): Int = ??? + sum(1, 2) + } +// <<< methods with tuples, but not single parameter + object tup5 { + def sum(a: Int, b: (Int, String)): Int = ??? + sum(1, (2, "foo")) + } +// <<< SKIP auto-tupling with lambdas +// object tup6 { +// val foo = (a: (Int, Boolean)) => a +// foo(2, true) +// } +// <<< SKIP auto-tupling with curried methods +// object tup7 { +// def foo: (((Int, String)) => ((String, List[Int])) => Int) = a => b => a._1 +// foo(1 + 2, "foo")("bar", 1 :: 2 :: Nil) +// } +// <<< auto-tupling with class constructors + object tup8 { + case class Foo(t: (Int, String))(s: (Boolean, List[Int])) + new Foo(1, "foo")(true, Nil) +// Foo(1, "foo")(true, Nil) // blocked by https://github.com/scalameta/scalameta/issues/846 + Foo.apply(1, "foo")(true, Nil) + } +} diff --git a/scalafix-tests/src/test/resources/checkSyntax/PatchTokenWithEmptyRange.source b/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala similarity index 51% rename from scalafix-tests/src/test/resources/checkSyntax/PatchTokenWithEmptyRange.source rename to scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala index 7a8f031be..860df5d2e 100644 --- a/scalafix-tests/src/test/resources/checkSyntax/PatchTokenWithEmptyRange.source +++ b/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala @@ -1,12 +1,9 @@ +/* rewrites = "scala:banana.rewrite.PatchTokenWithEmptyRange" +*/ +package test -<<< patch empty tokens -object A { +class PatchWithEmptyRange { s"${1}${2}" {1}{2} } ->>> -object A { - s"${1}a${2}a" - {1}a{2}a -} diff --git a/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala b/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala new file mode 100644 index 000000000..8c21c1514 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala @@ -0,0 +1,21 @@ +/* +rewrites = ProcedureSyntax +*/ +package test + +object ProcedureSyntax { + // This is a comment + def main(args: Seq[String]) { + var number = 2 + def increment(n: Int) { + number += n + } + increment(3) + args.foreach(println) + } + def foo { + println(1) + } + def main() /* unit */ { + } +} diff --git a/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala b/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala new file mode 100644 index 000000000..30cf093c9 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala @@ -0,0 +1,59 @@ +/* +rewrites = RemoveXmlLiterals +*/ +package test + +class RemoveXmlLiterals { + object A { +
+ } + + object B { + val a =
+ val b = \ + } + + object C { + val bar = "bar" +
{bar}
+ } + + object D { + val foo = +
+ Hello +
+ } + + object E { + val foo = +
+ {"Hello"} +
+ } + + object F { + + } + + object G { + {{"Hello"}} + } + + object H { +
$
+ } + + object I { +
{{
+ } + + object J { +
+ } + + object K { + {1}{2} + } + +} diff --git a/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala b/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala new file mode 100644 index 000000000..d1978cfdb --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala @@ -0,0 +1,17 @@ +/* +rewrites = VolatileLazyVal +*/ +package test + +class VolatileLazyVal { + lazy val x = 2 + @volatile lazy val dontChangeMe = 2 + private lazy val y = 2 + + class foo { + lazy val z = { + println() + } + } + +} diff --git a/scalafix-tests/input/src/main/scala/test/Xor2Either.scala b/scalafix-tests/input/src/main/scala/test/Xor2Either.scala new file mode 100644 index 000000000..27462f28d --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/Xor2Either.scala @@ -0,0 +1,15 @@ +/* +rewrites = Xor2Either +*/ +package test + +import scala.concurrent.Future +import cats.data.{ Xor, XorT } +trait Xor2Either { + type MyDisjunction = Xor[Int, String] + val r: MyDisjunction = Xor.Right.apply("") + val s: Xor[Int, String] = cats.data.Xor.Left(1 /* comment */) + val t: Xor[Int, String] = r.map(_ + "!") + val nest: Seq[Xor[Int, cats.data.Xor[String, Int]]] + val u: XorT[Future, Int, String] = ??? +} diff --git a/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala b/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala new file mode 100644 index 000000000..d3281783e --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala @@ -0,0 +1,66 @@ +package test + +object ExplicitReturnTypesInput { + implicit val L: List[Int] = List(1) + implicit val M: scala.collection.immutable.Map[Int, String] = Map(1 -> "STRING") + implicit def D: Int = 2 + implicit def tparam[T](e: T): T = e + implicit def tparam2[T](e: T): List[T] = List(e) + implicit def tparam3[T](e: T): scala.collection.immutable.Map[T, T] = Map(e -> e) + class Path { + class B { class C } + implicit val x: Path.this.B = new B + implicit val y: Path.this.x.C = new x.C + } + class TwoClasses[T](e: T) + class TwoClasses2 { + implicit val x: test.ExplicitReturnTypesInput.TwoClasses[Int] = new TwoClasses(10) + } + class implicitlytrick { + implicit val s: String = "string" + implicit val x = implicitly[String] + } + object InnerInnerObject { + object B { + class C + object C { + implicit val x: List[test.ExplicitReturnTypesInput.InnerInnerObject.B.C] = List(new C) + } + } + } + object SiblingObject { + class B + } + object A { + class C { + implicit val x: List[test.ExplicitReturnTypesInput.SiblingObject.B] = List(new SiblingObject.B) + } + } + object slick { + case class Supplier(id: Int, name: String) + implicit val supplierGetter: ((Int, String)) => test.ExplicitReturnTypesInput.slick.Supplier = (arg: (Int, String)) => + Supplier(arg._1, arg._2) + } +} + +class DeeperPackage[T](e: T) +package foo { + class B { + implicit val x: test.DeeperPackage[Int] = new DeeperPackage(10) + } +} + +package shallwpackage { + class A[T](e: T) +} +class shallobpackage { + implicit val x: test.shallwpackage.A[Int] = new shallwpackage.A(10) +} + +package enclosingPackageStripIsLast { class B } +package a { + import enclosingPackageStripIsLast.B + class A { + implicit val x: test.enclosingPackageStripIsLast.B = new B + } +} diff --git a/scalafix-tests/output/src/main/scala/test/ExplicitUnit.scala b/scalafix-tests/output/src/main/scala/test/ExplicitUnit.scala new file mode 100644 index 000000000..67ba42524 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/ExplicitUnit.scala @@ -0,0 +1,22 @@ +package test + +object ExplicitUnit { + trait A { + def x: Unit + } + abstract class B { + def x: Unit + } + trait C { + def x: Unit /* comment */ + } + trait D { + def x(): Unit + } + trait E { + def x(a: String, b: Boolean): Unit + } + trait F { + def x: String // don't touch this + } +} diff --git a/scalafix-tests/output/src/main/scala/test/FileRewrite.scala b/scalafix-tests/output/src/main/scala/test/FileRewrite.scala new file mode 100644 index 000000000..58042fc3f --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/FileRewrite.scala @@ -0,0 +1,4 @@ +package test1 + +import scala.collection.immutable.Seq +object FileRewrite1 diff --git a/scalafix-tests/output/src/main/scala/test/FileRewrite2.scala b/scalafix-tests/output/src/main/scala/test/FileRewrite2.scala new file mode 100644 index 000000000..8c1c74d27 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/FileRewrite2.scala @@ -0,0 +1,4 @@ +package test1 + +import scala.collection.immutable.Seq +object FileRewrite21 diff --git a/scalafix-tests/output/src/main/scala/test/FlipEither.scala b/scalafix-tests/output/src/main/scala/test/FlipEither.scala new file mode 100644 index 000000000..84697b80c --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/FlipEither.scala @@ -0,0 +1,6 @@ +package test + +import scala.collection.immutable.Seq +object FlipEither { + val x: Either[String, Int] = if (true) Right(1) else Left("msg") +} diff --git a/scalafix-tests/output/src/main/scala/test/FqnRewrite.scala b/scalafix-tests/output/src/main/scala/test/FqnRewrite.scala new file mode 100644 index 000000000..3fc70d208 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/FqnRewrite.scala @@ -0,0 +1,7 @@ +// comment + +package test2 + +import scala.collection.mutable +import scala.collection.immutable +object FqnRewrite diff --git a/scalafix-tests/output/src/main/scala/test/NoAutoTupling.scala b/scalafix-tests/output/src/main/scala/test/NoAutoTupling.scala new file mode 100644 index 000000000..bb7c30b31 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/NoAutoTupling.scala @@ -0,0 +1,60 @@ +package test + +class NoAutoTupling { +// <<< add explicit tuple + object tup { + def fooo(t: (Int, Int)): Int = ??? + fooo((1 + 1, 2)) + } +// <<< multiple parameter lists, all auto-tupled + object tup1 { + def fooo(t: (Int, Int))(s: (String, String)): Int = ??? + fooo((1, 2))(("a", "b")) + + def baar(t: (Boolean, Int, String))(s: (Boolean, String))( + k: (Int, String)): String = ??? + baar((true, 1, "foo"))((false, "42"))((42, "foo")) + } +// <<< multiple parameter lists, some auto-tupled + object tup2 { + def fooo(t: (Int, Int))(s: (String, String)): Int = ??? + fooo((1, 2))(("a", "b")) + + def baar(t: (Boolean, Int, String))(s: (Boolean, String))( + k: (Int, String)): String = ??? + baar((true, 1, "foo"))((false, "42"))((42, "foo")) + } +// <<< already tupled calls stay the same + object tup3 { + def fooo(t: (Int, Int)): Int = ??? + fooo((1, 2)) + } +// <<< methods not involving tuples stay the same + object tup4 { + def sum(a: Int, b: Int): Int = ??? + sum(1, 2) + } +// <<< methods with tuples, but not single parameter + object tup5 { + def sum(a: Int, b: (Int, String)): Int = ??? + sum(1, (2, "foo")) + } +// <<< SKIP auto-tupling with lambdas +// object tup6 { +// val foo = (a: (Int, Boolean)) => a +// foo(2, true) +// } +// <<< SKIP auto-tupling with curried methods +// object tup7 { +// def foo: (((Int, String)) => ((String, List[Int])) => Int) = a => b => a._1 +// foo(1 + 2, "foo")("bar", 1 :: 2 :: Nil) +// } +// <<< auto-tupling with class constructors + object tup8 { + case class Foo(t: (Int, String))(s: (Boolean, List[Int])) + new Foo((1, "foo"))((true, Nil)) +// Foo(1, "foo")(true, Nil) // blocked by https://github.com/scalameta/scalameta/issues/846 + Foo.apply((1, "foo"))((true, Nil)) + } +} + diff --git a/scalafix-tests/output/src/main/scala/test/PatchWithEmptyRange.scala b/scalafix-tests/output/src/main/scala/test/PatchWithEmptyRange.scala new file mode 100644 index 000000000..831add1aa --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/PatchWithEmptyRange.scala @@ -0,0 +1,6 @@ +package test + +class PatchWithEmptyRange { + s"${1}a${2}a" + {1}a{2}a +} diff --git a/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala b/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala new file mode 100644 index 000000000..e3c348a56 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala @@ -0,0 +1,18 @@ +package test + +object ProcedureSyntax { + // This is a comment + def main(args: Seq[String]): Unit = { + var number = 2 + def increment(n: Int): Unit = { + number += n + } + increment(3) + args.foreach(println) + } + def foo: Unit = { + println(1) + } + def main(): Unit = /* unit */ { + } +} diff --git a/scalafix-tests/output/src/main/scala/test/RemoveXmlLiterals.scala b/scalafix-tests/output/src/main/scala/test/RemoveXmlLiterals.scala new file mode 100644 index 000000000..5dc0a559b --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/RemoveXmlLiterals.scala @@ -0,0 +1,58 @@ +package test + +import scala.xml.quote._ +class RemoveXmlLiterals { + object A { + xml"
" + } + + object B { + val a = xml"""
""" + val b = xml"""\""" + } + + object C { + val bar = "bar" + xml"
${bar}
" + } + + object D { + val foo = + xml"""
+ Hello +
""" + } + + object E { + val foo = + xml"""
+ ${"Hello"} +
""" + } + + object F { + xml"" + } + + object G { + xml"${xml"${"Hello"}"}" + } + + object H { + xml"
$$
" + } + + object I { + xml"
{
" + } + + object J { + xml"""
""" + } + + object K { + xml"${1}${2}" + } + +} + diff --git a/scalafix-tests/output/src/main/scala/test/VolatileLazyVal.scala b/scalafix-tests/output/src/main/scala/test/VolatileLazyVal.scala new file mode 100644 index 000000000..f0cd237db --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/VolatileLazyVal.scala @@ -0,0 +1,14 @@ +package test + +class VolatileLazyVal { + @volatile lazy val x = 2 + @volatile lazy val dontChangeMe = 2 + @volatile private lazy val y = 2 + + class foo { + @volatile lazy val z = { + println() + } + } + +} diff --git a/scalafix-tests/output/src/main/scala/test/Xor2Either.scala b/scalafix-tests/output/src/main/scala/test/Xor2Either.scala new file mode 100644 index 000000000..03a8fdc15 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/Xor2Either.scala @@ -0,0 +1,14 @@ +package test + +import cats.implicits._ +import cats.data.EitherT +import scala.concurrent.Future + +trait Xor2Either { + type MyDisjunction = Either[Int, String] + val r: MyDisjunction = Right("") + val s: Either[Int, String] = Left(1 /* comment */) + val t: Either[Int, String] = r.map(_ + "!") + val nest: Seq[Either[Int, Either[String, Int]]] + val u: EitherT[Future, Int, String] = ??? +} diff --git a/scalafix-tests/src/main/scala/cats/data/Xor.scala b/scalafix-tests/shared/src/main/scala/cats/data/Xor.scala similarity index 100% rename from scalafix-tests/src/main/scala/cats/data/Xor.scala rename to scalafix-tests/shared/src/main/scala/cats/data/Xor.scala diff --git a/scalafix-tests/src/main/scala/cats/implicits.scala b/scalafix-tests/shared/src/main/scala/cats/implicits.scala similarity index 100% rename from scalafix-tests/src/main/scala/cats/implicits.scala rename to scalafix-tests/shared/src/main/scala/cats/implicits.scala diff --git a/scalafix-tests/src/test/resources/ExplicitImplicit/ExplicitImplicit.source b/scalafix-tests/src/test/resources/ExplicitImplicit/ExplicitImplicit.source deleted file mode 100644 index 74d239651..000000000 --- a/scalafix-tests/src/test/resources/ExplicitImplicit/ExplicitImplicit.source +++ /dev/null @@ -1,215 +0,0 @@ -rewrites = ExplicitImplicit -<<< list -class A { - implicit val x = List(1) -} ->>> -class A { - implicit val x: List[Int] = List(1) -} -<<< map -class A { - implicit val x = Map(1 -> "STRING") -} ->>> -class A { - implicit val x: scala.collection.immutable.Map[Int, String] = Map(1 -> "STRING") -} -<<< def works -class A { - implicit def x = 2 -} ->>> -class A { - implicit def x: Int = 2 -} -<<< def param works -class A { - implicit def x[T](e: T) = e -} ->>> -class A { - implicit def x[T](e: T): T = e -} -<<< def param works 2 -class A { - implicit def x[T](e: T) = List(e) -} ->>> -class A { - implicit def x[T](e: T): List[T] = List(e) -} -<<< def param works 3 -class A { - implicit def x[T](e: T) = Map(e -> e) -} ->>> -class A { - implicit def x[T](e: T): scala.collection.immutable.Map[T, T] = Map(e -> e) -} -<<< type param -class A { - implicit def x = new Array[String](10) -} ->>> -class A { - implicit def x: Array[String] = new Array[String](10) -} -<<< T.this -class A { - class B { class C } - implicit val x = new B - implicit val y = new x.C -} ->>> -class A { - class B { class C } - implicit val x: A.this.B = new B - implicit val y: A.this.x.C = new x.C -} -<<< two classes -class A[T](e: T) -class B { - implicit val x = new A(10) -} ->>> -class A[T](e: T) -class B { - implicit val x: twoclasses.A[Int] = new A(10) -} -<<< deeper package -class A[T](e: T) -package foo { - class B { - implicit val x = new A(10) - } -} ->>> -class A[T](e: T) -package foo { - class B { - implicit val x: deeperpackage.A[Int] = new A(10) - } -} -<<< shallow package -package foo { - class A[T](e: T) -} -class B { - implicit val x = new foo.A(10) -} ->>> -package foo { - class A[T](e: T) -} -class B { - implicit val x: shallowpackage.foo.A[Int] = new foo.A(10) -} -<<< implicitly 2712 trick -class A { - implicit val s = "string" - implicit val x = implicitly[String] -} ->>> -class A { - implicit val s: String = "string" - implicit val x = implicitly[String] -} -<<< shorten imported name -import scala.collection.immutable.Map -class A { - implicit val x = Map(1 -> "") -} ->>> -import scala.collection.immutable.Map -class A { - implicit val x: scala.collection.immutable.Map[Int, String] = Map(1 -> "") -} -<<< shorten imported name 2 -import scala.collection.immutable._ -class A { - implicit val x = Map(1 -> "") -} ->>> -import scala.collection.immutable._ -class A { - implicit val x: scala.collection.immutable.Map[Int, String] = Map(1 -> "") -} -<<< enclosing package strip is last -package b { class B } -package a { - import b.B - class A { - implicit val x = new B - } -} ->>> -package b { class B } -package a { - import b.B - class A { - implicit val x: enclosingpackagestripislast.b.B = new B - } -} -<<< inner inner object -object A { - object B { - class C - object C { - implicit val x = List(new C) - } - } -} ->>> -object A { - object B { - class C - object C { - implicit val x: List[innerinnerobject.A.B.C] = List(new C) - } - } -} -<<< sibling objects -object D { - class B -} -object A { - class C { - implicit val x = List(new D.B) - } -} ->>> -object D { - class B -} -object A { - class C { - implicit val x: List[siblingobjects.D.B] = List(new D.B) - } -} -<<< slick tuple -object slick { - case class Supplier(id: Int, name: String) - implicit val supplierGetter = (arg: (Int, String)) => Supplier(arg._1, arg._2) -} ->>> -object slick { - case class Supplier(id: Int, name: String) - implicit val supplierGetter: ((Int, String)) => slicktuple.slick.Supplier = (arg: (Int, String)) => Supplier(arg._1, arg._2) -} -<<< NOWRAP package import -package scala.concurrent { - package banana { - object x { - implicit val f = Future.successful(1) - } - } -} ->>> -package scala.concurrent { - package banana { - object x { - implicit val f: scala.concurrent.Future[Int] = Future.successful(1) - } - } -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/DemandJsGlobal.source b/scalafix-tests/src/test/resources/checkSyntax/DemandJsGlobal.source deleted file mode 100644 index 71a94ce87..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/DemandJsGlobal.source +++ /dev/null @@ -1,115 +0,0 @@ -rewrites = [DemandJSGlobal] -imports.organize=true -<<< pull request example -import scala.scalajs.js -import scala.scalajs.js.annotation.JSName - -@js.native class Foo extends js.Object -@js.native @JSName("Foobaz") object Bar extends js.Object -@js.native trait Baz extends js.Object ->>> -import scala.scalajs.js -import scala.scalajs.js.annotation.JSGlobal -import scala.scalajs.js.annotation.JSName - -@js.native @JSGlobal class Foo extends js.Object -@js.native @JSGlobal("Foobaz") object Bar extends js.Object -@js.native trait Baz extends js.Object -<<< fully qualified annotation -@scala.scalajs.js.native -class Foo extends scala.scalajs.js.Object ->>> -import scala.scalajs.js.annotation.JSGlobal -@scala.scalajs.js.native @JSGlobal -class Foo extends scala.scalajs.js.Object -<<< false alarm -import scala.scalajs.annotation.falsealarm.js -@js.native -class Foo ->>> -import scala.scalajs.annotation.falsealarm.js -@js.native -class Foo -<<< nested classes -import scala.scalajs.js -import scala.scalajs.js.annotation.JSName -@js.native -object Foo extends js.Object { - @js.native - class Bar extends js.Object - - @js.native - @JSName("Foobaz") - object Baz extends js.Object -} ->>> -import scala.scalajs.js -import scala.scalajs.js.annotation.JSGlobal -import scala.scalajs.js.annotation.JSName -@js.native @JSGlobal -object Foo extends js.Object { - @js.native - class Bar extends js.Object - - @js.native - @JSName("Foobaz") - object Baz extends js.Object -} -<<< untouched -import scala.scalajs.js -import scala.scalajs.js.annotation._ -@js.native -@JSImport("foo.js", "Foo") -class Foo1 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -@JSImport("foo.js", "Foo") -object Foo1 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -@JSGlobalScope -object Foo2 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -object Foo3 extends js.GlobalScope { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} ->>> -import scala.scalajs.js -import scala.scalajs.js.annotation._ -@js.native -@JSImport("foo.js", "Foo") -class Foo1 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -@JSImport("foo.js", "Foo") -object Foo1 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -@JSGlobalScope -object Foo2 extends js.Object { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} - -@js.native -object Foo3 extends js.GlobalScope { - @js.native class Inner1 extends js.Object - @js.native @JSName("Baz") object Inner2 extends js.Object -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/ExplicitUnit.source b/scalafix-tests/src/test/resources/checkSyntax/ExplicitUnit.source deleted file mode 100644 index 4230ab1db..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/ExplicitUnit.source +++ /dev/null @@ -1,49 +0,0 @@ -rewrites = [ExplicitUnit] -<<< def inside a trait -trait A { - def x -} ->>> -trait A { - def x: Unit -} -<<< def inside an abstract class -abstract class A { - def x -} ->>> -abstract class A { - def x: Unit -} -<<< def with comment -trait B { - def x /* comment */ -} ->>> -trait B { - def x: Unit /* comment */ -} -<<< def with empty params -trait C { - def x() -} ->>> -trait C { - def x(): Unit -} -<<< def with params -trait D { - def x(a: String, b: Boolean) -} ->>> -trait D { - def x(a: String, b: Boolean): Unit -} -<<< def with return type -trait E { - def x: String // don't touch this -} ->>> -trait E { - def x: String // don't touch this -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/FileRewrite.source b/scalafix-tests/src/test/resources/checkSyntax/FileRewrite.source deleted file mode 100644 index 9c24c8b65..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/FileRewrite.source +++ /dev/null @@ -1,9 +0,0 @@ -rewrites = [ - "file:scalafix-tests/src/test/resources/rewrites/MyRewrite.scala" -] -<<< NOWRAP basic -object Name ->>> -import scala.collection.immutable.Seq -object Name1 - diff --git a/scalafix-tests/src/test/resources/checkSyntax/FileRewrite2.source b/scalafix-tests/src/test/resources/checkSyntax/FileRewrite2.source deleted file mode 100644 index ce96df7c7..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/FileRewrite2.source +++ /dev/null @@ -1,8 +0,0 @@ -rewrites = - "file:scalafix-tests/src/test/resources/rewrites/MyRewrite2.scala" -<<< NOWRAP basic -object Name ->>> -import scala.collection.immutable.Seq -object Name1 - diff --git a/scalafix-tests/src/test/resources/checkSyntax/LazyVal.source b/scalafix-tests/src/test/resources/checkSyntax/LazyVal.source deleted file mode 100644 index d3ce19813..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/LazyVal.source +++ /dev/null @@ -1,32 +0,0 @@ -rewrites = [VolatileLazyVal] -<<< basic -object a { - -val foo = 1 - - lazy val x = 2 - @volatile lazy val dontChangeMe = 2 - private lazy val y = 2 - - class foo { - lazy val z = { - println() - } - } -} ->>> -object a { - -val foo = 1 - - @volatile lazy val x = 2 - @volatile lazy val dontChangeMe = 2 - @volatile private lazy val y = 2 - - class foo { - @volatile lazy val z = { - println() - } - } -} - diff --git a/scalafix-tests/src/test/resources/checkSyntax/NoAutoTupling.source b/scalafix-tests/src/test/resources/checkSyntax/NoAutoTupling.source deleted file mode 100644 index 0cc4153bb..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/NoAutoTupling.source +++ /dev/null @@ -1,115 +0,0 @@ -rewrites = [NoAutoTupling] -<<< add explicit tuple -object tup { - def fooo(t: (Int, Int)): Int = ??? - fooo(1 + 1, 2) -} ->>> -object tup { - def fooo(t: (Int, Int)): Int = ??? - fooo((1 + 1, 2)) -} - -<<< multiple parameter lists, all auto-tupled -object tup { - def fooo(t: (Int, Int))(s: (String, String)): Int = ??? - fooo(1, 2)("a", "b") - - def baar(t: (Boolean, Int, String))(s: (Boolean, String))(k: (Int, String)): String = ??? - baar(true, 1, "foo")(false, "42")(42, "foo") -} ->>> -object tup { - def fooo(t: (Int, Int))(s: (String, String)): Int = ??? - fooo((1, 2))(("a", "b")) - - def baar(t: (Boolean, Int, String))(s: (Boolean, String))(k: (Int, String)): String = ??? - baar((true, 1, "foo"))((false, "42"))((42, "foo")) -} - -<<< multiple parameter lists, some auto-tupled -object tup { - def fooo(t: (Int, Int))(s: (String, String)): Int = ??? - fooo((1, 2))("a", "b") - - def baar(t: (Boolean, Int, String))(s: (Boolean, String))(k: (Int, String)): String = ??? - baar(true, 1, "foo")((false, "42"))(42, "foo") -} ->>> -object tup { - def fooo(t: (Int, Int))(s: (String, String)): Int = ??? - fooo((1, 2))(("a", "b")) - - def baar(t: (Boolean, Int, String))(s: (Boolean, String))(k: (Int, String)): String = ??? - baar((true, 1, "foo"))((false, "42"))((42, "foo")) -} - -<<< already tupled calls stay the same -object tup { - def fooo(t: (Int, Int)): Int = ??? - fooo((1, 2)) -} ->>> -object tup { - def fooo(t: (Int, Int)): Int = ??? - fooo((1, 2)) -} - -<<< methods not involving tuples stay the same -object tup { - def sum(a: Int, b: Int): Int = ??? - sum(1, 2) -} ->>> -object tup { - def sum(a: Int, b: Int): Int = ??? - sum(1, 2) -} - -<<< methods with tuples, but not single parameter -object tup { - def sum(a: Int, b: (Int, String)): Int = ??? - sum(1, (2, "foo")) -} ->>> -object tup { - def sum(a: Int, b: (Int, String)): Int = ??? - sum(1, (2, "foo")) -} - -<<< SKIP auto-tupling with lambdas -object tup { - val foo = (a: (Int, Boolean)) => a - foo(2, true) -} ->>> -object tup { - val foo = (a: (Int, Boolean)) => a - foo((2, true)) -} - -<<< SKIP auto-tupling with curried methods -object tup { - def foo: (((Int, String)) => ((String, List[Int])) => Int) = a => b => a._1 - foo(1 + 2, "foo")("bar", 1 :: 2 :: Nil) -} ->>> -object tup { - def foo: (((Int, String)) => ((String, List[Int])) => Int) = a => b => a._1 - foo((1 + 2, "foo"))(("bar", 1 :: 2 :: Nil)) -} - -<<< auto-tupling with class constructors -object tup { - case class Foo(t: (Int, String))(s: (Boolean, List[Int])) - new Foo(1, "foo")(true, Nil) - Foo(1, "foo")(true, Nil) // blocked by https://github.com/scalameta/scalameta/issues/846 - Foo.apply(1, "foo")(true, Nil) -} ->>> -object tup { - case class Foo(t: (Int, String))(s: (Boolean, List[Int])) - new Foo((1, "foo"))((true, Nil)) - Foo(1, "foo")(true, Nil) // blocked by https://github.com/scalameta/scalameta/issues/846 - Foo.apply((1, "foo"))((true, Nil)) -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsBase.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsBase.source deleted file mode 100644 index 59a81ba2a..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsBase.source +++ /dev/null @@ -1,84 +0,0 @@ -rewrites = [] -imports.organize = true -imports.removeUnused = false -imports.expandRelative = false -<<< Basic -import scala.collection.immutable.{Seq, Map, List => L} ->>> -import scala.collection.immutable.{List => L} -import scala.collection.immutable.Map -import scala.collection.immutable.Seq -<<< order -import scalafix._ -import java.{util => ju} -import javax._ -import scala.collection.mutable -import scala.language.implicitConversions ->>> -import scala.language.implicitConversions - -import scala.collection.mutable - -import java.{util => ju} - -import javax._ -import scalafix._ -<<< spaces -import scala.collection.immutable.List -import scala.collection.immutable.Map -import scala.collection.immutable.Seq -trait foo ->>> -import scala.collection.immutable.List -import scala.collection.immutable.Map -import scala.collection.immutable.Seq -trait foo -<<< unimport -import scala.collection.mutable.{ ListBuffer => _, _ } ->>> -import scala.collection.mutable.{ListBuffer => _, _} -<<< comments -import scala.collection.immutable.List // comment -// leading -import scala.collection.immutable.{ - Map, // Map - Set // Set -} -trait a ->>> -import scala.collection.immutable.List // comment -// leading -import scala.collection.immutable.Map // Map -import scala.collection.immutable.Set // Set -trait a -<<< relative imports -import scalafix._ -import rewrite.ExplicitImplicit ->>> -import scalafix._ - -import rewrite.ExplicitImplicit -<<< wildcard does not subsume -import scala.collection.mutable._ -import scala.collection.mutable.ListBuffer -object a { ListBuffer(1) } ->>> -import scala.collection.mutable._ -import scala.collection.mutable.ListBuffer -object a { ListBuffer(1) } -<<< rename + wildcard -import java.sql.{Array => SQLArray, _} -object a { val x: Array[Int] = Array(1) } ->>> -import java.sql.{Array => SQLArray, _} -object a { val x: Array[Int] = Array(1) } -<<< keep importee.name with wildcard -import scala.collection.immutable.{Seq, _} ->>> -import scala.collection.immutable.{Seq, _} -<<< ref prefix -import scala.collection.mutable -import scala.collection.immutable._ ->>> -import scala.collection.immutable._ -import scala.collection.mutable diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsExpandRelative.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsExpandRelative.source deleted file mode 100644 index 487ad4f0d..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsExpandRelative.source +++ /dev/null @@ -1,50 +0,0 @@ -rewrites = [] -imports.organize = true -imports.removeUnused = false -imports.expandRelative = true -<<< relative imports -import scalafix._ -import rewrite.ExplicitImplicit ->>> -import scalafix._ -import scalafix.rewrite.ExplicitImplicit -<<< language imports -import scala.annotation.implicitNotFound -import scala.collection.generic.CanBuild -import scala.collection.mutable.ArrayBuilder -import scala.collection.mutable.Builder -import scala.language.higherKinds -import scala.language.implicitConversions ->>> -import scala.language.higherKinds -import scala.language.implicitConversions - -import scala.annotation.implicitNotFound -import scala.collection.generic.CanBuild -import scala.collection.mutable.ArrayBuilder -import scala.collection.mutable.Builder -<<< don't rename trait -import slick.jdbc.H2Profile.api._ ->>> -import slick.jdbc.H2Profile.api._ -<<< root imports -import _root_.scalafix.rewrite.{ExplicitImplicit, ProcedureSyntax} -package object scalafix { - object a { - ExplicitImplicit.toString - ProcedureSyntax.toString - } -} ->>> -import _root_.scalafix.rewrite.ExplicitImplicit -import _root_.scalafix.rewrite.ProcedureSyntax -package object scalafix { - object a { - ExplicitImplicit.toString - ProcedureSyntax.toString - } -} -<<< useless package #55 -import shapeless.nat._0 ->>> -import shapeless.nat._0 diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsGroupByPrefix.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsGroupByPrefix.source deleted file mode 100644 index 0d31ed16d..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsGroupByPrefix.source +++ /dev/null @@ -1,16 +0,0 @@ -rewrites = [] -imports.organize = true -imports.removeUnused = false -imports.groupByPrefix = true -imports.expandRelative = false -<<< Basic -import scala.collection.immutable.{Seq, Map, List => L} ->>> -import scala.collection.immutable.{ List => L, Map, Seq } -<<< relative imports -import scala.collection.{mutable, immutable} -import immutable.Seq ->>> -import scala.collection.{ immutable, mutable } - -import immutable.Seq diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoGroups.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoGroups.source deleted file mode 100644 index d0005941a..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoGroups.source +++ /dev/null @@ -1,9 +0,0 @@ -rewrites = [] -imports.groups = [] -imports.removeUnused = false -<<< Simple test case (see #86) -import java.util.HashMap -import scala.collection.immutable.HashSet ->>> -import java.util.HashMap -import scala.collection.immutable.HashSet diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoPreviousImport.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoPreviousImport.source deleted file mode 100644 index 5eea20f38..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsNoPreviousImport.source +++ /dev/null @@ -1,11 +0,0 @@ -imports.organize = true -imports.removeUnused = false -imports.expandRelative = false -patches.addGlobalImports = [ - "scala.collection.immutable.Seq" -] -<<< no previous imports -object a ->>> -import scala.collection.immutable.Seq -object a diff --git a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsRemoveUnused.source b/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsRemoveUnused.source deleted file mode 100644 index 5e468dd53..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/OrganizeImportsRemoveUnused.source +++ /dev/null @@ -1,146 +0,0 @@ -SKIP rewrites = [] -imports.organize = true -imports.removeUnused = true -imports.expandRelative = false -<<< duplicate -import scala.collection.mutable.ListBuffer -import scala.collection.mutable.ListBuffer -object a { ListBuffer(1) } ->>> -import scala.collection.mutable.ListBuffer -object a { ListBuffer(1) } -<<< duplicate with curly -import scala.collection.mutable.ListBuffer -import scala.collection.mutable.{HashMap, ListBuffer} -object a { ListBuffer(1) } ->>> -import scala.collection.mutable.ListBuffer -object a { ListBuffer(1) } -<<< unused -import scala.collection.mutable.ListBuffer -object a { List(1) } ->>> -object a { List(1) } -<<< rename used -import scala.collection.mutable.{ListBuffer => LB} -import scala.collection.mutable.{HashMap => HM} -object a { LB(1) } ->>> -import scala.collection.mutable.{ListBuffer => LB} -object a { LB(1) } -<<< annotation -import scala.annotation.tailrec -import scala.{ specialized => sp } -object a { - @deprecated - @tailrec - def loop(sum: Int, xs: List[Int]): Int = loop(sum + xs.head, xs.tail) -} -trait CommutativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any ->>> -import scala.annotation.tailrec -import scala.{specialized => sp} -object a { - @deprecated - @tailrec - def loop(sum: Int, xs: List[Int]): Int = loop(sum + xs.head, xs.tail) -} -trait CommutativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any -<<< type position -import scala.collection.mutable.ListBuffer -trait a { - def lb: (Int, ListBuffer[Int]) -} ->>> -import scala.collection.mutable.ListBuffer -trait a { - def lb: (Int, ListBuffer[Int]) -} -<<< catalysts.Platform -import catalysts.Platform -object a { - def apply(): Boolean = (!Platform.isJs) && true -} ->>> -import catalysts.Platform -object a { - def apply(): Boolean = (!Platform.isJs) && true -} -<<< extends trait -import org.scalatest.FunSuiteLike -trait Foo extends FunSuiteLike ->>> -import org.scalatest.FunSuiteLike -trait Foo extends FunSuiteLike -<<< import method -import scala.collection.mutable.ListBuffer.apply -object a { val x = apply(2) } ->>> -import scala.collection.mutable.ListBuffer.apply -object a { val x = apply(2) } -<<< relative import becomes unused -import scala.collection.mutable.ListBuffer -import ListBuffer._ -object a { val x = empty[Int] } ->>> -import scala.collection.mutable.ListBuffer - -import ListBuffer._ -object a { val x = empty[Int] } -<<< pattern -import scala.concurrent.Future -import scala.util.Failure -import scala.util.Try -import scala.util.Success -object a { - Try(1) match { - case Success(a) => () - case Failure(a) => () - } -} ->>> -import scala.util.Failure -import scala.util.Success -import scala.util.Try -object a { - Try(1) match { - case Success(a) => () - case Failure(a) => () - } -} -<<< language imports -import scala.language.implicitConversions -import scala.language.higherKinds -object a { implicit def foo(x: Int): String = x.toString } ->>> -import scala.language.implicitConversions -object a { implicit def foo(x: Int): String = x.toString } -<<< SKIP macro string interpolator -import scalafix.tests.ImportMe.sc2xtensoin -object a { val x = foobar"kas" } ->>> -import scalafix.tests.ImportMe.sc2xtensoin -object a { val x = foobar"kas" } -<<< remove unused importee.name with wildcard -import scala.collection.immutable.{Seq, _} -object A { IntMap.empty[String] } ->>> -import scala.collection.immutable._ -object A { IntMap.empty[String] } -<<< remove unused importee.Name -import scala.collection.immutable._ -import scala.collection.immutable.Seq -object A { IntMap.empty[String] } ->>> -import scala.collection.immutable._ -object A { IntMap.empty[String] } -<<< keep used importee.Name -import shapeless._ -import scalafix.test.Generic -import scalafix.test._ -object A { val x = Generic[Int]; new Used } ->>> -import scalafix.test._ -import scalafix.test.Generic -import shapeless._ -object A { val x = Generic[Int]; new Used } diff --git a/scalafix-tests/src/test/resources/checkSyntax/ProcedureSyntax.source b/scalafix-tests/src/test/resources/checkSyntax/ProcedureSyntax.source deleted file mode 100644 index 8c861485b..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/ProcedureSyntax.source +++ /dev/null @@ -1,45 +0,0 @@ -rewrites = [ProcedureSyntax] -<<< nested function -object Main { -// This is a comment - def main(args: Seq[String]) { - var number = 2 - def increment(n: Int) { - number += n - } - increment(3) - args.foreach(println) - } -} ->>> -object Main { -// This is a comment - def main(args: Seq[String]): Unit = { - var number = 2 - def increment(n: Int): Unit = { - number += n - } - increment(3) - args.foreach(println) - } -} -<<< right no paren -object a { -def foo { - println(1) -} -} ->>> -object a { -def foo: Unit = { - println(1) -} -} -<<< pathological comment -object a { -def main() /* unit */ { -}} ->>> -object a { -def main(): Unit = /* unit */ { -}} diff --git a/scalafix-tests/src/test/resources/checkSyntax/RemoveXmlLiterals.source b/scalafix-tests/src/test/resources/checkSyntax/RemoveXmlLiterals.source deleted file mode 100644 index e4ce3eff9..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/RemoveXmlLiterals.source +++ /dev/null @@ -1,132 +0,0 @@ -rewrites = [RemoveXmlLiterals] - -<<< don't add import when not needed -object A {} ->>> -object A {} - -<<< single line, no splice -object A { -
-} ->>> -import scala.xml.quote._ -object A { - xml"
" -} - -<<< single line, triple quoted -object A { - val a =
- val b = \ -} ->>> -import scala.xml.quote._ -object A { - val a = xml"""
""" - val b = xml"""\""" -} - -<<< single line, splice -object A { - val bar = "bar" -
{bar}
-} ->>> -import scala.xml.quote._ -object A { - val bar = "bar" - xml"
${bar}
" -} - -<<< multi-line, no splice -object A { - val foo = -
- Hello -
-} ->>> -import scala.xml.quote._ -object A { - val foo = - xml"""
- Hello -
""" -} - -<<< multi-line, splice -object A { - val foo = -
- {"Hello"} -
-} ->>> -import scala.xml.quote._ -object A { - val foo = - xml"""
- ${"Hello"} -
""" -} - -<<< splice in attribute position -object A { - -} ->>> -import scala.xml.quote._ -object A { - xml"" -} - -<<< nested xml literals -object A { - {{"Hello"}} -} ->>> -import scala.xml.quote._ -object A { - xml"${xml"${"Hello"}"}" -} - -<<< protect $ -object A { -
$
-} ->>> -import scala.xml.quote._ -object A { - xml"
$$
" -} - -<<< protect curly brace -object A { -
{{
-} ->>> -import scala.xml.quote._ -object A { - xml"
{
" -} - -<<< SKIP protect curly brace 2 -object A { -
-} ->>> -import scala.xml.quote._ -object A { - xml"""
""" -} - -<<< multiple splices -object A { - {1}{2} -} ->>> -import scala.xml.quote._ -object A { - xml"${1}${2}" -} diff --git a/scalafix-tests/src/test/resources/checkSyntax/Xor2Either.source b/scalafix-tests/src/test/resources/checkSyntax/Xor2Either.source deleted file mode 100644 index 80682e2bd..000000000 --- a/scalafix-tests/src/test/resources/checkSyntax/Xor2Either.source +++ /dev/null @@ -1,44 +0,0 @@ -rewrites = [Xor2Either] -<<< xor 1 -import scala.concurrent.Future -import cats.data.{ Xor, XorT } -trait A { -type MyDisjunction = Xor[Int, String] - val r: MyDisjunction = Xor.Right.apply("") - val s: Xor[Int, String] = cats.data.Xor.Left(1 /* comment */) - val t: Xor[Int, String] = r.map(_ + "!") - val nest: Seq[Xor[Int, cats.data.Xor[String, Int]]] - val u: XorT[Future, Int, String] = ??? -} ->>> -import scala.concurrent.Future - -import cats.data.EitherT -import cats.implicits._ -trait A { -type MyDisjunction = Either[Int, String] - val r: MyDisjunction = Right("") - val s: Either[Int, String] = Left(1 /* comment */) - val t: Either[Int, String] = r.map(_ + "!") - val nest: Seq[Either[Int, Either[String, Int]]] - val u: EitherT[Future, Int, String] = ??? -} -<<< no implicits -object a { val x = cats.data.Xor.left[String, Int]("str") } ->>> -object a { val x = Left[String, Int]("str") } -<<< SKIP .right -import cats.data.Xor -class a { - val x: Xor[Int, String] = Xor.right("foo") - for { - y <- x - } yield y -} ->>> -class a { - val x: Either[Int, String] = Right("foo") - for { - y <- x.right - } yield y -} diff --git a/scalafix-tests/src/test/scala/scalafix/tests/SemanticTests.scala b/scalafix-tests/src/test/scala/scalafix/tests/SemanticTests.scala deleted file mode 100644 index 659db8ea5..000000000 --- a/scalafix-tests/src/test/scala/scalafix/tests/SemanticTests.scala +++ /dev/null @@ -1,10 +0,0 @@ -package scalafix.tests - -import scalafix.testkit._ - -class SemanticTests - extends SemanticRewriteSuite( /* optionally pass in custom classpath */ ) { - // directory containing .source files - val testDir = "scalafix-tests/src/test/resources" - DiffTest.fromFile(new java.io.File(testDir)).foreach(runDiffTest) -} diff --git a/scalafix-tests/src/it/scala/scalafix/tests/ProjectTests.scala b/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala similarity index 100% rename from scalafix-tests/src/it/scala/scalafix/tests/ProjectTests.scala rename to scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala diff --git a/scalafix-tests/src/it/scala/scalafix/tests/URLConfiguration.scala b/scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala similarity index 100% rename from scalafix-tests/src/it/scala/scalafix/tests/URLConfiguration.scala rename to scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js/GlobalScope.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js/GlobalScope.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js/GlobalScope.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js/GlobalScope.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js/Object.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js/Object.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js/Object.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js/Object.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/JSGlobal.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js/annotation/JSName.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/JSName.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js/annotation/JSName.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/JSName.scala diff --git a/scalafix-tests/src/main/scala/scala/scalajs/js/annotation/falsealarm/js.scala b/scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/falsealarm/js.scala similarity index 100% rename from scalafix-tests/src/main/scala/scala/scalajs/js/annotation/falsealarm/js.scala rename to scalafix-tests/unit/src/main/scala/scala/scalajs/js/annotation/falsealarm/js.scala diff --git a/scalafix-tests/src/main/scala/scalafix/test/FqnRewrite.scala b/scalafix-tests/unit/src/main/scala/scalafix/test/FqnRewrite.scala similarity index 88% rename from scalafix-tests/src/main/scala/scalafix/test/FqnRewrite.scala rename to scalafix-tests/unit/src/main/scala/scalafix/test/FqnRewrite.scala index 3e73f4a23..8b151a7a3 100644 --- a/scalafix-tests/src/main/scala/scalafix/test/FqnRewrite.scala +++ b/scalafix-tests/unit/src/main/scala/scalafix/test/FqnRewrite.scala @@ -6,7 +6,7 @@ import scalafix._ case class FqnRewrite(mirror: Mirror) extends SemanticRewrite(mirror) { override def rewrite(ctx: RewriteCtx): Patch = - ctx.addGlobalImport(importer"scala.meta._") + ctx.addGlobalImport(importer"scala.collection.immutable") } case object FqnRewrite2 extends Rewrite { @@ -22,7 +22,7 @@ object LambdaRewrites { } val semantic = Rewrite.semantic { implicit mirror => ctx => - ctx.addGlobalImport(importer"hello.semantic") + ctx.addGlobalImport(importer"scala.collection.mutable") } } diff --git a/scalafix-tests/src/main/scala/scalafix/test/Generic.scala b/scalafix-tests/unit/src/main/scala/scalafix/test/Generic.scala similarity index 100% rename from scalafix-tests/src/main/scala/scalafix/test/Generic.scala rename to scalafix-tests/unit/src/main/scala/scalafix/test/Generic.scala diff --git a/scalafix-tests/src/test/scala/scalafix/tests/ErrorSuite.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/ErrorSuite.scala similarity index 100% rename from scalafix-tests/src/test/scala/scalafix/tests/ErrorSuite.scala rename to scalafix-tests/unit/src/test/scala/scalafix/tests/ErrorSuite.scala diff --git a/scalafix-tests/src/test/scala/scalafix/tests/GitHubUrlRewriteSuite.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/GitHubUrlRewriteSuite.scala similarity index 100% rename from scalafix-tests/src/test/scala/scalafix/tests/GitHubUrlRewriteSuite.scala rename to scalafix-tests/unit/src/test/scala/scalafix/tests/GitHubUrlRewriteSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala new file mode 100644 index 000000000..997df05f2 --- /dev/null +++ b/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala @@ -0,0 +1,21 @@ +package scalafix.tests + +import scala.meta._ +import scalafix.testkit._ + +class SemanticTests + extends SemanticRewriteSuite( + Database.load(Classpath(AbsolutePath(BuildInfo.mirrorClasspath))), + AbsolutePath(BuildInfo.inputSourceroot), + AbsolutePath(BuildInfo.outputSourceroot) + ) { + +// DiffTest.fromFile(BuildInfo.testsInputResources).groupBy(_.spec).foreach { +// case (spec, tests) => +// println(s"SPEC: $spec") +// tests.foreach { test => +// println() +// println(test.expected) +// } +// } +} From 51d868105ef3d4ef391c8bf5c42b9006c8a79157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 25 May 2017 23:37:16 +0200 Subject: [PATCH 04/14] Clean up DiffTest. - Remove more legacy. - Support SKIP and ONLY. - Throw error at end of test suite if some test is marked as ONLY --- .../scala/scalafix/config/ImportsConfig.scala | 27 ---- .../scalafix/config/ScalafixConfig.scala | 1 - .../scalafix/rewrite/NoAutoTupling.scala | 1 - .../scala/scalafix/rewrite/RewriteCtx.scala | 2 +- .../scalafix/util/AssociatedComments.scala | 62 -------- .../scala/scalafix/util/CanonicalImport.scala | 124 ---------------- .../scala/scalafix/testkit/DiffTest.scala | 138 ++++++------------ .../testkit/SemanticRewriteSuite.scala | 69 +++++---- .../src/main/scala/test/FqnRewrite.scala | 1 - .../scala/scalafix/tests/SemanticTests.scala | 10 +- 10 files changed, 83 insertions(+), 352 deletions(-) delete mode 100644 scalafix-core/src/main/scala/scalafix/config/ImportsConfig.scala delete mode 100644 scalafix-core/src/main/scala/scalafix/util/AssociatedComments.scala delete mode 100644 scalafix-core/src/main/scala/scalafix/util/CanonicalImport.scala diff --git a/scalafix-core/src/main/scala/scalafix/config/ImportsConfig.scala b/scalafix-core/src/main/scala/scalafix/config/ImportsConfig.scala deleted file mode 100644 index d0b9c6ad1..000000000 --- a/scalafix-core/src/main/scala/scalafix/config/ImportsConfig.scala +++ /dev/null @@ -1,27 +0,0 @@ -package scalafix.config - -import scala.meta.Ref -import metaconfig._ - -@DeriveConfDecoder -case class ImportsConfig( - // Disabled because unused imports can be created when expanding relative - // imports, see https://github.com/scalacenter/scalafix/issues/83 - expandRelative: Boolean = false, - spaceAroundCurlyBrace: Boolean = false, - // Disabled since users should explicitly opt into it. - organize: Boolean = false, - // TODO(olafur) renable when Mirror.messages - removeUnused: Boolean = false, - alwaysUsed: List[Ref] = List(), - groups: List[FilterMatcher] = List( - FilterMatcher("scala.language.*"), - FilterMatcher("(scala|scala\\..*)$"), - FilterMatcher("(java|java\\..*)$") - ), - groupByPrefix: Boolean = false -) - -object ImportsConfig { - def default: ImportsConfig = ImportsConfig() -} diff --git a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala index 7fb6bef99..ccf3cbf61 100644 --- a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala +++ b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala @@ -14,7 +14,6 @@ import metaconfig.typesafeconfig.typesafeConfigMetaconfigParser case class ScalafixConfig( parser: Parse[_ <: Tree] = Parse.parseSource, @Recurse explicitReturnTypes: ExplicitReturnTypesConfig = ExplicitReturnTypesConfig(), - @Recurse imports: ImportsConfig = ImportsConfig(), @Recurse patches: PatchConfig = PatchConfig(), @Recurse debug: DebugConfig = DebugConfig(), fatalWarnings: Boolean = true, diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/NoAutoTupling.scala b/scalafix-core/src/main/scala/scalafix/rewrite/NoAutoTupling.scala index cdd326138..b3bae35e9 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/NoAutoTupling.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/NoAutoTupling.scala @@ -5,7 +5,6 @@ import scala.meta._ import scalafix.syntax._ import scala.meta.semantic.Signature import scala.collection.mutable -import org.scalameta.logger case class NoAutoTupling(mirror: Mirror) extends SemanticRewrite(mirror) { diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala b/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala index acc849ccc..480ec7143 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/RewriteCtx.scala @@ -1,13 +1,13 @@ package scalafix package rewrite import scala.meta.Tree +import scala.meta.contrib.AssociatedComments import scala.meta.inputs.Input import scala.meta.io.AbsolutePath import scala.meta.tokens.Tokens import scalafix.syntax._ import scalafix.config.ScalafixConfig import scalafix.config.ScalafixReporter -import scalafix.util.AssociatedComments import scalafix.util.TokenList /** Bundle of useful things when implementing [[Rewrite]]. */ diff --git a/scalafix-core/src/main/scala/scalafix/util/AssociatedComments.scala b/scalafix-core/src/main/scala/scalafix/util/AssociatedComments.scala deleted file mode 100644 index cf7337097..000000000 --- a/scalafix-core/src/main/scala/scalafix/util/AssociatedComments.scala +++ /dev/null @@ -1,62 +0,0 @@ -package scalafix.util - -import scala.meta.Tree -import scala.meta.tokens.Token -import scala.meta.tokens.Token.Comment -import scala.meta.tokens.Tokens -import scala.collection.immutable.Seq - -sealed abstract class AssociatedComments( - leadingMap: Map[Token, Seq[Comment]], - trailingMap: Map[Token, Seq[Comment]]) { - def leading(tree: Tree): Set[Comment] = - (for { - token <- tree.tokens.headOption - comments <- leadingMap.get(token) - } yield comments).getOrElse(Nil).toSet - - def trailing(tree: Tree): Set[Comment] = - (for { - token <- tree.tokens.lastOption - comments <- trailingMap.get(token) - } yield comments).getOrElse(Nil).toSet - - def hasComment(tree: Tree): Boolean = - trailing(tree).nonEmpty || leading(tree).nonEmpty -} - -object AssociatedComments { - - def apply(tokens: Tokens): AssociatedComments = { - import scala.meta.tokens.Token._ - val leadingBuilder = Map.newBuilder[Token, Seq[Comment]] - val trailingBuilder = Map.newBuilder[Token, Seq[Comment]] - val leading = Seq.newBuilder[Comment] - val trailing = Seq.newBuilder[Comment] - var isLeading = true - var lastToken: Token = tokens.head - tokens.foreach { - case c: Comment => - if (isLeading) leading += c - else trailing += c - case Token.LF() => isLeading = true - case Trivia() => - case currentToken => - val t = trailing.result() - if (t.nonEmpty) { - trailingBuilder += lastToken -> trailing.result() - trailing.clear() - } - val l = leading.result() - if (l.nonEmpty) { - leadingBuilder += currentToken -> leading.result() - leading.clear() - } - if (!currentToken.is[Comma]) { - lastToken = currentToken - } - isLeading = false - } - new AssociatedComments(leadingBuilder.result(), trailingBuilder.result()) {} - } -} diff --git a/scalafix-core/src/main/scala/scalafix/util/CanonicalImport.scala b/scalafix-core/src/main/scala/scalafix/util/CanonicalImport.scala deleted file mode 100644 index 8898c9c95..000000000 --- a/scalafix-core/src/main/scala/scalafix/util/CanonicalImport.scala +++ /dev/null @@ -1,124 +0,0 @@ -package scalafix -package util - -import scala.collection.immutable.Seq -import scala.meta._, contrib._ -import scala.meta.tokens.Token.Comment - -object CanonicalImport { - def fromWildcard(ref: Term.Ref, - wildcard: Importee.Wildcard, - extraImportees: Seq[Importee])( - implicit ctx: RewriteCtx, - ownerImport: Import - ): CanonicalImport = - new CanonicalImport( - ref, - wildcard, - extraImportees, - leadingComments = ctx.comments.leading(ownerImport), - trailingComments = ctx.comments.trailing(ownerImport) ++ - extraImportees.flatMap(ctx.comments.trailing), - None - ) {} - def fromImportee(ref: Term.Ref, importee: Importee)( - implicit ctx: RewriteCtx, - ownerImport: Import - ): CanonicalImport = - new CanonicalImport( - ref, - importee, - Nil, - leadingComments = ctx.comments.leading(ownerImport), - trailingComments = ctx.comments.trailing(ownerImport) ++ - ctx.comments.trailing(importee), - None - ) {} -} - -/** A canonical imports is the minimal representation for a single import statement - * - * Only construct this class from custom constructors in the companion object. - * This class should be sealed abstract but the abstract modifier removes the - * convenient copy method. - */ -sealed case class CanonicalImport( - ref: Term.Ref, - importee: Importee, - extraImportees: Seq[Importee], - leadingComments: Set[Comment], - trailingComments: Set[Comment], - fullyQualifiedRef: Option[Term.Ref] -)(implicit ctx: RewriteCtx) - extends Ordered[CanonicalImport] { - lazy val isRootImport: Boolean = ref.collectFirst { - case q"_root_.$name" => name - }.isDefined - private def getRootName(ref: Term.Ref): Term.Name = - ref.collectFirst { - case q"_root_.$name" => name - case q"${name: Term.Name}.$_" => name - }.get - lazy val rootName: Term.Name = getRootName(ref) - private def addRootImport(rootImports: Seq[CanonicalImport])( - fullyQualifiedRef: Term.Ref): Term.Ref = { - val fqnRoot = getRootName(fullyQualifiedRef) - def otherImportIsRoot = - rootImports.exists(_.rootName.value == fqnRoot.value) - if (isRootImport || otherImportIsRoot) { - ("_root_." + fullyQualifiedRef.syntax) - .parse[Term] - .get - .asInstanceOf[Term.Ref] - } else fullyQualifiedRef - } - def withFullyQualifiedRef( - fqnRef: Option[Term.Ref], - rootImports: Seq[CanonicalImport]): CanonicalImport = - copy(fullyQualifiedRef = fqnRef.map(addRootImport(rootImports))) - def withoutLeading(leading: Set[Comment]): CanonicalImport = - copy(leadingComments = leadingComments.filterNot(leading)) - def tree: Import = Import(Seq(Importer(ref, extraImportees :+ importee))) - def syntax: String = - s"${leading}import $importerSyntax$trailing" - def leading: String = - if (leadingComments.isEmpty) "" - else leadingComments.mkString("", "\n", "\n") - def trailing: String = - if (trailingComments.isEmpty) "" - else trailingComments.mkString(" ", "\n", "") - def importerSyntax: String = - s"$refSyntax.$importeeSyntax" - private def curlySpace = - if (ctx.config.imports.spaceAroundCurlyBrace) " " - else "" - def actualRef: Term.Ref = - if (ctx.config.imports.expandRelative) fullyQualifiedRef.getOrElse(ref) - else ref - def refSyntax: String = - actualRef.syntax - def importeeSyntax: String = - if (extraImportees.nonEmpty) - s"""{$curlySpace${extraImportees - .map(_.syntax) - .mkString(", ")}, $importee$curlySpace}""" - else - importee match { - case i: Importee.Rename => s"{$curlySpace$i$curlySpace}" - case i => i.syntax - } - private def importeeOrder = importee match { - case i: Importee.Rename => (1, i.name.syntax) - case i: Importee.Wildcard => (0, i.syntax) - case i => (1, i.syntax) - } - def sortOrder: (String, (Int, String)) = (refSyntax, importeeOrder) - def structure: String = Importer(ref, Seq(importee)).structure - - override def compare(that: CanonicalImport): Int = { - import Ordered.orderingToOrdered - if (ref.syntax == that.ref.syntax) { - importeeOrder.compare(that.importeeOrder) - } else syntax.compareTo(that.syntax) - } -} diff --git a/scalafix-testkit/src/main/scala/scalafix/testkit/DiffTest.scala b/scalafix-testkit/src/main/scala/scalafix/testkit/DiffTest.scala index 0dbec4793..122986b93 100644 --- a/scalafix-testkit/src/main/scala/scalafix/testkit/DiffTest.scala +++ b/scalafix-testkit/src/main/scala/scalafix/testkit/DiffTest.scala @@ -1,107 +1,63 @@ package scalafix.testkit -import metaconfig._, typesafeconfig._ import scala.collection.immutable.Seq import scala.meta._ import scalafix.Rewrite import scalafix.config.ScalafixConfig -import scalafix.config.ScalafixMetaconfigReaders import scalafix.reflect.ScalafixCompilerDecoder -import scalafix.util.FileOps - -import java.io.File - -import metaconfig.Configured - -case class DiffTest(spec: String, - name: String, - filename: String, - original: String, - expected: String, - skip: Boolean, - only: Boolean, - config: Option[Mirror] => (Rewrite, ScalafixConfig)) { - def noWrap: Boolean = name.startsWith("NOWRAP ") - def checkSyntax: Boolean = spec.startsWith("checkSyntax") - private def packageName = name.replaceAll("[^a-zA-Z0-9]", "") - private def packagePrefix = s"package $packageName {\n" - private def packageSuffix = s" }\n" - def wrapped(code: String = original): String = - if (noWrap) original - else s"$packagePrefix$code$packageSuffix" - def unwrap(code: String): String = - if (noWrap) code - else code.stripPrefix(packagePrefix).stripSuffix(packageSuffix) - val fullName = s"$spec: $name" +import org.scalatest.exceptions.TestFailedException + +case class DiffTest(filename: RelativePath, + original: Input, + attributes: Attributes, + config: () => (Rewrite, ScalafixConfig), + isSkip: Boolean, + isOnly: Boolean) { + def name: String = filename.toString() + private def prefix = + if (isOnly) "ONLY " + else if (isSkip) "SKIP " + else "" + def originalStr = new String(original.chars) } object DiffTest { - def fromFile(directory: File): Seq[DiffTest] = { - val tests: Seq[DiffTest] = { - for { - filename <- getTestFiles(directory) - test <- { - val content = FileOps.readFile(filename) - DiffTest(directory, content, filename) - } - } yield test - } - val onlyOne = tests.exists(_.only) - def testShouldRun(t: DiffTest): Boolean = !onlyOne || t.only - tests.filter(testShouldRun) - } - private def isOnly(name: String): Boolean = name.startsWith("ONLY ") - private def isSkip(name: String): Boolean = name.startsWith("SKIP ") - private def stripPrefix(name: String) = - name.stripPrefix("SKIP ").stripPrefix("ONLY ").trim - private def apply(testDir: File, - content: String, - filename: String): Seq[DiffTest] = - apply(filename.stripPrefix(testDir.getPath + File.separator), - content, - filename) - - def apply(spec: String, content: String, filename: String): Seq[DiffTest] = { - val moduleOnly = isOnly(content) - val moduleSkip = isSkip(content) - val split = content.split("\n<<< ") - - val style: (Option[Mirror]) => (Rewrite, ScalafixConfig) = { - mirror: Option[Mirror] => - val firstLine = stripPrefix(split.head) - val decoder = ScalafixMetaconfigReaders.scalafixConfigConfDecoder( - ScalafixCompilerDecoder.fromMirrorOption(mirror)) - Input.String(firstLine).toConf.flatMap(decoder.read) match { - case Configured.Ok(x) => x - case Configured.NotOk(x) => - throw new IllegalArgumentException(s"""Failed to parse $filename - |Mirror: $mirror - |Error: $x""".stripMargin) - } - } - - split.tail.map { t => - val before :: expected :: Nil = t.split("\n>>>\n", 2).toList - val name :: original :: Nil = before.split("\n", 2).toList - val actualName = stripPrefix(name) - DiffTest(spec, - actualName, - filename, - original, - expected, - moduleSkip || isSkip(name), - moduleOnly || isOnly(name), - style) - }.toList + private val PrefixRegex = "\\s+(ONLY|SKIP)".r + private def stripPrefix(str: String) = PrefixRegex.replaceFirstIn(str, "") + + def fromMirror(mirror: Database): Seq[DiffTest] = mirror.entries.collect { + case (input @ Input.LabeledString(label, code), attributes) => + val relpath = RelativePath(label) + val config: () => (Rewrite, ScalafixConfig) = { () => + input.tokenize.get + .collectFirst { + case Token.Comment(comment) => + val decoder = + ScalafixCompilerDecoder.fromMirrorOption(Some(mirror)) + ScalafixConfig + .fromInput(Input.LabeledString(label, stripPrefix(comment)), + Some(mirror))(decoder) + .get + } + .getOrElse(throw new TestFailedException( + s"Missing scalafix configuration inside comment at top of file $relpath", + 0)) + } + DiffTest( + filename = relpath, + original = input, + attributes = attributes, + config = config, + isSkip = code.contains("SKIP"), + isOnly = code.contains("ONLY") + ) } - /** Avoids parsing all files if some tests are marked ONLY. */ - private def getTestFiles(directory: File): Vector[String] = { - val testsFiles = FileOps.listFiles(directory).filter(_.endsWith(".source")) - val onlyTests = testsFiles.filter(_.contains("\n<<< ONLY")) - if (onlyTests.nonEmpty) onlyTests - else testsFiles + def testToRun(tests: Seq[DiffTest]): Seq[DiffTest] = { + val onlyOne = tests.exists(_.isOnly) + def testShouldRun(t: DiffTest): Boolean = !onlyOne || t.isOnly + tests.filter(testShouldRun) } } diff --git a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala index fb0d6f3f1..8a5d83141 100644 --- a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala +++ b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala @@ -2,48 +2,47 @@ package scalafix package testkit import scala.meta._ -import scala.meta.internal.io.FileIO -import scalafix.reflect.ScalafixCompilerDecoder -import metaconfig.Configured +import org.scalatest.BeforeAndAfterAll import org.scalatest.FunSuite -import org.scalatest.exceptions.TestFailedException abstract class SemanticRewriteSuite( val mirror: Database, val inputSourceroot: AbsolutePath, val expectedOutputSourceroot: AbsolutePath ) extends FunSuite - with DiffAssertions { self => - mirror.entries.foreach { - case (input @ Input.LabeledString(relpath, code), attributes) - if relpath.contains("test") => - test(relpath) { - val (rewrite, config) = input.tokenize.get - .collectFirst { - case Token.Comment(comment) => - val decoder = - ScalafixCompilerDecoder.fromMirrorOption(Some(mirror)) - ScalafixConfig - .fromInput(Input.LabeledString(relpath, comment), - Some(mirror))(decoder) - .get - } - .getOrElse(throw new TestFailedException( - s"Missing scalafix configuration inside comment at top of file $relpath", - 0)) - val obtainedWithComment = - rewrite.apply(input, config.copy(dialect = attributes.dialect)) - val obtained = { - val tokens = obtainedWithComment.tokenize.get - val comment = tokens - .find(x => x.is[Token.Comment] && x.syntax.startsWith("/*")) - .get - tokens.filterNot(_ eq comment).mkString - } - val expected = - new String(expectedOutputSourceroot.resolve(relpath).readAllBytes) - assertNoDiff(obtained, expected) + with DiffAssertions + with BeforeAndAfterAll { self => + def runOn(diffTest: DiffTest): Unit = { + test(diffTest.name) { + val (rewrite, config) = diffTest.config.apply() + val obtainedWithComment = + rewrite.apply(diffTest.original, + config.copy(dialect = diffTest.attributes.dialect)) + val obtained = { + val tokens = obtainedWithComment.tokenize.get + val comment = tokens + .find(x => x.is[Token.Comment] && x.syntax.startsWith("/*")) + .get + tokens.filter(_ ne comment).mkString } - case els => // do nothing + val expected = + new String( + expectedOutputSourceroot.resolve(diffTest.filename).readAllBytes) + assertNoDiff(obtained, expected) + } + } + + override def afterAll(): Unit = { + val onlyTests = testsToRun.filter(_.isOnly) + if (sys.env.contains("CI") && testsToRun.nonEmpty) { + sys.error( + s"sys.env('CI') is set and the following tests are marked as ONLY: " + + s"${onlyTests.map(_.filename).mkString(", ")}") + } + super.afterAll() + } + lazy val testsToRun = DiffTest.testToRun(DiffTest.fromMirror(mirror)) + def runAllTests(): Unit = { + testsToRun.foreach(runOn) } } diff --git a/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala index c30930abe..6689fdcff 100644 --- a/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala +++ b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala @@ -5,7 +5,6 @@ rewrites = [ "scala:banana.rewrite.LambdaRewrites.syntax" "scala:banana.rewrite.LambdaRewrites.semantic" ] -imports.removeUnused = true */ package test diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala index 997df05f2..d21be82db 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala +++ b/scalafix-tests/unit/src/test/scala/scalafix/tests/SemanticTests.scala @@ -9,13 +9,5 @@ class SemanticTests AbsolutePath(BuildInfo.inputSourceroot), AbsolutePath(BuildInfo.outputSourceroot) ) { - -// DiffTest.fromFile(BuildInfo.testsInputResources).groupBy(_.spec).foreach { -// case (spec, tests) => -// println(s"SPEC: $spec") -// tests.foreach { test => -// println() -// println(test.expected) -// } -// } + runAllTests() } From cea1ac9532821300b2b4f2eced434c1b9bbb1cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 00:02:42 +0200 Subject: [PATCH 05/14] Follow the failing tests and compilation errors. --- bin/runci.sh | 3 - readme/Changelog.scalatex | 4 +- readme/Configuration.scalatex | 29 ---- readme/Readme.scalatex | 2 +- readme/Rewrites.scalatex | 6 +- ...tingRewrites.scalatex => Testkit.scalatex} | 0 .../src/test/scala/scalafix/cli/CliTest.scala | 4 +- .../scalafix/config/ScalafixConfig.scala | 3 +- .../config/ScalafixMetaconfigReaders.scala | 11 +- .../scala/scalafix/patch/ImportPatchOps.scala | 8 +- .../rewrite/ExplicitReturnTypes.scala | 11 +- .../scalafix/config/ScalafixConfigTest.scala | 14 +- .../main/scala/scalafix/testkit/ItTest.scala | 4 - .../main/scala/test/ExplicitReturnTypes.scala | 2 +- .../src/main/scala/test/ExplicitUnit.scala | 2 +- .../src/main/scala/test/FileRewrite.scala | 2 +- .../src/main/scala/test/FileRewrite2.scala | 2 +- .../src/main/scala/test/FlipEither.scala | 2 +- .../src/main/scala/test/FqnRewrite.scala | 2 +- .../main/scala/test/PatchWithEmptyRange.scala | 2 +- .../src/main/scala/test/ProcedureSyntax.scala | 5 +- .../main/scala/test/RemoveXmlLiterals.scala | 2 +- .../src/main/scala/test/VolatileLazyVal.scala | 2 +- .../src/main/scala/test/Xor2Either.scala | 6 +- .../main/scala/test/ExplicitReturnTypes.scala | 10 +- .../src/main/scala/test/ProcedureSyntax.scala | 3 +- .../src/main/scala/test/Xor2Either.scala | 2 +- .../scala/scalafix/tests/ProjectTests.scala | 129 ------------------ 28 files changed, 53 insertions(+), 219 deletions(-) rename readme/{ImplementingRewrites.scalatex => Testkit.scalatex} (100%) diff --git a/bin/runci.sh b/bin/runci.sh index e3848e02d..508962560 100755 --- a/bin/runci.sh +++ b/bin/runci.sh @@ -11,6 +11,3 @@ case "$TEST" in ;; esac - - - diff --git a/readme/Changelog.scalatex b/readme/Changelog.scalatex index 50dbaad5b..9c7e96c32 100644 --- a/readme/Changelog.scalatex +++ b/readme/Changelog.scalatex @@ -116,7 +116,7 @@ @li Configuration in .scalafix.conf has been greatly improved to support a wide range of options. - Examples, see @sect.ref{patches}, @sect.ref{imports} and @sect.ref{All options}. + Examples, see @sect.ref{patches}, @code{imports} (now removed) and @sect.ref{All options}. @sect{0.2.1} @ul @li @@ -127,7 +127,7 @@ @sect{0.2.0} @ul @li - First semantic rewrite! See @sect.ref{ExplicitImplicit} + First semantic rewrite! See @sect.ref{ExplicitReturnTypes}. @li Removed command line interface in favor of compiler plugin. Why? To run semantic rewrites, scalafix needs to compile source files. diff --git a/readme/Configuration.scalatex b/readme/Configuration.scalatex index 176d476f8..c35b8d192 100644 --- a/readme/Configuration.scalatex +++ b/readme/Configuration.scalatex @@ -27,35 +27,6 @@ "scala:scalafix.rewrite.ProcedureSyntax" ] - @sect{imports} - - @b{NOTE.} This feature is new and may still have bugs that cause rewritten - code to not compile. Please report back you bump into issues. - - @p - Scalafix can organize imports. - If you use import patches such as @code{Add/RemoveGlobalImport}, - you need to allow scalafix to organize you imports. - To minimize the diff from import patches, it's best to run scalafix once - with organize imports enabled and no zero patches. - @config - // Group and sort imports - imports.organize = true - // Example relative import: `import collection.immutable` - // Expanded: `import scala.collection.immutable` - imports.expandRelative = true - // Removes global imports that -Ywarn-unused-import complains about - // Requires sbt-scalafix/ScalafixMirror - imports.removeUnused = true - // Groups are separated by a blank line, example: - // import com.a - // import com.b - // - // import scala.collection.immutable._ - imports.groups = [ - "com.mycompany.*" - "scala\\..*" - ] @sect{patches} For simple use-cases, it's possible to write custom rewrites directly .scalafix.conf. diff --git a/readme/Readme.scalatex b/readme/Readme.scalatex index a860dfb10..f3a658986 100644 --- a/readme/Readme.scalatex +++ b/readme/Readme.scalatex @@ -6,7 +6,7 @@ @scalatex.Installation() @scalatex.Configuration() @scalatex.Rewrites() - @scalatex.ImplementingRewrites() + @scalatex.Testkit() @scalatex.Faq() @scalatex.Changelog() @scalatex.Footer() diff --git a/readme/Rewrites.scalatex b/readme/Rewrites.scalatex index 792530ac7..298160b44 100644 --- a/readme/Rewrites.scalatex +++ b/readme/Rewrites.scalatex @@ -10,10 +10,10 @@ "http://scala-lang.org/blog/2016/05/30/scala-center-advisory-board.html#the-first-meeting"). To create custom rewrites, see @sect.ref{scalafix-core}. - @sect(ExplicitImplicit.toString) + @sect(ExplicitReturnTypes.toString) Dotty requires implicit @code{val}s and @code{def}s to explicitly annotate return types. - The @ExplicitImplicit.toString rewrite inserts the inferred type from the + The @ExplicitReturnTypes.toString rewrite inserts the inferred type from the compiler for implicit definitions that are missing an explicit return type. For example, @@ -26,7 +26,7 @@ @ul @li @note. This rewrite is new and may insert an ambiguous type name in rare cases. - For example, running ExplicitImplicit (as of v0.2.0) on the Scala.js repo + For example, running ExplicitReturnTypes (as of v0.2.0) on the Scala.js repo did introduce compilation errors. @li scalafix tries to minimize the inserted type signature, by using diff --git a/readme/ImplementingRewrites.scalatex b/readme/Testkit.scalatex similarity index 100% rename from readme/ImplementingRewrites.scalatex rename to readme/Testkit.scalatex diff --git a/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala b/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala index 362a17160..52fbd2f7d 100644 --- a/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala +++ b/scalafix-cli/src/test/scala/scalafix/cli/CliTest.scala @@ -45,7 +45,7 @@ class CliTest extends FunSuite with DiffAssertions { Seq( "--verbose", "--config-str", - "imports.groupByPrefix=true", + "fatalWarnings=true", "--single-thread", "--files", "a.scala", @@ -56,7 +56,7 @@ class CliTest extends FunSuite with DiffAssertions { )) val obtained = runner.cli assert(!runner.writeMode.isWriteFile) - assert(runner.config.imports.groupByPrefix) + assert(runner.config.fatalWarnings) assert(obtained.verbose) assert(obtained.singleThread) assert( diff --git a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala index ccf3cbf61..026e3646b 100644 --- a/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala +++ b/scalafix-core/src/main/scala/scalafix/config/ScalafixConfig.scala @@ -13,7 +13,8 @@ import metaconfig.typesafeconfig.typesafeConfigMetaconfigParser @DeriveConfDecoder case class ScalafixConfig( parser: Parse[_ <: Tree] = Parse.parseSource, - @Recurse explicitReturnTypes: ExplicitReturnTypesConfig = ExplicitReturnTypesConfig(), + @Recurse explicitReturnTypes: ExplicitReturnTypesConfig = + ExplicitReturnTypesConfig(), @Recurse patches: PatchConfig = PatchConfig(), @Recurse debug: DebugConfig = DebugConfig(), fatalWarnings: Boolean = true, diff --git a/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala b/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala index c4a834529..99e8a9957 100644 --- a/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala +++ b/scalafix-core/src/main/scala/scalafix/config/ScalafixMetaconfigReaders.scala @@ -15,10 +15,12 @@ import java.io.OutputStream import java.io.PrintStream import java.net.URI import java.util.regex.Pattern +import scala.util.control.NonFatal import metaconfig.Conf import metaconfig.ConfDecoder import metaconfig.ConfError import metaconfig.Configured +import metaconfig.Configured.Ok object ScalafixMetaconfigReaders extends ScalafixMetaconfigReaders // A collection of metaconfig.Reader instances that are shared across @@ -157,7 +159,14 @@ trait ScalafixMetaconfigReaders { implicit lazy val AddGlobalImportReader: ConfDecoder[AddGlobalImport] = importerReader.map(AddGlobalImport.apply) implicit lazy val RemoveGlobalImportReader: ConfDecoder[RemoveGlobalImport] = - symbolReader.map(RemoveGlobalImport.apply) + termRefReader.flatMap { ref => + try { + Ok(RemoveGlobalImport(Symbol(s"_root_.$ref."))) + } catch { + case NonFatal(e) => + ConfError.exception(e, 0).notOk + } + } implicit lazy val PrintStreamReader: ConfDecoder[PrintStream] = { val empty = new PrintStream(new OutputStream { diff --git a/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala b/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala index 9f1e8faff..96047c361 100644 --- a/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala +++ b/scalafix-core/src/main/scala/scalafix/patch/ImportPatchOps.scala @@ -65,10 +65,10 @@ object ImportPatchOps { trailingComma + leadingComma + PatchOps.removeTokens(tokens) } - extraPatches ++ - (isRemovedImportee ++ - isRemovedImporter ++ - isRemovedImport).map(remove) + extraPatches ++ + (isRemovedImportee ++ + isRemovedImporter ++ + isRemovedImport).map(remove) } private def extractImports(stats: Seq[Stat]): Seq[Import] = { diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala b/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala index 6cd95d751..f895b6dcf 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/ExplicitReturnTypes.scala @@ -2,12 +2,13 @@ package scalafix package rewrite import scalafix.syntax._ -import scala.meta._ +import scala.meta._, contrib._ import scalafix.util.Whitespace import scala.collection.immutable.Seq -import org.scalameta.logger -case class ExplicitReturnTypes(mirror: Mirror) extends SemanticRewrite(mirror) { +// TODO: implement ExplicitReturnTypesConfig +case class ExplicitReturnTypes(mirror: Mirror) + extends SemanticRewrite(mirror) { // Don't explicitly annotate vals when the right-hand body is a single call // to `implicitly`. Prevents ambiguous implicit. Not annotating in such cases, // this a common trick employed implicit-heavy code to workaround SI-2712. @@ -60,11 +61,11 @@ case class ExplicitReturnTypes(mirror: Mirror) extends SemanticRewrite(mirror) { tree .collect { case t @ Defn.Val(mods, _, None, body) - if mods.exists(_.syntax == "implicit") && + if t.hasMod(mod"implicit") && !isImplicitly(body) => fix(t, body) case t @ Defn.Def(mods, _, _, _, None, body) - if mods.exists(_.syntax == "implicit") => + if t.hasMod(mod"implicit") => fix(t, body) } .flatten diff --git a/scalafix-core/src/test/scala/scalafix/config/ScalafixConfigTest.scala b/scalafix-core/src/test/scala/scalafix/config/ScalafixConfigTest.scala index e22799087..334d4e3b5 100644 --- a/scalafix-core/src/test/scala/scalafix/config/ScalafixConfigTest.scala +++ b/scalafix-core/src/test/scala/scalafix/config/ScalafixConfigTest.scala @@ -22,7 +22,7 @@ class ScalafixConfigTest extends FunSuite { check( """ |patches.removeGlobalImports = [ - | "scala.{meta => m}" + | "scala.meta" |] |patches.addGlobalImports = [ | "scala.meta._" @@ -34,10 +34,6 @@ class ScalafixConfigTest extends FunSuite { | scala.meta._ | ] |}] - |imports.organize = false - |imports.groups = [ - | foo.bar - |] """.stripMargin, default.copy( patches = default.patches.copy( @@ -52,13 +48,7 @@ class ScalafixConfigTest extends FunSuite { AddGlobalImport(importer"scala.meta._") ), removeGlobalImports = List( - RemoveGlobalImport(importer"scala.{meta => m}") - ) - ), - imports = default.imports.copy( - organize = false, - groups = List( - FilterMatcher("foo.bar") + RemoveGlobalImport(Symbol("_root_.scala.meta.")) ) ) ) diff --git a/scalafix-testkit/src/main/scala/scalafix/testkit/ItTest.scala b/scalafix-testkit/src/main/scala/scalafix/testkit/ItTest.scala index 06da59a6c..3ebacf7a9 100644 --- a/scalafix-testkit/src/main/scala/scalafix/testkit/ItTest.scala +++ b/scalafix-testkit/src/main/scala/scalafix/testkit/ItTest.scala @@ -25,9 +25,5 @@ case class ItTest( } object ItTest { - val catsImportConfig: String = - """|imports.organize = true - |imports.removeUnused = false - |imports.groupByPrefix = true""".stripMargin val root: Path = pwd / "target" / "it" } diff --git a/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala b/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala index e522df4c6..9864e6640 100644 --- a/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala +++ b/scalafix-tests/input/src/main/scala/test/ExplicitReturnTypes.scala @@ -3,7 +3,7 @@ rewrites = ExplicitReturnTypes */ package test -object ExplicitReturnTypesInput { +object ExplicitReturnTypes { implicit val L = List(1) implicit val M = Map(1 -> "STRING") implicit def D = 2 diff --git a/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala b/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala index 99fcfeeaa..b0b6db7fd 100644 --- a/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala +++ b/scalafix-tests/input/src/main/scala/test/ExplicitUnit.scala @@ -1,6 +1,6 @@ /* rewrites = ExplicitUnit -*/ + */ package test object ExplicitUnit { diff --git a/scalafix-tests/input/src/main/scala/test/FileRewrite.scala b/scalafix-tests/input/src/main/scala/test/FileRewrite.scala index 8822468cc..06e8451c0 100644 --- a/scalafix-tests/input/src/main/scala/test/FileRewrite.scala +++ b/scalafix-tests/input/src/main/scala/test/FileRewrite.scala @@ -2,7 +2,7 @@ rewrites = [ "file:scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala" ] -*/ + */ package test object FileRewrite diff --git a/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala b/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala index fa96e79bb..0d6e8fdf2 100644 --- a/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala +++ b/scalafix-tests/input/src/main/scala/test/FileRewrite2.scala @@ -2,7 +2,7 @@ rewrites = [ "file:scalafix-tests/input/src/main/resources/rewrites/MyRewrite.scala" ] -*/ + */ package test object FileRewrite2 diff --git a/scalafix-tests/input/src/main/scala/test/FlipEither.scala b/scalafix-tests/input/src/main/scala/test/FlipEither.scala index 372e5c4b4..cb6531504 100644 --- a/scalafix-tests/input/src/main/scala/test/FlipEither.scala +++ b/scalafix-tests/input/src/main/scala/test/FlipEither.scala @@ -29,7 +29,7 @@ patches.addGlobalImports = [ "scala.collection.immutable.Seq" ] rewrites = [] -*/ + */ package test object FlipEither { diff --git a/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala index 6689fdcff..07393667d 100644 --- a/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala +++ b/scalafix-tests/input/src/main/scala/test/FqnRewrite.scala @@ -5,7 +5,7 @@ rewrites = [ "scala:banana.rewrite.LambdaRewrites.syntax" "scala:banana.rewrite.LambdaRewrites.semantic" ] -*/ + */ package test object FqnRewrite diff --git a/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala b/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala index 860df5d2e..d9e2b3292 100644 --- a/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala +++ b/scalafix-tests/input/src/main/scala/test/PatchWithEmptyRange.scala @@ -1,6 +1,6 @@ /* rewrites = "scala:banana.rewrite.PatchTokenWithEmptyRange" -*/ + */ package test class PatchWithEmptyRange { diff --git a/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala b/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala index 8c21c1514..47220ae52 100644 --- a/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala +++ b/scalafix-tests/input/src/main/scala/test/ProcedureSyntax.scala @@ -1,6 +1,6 @@ /* rewrites = ProcedureSyntax -*/ + */ package test object ProcedureSyntax { @@ -16,6 +16,5 @@ object ProcedureSyntax { def foo { println(1) } - def main() /* unit */ { - } + def main() /* unit */ {} } diff --git a/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala b/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala index 30cf093c9..601152531 100644 --- a/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala +++ b/scalafix-tests/input/src/main/scala/test/RemoveXmlLiterals.scala @@ -1,6 +1,6 @@ /* rewrites = RemoveXmlLiterals -*/ + */ package test class RemoveXmlLiterals { diff --git a/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala b/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala index d1978cfdb..4a943ee09 100644 --- a/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala +++ b/scalafix-tests/input/src/main/scala/test/VolatileLazyVal.scala @@ -1,6 +1,6 @@ /* rewrites = VolatileLazyVal -*/ + */ package test class VolatileLazyVal { diff --git a/scalafix-tests/input/src/main/scala/test/Xor2Either.scala b/scalafix-tests/input/src/main/scala/test/Xor2Either.scala index 27462f28d..a22477774 100644 --- a/scalafix-tests/input/src/main/scala/test/Xor2Either.scala +++ b/scalafix-tests/input/src/main/scala/test/Xor2Either.scala @@ -1,14 +1,14 @@ /* rewrites = Xor2Either -*/ + */ package test import scala.concurrent.Future -import cats.data.{ Xor, XorT } +import cats.data.{Xor, XorT} trait Xor2Either { type MyDisjunction = Xor[Int, String] val r: MyDisjunction = Xor.Right.apply("") - val s: Xor[Int, String] = cats.data.Xor.Left(1 /* comment */) + val s: Xor[Int, String] = cats.data.Xor.Left(1 /* comment */ ) val t: Xor[Int, String] = r.map(_ + "!") val nest: Seq[Xor[Int, cats.data.Xor[String, Int]]] val u: XorT[Future, Int, String] = ??? diff --git a/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala b/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala index d3281783e..232eeb49d 100644 --- a/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala +++ b/scalafix-tests/output/src/main/scala/test/ExplicitReturnTypes.scala @@ -1,6 +1,6 @@ package test -object ExplicitReturnTypesInput { +object ExplicitReturnTypes { implicit val L: List[Int] = List(1) implicit val M: scala.collection.immutable.Map[Int, String] = Map(1 -> "STRING") implicit def D: Int = 2 @@ -14,7 +14,7 @@ object ExplicitReturnTypesInput { } class TwoClasses[T](e: T) class TwoClasses2 { - implicit val x: test.ExplicitReturnTypesInput.TwoClasses[Int] = new TwoClasses(10) + implicit val x: test.ExplicitReturnTypes.TwoClasses[Int] = new TwoClasses(10) } class implicitlytrick { implicit val s: String = "string" @@ -24,7 +24,7 @@ object ExplicitReturnTypesInput { object B { class C object C { - implicit val x: List[test.ExplicitReturnTypesInput.InnerInnerObject.B.C] = List(new C) + implicit val x: List[test.ExplicitReturnTypes.InnerInnerObject.B.C] = List(new C) } } } @@ -33,12 +33,12 @@ object ExplicitReturnTypesInput { } object A { class C { - implicit val x: List[test.ExplicitReturnTypesInput.SiblingObject.B] = List(new SiblingObject.B) + implicit val x: List[test.ExplicitReturnTypes.SiblingObject.B] = List(new SiblingObject.B) } } object slick { case class Supplier(id: Int, name: String) - implicit val supplierGetter: ((Int, String)) => test.ExplicitReturnTypesInput.slick.Supplier = (arg: (Int, String)) => + implicit val supplierGetter: ((Int, String)) => test.ExplicitReturnTypes.slick.Supplier = (arg: (Int, String)) => Supplier(arg._1, arg._2) } } diff --git a/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala b/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala index e3c348a56..281b1e48f 100644 --- a/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala +++ b/scalafix-tests/output/src/main/scala/test/ProcedureSyntax.scala @@ -13,6 +13,5 @@ object ProcedureSyntax { def foo: Unit = { println(1) } - def main(): Unit = /* unit */ { - } + def main(): Unit = /* unit */ {} } diff --git a/scalafix-tests/output/src/main/scala/test/Xor2Either.scala b/scalafix-tests/output/src/main/scala/test/Xor2Either.scala index 03a8fdc15..f92d2fb2e 100644 --- a/scalafix-tests/output/src/main/scala/test/Xor2Either.scala +++ b/scalafix-tests/output/src/main/scala/test/Xor2Either.scala @@ -7,7 +7,7 @@ import scala.concurrent.Future trait Xor2Either { type MyDisjunction = Either[Int, String] val r: MyDisjunction = Right("") - val s: Either[Int, String] = Left(1 /* comment */) + val s: Either[Int, String] = Left(1 /* comment */ ) val t: Either[Int, String] = r.map(_ + "!") val nest: Seq[Either[Int, Either[String, Int]]] val u: EitherT[Future, Int, String] = ??? diff --git a/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala b/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala index 3f85af5c4..2eb63d3f5 100644 --- a/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala +++ b/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala @@ -3,28 +3,6 @@ package scalafix.tests import scalafix.rewrite.ProcedureSyntax import scalafix.rewrite.ScalaJsRewrites -class Akka - extends IntegrationPropertyTest( - ItTest( - name = "akka", - repo = "https://github.com/akka/akka.git", - hash = "3936883e9ae9ef0f7a3b0eaf2ccb4c0878fcb145", - rewrites = Seq() - ), - skip = true - ) - -class Circe - extends IntegrationPropertyTest( - ItTest( - name = "circe", - repo = "https://github.com/circe/circe.git", - hash = "717e1d7d5d146cbd0455770771261e334f419b14", - rewrites = Seq() - ), - skip = true - ) - class Slick extends IntegrationPropertyTest( ItTest( @@ -36,110 +14,3 @@ class Slick ), skip = false ) - -class Scalaz - extends IntegrationPropertyTest( - ItTest( - name = "scalaz", - repo = "https://github.com/scalaz/scalaz.git", - hash = "cba156fb2f1f178dbaa32cbca21e95f8199d2f91" - ), - skip = true // kind-projector causes problems. - ) - -class Cats - extends IntegrationPropertyTest( - ItTest( - name = "cats", - repo = "https://github.com/typelevel/cats.git", - config = ItTest.catsImportConfig, - hash = "31080daf3fd8c6ddd80ceee966a8b3eada578198" - ), - skip = true - ) - -class Monix - extends IntegrationPropertyTest( - ItTest( - name = "monix", - repo = "https://github.com/monix/monix.git", - hash = "45c15b5989685668f5ad7ec886af6b74b881a7b4" - ), - // monix fails on reporter info messages and scala.meta has a parser bug. - // Pipe.scala:32: error: identifier expected but ] found - // [error] extends ObservableLike[O, ({type ?[+?] = Pipe[I, ?]})#?] { - skip = true - ) - -class ScalaJs - extends IntegrationPropertyTest( - ItTest( - name = "Scala.js", - repo = "https://github.com/scala-js/scala-js.git", - hash = "8917b5a9bd8fb2175a112fc15c761050eeb4099f", - commands = Seq( - Command("set scalafixEnabled in Global := true"), - Command("compiler/test:compile"), - Command("examples/test:compile") - ) - ), - skip = true // GenJsCode is hard: import renames + dependent types - ) - -class ScalacheckShapeless - extends IntegrationPropertyTest( - ItTest( - name = "scalacheck-shapeless", - repo = "https://github.com/alexarchambault/scalacheck-shapeless.git", - hash = "bb25ecee23c42148f66d9b27920a89ba5cc189d2", - addCoursier = false - ), - skip = true // coursier can't resolve locally published snapshot on ci, sbt.ivy.home is not read. - ) - -class ScalafixIntegrationTest - extends IntegrationPropertyTest( - ItTest( - name = "scalafix", - repo = "https://github.com/scalacenter/scalafix.git", - hash = "69069ff8d028f9fc553fac62c28b3d4eb6707bcb", - rewrites = Nil, - commands = Seq( - Command.clean, - Command.enableScalafix, - Command("scalafix-nsc/test:compile"), - Command.disableScalafix - ), - addCoursier = false - ), - skip = true - ) - -class ScalajsBootstrap - extends IntegrationPropertyTest( - ItTest( - name = "scalajs-bootstrap", - repo = "https://github.com/Karasiq/scalajs-bootstrap.git", - hash = "1cf125a8f78951df9a1a274f19b81221e55ad4bd", - rewrites = List("DemandJSGlobal"), - commands = Seq( - Command("scalafix") - ) - ), - skip = true - ) - -class ScalajsSri - extends IntegrationPropertyTest( - ItTest( - name = "sri", - repo = "https://github.com/chandu0101/sri.git", - hash = "2526f0574f7ef8088f209ff50d38f72c458e0a62", - rewrites = List("DemandJSGlobal"), - config = "imports.organize = false", - commands = Seq( - Command("scalafix") - ) - ), - skip = true - ) From 00d2e3253cc2bda9f88dd02dbbb620565adfc78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 00:37:54 +0200 Subject: [PATCH 06/14] Try out travis. --- .travis.yml | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index dfd18db08..07983ac58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,28 @@ language: scala -sudo: false -cache: - directories: - - $HOME/.ivy2/cache - - $HOME/.sbt/boot/ -git: - submodules: false -scala: - - 2.11.8 -before_install: - - ./bin/setupCI.sh script: - - ./bin/testAll.sh -after_success: - - codecov + - ./bin/runci.sh jdk: - - oraclejdk7 -notifications: - email: - - olafurpg@gmail.com -branches: - only: - - master + - oraclejdk8 +env: + matrix: + - CI_TEST: ci-fast + CI_SCALA_VERSION: 2.11.11 + CI_PUBLISH: true + - CI_TEST: ci-fast + CI_SCALA_VERSION: 2.12.2 + - CI_TEST: ci-slow + CI_SCALA_VERSION: 2.11.11 + - CI_TEST: scalafmt + +cache: + directories: + - $HOME/.sbt/0.13/dependency + - $HOME/.sbt/boot/scala* + - $HOME/.sbt/launchers + - $HOME/.ivy2/cache +before_cache: + - du -h -d 1 $HOME/.ivy2/cache + - du -h -d 2 $HOME/.sbt/ + - find $HOME/.sbt -name "*.lock" -type f -delete + - find $HOME/.ivy2/cache -name "ivydata-*.properties" -type f -delete From ee582de56cbad7547342df359f3522a190ffa00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 00:41:35 +0200 Subject: [PATCH 07/14] Fix .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 07983ac58..909f131ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: scala script: - - ./bin/runci.sh + - ./bin/runci.sh $CI_TEST jdk: - oraclejdk8 env: @@ -20,6 +20,7 @@ cache: - $HOME/.sbt/boot/scala* - $HOME/.sbt/launchers - $HOME/.ivy2/cache + - $HOME/.coursier before_cache: - du -h -d 1 $HOME/.ivy2/cache From 751dfbe087814e0be31af27372b938e1c666b66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 00:47:54 +0200 Subject: [PATCH 08/14] Fix ONLY check --- .../main/scala/scalafix/testkit/SemanticRewriteSuite.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala index 8a5d83141..8849cb099 100644 --- a/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala +++ b/scalafix-testkit/src/main/scala/scalafix/testkit/SemanticRewriteSuite.scala @@ -33,8 +33,8 @@ abstract class SemanticRewriteSuite( } override def afterAll(): Unit = { - val onlyTests = testsToRun.filter(_.isOnly) - if (sys.env.contains("CI") && testsToRun.nonEmpty) { + val onlyTests = testsToRun.filter(_.isOnly).toList + if (sys.env.contains("CI") && onlyTests.nonEmpty) { sys.error( s"sys.env('CI') is set and the following tests are marked as ONLY: " + s"${onlyTests.map(_.filename).mkString(", ")}") From 65d62e242187a1165cda5350344ad48a3f47cebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 00:56:17 +0200 Subject: [PATCH 09/14] Move integration tests to their right home. --- build.sbt | 1 + .../scala/scalafix/tests/ProjectTests.scala | 1 - .../scalafix/tests/URLConfiguration.scala | 21 +++++++++++++++++ .../scalafix/tests/URLConfiguration.scala | 23 ------------------- 4 files changed, 22 insertions(+), 24 deletions(-) rename scalafix-tests/{unit => integration}/src/it/scala/scalafix/tests/ProjectTests.scala (90%) create mode 100644 scalafix-tests/integration/src/it/scala/scalafix/tests/URLConfiguration.scala delete mode 100644 scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala diff --git a/build.sbt b/build.sbt index 2260b8935..a00df4d66 100644 --- a/build.sbt +++ b/build.sbt @@ -21,6 +21,7 @@ commands += Command.command("release") { s => commands += CiCommand("ci-fast")("test" :: Nil) commands += Command.command("ci-slow") { s => "scalafix-sbt/it:test" :: + "integration/it:test" :: s } commands += Command.command("ci-publish") { s => diff --git a/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala b/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala similarity index 90% rename from scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala rename to scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala index 2eb63d3f5..fb0271bbe 100644 --- a/scalafix-tests/unit/src/it/scala/scalafix/tests/ProjectTests.scala +++ b/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala @@ -1,7 +1,6 @@ package scalafix.tests import scalafix.rewrite.ProcedureSyntax -import scalafix.rewrite.ScalaJsRewrites class Slick extends IntegrationPropertyTest( diff --git a/scalafix-tests/integration/src/it/scala/scalafix/tests/URLConfiguration.scala b/scalafix-tests/integration/src/it/scala/scalafix/tests/URLConfiguration.scala new file mode 100644 index 000000000..2ff8926b0 --- /dev/null +++ b/scalafix-tests/integration/src/it/scala/scalafix/tests/URLConfiguration.scala @@ -0,0 +1,21 @@ +package scalafix.tests + +import scala.meta.semantic.Database +import scalafix.reflect.ScalafixCompilerDecoder +import metaconfig.Conf +import org.scalatest.FunSuite + +class URLConfiguration extends FunSuite { + import scalafix.config.ScalafixConfig + val url = + "https://gist.githubusercontent.com/olafurpg/fc6f43a695ac996bd02000f45ed02e63/raw/193f22e4e2aa624c90fe2ac3bb530b025e104a69/ExampleRewrite.scala" + test("compile from URL works") { + + val mirror = Some(Database(Nil)) + val obtained = + ScalafixCompilerDecoder + .fromMirrorOption(mirror) + .read(Conf.Str(url)) + assert(obtained.get.name.contains("Rewrite2")) + } +} diff --git a/scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala b/scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala deleted file mode 100644 index 212802fda..000000000 --- a/scalafix-tests/unit/src/it/scala/scalafix/tests/URLConfiguration.scala +++ /dev/null @@ -1,23 +0,0 @@ -package scalafix.tests - -import scalafix.testkit._ - -class URLConfiguration - extends SemanticRewriteSuite(SemanticRewriteSuite.thisClasspath) { - import scalafix.config.ScalafixConfig - val url = - "https://gist.githubusercontent.com/olafurpg/fc6f43a695ac996bd02000f45ed02e63/raw/193f22e4e2aa624c90fe2ac3bb530b025e104a69/ExampleRewrite.scala" - val code = - s""" - |rewrites = [ - | "$url" - |] - |<<< NOWRAP basic - |object Name - |>>> - |import scala.collection.immutable.Seq - |object Name1 - | - """.stripMargin - DiffTest("url", code, "UrlRewrite.stat").foreach(runDiffTest) -} From 013552d5263f30066116c28fc39f04eeeca6217f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 01:07:17 +0200 Subject: [PATCH 10/14] Skip publishLocal in integration/it:test --- .travis.yml | 1 + build.sbt | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 909f131ec..a679670de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,3 +27,4 @@ before_cache: - du -h -d 2 $HOME/.sbt/ - find $HOME/.sbt -name "*.lock" -type f -delete - find $HOME/.ivy2/cache -name "ivydata-*.properties" -type f -delete + - find $HOME/.ivy2/cache -name "*scalafix*.xml" -type f -delete diff --git a/build.sbt b/build.sbt index a00df4d66..a72e84c32 100644 --- a/build.sbt +++ b/build.sbt @@ -306,12 +306,7 @@ lazy val integration = project allSettings, noPublish, Defaults.itSettings, - libraryDependencies += scalatest % IntegrationTest, - test.in(IntegrationTest) := RunSbtCommand( - s"; plz $scala212 publishLocal " + - s"; such scalafix-sbt/publishLocal " + - "; tests/it:testQuick" // hack to workaround cyclic dependencies in test. - )(state.value) + libraryDependencies += scalatest % IntegrationTest ) .dependsOn( testsInput % Scalameta, From ab88156ee4075d7255e48a237e688889acc433cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Fri, 26 May 2017 01:48:57 +0200 Subject: [PATCH 11/14] Remove ivy2/local --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a679670de..8db507638 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,3 +28,4 @@ before_cache: - find $HOME/.sbt -name "*.lock" -type f -delete - find $HOME/.ivy2/cache -name "ivydata-*.properties" -type f -delete - find $HOME/.ivy2/cache -name "*scalafix*.xml" -type f -delete + - rm -rf $HOME/.ivy2/local From 152e97119bc3d491ea5ad45232862dc6f32d1200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Sat, 27 May 2017 14:54:21 +0200 Subject: [PATCH 12/14] Update integration tests for ExplicitReturnTypes --- build.sbt | 13 ++++++++++++- scalafix-cli/src/main/scala/scalafix/cli/Cli.scala | 1 - .../src/main/scala/scalafix/cli/CliRunner.scala | 5 +++-- .../scala/scalafix/rewrite/ScalafixRewrites.scala | 3 ++- .../main/scala/scalafix/sbt/ScalafixPlugin.scala | 4 +++- .../src/it/scala/scalafix/tests/ProjectTests.scala | 7 ++++++- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index a72e84c32..fc4dedaba 100644 --- a/build.sbt +++ b/build.sbt @@ -186,7 +186,7 @@ lazy val `scalafix-sbt` = project ScriptedPlugin.scriptedSettings, sbtPlugin := true, testQuick := {}, // these test are slow. - test in IntegrationTest := { + test.in(IntegrationTest) := { RunSbtCommand( s"; plz $scala212 publishLocal " + "; very scalafix-sbt/scripted" @@ -306,6 +306,17 @@ lazy val integration = project allSettings, noPublish, Defaults.itSettings, + test.in(IntegrationTest) := { + test + .in(IntegrationTest) + .dependsOn( + publishLocal.in(core), + publishLocal.in(cli), + publishLocal.in(reflect), + publishLocal.in(`scalafix-sbt`) + ) + .value + }, libraryDependencies += scalatest % IntegrationTest ) .dependsOn( diff --git a/scalafix-cli/src/main/scala/scalafix/cli/Cli.scala b/scalafix-cli/src/main/scala/scalafix/cli/Cli.scala index fd2ea77e3..7d77b2926 100644 --- a/scalafix-cli/src/main/scala/scalafix/cli/Cli.scala +++ b/scalafix-cli/src/main/scala/scalafix/cli/Cli.scala @@ -11,7 +11,6 @@ import metaconfig.Configured.NotOk import metaconfig.Configured.Ok object Cli { - val emptyDatabase = Database(Nil) import ArgParserImplicits._ private val withHelp = OptionsMessages.withHelp val helpMessage: String = withHelp.helpMessage + diff --git a/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala b/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala index 16e5fb950..3a38807b7 100644 --- a/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala +++ b/scalafix-cli/src/main/scala/scalafix/cli/CliRunner.scala @@ -25,6 +25,7 @@ import scalafix.config.ScalafixConfig import scalafix.config.ScalafixReporter import scalafix.reflect.ScalafixCompilerDecoder import scalafix.reflect.ScalafixToolbox +import scalafix.rewrite.ScalafixRewrites import scalafix.syntax._ import metaconfig.Configured.Ok import metaconfig._ @@ -181,11 +182,11 @@ object CliRunner { s"Missing --classpath, cannot use --sourcepath $sp without --classpath") .notOk case (None, None) => - Ok(Cli.emptyDatabase) + Ok(ScalafixRewrites.emptyDatabase) } val resolvedMirror: Configured[Option[Database]] = resolvedDatabase.map { x => - if (x == Cli.emptyDatabase) None else Some(x) + if (x == ScalafixRewrites.emptyDatabase) None else Some(x) } // Inputs diff --git a/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala b/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala index 3e2a88dfa..9f07602a6 100644 --- a/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala +++ b/scalafix-core/src/main/scala/scalafix/rewrite/ScalafixRewrites.scala @@ -22,5 +22,6 @@ object ScalafixRewrites { all(mirror).map(x => x.name -> x).toMap lazy val syntaxName2rewrite: Map[String, Rewrite] = syntax.map(x => x.name -> x).toMap - lazy val semanticNames: List[String] = semantic(Database(Nil)).map(_.name) + val emptyDatabase = Database(Nil) + lazy val semanticNames: List[String] = semantic(emptyDatabase).map(_.name) } diff --git a/scalafix-sbt/src/main/scala/scalafix/sbt/ScalafixPlugin.scala b/scalafix-sbt/src/main/scala/scalafix/sbt/ScalafixPlugin.scala index 55db308f3..476eee66d 100644 --- a/scalafix-sbt/src/main/scala/scalafix/sbt/ScalafixPlugin.scala +++ b/scalafix-sbt/src/main/scala/scalafix/sbt/ScalafixPlugin.scala @@ -111,7 +111,9 @@ object ScalafixPlugin extends AutoPlugin { Def.taskDyn(compile.all(scalahostAggregateFilter.value)) private[scalafix] implicit class XtensionFormatClasspath(paths: Seq[File]) { def asPath: String = - paths.map(_.getAbsolutePath).mkString(java.io.File.pathSeparator) + paths.toIterator + .collect { case f if f.exists() => f.getAbsolutePath } + .mkString(java.io.File.pathSeparator) } } diff --git a/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala b/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala index fb0271bbe..9ea603bfa 100644 --- a/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala +++ b/scalafix-tests/integration/src/it/scala/scalafix/tests/ProjectTests.scala @@ -1,13 +1,18 @@ package scalafix.tests +import scala.meta.semantic.Database +import scalafix.rewrite.ExplicitReturnTypes import scalafix.rewrite.ProcedureSyntax +import scalafix.rewrite.ScalafixRewrites class Slick extends IntegrationPropertyTest( ItTest( name = "slick", repo = "https://github.com/slick/slick.git", - rewrites = Seq(ProcedureSyntax.toString, "ExplicitImplicit"), + rewrites = + Seq(ProcedureSyntax.name, + ExplicitReturnTypes(ScalafixRewrites.emptyDatabase).name), hash = "bd3c24be419ff2791c123067668c81e7de858915", addCoursier = false ), From 25e2e79c9279f47d49cfa4f4e824a48d3d46a067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Sat, 27 May 2017 15:00:07 +0200 Subject: [PATCH 13/14] Add .jvmopts file. --- .jvmopts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .jvmopts diff --git a/.jvmopts b/.jvmopts new file mode 100644 index 000000000..6ac9d80a5 --- /dev/null +++ b/.jvmopts @@ -0,0 +1,11 @@ +-Dfile.encoding=UTF8 +-Xms1G +-Xmx6G +-XX:MaxPermSize=512M +-XX:ReservedCodeCacheSize=250M +-XX:+TieredCompilation +-XX:-UseGCOverheadLimit +# effectively adds GC to Perm space +-XX:+CMSClassUnloadingEnabled +# must be enabled for CMSClassUnloadingEnabled to work +-XX:+UseConcMarkSweepGC From b05808a62bd467fa1b125e93060c13911bc45c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Sat, 27 May 2017 15:03:06 +0200 Subject: [PATCH 14/14] Disable heavy integration tests running scalafix on community projects. Travis CI kills the jobs. Those tests only run a subset of rewrites anyways. Those tests are incredibly handy for manual testing, less so for automated CI on every PR commit. --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index fc4dedaba..96aa2635b 100644 --- a/build.sbt +++ b/build.sbt @@ -21,7 +21,6 @@ commands += Command.command("release") { s => commands += CiCommand("ci-fast")("test" :: Nil) commands += Command.command("ci-slow") { s => "scalafix-sbt/it:test" :: - "integration/it:test" :: s } commands += Command.command("ci-publish") { s =>