Skip to content

Commit 08a418a

Browse files
committed
Implement ExplicitNonNullaryApply, using Olaf's draft
1 parent eb89168 commit 08a418a

File tree

6 files changed

+373
-0
lines changed

6 files changed

+373
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
rule = fix.scala213.ExplicitNonNullaryApply
3+
*/
4+
package fix.scala213
5+
6+
class ExplicitNonNullaryApply {
7+
val enna = new ExplicitNonNullaryApply()
8+
9+
def prop = ""
10+
def meth() = ""
11+
12+
def propNullAs[A] = null.asInstanceOf[A]
13+
def methNullAs[A]() = null.asInstanceOf[A]
14+
15+
def id[A](x: A) = x
16+
17+
18+
def def_prop_p = prop
19+
def def_meth_p = meth
20+
def def_meth_m = meth()
21+
22+
def def_propNullAs_p = propNullAs
23+
def def_propNullAs_p_ta = propNullAs[String]
24+
def def_methNullAs_p = methNullAs
25+
def def_methNullAs_p_ta = methNullAs[String]
26+
def def_methNullAs_m = methNullAs()
27+
def def_methNullAs_m_ta = methNullAs[String]()
28+
29+
def def_id = id("")
30+
def def_id_ta = id[String]("")
31+
32+
33+
def def_this_prop_p = this.prop
34+
def def_this_meth_p = this.meth
35+
def def_this_meth_m = this.meth()
36+
def def_this_meth_m_in = this meth ()
37+
38+
def def_this_propNullAs_p = this.propNullAs
39+
def def_this_propNullAs_p_ta = this.propNullAs[String]
40+
def def_this_methNullAs_p = this.methNullAs
41+
def def_this_methNullAs_p_ta = this.methNullAs[String]
42+
def def_this_methNullAs_m = this.methNullAs()
43+
def def_this_methNullAs_m_ta = this.methNullAs[String]()
44+
def def_this_methNullAs_m_in = this methNullAs ()
45+
def def_this_methNullAs_m_in_ta = this methNullAs[String] ()
46+
47+
def def_this_id_m = this.id("")
48+
def def_this_id_m_ta = this.id[String]("")
49+
def def_this_id_m_in = this id ""
50+
def def_this_id_m_in_ta = this id[String] ""
51+
52+
53+
def def_enna_prop_p = enna.prop
54+
def def_enna_meth_p = enna.meth
55+
def def_enna_meth_m = enna.meth()
56+
def def_enna_meth_m_in = enna meth ()
57+
58+
def def_enna_propNullAs_p = enna.propNullAs
59+
def def_enna_propNullAs_p_ta = enna.propNullAs[String]
60+
def def_enna_methNullAs_p = enna.methNullAs
61+
def def_enna_methNullAs_p_ta = enna.methNullAs[String]
62+
def def_enna_methNullAs_m = enna.methNullAs()
63+
def def_enna_methNullAs_m_ta = enna.methNullAs[String]()
64+
def def_enna_methNullAs_m_in = enna methNullAs ()
65+
def def_enna_methNullAs_m_in_ta = enna methNullAs[String] ()
66+
67+
def def_enna_id_m = enna.id("")
68+
def def_enna_id_m_ta = enna.id[String]("")
69+
def def_enna_id_m_in = enna id ""
70+
def def_enna_id_m_in_ta = enna id[String] ""
71+
72+
73+
def def_this_enna_prop_p = this.enna.prop
74+
def def_this_enna_meth_p = this.enna.meth
75+
def def_this_enna_meth_m = this.enna.meth()
76+
def def_this_enna_meth_m_in = this.enna meth ()
77+
78+
def def_this_enna_propNullAs_p = this.enna.propNullAs
79+
def def_this_enna_propNullAs_p_ta = this.enna.propNullAs[String]
80+
def def_this_enna_methNullAs_p = this.enna.methNullAs
81+
def def_this_enna_methNullAs_p_ta = this.enna.methNullAs[String]
82+
def def_this_enna_methNullAs_m = this.enna.methNullAs()
83+
def def_this_enna_methNullAs_m_ta = this.enna.methNullAs[String]()
84+
def def_this_enna_methNullAs_m_in = this.enna methNullAs ()
85+
def def_this_enna_methNullAs_m_in_ta = this.enna methNullAs[String] ()
86+
87+
def def_this_enna_id_m = this.enna.id("")
88+
def def_this_enna_id_m_ta = this.enna.id[String]("")
89+
def def_this_enna_id_m_in = this.enna id ""
90+
def def_this_enna_id_m_in_ta = this.enna id[String] ""
91+
92+
93+
def def_enna_this_prop_p = ExplicitNonNullaryApply.this.prop
94+
def def_enna_this_meth_p = ExplicitNonNullaryApply.this.meth
95+
def def_enna_this_meth_m = ExplicitNonNullaryApply.this.meth()
96+
def def_enna_this_meth_m_in = ExplicitNonNullaryApply.this meth ()
97+
98+
def def_enna_this_propNullAs_p = ExplicitNonNullaryApply.this.propNullAs
99+
def def_enna_this_propNullAs_p_ta = ExplicitNonNullaryApply.this.propNullAs[String]
100+
def def_enna_this_methNullAs_p = ExplicitNonNullaryApply.this.methNullAs
101+
def def_enna_this_methNullAs_p_ta = ExplicitNonNullaryApply.this.methNullAs[String]
102+
def def_enna_this_methNullAs_m = ExplicitNonNullaryApply.this.methNullAs()
103+
def def_enna_this_methNullAs_m_ta = ExplicitNonNullaryApply.this.methNullAs[String]()
104+
def def_enna_this_methNullAs_m_in = ExplicitNonNullaryApply.this methNullAs ()
105+
def def_enna_this_methNullAs_m_in_ta = ExplicitNonNullaryApply.this methNullAs[String] ()
106+
107+
def def_enna_this_id_m = ExplicitNonNullaryApply.this.id("")
108+
def def_enna_this_id_m_ta = ExplicitNonNullaryApply.this.id[String]("")
109+
def def_enna_this_id_m_in = ExplicitNonNullaryApply.this id ""
110+
def def_enna_this_id_m_in_ta = ExplicitNonNullaryApply.this id[String] ""
111+
112+
113+
def def_enna_enna_prop_p = enna.enna.prop
114+
def def_enna_enna_meth_p = enna.enna.meth
115+
def def_enna_enna_meth_m = enna.enna.meth()
116+
def def_enna_enna_meth_m_in = enna.enna meth ()
117+
118+
def def_enna_enna_propNullAs_p = enna.enna.propNullAs
119+
def def_enna_enna_propNullAs_p_ta = enna.enna.propNullAs[String]
120+
def def_enna_enna_methNullAs_p = enna.enna.methNullAs
121+
def def_enna_enna_methNullAs_p_ta = enna.enna.methNullAs[String]
122+
def def_enna_enna_methNullAs_m = enna.enna.methNullAs()
123+
def def_enna_enna_methNullAs_m_ta = enna.enna.methNullAs[String]()
124+
def def_enna_enna_methNullAs_m_in = enna.enna methNullAs ()
125+
def def_enna_enna_methNullAs_m_in_ta = enna.enna methNullAs[String] ()
126+
127+
def def_enna_enna_id_m = enna.enna.id("")
128+
def def_enna_enna_id_m_ta = enna.enna.id[String]("")
129+
def def_enna_enna_id_m_in = enna.enna id ""
130+
def def_enna_enna_id_m_in_ta = enna.enna id[String] ""
131+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
rule = fix.scala213.ExplicitNonNullaryApply
3+
*/
4+
package fix.scala213
5+
6+
object NoAutoApply {
7+
object buz {
8+
override def toString(): String = ""
9+
def empty[T]() = List.empty[T]
10+
}
11+
val x: Iterator[Int] = ???
12+
def foo() = println(1)
13+
def bar = 32
14+
foo
15+
println(foo)
16+
foo()
17+
bar
18+
x.next
19+
class buz() {
20+
def qux() = List(1)
21+
}
22+
new buz().qux.toIterator.next
23+
new java.util.ArrayList[Int]().toString
24+
val builder = List.newBuilder[Int]
25+
builder.result()
26+
builder result ()
27+
builder.result
28+
fix.scala213.NoAutoApply.buz.empty[String]
29+
var opt: Option[() => Int] = None
30+
opt = None
31+
println(1.toString)
32+
println(buz.toString) // not inserted
33+
List(builder) map (_.result)
34+
builder.##
35+
def lzy(f: => Int) = {
36+
var k = f _
37+
k = () => 3
38+
}
39+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package fix.scala213
2+
3+
class ExplicitNonNullaryApply {
4+
val enna = new ExplicitNonNullaryApply()
5+
6+
def prop = ""
7+
def meth() = ""
8+
9+
def propNullAs[A] = null.asInstanceOf[A]()
10+
def methNullAs[A]() = null.asInstanceOf[A]()
11+
12+
def id[A](x: A) = x
13+
14+
15+
def def_prop_p = prop
16+
def def_meth_p = meth()
17+
def def_meth_m = meth()
18+
19+
def def_propNullAs_p = propNullAs
20+
def def_propNullAs_p_ta = propNullAs[String]
21+
def def_methNullAs_p = methNullAs()
22+
def def_methNullAs_p_ta = methNullAs[String]()
23+
def def_methNullAs_m = methNullAs()
24+
def def_methNullAs_m_ta = methNullAs[String]()
25+
26+
def def_id = id("")
27+
def def_id_ta = id[String]("")
28+
29+
30+
def def_this_prop_p = this.prop
31+
def def_this_meth_p = this.meth()
32+
def def_this_meth_m = this.meth()
33+
def def_this_meth_m_in = this meth ()
34+
35+
def def_this_propNullAs_p = this.propNullAs
36+
def def_this_propNullAs_p_ta = this.propNullAs[String]
37+
def def_this_methNullAs_p = this.methNullAs()
38+
def def_this_methNullAs_p_ta = this.methNullAs[String]()
39+
def def_this_methNullAs_m = this.methNullAs()
40+
def def_this_methNullAs_m_ta = this.methNullAs[String]()
41+
def def_this_methNullAs_m_in = this methNullAs ()
42+
def def_this_methNullAs_m_in_ta = this methNullAs[String] ()
43+
44+
def def_this_id_m = this.id("")
45+
def def_this_id_m_ta = this.id[String]("")
46+
def def_this_id_m_in = this id ""
47+
def def_this_id_m_in_ta = this id[String] ""
48+
49+
50+
def def_enna_prop_p = enna.prop
51+
def def_enna_meth_p = enna.meth()
52+
def def_enna_meth_m = enna.meth()
53+
def def_enna_meth_m_in = enna meth ()
54+
55+
def def_enna_propNullAs_p = enna.propNullAs
56+
def def_enna_propNullAs_p_ta = enna.propNullAs[String]
57+
def def_enna_methNullAs_p = enna.methNullAs()
58+
def def_enna_methNullAs_p_ta = enna.methNullAs[String]()
59+
def def_enna_methNullAs_m = enna.methNullAs()
60+
def def_enna_methNullAs_m_ta = enna.methNullAs[String]()
61+
def def_enna_methNullAs_m_in = enna methNullAs ()
62+
def def_enna_methNullAs_m_in_ta = enna methNullAs[String] ()
63+
64+
def def_enna_id_m = enna.id("")
65+
def def_enna_id_m_ta = enna.id[String]("")
66+
def def_enna_id_m_in = enna id ""
67+
def def_enna_id_m_in_ta = enna id[String] ""
68+
69+
70+
def def_this_enna_prop_p = this.enna.prop
71+
def def_this_enna_meth_p = this.enna.meth()
72+
def def_this_enna_meth_m = this.enna.meth()
73+
def def_this_enna_meth_m_in = this.enna meth ()
74+
75+
def def_this_enna_propNullAs_p = this.enna.propNullAs
76+
def def_this_enna_propNullAs_p_ta = this.enna.propNullAs[String]
77+
def def_this_enna_methNullAs_p = this.enna.methNullAs()
78+
def def_this_enna_methNullAs_p_ta = this.enna.methNullAs[String]()
79+
def def_this_enna_methNullAs_m = this.enna.methNullAs()
80+
def def_this_enna_methNullAs_m_ta = this.enna.methNullAs[String]()
81+
def def_this_enna_methNullAs_m_in = this.enna methNullAs ()
82+
def def_this_enna_methNullAs_m_in_ta = this.enna methNullAs[String] ()
83+
84+
def def_this_enna_id_m = this.enna.id("")
85+
def def_this_enna_id_m_ta = this.enna.id[String]("")
86+
def def_this_enna_id_m_in = this.enna id ""
87+
def def_this_enna_id_m_in_ta = this.enna id[String] ""
88+
89+
90+
def def_enna_this_prop_p = ExplicitNonNullaryApply.this.prop
91+
def def_enna_this_meth_p = ExplicitNonNullaryApply.this.meth()
92+
def def_enna_this_meth_m = ExplicitNonNullaryApply.this.meth()
93+
def def_enna_this_meth_m_in = ExplicitNonNullaryApply.this meth ()
94+
95+
def def_enna_this_propNullAs_p = ExplicitNonNullaryApply.this.propNullAs
96+
def def_enna_this_propNullAs_p_ta = ExplicitNonNullaryApply.this.propNullAs[String]
97+
def def_enna_this_methNullAs_p = ExplicitNonNullaryApply.this.methNullAs()
98+
def def_enna_this_methNullAs_p_ta = ExplicitNonNullaryApply.this.methNullAs[String]()
99+
def def_enna_this_methNullAs_m = ExplicitNonNullaryApply.this.methNullAs()
100+
def def_enna_this_methNullAs_m_ta = ExplicitNonNullaryApply.this.methNullAs[String]()
101+
def def_enna_this_methNullAs_m_in = ExplicitNonNullaryApply.this methNullAs ()
102+
def def_enna_this_methNullAs_m_in_ta = ExplicitNonNullaryApply.this methNullAs[String] ()
103+
104+
def def_enna_this_id_m = ExplicitNonNullaryApply.this.id("")
105+
def def_enna_this_id_m_ta = ExplicitNonNullaryApply.this.id[String]("")
106+
def def_enna_this_id_m_in = ExplicitNonNullaryApply.this id ""
107+
def def_enna_this_id_m_in_ta = ExplicitNonNullaryApply.this id[String] ""
108+
109+
110+
def def_enna_enna_prop_p = enna.enna.prop
111+
def def_enna_enna_meth_p = enna.enna.meth()
112+
def def_enna_enna_meth_m = enna.enna.meth()
113+
def def_enna_enna_meth_m_in = enna.enna meth ()
114+
115+
def def_enna_enna_propNullAs_p = enna.enna.propNullAs
116+
def def_enna_enna_propNullAs_p_ta = enna.enna.propNullAs[String]
117+
def def_enna_enna_methNullAs_p = enna.enna.methNullAs()
118+
def def_enna_enna_methNullAs_p_ta = enna.enna.methNullAs[String]()
119+
def def_enna_enna_methNullAs_m = enna.enna.methNullAs()
120+
def def_enna_enna_methNullAs_m_ta = enna.enna.methNullAs[String]()
121+
def def_enna_enna_methNullAs_m_in = enna.enna methNullAs ()
122+
def def_enna_enna_methNullAs_m_in_ta = enna.enna methNullAs[String] ()
123+
124+
def def_enna_enna_id_m = enna.enna.id("")
125+
def def_enna_enna_id_m_ta = enna.enna.id[String]("")
126+
def def_enna_enna_id_m_in = enna.enna id ""
127+
def def_enna_enna_id_m_in_ta = enna.enna id[String] ""
128+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package fix.scala213
2+
3+
object NoAutoApply {
4+
object buz {
5+
override def toString(): String = ""
6+
def empty[T]() = List.empty[T]
7+
}
8+
val x: Iterator[Int] = ???
9+
def foo() = println(1)
10+
def bar = 32
11+
foo()
12+
println(foo())
13+
foo()
14+
bar
15+
x.next()
16+
class buz() {
17+
def qux() = List(1)
18+
}
19+
new buz().qux().toIterator.next()
20+
new java.util.ArrayList[Int]().toString
21+
val builder = List.newBuilder[Int]
22+
builder.result()
23+
builder result ()
24+
builder.result()
25+
fix.scala213.NoAutoApply.buz.empty[String]()
26+
var opt: Option[() => Int] = None
27+
opt = None
28+
println(1.toString())
29+
println(buz.toString()) // not inserted
30+
List(builder) map (_.result())
31+
builder.##
32+
def lzy(f: => Int) = {
33+
var k = f _
34+
k = () => 3
35+
}
36+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fix.scala213.Any2StringAdd
22
fix.scala213.Core
3+
fix.scala213.ExplicitNonNullaryApply
34
fix.scala213.ScalaSeq
45
fix.scala213.Varargs
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package fix.scala213
2+
3+
import scala.PartialFunction.{ cond, condOpt }
4+
import scala.collection.mutable
5+
6+
import scala.meta._
7+
8+
import scalafix.v1._
9+
10+
final class ExplicitNonNullaryApply extends SemanticRule("fix.scala213.ExplicitNonNullaryApply") {
11+
override def fix(implicit doc: SemanticDocument) = {
12+
val handled = mutable.Set.empty[Name]
13+
14+
def fix(tree: Tree, meth: Term, noTypeArgs: Boolean, noArgs: Boolean) = {
15+
for {
16+
name <- termName(meth)
17+
if handled.add(name)
18+
if noArgs
19+
if name.isReference
20+
if !name.parent.exists(_.is[Term.ApplyInfix])
21+
info <- name.symbol.info
22+
if !info.isJava
23+
if cond(info.signature) { case MethodSignature(_, List(Nil), _) => true }
24+
} yield Patch.addRight(if (noTypeArgs) name else tree, "()")
25+
}.asPatch
26+
27+
doc.tree.collect {
28+
case t @ q"$meth[..$targs](...$args)" => fix(t, meth, targs.isEmpty, args.isEmpty)
29+
case t @ q"$meth(...$args)" => fix(t, meth, true, args.isEmpty)
30+
}.asPatch
31+
}
32+
33+
private def termName(term: Term): Option[Name] = condOpt(term) {
34+
case name: Term.Name => name
35+
case Term.Select(_, name: Term.Name) => name
36+
case Type.Select(_, name: Type.Name) => name
37+
}
38+
}

0 commit comments

Comments
 (0)