@@ -22,6 +22,14 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
2222import org.jetbrains.kotlin.ir.IrFileEntry
2323import org.jetbrains.kotlin.ir.types.IrType
2424import 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
2634class 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
8295fun 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
0 commit comments