This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Scala plugin

3 replies
Ali ektefa
Joined: 2011-11-08,
User offline. Last seen 42 years 45 weeks ago.

Hi,

I'm trying to write a simple static checker for regular expressions. The idea is to look for calls to the r method where the receiver is a constant String and to check that the string contains a well-formed regular expression. I've read the tutorial in scala-lang.org, but I can't find any documentation on how to chane it to achive my goal. I will be greatful if anybody can help.

cheers,
Ali

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Scala plugin

On Sat, Nov 5, 2011 at 6:29 AM, Ali ektefa wrote:
> I'm trying to write a simple static checker for regular expressions. The
> idea is to look for calls to the r method where the receiver is a constant
> String and to check that the string contains a well-formed regular
> expression. I've read the tutorial in scala-lang.org, but I can't find any
> documentation on how to chane it to achive my goal. I will be greatful if
> anybody can help.

See this part?

def apply(unit: CompilationUnit) {
for ( tree @ Apply(Select(rcvr, nme.DIV),
List(Literal(Constant(0)))) <- unit.body;
if rcvr.tpe <:< definitions.IntClass.tpe)
{
unit.error(tree.pos, "definitely division by zero")
}
}

You instead write something like this. ("Something like" chosen
specifically because this isn't tested and there are a lot of little
things one can do to make things not work.)

def apply(unit: CompilationUnit) {
import definitions._
// the symbol of the implicit in Predef which installs the r method
val augmentMethod = getMember(PredefModule, "augmentString")

// iterating over all subtrees looking for calls to the r method
unit.body foreach {
// which should look about like this for the case you're interested in
case Apply(fn, Literal(Constant(value: String)) :: Nil) if
fn.symbol == augmentMethod =>
println("My logic to check \"" + value + "\" for regex
goodness goes here.")
case _ =>
}
}
}

Ali ektefa
Joined: 2011-11-08,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala plugin
Dear Paul, Thank you very much, It was very helpful. cheers,

 On Tue, Nov 8, 2011 at 2:04 PM, Paul Phillips <paulp@improving.org> wrote:
On Sat, Nov 5, 2011 at 6:29 AM, Ali ektefa <ali.ektefa@gmail.com> wrote:
> I'm trying to write a simple static checker for regular expressions. The
> idea is to look for calls to the r method where the receiver is a constant
> String and to check that the string contains a well-formed regular
> expression. I've read the tutorial in scala-lang.org, but I can't find any
> documentation on how to chane it to achive my goal. I will be greatful if
> anybody can help.

See this part?

 def apply(unit: CompilationUnit) {
   for ( tree @ Apply(Select(rcvr, nme.DIV),
List(Literal(Constant(0)))) <- unit.body;
        if rcvr.tpe <:< definitions.IntClass.tpe)
     {
       unit.error(tree.pos, "definitely division by zero")
     }
 }

You instead write something like this.  ("Something like" chosen
specifically because this isn't tested and there are a lot of little
things one can do to make things not work.)

 def apply(unit: CompilationUnit) {
   import definitions._
   // the symbol of the implicit in Predef which installs the r method
   val augmentMethod = getMember(PredefModule, "augmentString")

   // iterating over all subtrees looking for calls to the r method
   unit.body foreach {
     // which should look about like this for the case you're interested in
     case Apply(fn, Literal(Constant(value: String)) :: Nil) if
fn.symbol == augmentMethod =>
       println("My logic to check \"" + value + "\" for regex
goodness goes here.")
     case _ =>
   }
 }
}

gbalcerek@echos...
Joined: 2009-10-21,
User offline. Last seen 31 weeks 2 days ago.
Re: Scala plugin
Maybe this example can give you some help.
This plugin runs after the "parser" phase.   $ type RegexPlugin.scala
import scala.tools.nsc.{Global, Phase}
import scala.tools.nsc.plugins.{Plugin, PluginComponent}
class RegexPlugin(override val global: Global) extends Plugin {
  override val name = "regex"
  override val description = "emits warnings about too short regexps"
  override val components = List(new RegexPluginComponent(global))
  class RegexPluginComponent(override val global: Global)
  extends PluginComponent {
    import global._
    override val phaseName = name
    override val runsAfter = List("parser")
    override val runsBefore = List("namer")
    override def newPhase(prev: Phase) = new StdPhase(prev) {
      override def apply(unit: CompilationUnit) {
        for (tree <- unit.body) tree match {
          case Select(Literal(Constant(regex: String)),symb)
               if symb.toString == "r" =>
            regexWarning(regex, tree).map{ unit.warning(tree.pos, _) }
          case _ => }
        def regexWarning(regex: String, tree: Tree): Option[String] =
          if (regex.length <= 2) Some("The regex "+regex+" is too short")
          else None
      }
    }
  }
}   $ type scalac-plugin.xml
<plugin>
  <name>regex</name>
  <classname>RegexPlugin</classname>
</plugin>   $ scalac RegexPlugin.scala   $ jar -cf regex.jar RegexPlugin*.class scalac-plugin.xml   $ type Example.scala
object Example {
  val r1 = "0+".r
  val r2 = "[0-9]+".r
}   $ scalac -Xplugin:regex.jar Example.scala
Example.scala:2: warning: The regex 0+ is too short
  val r1 = "0+".r
                ^
one warning found  
When trying to figure out the proper pattern match expression, the following might be helpful.   $ scalac -Xprint:parser -Yshow-trees Example.scala
[[syntax trees at end of parser]]// Scala source: Example.scala
(...)
          Select( // sym=<none>, sym.tpe=<notype>, tpe=null
            Literal(Constant([0-9]+)),
            "r")
(...)   Regards,
Grzegorz Balcerek    
----- Original Message ----- From: ali [dot] ektefa [at] gmail [dot] com" href="mailto:ali.ektefa@gmail.com" rel="nofollow">Ali ektefa To: scala-internals@googlegroups.com Sent: Saturday, November 05, 2011 6:29 AM Subject: [scala-internals] Scala plugin

Hi,

I'm trying to write a simple static checker for regular expressions. The idea is to look for calls to the r method where the receiver is a constant String and to check that the string contains a well-formed regular expression. I've read the tutorial in scala-lang.org, but I can't find any documentation on how to chane it to achive my goal. I will be greatful if anybody can help.

cheers,
Ali

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland