@@ -8,19 +8,21 @@ import scala.collection.mutable
8
8
9
9
object CanBuildFrom {
10
10
def apply (paramss : List [List [Term .Param ]],
11
- body : Term ,
11
+ stats : List [ Tree ] ,
12
12
ctx : RuleCtx ,
13
13
collectionCanBuildFrom : SymbolMatcher ,
14
14
nothing : SymbolMatcher )(implicit index : SemanticdbIndex ): Patch = {
15
15
// CanBuildFrom has def apply() but not CanBuild
16
16
def emptyApply (param : Name ): Boolean = {
17
17
import scala .meta .contrib ._
18
18
val matchCbf = SymbolMatcher .exact(ctx.index.symbol(param).get)
19
- body.exists {
20
- case Term .Apply (Term .Select (matchCbf(_), _), Nil ) => true
21
- case Term .Apply (matchCbf(_), Nil ) => true
22
- case _ => false
23
- }
19
+ stats.exists(
20
+ _.exists {
21
+ case Term .Apply (Term .Select (matchCbf(_), _), Nil ) => true
22
+ case Term .Apply (matchCbf(_), Nil ) => true
23
+ case _ => false
24
+ }
25
+ )
24
26
}
25
27
26
28
paramss.flatten
@@ -38,7 +40,7 @@ object CanBuildFrom {
38
40
) if ! nothing.matches(p1) && ! emptyApply(param) =>
39
41
new CanBuildFrom (param, cbf)
40
42
}
41
- .map(_.toBuildFrom(body , ctx))
43
+ .map(_.toBuildFrom(stats , ctx))
42
44
.asPatch
43
45
}
44
46
}
@@ -48,7 +50,7 @@ object CanBuildFrom {
48
50
// param: cbf
49
51
// cbf : collection.generic.CanBuildFrom
50
52
case class CanBuildFrom (param : Name , cbf : Type ) {
51
- def toBuildFrom (body : Term , ctx : RuleCtx )(implicit index : SemanticdbIndex ): Patch = {
53
+ def toBuildFrom (stats : List [ Tree ] , ctx : RuleCtx )(implicit index : SemanticdbIndex ): Patch = {
52
54
53
55
val matchCbf = SymbolMatcher .exact(ctx.index.symbol(param).get)
54
56
@@ -60,15 +62,17 @@ case class CanBuildFrom(param: Name, cbf: Type) {
60
62
)
61
63
62
64
val cbfCalls =
63
- body.collect {
64
- // cbf.apply(x)
65
- case ap @ Term .Apply (sel @ Term .Select (cbf2 @ matchCbf(_), apply), List (x)) =>
66
- replaceNewBuilder(ap, cbf2, x)
67
-
68
- // cbf(x)
69
- case ap @ Term .Apply (cbf2 @ matchCbf(_), List (x)) =>
70
- replaceNewBuilder(ap, cbf2, x)
71
- }.asPatch
65
+ stats
66
+ .map(_.collect {
67
+ // cbf.apply(x)
68
+ case ap @ Term .Apply (sel @ Term .Select (cbf2 @ matchCbf(_), apply), List (x)) =>
69
+ replaceNewBuilder(ap, cbf2, x)
70
+
71
+ // cbf(x)
72
+ case ap @ Term .Apply (cbf2 @ matchCbf(_), List (x)) =>
73
+ replaceNewBuilder(ap, cbf2, x)
74
+ }.asPatch)
75
+ .asPatch
72
76
73
77
val parameterType =
74
78
ctx.replaceTree(cbf, " BuildFrom" )
@@ -79,12 +83,13 @@ case class CanBuildFrom(param: Name, cbf: Type) {
79
83
80
84
object CanBuildFromNothing {
81
85
def apply (paramss : List [List [Term .Param ]],
82
- body : Term ,
86
+ stats : List [ Tree ] ,
83
87
ctx : RuleCtx ,
84
88
collectionCanBuildFrom : SymbolMatcher ,
85
89
nothing : SymbolMatcher ,
86
90
toTpe : SymbolMatcher ,
87
91
handledTo : mutable.Set [Tree ])(implicit index : SemanticdbIndex ): Patch = {
92
+
88
93
paramss.flatten
89
94
.collect {
90
95
case Term .Param (
@@ -96,16 +101,13 @@ object CanBuildFromNothing {
96
101
List (
97
102
nothing(_),
98
103
t,
99
- cct @ Type .Apply (
100
- cc,
101
- _
102
- )
104
+ toT
103
105
)
104
106
)
105
107
),
106
108
_
107
109
) =>
108
- new CanBuildFromNothing (param, tpe, t, cct, cc, body , ctx, toTpe, handledTo)
110
+ new CanBuildFromNothing (param, tpe, t, toT, stats , ctx, toTpe, handledTo)
109
111
}
110
112
.map(_.toFactory)
111
113
.asPatch
@@ -119,14 +121,12 @@ object CanBuildFromNothing {
119
121
// tpe : collection.generic.CanBuildFrom[Nothing, Int, CC[Int]]
120
122
// cbf : CanBuildFrom
121
123
// v : Int
122
- // cct : CC[Int]
123
- // cc : CC
124
+ // toT : CC[Int]
124
125
case class CanBuildFromNothing (param : Name ,
125
126
tpe : Type .Apply ,
126
127
t : Type ,
127
- cct : Type .Apply ,
128
- cc : Type ,
129
- body : Term ,
128
+ toT : Type ,
129
+ stats : List [Tree ],
130
130
ctx : RuleCtx ,
131
131
toTpe : SymbolMatcher ,
132
132
handledTo : mutable.Set [Tree ]) {
@@ -141,53 +141,61 @@ case class CanBuildFromNothing(param: Name,
141
141
val visitedCbfCalls = mutable.Set [Tree ]()
142
142
143
143
val cbfCalls =
144
- body.collect {
145
- // cbf.apply()
146
- case ap @ Term . Apply (sel @ Term . Select (cbf2 @ matchCbf(_), apply), Nil ) =>
147
- visitedCbfCalls += sel
148
- replaceNewBuilder(ap, cbf2)
149
-
150
- // cbf.apply
151
- case sel @ Term . Select (cbf2 @ matchCbf(_), ap) if ( ! visitedCbfCalls.contains(sel)) =>
152
- replaceNewBuilder( sel, cbf2)
153
-
154
- // cbf()
155
- case ap @ Term . Apply (cbf2 @ matchCbf(_), Nil ) =>
156
- replaceNewBuilder(ap, cbf2)
157
- }.asPatch
158
-
159
- val matchCC = SymbolMatcher .exact(ctx.index.symbol(cc).get)
144
+ stats
145
+ .map(_.collect {
146
+ // cbf.apply()
147
+ case ap @ Term . Apply ( sel @ Term . Select (cbf2 @ matchCbf(_), apply), Nil ) =>
148
+ visitedCbfCalls += sel
149
+ replaceNewBuilder(ap, cbf2)
150
+
151
+ // cbf.apply
152
+ case sel @ Term . Select ( cbf2 @ matchCbf(_), ap) if ( ! visitedCbfCalls.contains(sel)) =>
153
+ replaceNewBuilder(sel, cbf2)
154
+
155
+ // cbf()
156
+ case ap @ Term . Apply ( cbf2 @ matchCbf(_), Nil ) =>
157
+ replaceNewBuilder(ap, cbf2)
158
+ }.asPatch)
159
+ .asPatch
160
160
161
161
// e.to[CC] => cbf.fromSpecific(e)
162
- val toCalls =
163
- body.collect {
164
- case ap @ Term .ApplyType (Term .Select (e, to @ toTpe(_)), List (cc2 @ matchCC(_))) =>
165
- handledTo += to
162
+ val toCalls = toT match {
163
+ case cct @ Type .Apply (cc, _) => {
164
+ val matchCC = SymbolMatcher .exact(ctx.index.symbol(cc).get)
165
+
166
+ stats
167
+ .map(_.collect {
168
+ case ap @ Term .ApplyType (Term .Select (e, to @ toTpe(_)), List (cc2 @ matchCC(_))) =>
169
+ handledTo += to
166
170
167
- // e.to[CC](*cbf*) extract implicit parameter
168
- val synth = ctx.index.synthetics.find(_.position.end == ap.pos.end).get
169
- val Term .Apply (_, List (implicitCbf)) = synth.text.parse[Term ].get
171
+ // e.to[CC](*cbf*) extract implicit parameter
172
+ val synth = ctx.index.synthetics.find(_.position.end == ap.pos.end).get
173
+ val Term .Apply (_, List (implicitCbf)) = synth.text.parse[Term ].get
170
174
171
- // This is a bit unsafe
172
- // https://github.com/scalameta/scalameta/issues/1636
173
- if (implicitCbf.syntax == param.syntax) {
175
+ // This is a bit unsafe
176
+ // https://github.com/scalameta/scalameta/issues/1636
177
+ if (implicitCbf.syntax == param.syntax) {
174
178
175
- // .to[CC]
176
- val apToRemove = ap.tokens.slice(e.tokens.end - ap.tokens.start, ap.tokens.size)
179
+ // .to[CC]
180
+ val apToRemove = ap.tokens.slice(e.tokens.end - ap.tokens.start, ap.tokens.size)
177
181
178
- ctx.removeTokens(apToRemove) +
179
- ctx.addLeft(e, implicitCbf.syntax + " .fromSpecific(" ) +
180
- ctx.addRight(e, " )" )
181
- } else Patch .empty
182
+ ctx.removeTokens(apToRemove) +
183
+ ctx.addLeft(e, implicitCbf.syntax + " .fromSpecific(" ) +
184
+ ctx.addRight(e, " )" )
185
+ } else Patch .empty
182
186
183
- }.asPatch
187
+ }.asPatch)
188
+ .asPatch
189
+ }
190
+ case _ => Patch .empty
191
+ }
184
192
185
193
// implicit cbf: collection.generic.CanBuildFrom[Nothing, Int, CC[Int]] =>
186
194
// implicit cbf: Factory[Int, CC[Int]]
187
195
val parameterType =
188
196
ctx.replaceTree(
189
197
tpe,
190
- Type .Apply (Type .Name (" Factory" ), List (t, cct )).syntax
198
+ Type .Apply (Type .Name (" Factory" ), List (t, toT )).syntax
191
199
)
192
200
193
201
parameterType + cbfCalls + toCalls
0 commit comments