Skip to content

Commit

Permalink
Pseudo-support for multi-labels
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Dec 11, 2024
1 parent 307fcce commit e6d1980
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ class Assignment(
/** The holder of this assignment */
@JsonIgnore val holder: AssignmentHolder
) : Edge<Node>(value, target as Node) {
override var label: String = "ASSIGMENT"
override var labels = setOf("ASSIGMENT")
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fun <T : Edge<Node>> Node.printGraph(
private fun Edge<Node>.label(): String {
val builder = StringBuilder()
builder.append("\"")
builder.append(this.label)
builder.append(this.labels)

if (this is Dataflow) {
var granularity = this.granularity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ abstract class Edge<NodeType : Node> : Persistable, Cloneable {
end = edge.end
}

abstract var label: String
abstract var labels: Set<String>

/**
* The index of this node, if it is stored in an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import org.neo4j.ogm.annotation.*

/** This property edge describes a parent/child relationship in the Abstract Syntax Tree (AST). */
@RelationshipEntity
open class AstEdge<T : Node>(start: Node, end: T, override var label: String = "AST") :
open class AstEdge<T : Node>(start: Node, end: T, override var labels: Set<String> = setOf("AST")) :
Edge<T>(start, end) {
init {
end.astParent = start
Expand All @@ -42,7 +42,7 @@ open class AstEdge<T : Node>(start: Node, end: T, override var label: String = "

/** Creates an [AstEdges] container starting from this node. */
fun <NodeType : Node> Node.astEdgesOf(
label: String = "AST",
label: String? = null,
onAdd: ((AstEdge<NodeType>) -> Unit)? = null,
onRemove: ((AstEdge<NodeType>) -> Unit)? = null,
): AstEdges<NodeType, AstEdge<NodeType>> {
Expand All @@ -54,12 +54,12 @@ fun <NodeType : Node> Node.astEdgesOf(
* container).
*/
fun <NodeType : Node> Node.astOptionalEdgeOf(
label: String = "AST",
label: String? = null,
onChanged: ((old: AstEdge<NodeType>?, new: AstEdge<NodeType>?) -> Unit)? = null
): EdgeSingletonList<NodeType, NodeType?, AstEdge<NodeType>> {
return EdgeSingletonList(
thisRef = this,
init = { start, end -> AstEdge(start, end, label = label) },
init = { start, end -> AstEdge(start, end, labels = setOfNotNull(label, "AST")) },
outgoing = true,
onChanged = onChanged,
of = null
Expand All @@ -71,12 +71,12 @@ fun <NodeType : Node> Node.astOptionalEdgeOf(
*/
fun <NodeType : Node> Node.astEdgeOf(
of: NodeType,
label: String,
label: String? = null,
onChanged: ((old: AstEdge<NodeType>?, new: AstEdge<NodeType>?) -> Unit)? = null,
): EdgeSingletonList<NodeType, NodeType, AstEdge<NodeType>> {
return EdgeSingletonList(
thisRef = this,
init = { start, end -> AstEdge(start, end, label = label) },
init = { start, end -> AstEdge(start, end, labels = setOfNotNull(label, "AST")) },
outgoing = true,
onChanged = onChanged,
of = of
Expand All @@ -86,12 +86,12 @@ fun <NodeType : Node> Node.astEdgeOf(
/** This property edge list describes elements that are AST children of a node. */
open class AstEdges<NodeType : Node, PropertyEdgeType : AstEdge<NodeType>>(
thisRef: Node,
label: String = "AST",
label: String? = null,
onAdd: ((PropertyEdgeType) -> Unit)? = null,
onRemove: ((PropertyEdgeType) -> Unit)? = null,
@Suppress("UNCHECKED_CAST")
init: (start: Node, end: NodeType) -> PropertyEdgeType = { start, end ->
AstEdge(start, end, label = label) as PropertyEdgeType
AstEdge(start, end, labels = setOfNotNull(label, "AST")) as PropertyEdgeType
},
) :
EdgeList<NodeType, PropertyEdgeType>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class TemplateArgument<NodeType : Node>(
end: NodeType,
label: String,
var instantiation: TemplateInitialization? = TemplateInitialization.EXPLICIT,
) : AstEdge<NodeType>(start, end, label)
) : AstEdge<NodeType>(start, end, setOf(label, "AST"))

/** A container for [TemplateArgument] edges. */
class TemplateArguments<NodeType : Node>(thisRef: Node, label: String) :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ControlDependence(
dependence = DependenceType.CONTROL
}

override var label: String = "CDG"
override var labels = setOf("CDG")

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ open class Dataflow(
@JsonIgnore
var granularity: Granularity = default()
) : Edge<Node>(start, end) {
override var label: String = "DFG"
override var labels = setOf("DFG")

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down Expand Up @@ -134,7 +134,7 @@ class ContextSensitiveDataflow(
val callingContext: CallingContext
) : Dataflow(start, end, granularity) {

override var label: String = "DFG"
override var labels = setOf("DFG")

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class EvaluationOrder(
return result
}

override var label: String = "EOG"
override var labels = setOf("EOG")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Invoke(
*/
var dynamicInvoke: Boolean = false,
) : Edge<FunctionDeclaration>(start, end) {
override var label: String = "INVOKES"
override var labels = setOf("INVOKES")

override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Usage(
return result
}

override var label: String = "USAGE"
override var labels = setOf("USAGE")
}

/** A container for [Usage] edges. [NodeType] is necessary because of the Neo4J OGM. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ open class CallExpression :

/** Adds the specified [expression] with an optional [name] to this call. */
fun addArgument(expression: Expression, name: String? = null) {
val edge = AstEdge(this, expression, label = "ARGUMENTS")
val edge = AstEdge(this, expression, labels = setOf("ARGUMENTS", "ARGUMENT"))
edge.name = name

argumentEdges.add(edge)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,16 @@ private fun Collection<Edge<*>>.persist() {

this.chunked(edgeChunkSize).map { chunk ->
createRelationships(
chunk.map {
mapOf(
"startId" to it.start.id.toString(),
"endId" to it.end.id.toString(),
"type" to it.label
) + it.properties()
chunk.flatMap { edge ->
// Since Neo4J does not support multiple labels on edges, but we do internally, we
// duplicate the edge for each label
edge.labels.map { label ->
mapOf(
"startId" to edge.start.id.toString(),
"endId" to edge.end.id.toString(),
"type" to label
) + edge.properties()
}
}
)
}
Expand Down

0 comments on commit e6d1980

Please sign in to comment.