File tree Expand file tree Collapse file tree 8 files changed +84
-1
lines changed
compiler/src/dotty/tools/dotc/plugins
sbt-dotty/sbt-test/sbt-dotty/compiler-plugin Expand file tree Collapse file tree 8 files changed +84
-1
lines changed Original file line number Diff line number Diff line change @@ -145,7 +145,7 @@ object Plugins {
145145 * Note: this algorithm is factored out for unit test.
146146 */
147147 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 }
149149 type OrderingReq = (Set [Class [_]], Set [Class [_]])
150150
151151 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+ )
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