From 1c5572624cc76d0ba2f34a21d6a49ca9e98a9250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bu=CC=80i=20Vie=CC=A3=CC=82t=20Tha=CC=80nh?= Date: Sat, 27 Jun 2020 23:01:43 +0700 Subject: [PATCH] ExplicitResultTypes: Add (Skip)LocalImplicits tests. Ref #1180 --- .../internal/rule/CompilerTypePrinter.scala | 12 ++++++----- .../internal/rule/ExplicitResultTypes.scala | 12 +++++------ .../explicitResultTypes/LocalImplicits.scala | 20 +++++++++++++++++++ .../SkipLocalImplicits.scala | 19 ++++++++++++++++++ .../explicitResultTypes/LocalImplicits.scala | 16 +++++++++++++++ .../SkipLocalImplicits.scala | 16 +++++++++++++++ .../tests/ExplicitResultTypesRefinement.scala | 2 +- .../src/main/scala/tests/RscCompat.scala | 2 +- 8 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 scalafix-tests/input/src/main/scala/test/explicitResultTypes/LocalImplicits.scala create mode 100644 scalafix-tests/input/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala create mode 100644 scalafix-tests/output/src/main/scala/test/explicitResultTypes/LocalImplicits.scala create mode 100644 scalafix-tests/output/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala diff --git a/scalafix-rules/src/main/scala/scalafix/internal/rule/CompilerTypePrinter.scala b/scalafix-rules/src/main/scala/scalafix/internal/rule/CompilerTypePrinter.scala index 5d2a9c5c60..7df5b3d38e 100644 --- a/scalafix-rules/src/main/scala/scalafix/internal/rule/CompilerTypePrinter.scala +++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/CompilerTypePrinter.scala @@ -45,11 +45,13 @@ class CompilerTypePrinter(g: ScalafixGlobal, config: ExplicitResultTypesConfig)( space: String ): Option[v1.Patch] = { val gpos = unit.position(pos.start) - GlobalProxy.typedTreeAt(g, gpos) - val inverseSemanticdbSymbol = g - .inverseSemanticdbSymbols(sym.value) - .find(s => g.semanticdbSymbol(s) == sym.value) - .getOrElse(g.NoSymbol) + val tpe = GlobalProxy.typedTreeAt(g, gpos) + val inverseSemanticdbSymbol = + if (sym.isLocal) tpe.symbol + else + g.inverseSemanticdbSymbols(sym.value) + .find(s => g.semanticdbSymbol(s) == sym.value) + .getOrElse(g.NoSymbol) val hasNothing = inverseSemanticdbSymbol.info.exists { case g.definitions.NothingTpe => true case _ => false diff --git a/scalafix-rules/src/main/scala/scalafix/internal/rule/ExplicitResultTypes.scala b/scalafix-rules/src/main/scala/scalafix/internal/rule/ExplicitResultTypes.scala index 8d809af71d..59fa03e05f 100644 --- a/scalafix-rules/src/main/scala/scalafix/internal/rule/ExplicitResultTypes.scala +++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/ExplicitResultTypes.scala @@ -138,12 +138,12 @@ final class ExplicitResultTypes( case _: Defn.Var => MemberKind.Var } - def isRuleCandidate[D <: Defn]( - defn: D, + def isRuleCandidate( + defn: Defn, nm: Name, mods: Iterable[Mod], body: Term - )(implicit ev: Extract[D, Mod], ctx: SemanticDocument): Boolean = { + )(implicit ctx: SemanticDocument): Boolean = { import config._ def matchesMemberVisibility(): Boolean = @@ -161,18 +161,18 @@ final class ExplicitResultTypes( config.skipSimpleDefinitions.isSimpleDefinition(body) def isImplicit: Boolean = - defn.hasMod(mod"implicit") && !isImplicitly(body) + mods.exists(_.is[Mod.Implicit]) && !isImplicitly(body) def hasParentWihTemplate: Boolean = defn.parent.exists(_.is[Template]) def isLocal: Boolean = - if (config.skipLocalImplicits) nm.symbol.isLocal + if (config.skipLocalImplicits) nm.symbol.isLocal && !hasParentWihTemplate else false isImplicit && !isFinalLiteralVal && !isLocal || { hasParentWihTemplate && - !defn.hasMod(mod"implicit") && + !mods.exists(_.is[Mod.Implicit]) && !matchesSimpleDefinition() && matchesMemberKind() && matchesMemberVisibility() diff --git a/scalafix-tests/input/src/main/scala/test/explicitResultTypes/LocalImplicits.scala b/scalafix-tests/input/src/main/scala/test/explicitResultTypes/LocalImplicits.scala new file mode 100644 index 0000000000..64bea76a41 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/explicitResultTypes/LocalImplicits.scala @@ -0,0 +1,20 @@ +/* +rule = ExplicitResultTypes +ExplicitResultTypes.skipLocalImplicits = false +*/ +package test.explicitResultTypes + +class LocalImplicits { + trait T + def f(): T = new T { + implicit val i = 1 + } + def g(): Unit = { + class C { + implicit val i = 2 + } + } + def h(): Unit = { + implicit val i = 3 + } +} diff --git a/scalafix-tests/input/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala b/scalafix-tests/input/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala new file mode 100644 index 0000000000..a956f04837 --- /dev/null +++ b/scalafix-tests/input/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala @@ -0,0 +1,19 @@ +/* +rule = ExplicitResultTypes +*/ +package test.explicitResultTypes + +class SkipLocalImplicits { + trait T + def f(): T = new T { + implicit val i = 1 + } + def g(): Unit = { + class C { + implicit val i = 2 + } + } + def h(): Unit = { + implicit val i = 3 + } +} diff --git a/scalafix-tests/output/src/main/scala/test/explicitResultTypes/LocalImplicits.scala b/scalafix-tests/output/src/main/scala/test/explicitResultTypes/LocalImplicits.scala new file mode 100644 index 0000000000..bc74fbceae --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/explicitResultTypes/LocalImplicits.scala @@ -0,0 +1,16 @@ +package test.explicitResultTypes + +class LocalImplicits { + trait T + def f(): T = new T { + implicit val i: Int = 1 + } + def g(): Unit = { + class C { + implicit val i: Int = 2 + } + } + def h(): Unit = { + implicit val i: Int = 3 + } +} diff --git a/scalafix-tests/output/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala b/scalafix-tests/output/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala new file mode 100644 index 0000000000..4eb7be1413 --- /dev/null +++ b/scalafix-tests/output/src/main/scala/test/explicitResultTypes/SkipLocalImplicits.scala @@ -0,0 +1,16 @@ +package test.explicitResultTypes + +class SkipLocalImplicits { + trait T + def f(): T = new T { + implicit val i: Int = 1 + } + def g(): Unit = { + class C { + implicit val i: Int = 2 + } + } + def h(): Unit = { + implicit val i = 3 + } +} diff --git a/scalafix-tests/output/src/main/scala/tests/ExplicitResultTypesRefinement.scala b/scalafix-tests/output/src/main/scala/tests/ExplicitResultTypesRefinement.scala index 81fc64d121..b95532ebba 100644 --- a/scalafix-tests/output/src/main/scala/tests/ExplicitResultTypesRefinement.scala +++ b/scalafix-tests/output/src/main/scala/tests/ExplicitResultTypesRefinement.scala @@ -51,7 +51,7 @@ object ExplicitResultTypesRefinement { } trait Chars { def chars: CharSequence } val chars: Chars = new Chars { - val chars = 42.toString() + val chars: String = 42.toString() } def app(): Unit = { println(field.results) diff --git a/scalafix-tests/output/src/main/scala/tests/RscCompat.scala b/scalafix-tests/output/src/main/scala/tests/RscCompat.scala index 7c514c2859..cc591452ad 100644 --- a/scalafix-tests/output/src/main/scala/tests/RscCompat.scala +++ b/scalafix-tests/output/src/main/scala/tests/RscCompat.scala @@ -179,7 +179,7 @@ object RscCompat_Test { val more2: more2 = new more2 class more2 extends { def foo(implicit x: Int, y: Int) = 42 } val more3: more3 = new more3 - class more3 extends { implicit def bar = 42 } + class more3 extends { implicit def bar: Int = 42 } implicit val crazy1 = implicitly[Int] implicit val crazy2: Bijection[In,Out1] = Bijection.connect[In, Out1]