Skip to content

Refactor name and module management in python code generation and fuzzing #1957

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

Merged
merged 6 commits into from
Mar 16, 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 @@ -137,7 +137,7 @@ object PythonDialogProcessor {
.mapNotNull {
val functionName = it.name ?: return@mapNotNull null
val moduleFilename = it.containingFile.virtualFile?.canonicalPath ?: ""
val containingClassId = it.containingClass?.name?.let{ PythonClassId(it) }
val containingClassId = it.containingClass?.name?.let{ cls -> PythonClassId(cls) }
return@mapNotNull PythonMethodHeader(
functionName,
moduleFilename,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ object PythonTestGenerationProcessor {

val classId =
if (containingClassName == null)
PythonClassId("$currentPythonModule.TopLevelFunctions")
PythonClassId(currentPythonModule, "TopLevelFunctions")
else
PythonClassId("$currentPythonModule.$containingClassName")
PythonClassId(currentPythonModule, containingClassName)

val methodIds = notEmptyTests.associate {
it.method to PythonMethodId(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,68 +45,75 @@ class MemoryDump(
sealed class MemoryObject(
val id: String,
val kind: String,
val module: String,
val comparable: Boolean,
)
) {
val qualname: String = if (module.isEmpty()) kind else "$module.$kind"
}

class ReprMemoryObject(
id: String,
kind: String,
module: String,
comparable: Boolean,
val value: String,
): MemoryObject(id, kind, comparable)
): MemoryObject(id, kind, module, comparable)

class ListMemoryObject(
id: String,
kind: String,
module: String,
comparable: Boolean,
val items: List<String>,
): MemoryObject(id, kind, comparable)
): MemoryObject(id, kind, module, comparable)

class DictMemoryObject(
id: String,
kind: String,
module: String,
comparable: Boolean,
val items: Map<String, String>,
): MemoryObject(id, kind, comparable)
): MemoryObject(id, kind, module, comparable)

class ReduceMemoryObject(
id: String,
kind: String,
module: String,
comparable: Boolean,
val constructor: String,
val args: String,
val state: String,
val listitems: String,
val dictitems: String
): MemoryObject(id, kind, comparable)
): MemoryObject(id, kind, module, comparable)

fun PythonTree.PythonTreeNode.toMemoryObject(memoryDump: MemoryDump): String {
val obj = when(this) {
is PythonTree.PrimitiveNode -> {
ReprMemoryObject(this.id.toString(), this.type.name, this.comparable, this.repr)
ReprMemoryObject(this.id.toString(), this.type.name, this.type.moduleName, this.comparable, this.repr)
}
is PythonTree.ListNode -> {
val items = this.items.entries
.sortedBy { it.key }
.map { it.value.toMemoryObject(memoryDump) }
ListMemoryObject(this.id.toString(), this.type.name, this.comparable, items)
ListMemoryObject(this.id.toString(), this.type.name, this.type.moduleName, this.comparable, items)
}
is PythonTree.TupleNode -> {
val items = this.items.entries
.sortedBy { it.key }
.map { it.value.toMemoryObject(memoryDump) }
ListMemoryObject(this.id.toString(), this.type.name, this.comparable, items)
ListMemoryObject(this.id.toString(), this.type.name, this.type.moduleName, this.comparable, items)
}
is PythonTree.SetNode -> {
val items = this.items.map { it.toMemoryObject(memoryDump) }
ListMemoryObject(this.id.toString(), this.type.name, this.comparable, items)
ListMemoryObject(this.id.toString(), this.type.name, this.type.moduleName, this.comparable, items)
}
is PythonTree.DictNode -> {
val items = this.items.entries
.associate {
it.key.toMemoryObject(memoryDump) to it.value.toMemoryObject(memoryDump)
}
DictMemoryObject(this.id.toString(), this.type.name, this.comparable, items)
DictMemoryObject(this.id.toString(), this.type.name, this.type.moduleName, this.comparable, items)
}
is PythonTree.ReduceNode -> {
val stateObjId = PythonTree.DictNode(this.state.entries.associate { PythonTree.PrimitiveNode(pythonStrClassId, it.key) to it.value }.toMutableMap())
Expand All @@ -116,6 +123,7 @@ fun PythonTree.PythonTreeNode.toMemoryObject(memoryDump: MemoryDump): String {
ReduceMemoryObject(
this.id.toString(),
this.type.name,
this.type.moduleName,
this.comparable,
this.constructor.name,
argsIds.toMemoryObject(memoryDump),
Expand All @@ -137,7 +145,7 @@ fun MemoryObject.toPythonTree(memoryDump: MemoryDump): PythonTree.PythonTreeNode
is ReprMemoryObject -> {
PythonTree.PrimitiveNode(
this.id.toLong(),
PythonClassId(this.kind),
PythonClassId(this.module, this.kind),
this.value
)
}
Expand All @@ -153,7 +161,7 @@ fun MemoryObject.toPythonTree(memoryDump: MemoryDump): PythonTree.PythonTreeNode
val elementsMap = items.withIndex().associate {
it.index to memoryDump.getById(it.value).toPythonTree(memoryDump)
}.toMutableMap()
when (this.kind) {
when (this.qualname) {
"builtins.tuple" -> {
PythonTree.TupleNode(this.id.toLong(), elementsMap)
}
Expand All @@ -172,7 +180,7 @@ fun MemoryObject.toPythonTree(memoryDump: MemoryDump): PythonTree.PythonTreeNode
val dictitemsObjs = memoryDump.getById(dictitems) as DictMemoryObject
PythonTree.ReduceNode(
this.id.toLong(),
PythonClassId(this.kind),
PythonClassId(this.module, this.kind),
PythonClassId(this.constructor),
arguments.items.map { memoryDump.getById(it).toPythonTree(memoryDump) },
stateObjs.items.entries.associate {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.utbot.python.framework.api.python

import org.utbot.common.withToStringThreadLocalReentrancyGuard
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.MethodId
import org.utbot.framework.plugin.api.UtModel
import org.utbot.python.framework.api.python.util.comparePythonTree
import org.utbot.python.framework.api.python.util.moduleOfType

/**
Expand All @@ -17,17 +17,18 @@ import org.utbot.python.framework.api.python.util.moduleOfType
const val pythonBuiltinsModuleName = "builtins"

class PythonClassId(
name: String // includes module (like "_ast.Assign")
) : ClassId(name) {
override fun toString(): String = name
val rootModuleName: String = this.toString().split(".")[0]
override val simpleName: String = name.split(".").last()
val moduleName: String
get() {
return moduleOfType(name) ?: pythonBuiltinsModuleName
}
override val packageName = moduleName
val moduleName: String,
val typeName: String,
) : ClassId("$moduleName.$typeName") {
constructor(fullName: String) : this(
moduleOfType(fullName) ?: pythonBuiltinsModuleName,
fullName.removePrefix(moduleOfType(fullName) ?: pythonBuiltinsModuleName).removePrefix(".")
)
override fun toString(): String = canonicalName
val rootModuleName: String = moduleName.split(".").first()
override val simpleName: String = typeName
override val canonicalName = name
override val packageName = moduleName
}

open class RawPythonAnnotation(
Expand Down Expand Up @@ -73,114 +74,13 @@ class PythonTreeModel(
}

override fun equals(other: Any?): Boolean {
if (other is PythonTreeModel) {
return tree == other.tree
if (other !is PythonTreeModel) {
return false
}
return false
return comparePythonTree(tree, other.tree)
}

override fun hashCode(): Int {
return tree.hashCode()
}
}

class PythonDefaultModel(
val repr: String,
classId: PythonClassId
): PythonModel(classId) {
override fun toString() = repr
}

class PythonPrimitiveModel(
val value: Any,
classId: PythonClassId
): PythonModel(classId) {
override fun toString() = "$value"
}

class PythonBoolModel(val value: Boolean): PythonModel(classId) {
override fun toString() =
if (value) "True" else "False"
companion object {
val classId = PythonClassId("builtins.bool")
}
}

class PythonInitObjectModel(
val type: String,
val initValues: List<PythonModel>
): PythonModel(PythonClassId(type)) {
override fun toString(): String {
val params = initValues.joinToString(separator = ", ") { it.toString() }
return "$type($params)"
}

override val allContainingClassIds: Set<PythonClassId>
get() = super.allContainingClassIds + initValues.flatMap { it.allContainingClassIds }
}

class PythonListModel(
val length: Int = 0,
val stores: List<PythonModel>
) : PythonModel(classId) {
override fun toString() =
(0 until length).joinToString(", ", "[", "]") { stores[it].toString() }

override val allContainingClassIds: Set<PythonClassId>
get() = super.allContainingClassIds + stores.flatMap { it.allContainingClassIds }

companion object {
val classId = PythonClassId("builtins.list")
}
}

class PythonTupleModel(
val length: Int = 0,
val stores: List<PythonModel>
) : PythonModel(classId) {
override fun toString() =
(0 until length).joinToString(", ", "(", ")") { stores[it].toString() }

override val allContainingClassIds: Set<PythonClassId>
get() = super.allContainingClassIds + stores.flatMap { it.allContainingClassIds }

companion object {
val classId = PythonClassId("builtins.tuple")
}
}

class PythonDictModel(
val length: Int = 0,
val stores: Map<PythonModel, PythonModel>
) : PythonModel(classId) {
override fun toString() = withToStringThreadLocalReentrancyGuard {
stores.entries.joinToString(", ", "{", "}") { "${it.key}: ${it.value}" }
}

override val allContainingClassIds: Set<PythonClassId>
get() = super.allContainingClassIds +
stores.entries.flatMap { it.key.allContainingClassIds + it.value.allContainingClassIds }

companion object {
val classId = PythonClassId("builtins.dict")
}
}

class PythonSetModel(
val length: Int = 0,
val stores: Set<PythonModel>
) : PythonModel(classId) {
override fun toString() = withToStringThreadLocalReentrancyGuard {
if (stores.isEmpty())
"set()"
else
stores.joinToString(", ", "{", "}") { it.toString() }
}

override val allContainingClassIds: Set<PythonClassId>
get() = super.allContainingClassIds + stores.flatMap { it.allContainingClassIds }

companion object {
val classId = PythonClassId("builtins.set")
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package org.utbot.python.framework.api.python

import org.utbot.python.framework.api.python.util.pythonBoolClassId
import org.utbot.python.framework.api.python.util.pythonDictClassId
import org.utbot.python.framework.api.python.util.pythonFloatClassId
import org.utbot.python.framework.api.python.util.pythonIntClassId
import org.utbot.python.framework.api.python.util.pythonListClassId
import org.utbot.python.framework.api.python.util.pythonNoneClassId
import org.utbot.python.framework.api.python.util.pythonObjectClassId
import org.utbot.python.framework.api.python.util.pythonSetClassId
import org.utbot.python.framework.api.python.util.pythonStrClassId
import org.utbot.python.framework.api.python.util.pythonTupleClassId
import org.utbot.python.framework.api.python.util.toPythonRepr
import org.utbot.python.newtyping.general.Type
import org.utbot.python.newtyping.pythonTypeName
Expand Down Expand Up @@ -121,7 +126,7 @@ object PythonTree {
class ListNode(
id: Long,
val items: MutableMap<Int, PythonTreeNode>
) : PythonTreeNode(id, PythonClassId("builtins.list")) {
) : PythonTreeNode(id, pythonListClassId) {
constructor(items: MutableMap<Int, PythonTreeNode>) : this(PythonIdGenerator.createId(), items)

override val children: List<PythonTreeNode>
Expand All @@ -139,7 +144,7 @@ object PythonTree {
class DictNode(
id: Long,
val items: MutableMap<PythonTreeNode, PythonTreeNode>
) : PythonTreeNode(id, PythonClassId("builtins.dict")) {
) : PythonTreeNode(id, pythonDictClassId) {
constructor(items: MutableMap<PythonTreeNode, PythonTreeNode>) : this(PythonIdGenerator.createId(), items)

override val children: List<PythonTreeNode>
Expand All @@ -159,7 +164,7 @@ object PythonTree {
class SetNode(
id: Long,
val items: MutableSet<PythonTreeNode>
) : PythonTreeNode(id, PythonClassId("builtins.set")) {
) : PythonTreeNode(id, pythonSetClassId) {
constructor(items: MutableSet<PythonTreeNode>) : this(PythonIdGenerator.createId(), items)

override val children: List<PythonTreeNode>
Expand All @@ -182,7 +187,7 @@ object PythonTree {
class TupleNode(
id: Long,
val items: MutableMap<Int, PythonTreeNode>
) : PythonTreeNode(id, PythonClassId("builtins.tuple")) {
) : PythonTreeNode(id, pythonTupleClassId) {
constructor(items: MutableMap<Int, PythonTreeNode>) : this(PythonIdGenerator.createId(), items)

override val children: List<PythonTreeNode>
Expand Down Expand Up @@ -259,7 +264,7 @@ object PythonTree {

fun fromObject(): PrimitiveNode {
return PrimitiveNode(
PythonClassId("builtins.object"),
pythonObjectClassId,
"object()"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ package org.utbot.python.framework.api.python.util

import org.utbot.python.framework.api.python.PythonClassId
import org.utbot.python.framework.api.python.NormalizedPythonAnnotation
import org.utbot.python.framework.api.python.PythonBoolModel
import org.utbot.python.framework.api.python.PythonListModel
import org.utbot.python.framework.api.python.PythonTupleModel
import org.utbot.python.framework.api.python.PythonDictModel
import org.utbot.python.framework.api.python.PythonSetModel

// none annotation can be used in code only since Python 3.10
val pythonNoneClassId = PythonClassId("types.NoneType")
Expand Down
Loading