File tree 8 files changed +85
-1
lines changed
compiler/src/dotty/tools/dotc/plugins
sbt-dotty/sbt-test/sbt-dotty/compiler-plugin
8 files changed +85
-1
lines changed Original file line number Diff line number Diff line change @@ -145,7 +145,7 @@ object Plugins {
145
145
* Note: this algorithm is factored out for unit test.
146
146
*/
147
147
def schedule (plan : List [List [Phase ]], pluginPhases : List [PluginPhase ]): List [List [Phase ]] = {
148
- import scala .collection .mutable .{ Map => MMap , Set => MSet }
148
+ import scala .collection .mutable .{ Map => MMap }
149
149
type OrderingReq = (Set [Class [_]], Set [Class [_]])
150
150
151
151
val orderRequirements = MMap [Class [_], OrderingReq ]()
Original file line number Diff line number Diff line change
1
+ lazy val dottyVersion = sys.props(" plugin.scalaVersion" )
2
+
3
+ lazy val pluginSetting = Seq (
4
+ name := " dividezero" ,
5
+ version := " 0.0.1" ,
6
+ organization := " ch.epfl.lamp" ,
7
+ scalaVersion := dottyVersion,
8
+
9
+ libraryDependencies ++= Seq (
10
+ " ch.epfl.lamp" %% " dotty" % scalaVersion.value % " provided"
11
+ )
12
+ )
13
+
14
+ lazy val plugin = (project in file(" plugin" )).settings(pluginSetting : _* )
15
+
16
+ lazy val app = (project in file(" ." )).settings(
17
+ scalaVersion := dottyVersion,
18
+ libraryDependencies += compilerPlugin(" ch.epfl.lamp" %% " dividezero" % " 0.0.1" )
19
+ )
20
+
Original file line number Diff line number Diff line change
1
+ package dividezero
2
+
3
+ import dotty .tools .dotc ._
4
+ import core ._
5
+ import Contexts .Context
6
+ import plugins .{Plugin , PluginPhase }
7
+ import Phases .Phase
8
+ import ast .tpd
9
+ import transform .MegaPhase .MiniPhase
10
+ import Decorators ._
11
+ import Symbols .Symbol
12
+ import Constants .Constant
13
+ import transform .{LinkAll , Pickler }
14
+
15
+ class DivideZero extends PluginPhase with Plugin {
16
+ val name : String = " divideZero"
17
+ override val description : String = " divide zero check"
18
+
19
+ val phaseName = name
20
+
21
+ override val runsAfter = Set (classOf [Pickler ])
22
+ override val runsBefore = Set (classOf [LinkAll ])
23
+
24
+ override def init (options : List [String ]): List [PluginPhase ] = this :: Nil
25
+
26
+ private def isNumericDivide (sym : Symbol )(implicit ctx : Context ): Boolean = {
27
+ def test (tpe : String ): Boolean =
28
+ (sym.owner eq ctx.requiredClass(tpe.toTermName)) && sym.name.show == " /"
29
+
30
+ test(" scala.Int" ) || test(" scala.Long" ) || test(" scala.Short" ) || test(" scala.FLoat" ) || test(" scala.Double" )
31
+ }
32
+
33
+ override def transformApply (tree : tpd.Apply )(implicit ctx : Context ): tpd.Tree = tree match {
34
+ case tpd.Apply (fun, tpd.Literal (Constants .Constant (v)) :: Nil ) if isNumericDivide(fun.symbol) && v == 0 =>
35
+ ctx.warning(" divide by zero" , tree.pos)
36
+ tpd.Literal (Constant (0 ))
37
+ case _ =>
38
+ tree
39
+ }
40
+ }
Original file line number Diff line number Diff line change
1
+ <plugin >
2
+ <name >divideZero</name >
3
+ <classname >dividezero.DivideZero</classname >
4
+ </plugin >
Original file line number Diff line number Diff line change
1
+ sbt.version =0.13.15
Original file line number Diff line number Diff line change
1
+ addSbtPlugin(" ch.epfl.lamp" % " sbt-dotty" % sys.props(" plugin.version" ))
Original file line number Diff line number Diff line change
1
+ package hello
2
+ object Hello {
3
+ def main (args : Array [String ]): Unit = {
4
+ val dotty : Int | String = " dotty"
5
+
6
+ val y = 5 / 0 // error
7
+ 100 + 6 / 0 // error
8
+ 6L / 0L // error
9
+ val z = 7 / 0.0 // error
10
+
11
+ println(s " Hello $dotty! " )
12
+ }
13
+ }
Original file line number Diff line number Diff line change
1
+ > plugin/publishLocal
2
+ > run
3
+ > 'set initialCommands := "1 + 1" '
4
+ # FIXME: does not work on the CI
5
+ #> console
You can’t perform that action at this time.
0 commit comments