Skip to content

Commit

Permalink
codegen: implement Product for nodes (new and stored) (#100)
Browse files Browse the repository at this point in the history
* stored nodes: implement Product

we did this in odb1 and need it for compatibility: e.g. for .toJson and
repl printing

* also for NewNodes
  • Loading branch information
mpollmeier authored Nov 13, 2023
1 parent 39fd40c commit 347e3ae
Show file tree
Hide file tree
Showing 3 changed files with 2,645 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ import overflowdb.codegen.CodeGen.ConstantContext

import java.nio.file.{Path, Paths}
import overflowdb.codegen.Helpers
import overflowdb.schema.{AbstractNodeType, AdjacentNode, Direction, EdgeType, MarkerTrait, NodeBaseType, NodeType, Property, Schema}
import overflowdb.schema.{
AbstractNodeType,
AdjacentNode,
Direction,
EdgeType,
MarkerTrait,
NodeBaseType,
NodeType,
ProductElement,
Property,
Schema
}
import overflowdb.schema.Property.{Cardinality, Default, ValueType}

import scala.collection.mutable
Expand Down Expand Up @@ -117,7 +128,7 @@ class DomainClassesGenerator(schema: Schema) {
|
|trait StaticType[+T]
|
|trait AbstractNode extends odb2.DNodeOrNode with StaticType[AnyRef] {
|trait AbstractNode extends odb2.DNodeOrNode with StaticType[AnyRef] with Product {
| def label: String
| def propertiesMap: java.util.Map[String, Any]
|}
Expand Down Expand Up @@ -272,10 +283,12 @@ class DomainClassesGenerator(schema: Schema) {
val baseNodeProps = mutable.ArrayBuffer.empty[String]
val propDictItems = mutable.ArrayBuffer.empty[String]
val flattenItems = mutable.ArrayBuffer.empty[String]
val productElements = mutable.ArrayBuffer.empty[String]

for (p <- nodeType.properties) {
val pname = Helpers.camelCase(p.name)
val ptyp = unpackTypeUnboxed(p.valueType, false, false)
productElements.addOne(pname)
val ptyp = unpackTypeUnboxed(p.valueType, false, false)
p.cardinality match {
case Cardinality.List =>
newNodeProps.append(s"var $pname: IndexedSeq[$ptyp] = ArraySeq.empty")
Expand Down Expand Up @@ -305,6 +318,7 @@ class DomainClassesGenerator(schema: Schema) {

for (c <- nodeType.containedNodes) {
val pname = c.localName
productElements.addOne(pname)
val ptyp = classNameToBase(c.nodeType.className)
val styp = c.nodeType.className
val index = relevantProperties.size + containedIndexByName(c.localName)
Expand Down Expand Up @@ -345,6 +359,18 @@ class DomainClassesGenerator(schema: Schema) {
}
}

val productElementNames = productElements.zipWithIndex
.map { case (name, index) =>
s"""case $index => "$name""""
}
.mkString("\n")

val productElementAccessors = productElements.zipWithIndex
.map { case (name, index) =>
s"case $index => this.$name"
}
.mkString("\n")

val newNode =
s"""object New${nodeType.className}{def apply(): New${nodeType.className} = new New${nodeType.className}}
|class New${nodeType.className} extends NewNode(${nodeKindByNodeType(nodeType)}.toShort) with ${nodeType.className}Base {
Expand All @@ -353,6 +379,22 @@ class DomainClassesGenerator(schema: Schema) {
|${newNodeProps.sorted.mkString("\n")}
|${newNodeFluent.sorted.mkString("\n")}
|${flattenItems.mkString("override def flattenProperties(interface: odb2.BatchedUpdateInterface): Unit = {\n", "\n", "\n}")}
|
| override def productElementName(n: Int): String =
| n match {
| $productElementNames
| case _ => ""
| }
|
| override def productElement(n: Int): Any =
| n match {
| $productElementAccessors
| case _ => null
| }
|
| override def productPrefix = "New${nodeType.className}"
| override def productArity = ${productElements.size}
| override def canEqual(that: Any): Boolean = that != null && that.isInstanceOf[New${nodeType.className}]
|}""".stripMargin

s"""$staticTyp
Expand All @@ -368,14 +410,32 @@ class DomainClassesGenerator(schema: Schema) {
)}
|}
|$stored {
|${storedNodeProps.mkString("\n")}
| ${storedNodeProps.mkString("\n")}
|
| override def productElementName(n: Int): String =
| n match {
| $productElementNames
| case _ => ""
| }
|
| override def productElement(n: Int): Any =
| n match {
| $productElementAccessors
| case _ => null
| }
|
| override def productPrefix = "${nodeType.className}"
| override def productArity = ${productElements.size}
|
| override def canEqual(that: Any): Boolean = that != null && that.isInstanceOf[${nodeType.className}]
|}
|$newNode
|""".stripMargin
}
.mkString(
s"""package $basePackage.nodes
|import io.joern.odb2
|import io.shiftleft.codepropertygraph.generated.v2.Language.*
|import scala.collection.immutable.{IndexedSeq, ArraySeq}
|
|""".stripMargin,
Expand Down
Loading

0 comments on commit 347e3ae

Please sign in to comment.