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

codegen: implement Product for nodes (new and stored) #100

Merged
merged 2 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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