Skip to content

Instantly share code, notes, and snippets.

@jpsacha
Created September 16, 2015 01:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpsacha/9864e30dc884683bee18 to your computer and use it in GitHub Desktop.
Save jpsacha/9864e30dc884683bee18 to your computer and use it in GitHub Desktop.
IntelliJ plugin to find all recursive Scala methods in s project (can be executed using https://github.com/dkandalov/live-plugin). Depends on IntelliJ Scala plugin.
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.Project
import org.jetbrains.plugins.scala.lang.psi.api._
import org.jetbrains.plugins.scala.lang.psi.api.expr.ScMethodCall
import org.jetbrains.plugins.scala.lang.psi.api.statements.ScFunctionDefinition
import groovy.lang.Closure
import liveplugin.PluginUtil._
import scala.collection.JavaConversions._
import scala.collection._
// depends-on-plugin org.intellij.scala
implicit def functionToGroovyClosure_ActionEvent[F](f: (AnActionEvent) => F): Closure[F] = {
new Closure[F]() {def doCall(event: AnActionEvent): F = f(event)}
}
implicit def functionToGroovyClosure_Unit[F](f: () => F): Closure[F] = {
new Closure[F]() {def doCall(arg: Any): F = f()}
}
doInBackground("Looking for recursive methods", () => {
runReadAction { () =>
val methods = findRecursiveMethodsIn(project)
if (methods.nonEmpty) {
show("Resursive methods:\n " +
methods.map { f => f.getContainingClass.getQualifiedName + "#" + f.getName }.mkString(" \n"))
} else {
show("No recursive methods found.")
}
}
})
def findRecursiveMethodsIn(project: Project): Iterable[ScFunctionDefinition] = {
allPsiItemsIn(project).collect {
case s: ScalaFile => allFunctionsIn(s).filter(isRecursive)
}.flatten
}
def allFunctionsIn(scalaFile: ScalaFile): Seq[ScFunctionDefinition] = {
var result = new mutable.ListBuffer[ScFunctionDefinition]()
scalaFile.acceptChildren(
new ScalaRecursiveElementVisitor() {
override def visitFunctionDefinition(function: ScFunctionDefinition): Unit = {
result += function
}
}
)
result.toSeq
}
def isRecursive(function: ScFunctionDefinition): Boolean = {
var result = false
function.acceptChildren(
new ScalaRecursiveElementVisitor() {
override def visitMethodCallExpression(methodCall: ScMethodCall): Unit = {
val ref = methodCall.getInvokedExpr.getReference
if (ref != null && ref.resolve() == function) {
result = true
} else {
super.visitMethodCallExpression(methodCall)
}
}
}
)
result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment