-
Notifications
You must be signed in to change notification settings - Fork 87
Make the breakOut rewrite rule cross compatible (fix #80) (fix #93) #102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a082870
to
765943b
Compare
|
||
val patchSpecificCollection = | ||
toCollection match { | ||
case "scala.collection.immutable.Map" => ctx.addRight(ap0, ".toMap") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@julienrf do you have more cases in mind where xs.to(C) is not cross compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any type constructor which has a kind different from * -> *
. For instance, SortedMap
, TreeMap
, HashMap
.
However, there are no toSortedMap
or toTreeMap
methods that we can use…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it safe to cast to the target collection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also: IntMap
patchSpecificCollection | ||
} | ||
|
||
def extractColFromBreakout(breakout: Tree): Term = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the trick I found.
import scala.reflect.runtime.universe._
reify { List(1).map(identity)(scala.collection.breakOut): Set[Int] }
List.apply(1).map(identity)(breakOut(Set.canBuildFrom)): Set[Int]
// ^^^ available in synthetics
765943b
to
67511b2
Compare
CI should be green, we are getting the same Scala.js runner error: https://travis-ci.org/scala/scala-collection-compat/jobs/405370378#L637 @sjrd does this stack trace ring a bell?
|
Looks like scala-js/scala-js#3408 |
67511b2
to
3c382a5
Compare
|
||
val `TraversableLike ++` = Symbol("_root_.scala.collection.TraversableLike#`++`(Lscala/collection/GenTraversableOnce;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;.") | ||
val `Vector ++` = Symbol("_root_.scala.collection.immutable.Vector#`++`(Lscala/collection/GenTraversableOnce;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;.") | ||
val `List ++` = Symbol("_root_.scala.collection.immutable.List#`++`(Lscala/collection/GenTraversableOnce;Lscala/collection/generic/CanBuildFrom;)Ljava/lang/Object;.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be TraversableLike. The way symbols work in scalafix right now is similar to go-to-definition in an IDE, It will hit the most concrete class first. @olafurpg Is there a way only to hit the base class?
3c382a5
to
7312b59
Compare
// == rule == | ||
def apply(ctx: RuleCtx): Patch = { | ||
|
||
var requiresCompatImport = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we only use .toMap
we don't need the compat import.
ab8f965
to
b8c613a
Compare
I just successfully removed breakout from Akka: akka/akka@3be0535 |
@julienrf this one is good to go. CI is green, works on akka codebase. |
import scala.collection.{immutable => i, mutable => m} | ||
|
||
class TraversableOnceKVExtensionMethods[K, V](private val self: TraversableOnce[(K, V)]) extends AnyVal { | ||
def toImmutableSortedMap(implicit ordering: Ordering[K]): i.SortedMap[K, V] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m on the fence. I think we should only try to provide the 2.13 syntax on 2.11 and 2.12, but we shouldn’t try to introduce new operations. Why can’t to(immutable.SortedMap)
cross-compile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because to
returns Coll[A]
, in the case of SortedMap
it returns a Iterable[(K, V)]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I remember this one. Then I guess we have to write immutable.SortedMap.from(List(1 -> "1").map(x => x))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not cross-compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be, with import scala.collection.compat._
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some ToCBF are missing, I will implement them and fix: #103
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no CBF instance involved in that code. We should just enrich the immutable.SortedMap
object with a from
operation, like we previously did: https://github.com/scala/scala-collection-compat/blob/master/compat/src/main/scala-2.11_2.12/scala/collection/compat/package.scala#L36
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this is a good idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not create an intermediate collection?
implicit class IterableFactoryExtensionMethods[CC[X] <: GenTraversable[X]](private val fact: GenericCompanion[CC]) {
def from[A](source: TraversableOnce[A]): CC[A] = fact.apply(source.toSeq: _*)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the .toSeq
call does create an intermediate collection :-/
@Test | ||
def t(): Unit = { | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the purpose of this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an empty test you can use as a sandbox. I keep finding myself to add it back locally, It's useful to have it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this a bit weird. Can’t you just have it locally if you only use it during development?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we keep it, it would save me some time when I want to test something quick or if I need to create another unit test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t understand why you can’t keep it locally only.
|
||
object Playground { | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is an oversight?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, it's useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this file testing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no testOnly in scalafix-testkit. I mimic this with: https://github.com/scala/scala-collection-compat/blob/master/scalafix/tests/src/test/scala/fix/ScalafixTests.scala#L20
cd3f48e
to
df2f4a2
Compare
df2f4a2
to
4f8d74b
Compare
@julienrf ready for round 2. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks!
@@ -1,25 +1,108 @@ | |||
/* | |||
rule = "scala:fix.NewCollections" | |||
rule = "scala:fix.CrossCompat" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
No description provided.