Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ruby] RubyProgramSummary types derive ReadWriter #4477

Merged
merged 11 commits into from
Apr 25, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.joern.x2cpg.Defines as XDefines
import io.joern.x2cpg.datastructures.{FieldLike, MethodLike, ProgramSummary, TypeLike}

import scala.annotation.targetName
import upickle.default.*

class RubyProgramSummary(
initialNamespaceMap: Map[String, Set[RubyType]] = Map.empty,
Expand All @@ -30,7 +31,20 @@ case class RubyMethod(
baseTypeFullName: Option[String]
) extends MethodLike

case class RubyField(name: String, typeName: String) extends FieldLike
object RubyMethod {
implicit val rubyMethodRwJson: ReadWriter[RubyMethod] = readwriter[ujson.Value].bimap[RubyMethod](
x => ujson.Obj("name" -> x.name),
json =>
RubyMethod(
name = json("name").str,
parameterTypes = List.empty,
returnType = XDefines.Any,
baseTypeFullName = Option(json("name").str.split("\\.").dropRight(1).mkString("."))
)
)
}

case class RubyField(name: String, typeName: String) extends FieldLike derives ReadWriter

case class RubyType(name: String, methods: List[RubyMethod], fields: List[RubyField])
extends TypeLike[RubyMethod, RubyField] {
Expand All @@ -44,3 +58,32 @@ case class RubyType(name: String, methods: List[RubyMethod], fields: List[RubyFi
methods.exists(_.name == XDefines.ConstructorMethodName)
}
}

object RubyType {
implicit val rubyTypeRw: ReadWriter[RubyType] = readwriter[ujson.Value].bimap[RubyType](
x =>
ujson.Obj(
"name" -> x.name,
"methods" -> x.methods.map { method =>
ujson.Obj("name" -> method.name)
},
"fields" -> x.fields.map { field => write[RubyField](field) }
),
json =>
RubyType(
name = json("name").str,
methods = json.obj.get("methods") match {
case Some(jsonMethods) =>
val methodsMap = read[collection.mutable.Map[String, RubyMethod]](jsonMethods)
methodsMap.map { case (name, func) =>
val splitName = name.split("\\.")
val baseTypeFullName = splitName.dropRight(1).mkString(".")

func.copy(name = name, baseTypeFullName = Option(baseTypeFullName))
}.toList
case None => Nil
},
fields = json.obj.get("fields").map(read[List[RubyField]](_)).getOrElse(Nil)
)
)
}
Loading