Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 03d5646

Browse files
committed
Kotlin: Add stmt/expr support
1 parent 49a4e47 commit 03d5646

7 files changed

Lines changed: 121 additions & 10 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
2222
import org.jetbrains.kotlin.ir.IrFileEntry
2323
import org.jetbrains.kotlin.ir.types.IrType
2424
import org.jetbrains.kotlin.ir.types.IrSimpleType
25+
import org.jetbrains.kotlin.ir.expressions.IrBody
26+
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
27+
import org.jetbrains.kotlin.ir.expressions.IrReturn
28+
import org.jetbrains.kotlin.ir.expressions.IrExpression
29+
import org.jetbrains.kotlin.ir.expressions.IrCall
30+
import org.jetbrains.kotlin.ir.expressions.IrGetValue
31+
import org.jetbrains.kotlin.ir.expressions.IrConst
32+
import org.jetbrains.kotlin.ir.IrStatement
2533

2634
class KotlinExtractorExtension(private val tests: List<String>) : IrGenerationExtension {
2735
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
@@ -54,17 +62,17 @@ class TrapWriter (
5462
val startColumn = fileEntry.getColumnNumber(startOffset) + 1
5563
val endLine = fileEntry.getLineNumber(endOffset) + 1
5664
val endColumn = fileEntry.getColumnNumber(endOffset)
57-
val id: Label<DbLocation_default> = getFreshId()
58-
val fileId: Label<DbFile> = getIdFor(fileLabel)
65+
val id: Label<DbLocation_default> = getFreshLabel()
66+
val fileId: Label<DbFile> = getLabelFor(fileLabel)
5967
writeTrap("$id = @\"loc,{$fileId},$startLine,$startColumn,$endLine,$endColumn\"\n")
6068
writeLocations_default(id, fileId, startLine, startColumn, endLine, endColumn)
6169
return id
6270
}
6371
val labelMapping: MutableMap<String, Label<*>> = mutableMapOf<String, Label<*>>()
64-
fun <T> getIdFor(label: String, initialise: (Label<T>) -> Unit = {}): Label<T> {
72+
fun <T> getLabelFor(label: String, initialise: (Label<T>) -> Unit = {}): Label<T> {
6573
val maybeId = labelMapping.get(label)
6674
if(maybeId == null) {
67-
val id: Label<T> = getFreshId()
75+
val id: Label<T> = getFreshLabel()
6876
labelMapping.put(label, id)
6977
writeTrap("$id = $label\n")
7078
initialise(id)
@@ -74,9 +82,14 @@ class TrapWriter (
7482
return maybeId as Label<T>
7583
}
7684
}
77-
fun <T> getFreshId(): Label<T> {
85+
fun <T> getFreshLabel(): Label<T> {
7886
return Label(nextId++)
7987
}
88+
fun <T> getFreshIdLabel(): Label<T> {
89+
val label = Label<T>(nextId++)
90+
writeTrap("$label = *\n")
91+
return label
92+
}
8093
}
8194

8295
fun extractFile(trapDir: File, srcDir: File, declaration: IrFile) {
@@ -95,7 +108,7 @@ fun extractFile(trapDir: File, srcDir: File, declaration: IrFile) {
95108
trapFileDir.mkdirs()
96109
trapFile.bufferedWriter().use { trapFileBW ->
97110
val tw = TrapWriter(fileLabel, trapFileBW, declaration.fileEntry)
98-
val id: Label<DbFile> = tw.getIdFor(fileLabel)
111+
val id: Label<DbFile> = tw.getLabelFor(fileLabel)
99112
tw.writeFiles(id, filePath, basename, extension, 0)
100113
val fileExtractor = KotlinFileExtractor(tw)
101114
val pkg = declaration.fqName.asString()
@@ -112,7 +125,7 @@ class KotlinFileExtractor(val tw: TrapWriter) {
112125

113126
fun extractPackage(pkg: String): Label<out DbPackage> {
114127
val pkgLabel = "@\"package;$pkg\""
115-
val id: Label<DbPackage> = tw.getIdFor(pkgLabel, {
128+
val id: Label<DbPackage> = tw.getLabelFor(pkgLabel, {
116129
tw.writePackages(it, pkg)
117130
})
118131
return id
@@ -130,7 +143,7 @@ class KotlinFileExtractor(val tw: TrapWriter) {
130143
fun useSimpleType(c: IrSimpleType): Label<out DbPrimitive> {
131144
// TODO: This shouldn't assume all SimpleType's are Int
132145
val label = "@\"type;int\""
133-
val id: Label<DbPrimitive> = tw.getIdFor(label, {
146+
val id: Label<DbPrimitive> = tw.getLabelFor(label, {
134147
tw.writePrimitives(it, "int")
135148
})
136149
return id
@@ -141,7 +154,7 @@ class KotlinFileExtractor(val tw: TrapWriter) {
141154
val cls = c.name.asString()
142155
val qualClassName = if (pkg.isEmpty()) cls else "$pkg.$cls"
143156
val label = "@\"class;$qualClassName\""
144-
val id: Label<DbClass> = tw.getIdFor(label)
157+
val id: Label<DbClass> = tw.getLabelFor(label)
145158
return id
146159
}
147160

@@ -183,7 +196,7 @@ class KotlinFileExtractor(val tw: TrapWriter) {
183196
val returnTypeId = useType(f.returnType)
184197
val parentId = useDeclarationParent(f.parent)
185198
val label = "@\"callable;{$parentId}.${f.name.asString()}($paramTypeIds){$returnTypeId}\""
186-
val id: Label<DbMethod> = tw.getIdFor(label)
199+
val id: Label<DbMethod> = tw.getLabelFor(label)
187200
return id
188201
}
189202

@@ -194,7 +207,80 @@ class KotlinFileExtractor(val tw: TrapWriter) {
194207
val returnTypeId = useType(f.returnType)
195208
tw.writeMethods(id, f.name.asString(), signature, returnTypeId, parentid, id)
196209
tw.writeHasLocation(id, locId)
210+
val body = f.body
211+
if(body != null) {
212+
extractBody(body, id)
213+
}
214+
}
215+
216+
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
217+
when(b) {
218+
is IrBlockBody -> extractBlockBody(b, callable, callable, 0)
219+
else -> extractorBug("Unrecognised IrBody: " + b.javaClass)
220+
}
221+
}
222+
223+
fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
224+
val id = tw.getFreshIdLabel<DbBlock>()
225+
val locId = tw.getLocation(b.startOffset, b.endOffset)
226+
val kind = 0 // TODO: stmt kind for block from generated module
227+
tw.writeStmts(id, kind, parent, idx, callable)
228+
tw.writeHasLocation(id, locId)
229+
for((sIdx, stmt) in b.statements.withIndex()) {
230+
extractStatement(stmt, callable, id, sIdx)
231+
}
197232
}
198233

234+
fun extractStatement(s: IrStatement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
235+
when(s) {
236+
is IrReturn -> {
237+
val id = tw.getFreshIdLabel<DbReturnstmt>()
238+
val locId = tw.getLocation(s.startOffset, s.endOffset)
239+
val kind = 9 // TODO: stmt kind for return from generated module
240+
tw.writeStmts(id, kind, parent, idx, callable)
241+
tw.writeHasLocation(id, locId)
242+
extractExpression(s.value, id, 0)
243+
}
244+
}
245+
}
246+
247+
fun extractExpression(e: IrExpression, parent: Label<out DbExprparent>, idx: Int) {
248+
when(e) {
249+
is IrCall -> {
250+
// TODO: This shouldn't assume all IrCalls's are addexpr's
251+
if(e.valueArgumentsCount == 1) {
252+
val left = e.dispatchReceiver
253+
val right = e.getValueArgument(0)
254+
if(left != null && right != null) {
255+
val kind = 27 // TODO: expr kind for addexpr from generated module
256+
val id = tw.getFreshIdLabel<DbAddexpr>()
257+
val typeId = useType(e.type)
258+
val locId = tw.getLocation(e.startOffset, e.endOffset)
259+
tw.writeExprs(id, kind, typeId, parent, idx)
260+
tw.writeHasLocation(id, locId)
261+
extractExpression(left, id, 0)
262+
extractExpression(right, id, 1)
263+
} else {
264+
extractorBug("Unrecognised IrCall: left or right is null")
265+
}
266+
} else {
267+
extractorBug("Unrecognised IrCall: Not binary")
268+
}
269+
}
270+
is IrConst<*> -> {
271+
val v = e.value as Int
272+
val kind = 17 // TODO: expr kind for integerliteral from generated module
273+
val id = tw.getFreshIdLabel<DbIntegerliteral>()
274+
val typeId = useType(e.type)
275+
val locId = tw.getLocation(e.startOffset, e.endOffset)
276+
tw.writeExprs(id, kind, typeId, parent, idx)
277+
tw.writeHasLocation(id, locId)
278+
tw.writeNamestrings(v.toString(), v.toString(), id)
279+
}
280+
else -> {
281+
extractorBug("Unrecognised IrExpression: " + e.javaClass)
282+
}
283+
}
284+
}
199285
}
200286

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| exprs.kt:3:12:3:14 | 123 |
2+
| exprs.kt:3:12:3:20 | ... + ... |
3+
| exprs.kt:3:18:3:20 | 456 |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
fun topLevelMethod(x: Int, y: Int): Int {
3+
return 123 + 456
4+
}
5+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java
2+
3+
from Expr e
4+
select e
5+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| stmts.kt:2:41:4:1 | { ... } |
2+
| stmts.kt:3:5:3:16 | return ... |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
fun topLevelMethod(x: Int, y: Int): Int {
3+
return x + y
4+
}
5+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java
2+
3+
from Stmt s
4+
select s
5+

0 commit comments

Comments
 (0)