Skip to content

Commit 81c4af4

Browse files
committed
parse types from annotations
1 parent ef2ae12 commit 81c4af4

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/python/PythonDialogProcessor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.utbot.python.code.PythonCodeGenerator.generateTestCode
2222
import org.utbot.python.code.PythonCodeGenerator.saveToFile
2323
import org.utbot.python.PythonMethod
2424
import org.utbot.python.PythonTestCaseGenerator
25+
import org.utbot.python.code.AnnotationProcessor.getTypesFromAnnotation
2526
import org.utbot.python.normalizeAnnotation
2627
import org.utbot.python.typing.PythonTypesStorage
2728

@@ -93,7 +94,7 @@ object PythonDialogProcessor {
9394
val pythonPath = model.srcModule.sdk?.homePath ?: error("Couldn't find Python interpreter")
9495
val testSourceRoot = model.testSourceRoot!!.path
9596
val filePath = model.file.virtualFile.path
96-
97+
9798
// PythonCodeCollector.refreshProjectClassesList(model.project.basePath!!)
9899
PythonTypesStorage.refreshProjectClassesList(
99100
filePath,

utbot-python/src/main/kotlin/org/utbot/python/code/PythonASTParser.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,24 @@ fun <A, B, C, D> classMethod(
249249
fname: Parser<A, B, Name>,
250250
fattributeId: Parser<B, C, String>,
251251
farguments: Parser<C, D, Arguments>
252-
):Parser<A, D, Atom> =
252+
): Parser<A, D, Atom> =
253253
atom(refl(fname), list2(refl(attribute(fattributeId)), refl(farguments)))
254254

255+
fun <A, B> nameWithPrefixFromAtom(
256+
fname: Parser<A, B, String>
257+
): Parser<A, B, Atom> =
258+
Parser { node, x ->
259+
if (node.atomElement !is Name)
260+
return@Parser Error()
261+
var res = (node.atomElement as Name).id.name
262+
for (elem in node.trailers) {
263+
if (elem !is Attribute)
264+
break
265+
res += "." + elem.attr.name
266+
}
267+
fname.go(res, x)
268+
}
269+
255270
fun <A, B, C> functionCallWithoutPrefix(
256271
fname: Parser<A, B, Name>,
257272
farguments: Parser<B, C, Arguments>

utbot-python/src/main/kotlin/org/utbot/python/code/PythonCodeAPI.kt

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.github.danielnaczo.python3parser.Python3Lexer
44
import io.github.danielnaczo.python3parser.Python3Parser
55
import io.github.danielnaczo.python3parser.model.AST
66
import io.github.danielnaczo.python3parser.model.expr.Expression
7+
import io.github.danielnaczo.python3parser.model.expr.atoms.Atom
78
import io.github.danielnaczo.python3parser.model.expr.atoms.Name
89
import io.github.danielnaczo.python3parser.model.expr.atoms.Num
910
import io.github.danielnaczo.python3parser.model.expr.atoms.Str
@@ -45,12 +46,7 @@ class PythonCode(private val body: Module, val filename: String? = null) {
4546

4647
companion object {
4748
fun getFromString(code: String, filename: String? = null): PythonCode {
48-
val lexer = Python3Lexer(fromString(code))
49-
val tokens = CommonTokenStream(lexer)
50-
val parser = Python3Parser(tokens)
51-
val moduleVisitor = ModuleVisitor()
52-
val ast = moduleVisitor.visit(parser.file_input()) as Module
53-
49+
val ast = textToModule(code)
5450
return PythonCode(ast, filename)
5551
}
5652
}
@@ -106,3 +102,36 @@ fun astToString(stmt: Statement): String {
106102
val modulePrettyPrintVisitor = ModulePrettyPrintVisitor()
107103
return modulePrettyPrintVisitor.visitModule(Module(listOf(stmt)), IndentationPrettyPrint(0))
108104
}
105+
106+
fun textToModule(code: String): Module {
107+
val lexer = Python3Lexer(fromString(code))
108+
val tokens = CommonTokenStream(lexer)
109+
val parser = Python3Parser(tokens)
110+
val moduleVisitor = ModuleVisitor()
111+
return moduleVisitor.visit(parser.file_input()) as Module
112+
}
113+
114+
object AnnotationProcessor {
115+
// get only types with modules in prefixes
116+
fun getTypesFromAnnotation(annotation: String): Set<String> {
117+
val annotationAST = textToModule(annotation)
118+
val visitor = Visitor()
119+
val result = mutableSetOf<String>()
120+
visitor.visitModule(annotationAST, result)
121+
return result
122+
}
123+
124+
private class Visitor: ModifierVisitor<MutableSet<String>>() {
125+
override fun visitAtom(atom: Atom, param: MutableSet<String>): AST {
126+
parse(
127+
nameWithPrefixFromAtom(apply()),
128+
onError = null,
129+
atom
130+
) { it } ?.let { typeName ->
131+
param.add(typeName)
132+
}
133+
134+
return super.visitAtom(atom, param)
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)