Skip to content

Commit 563f6b4

Browse files
committed
enhance ImplicitValueClasses rule to prevent implicit classes from being derived value classes and add corresponding tests
1 parent 1856639 commit 563f6b4

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

analyzer/src/main/scala/com/avsystem/commons/analyzer/ImplicitValueClasses.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ class ImplicitValueClasses(g: Global) extends AnalyzerRule(g, "implicitValueClas
2828

2929
cls != cd.symbol && !isDefault && !isUniversalTrait
3030
}
31-
def hasExactlyOneParam = paramLists.forall(lists => lists.size == 1 && lists.head.size == 1)
31+
def hasExactlyOneParam = paramLists.exists(lists => lists.size == 1 && lists.head.size == 1)
3232

33-
if (!inheritsAnyVal && !inheritsOtherClass && hasExactlyOneParam) {
33+
def paramIsValueClass = paramLists.exists { lists =>
34+
/* lists.nonEmpty && lists.head.nonEmpty && */
35+
lists.head.head.typeSignature.typeSymbol.isDerivedValueClass
36+
}
37+
38+
if (!inheritsAnyVal && !inheritsOtherClass && hasExactlyOneParam && !paramIsValueClass) {
3439
val isNestedClass =
3540
//implicit classes are always nested classes, so we want to check if the outer class's an object
3641
/*cd.symbol.isNestedClass &&*/ !cd.symbol.isStatic

analyzer/src/test/scala/com/avsystem/commons/analyzer/ImplicitValueClassesTest.scala

+19
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,26 @@ class ImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
112112
|}
113113
""".stripMargin)
114114
}
115+
116+
test("implicit class for value class should not be affected") {
117+
assertNoErrors(
118+
//language=Scala
119+
"""
120+
|object whatever {
121+
| implicit final class ValueClass(x: com.avsystem.commons.misc.Timestamp) {
122+
| def sth: Long = x.millis
123+
| }
124+
|}
125+
""".stripMargin)
126+
}
115127
}
116128

117129
class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
118130
settings.pluginOptions.value ++= List("AVSystemAnalyzer:+implicitValueClasses:true")
119131

120132
test("nested implicit class not extending AnyVal should fail") {
121133
assertErrors(1,
134+
//language=Scala
122135
"""
123136
|object whatever {
124137
| class Outer {
@@ -134,6 +147,8 @@ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
134147
test("nested implicit class with type parameter not extending AnyVal should fail") {
135148
assertErrors(1,
136149
"""
150+
| //language=Scala
151+
|
137152
|object whatever {
138153
| class Outer {
139154
| implicit final class BadNestedImplicitClass[T <: Int](val x: T) {
@@ -146,6 +161,7 @@ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
146161

147162
test("deeply nested implicit class not extending AnyVal should fail") {
148163
assertErrors(1,
164+
//language=Scala
149165
"""
150166
|object whatever {
151167
| class Outer {
@@ -161,6 +177,7 @@ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
161177

162178
test("regular class should not be affected") {
163179
assertNoErrors(
180+
//language=Scala
164181
"""
165182
|object whatever {
166183
| class Outer {
@@ -174,6 +191,7 @@ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
174191

175192
test("implicit class extending other classes should not be affected") {
176193
assertNoErrors(
194+
//language=Scala
177195
"""
178196
|object whatever {
179197
| class Outer {
@@ -194,6 +212,7 @@ class NestedImplicitValueClassesSuite extends AnyFunSuite with AnalyzerTest {
194212

195213
test("implicit class extending AnyVal with traits should be handled correctly") {
196214
assertErrors(1,
215+
//language=Scala
197216
"""
198217
|object whatever {
199218
| class Outer {

0 commit comments

Comments
 (0)