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

Skip to content

Commit 6dd1027

Browse files
committed
Kotlin: Refactoring
1 parent fb26859 commit 6dd1027

1 file changed

Lines changed: 60 additions & 71 deletions

File tree

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

Lines changed: 60 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import kotlin.system.exitProcess
88
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
99
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
1010
import org.jetbrains.kotlin.ir.IrElement
11+
import org.jetbrains.kotlin.ir.declarations.path
1112
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
1213
import org.jetbrains.kotlin.ir.declarations.IrClass
14+
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
1315
import org.jetbrains.kotlin.ir.declarations.IrFile
14-
import org.jetbrains.kotlin.ir.declarations.path
1516
import org.jetbrains.kotlin.ir.util.dump
1617
import org.jetbrains.kotlin.ir.util.packageFqName
1718
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -23,7 +24,7 @@ class KotlinExtractorExtension(private val tests: List<String>) : IrGenerationEx
2324
trapDir.mkdirs()
2425
val srcDir = File(System.getenv("CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR").takeUnless { it.isNullOrEmpty() } ?: "kotlin-extractor/src")
2526
srcDir.mkdirs()
26-
moduleFragment.accept(KotlinExtractorVisitor(trapDir, srcDir), RootTrapWriter())
27+
moduleFragment.files.map { extractFile(trapDir, srcDir, it) }
2728
// We don't want the compiler to continue and generate class
2829
// files etc, so we just exit when we are finished extracting.
2930
exitProcess(0)
@@ -34,41 +35,16 @@ fun extractorBug(msg: String) {
3435
println(msg)
3536
}
3637

37-
interface TrapWriter {
38-
fun writeTrap(trap: String)
39-
fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation_default>
40-
fun <T> getIdFor(label: String): Label<T>
41-
fun <T> getFreshId(): Label<T>
42-
}
43-
44-
class RootTrapWriter: TrapWriter {
45-
override fun writeTrap(trap: String) {
46-
extractorBug("Tried to write TRAP outside a file: $trap")
47-
}
48-
override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation_default> {
49-
extractorBug("Asked for location, but not in a file")
50-
return Label(0)
51-
}
52-
override fun <T> getIdFor(label: String): Label<T> {
53-
extractorBug("Asked for ID for '$label' outside a file")
54-
return Label(0)
55-
}
56-
override fun <T> getFreshId(): Label<T> {
57-
extractorBug("Asked for fresh ID outside a file")
58-
return Label(0)
59-
}
60-
}
61-
62-
class FileTrapWriter(
38+
class TrapWriter (
6339
val fileLabel: String,
6440
val file: BufferedWriter,
6541
val fileEntry: IrFileEntry
66-
): TrapWriter {
42+
) {
6743
var nextId: Int = 100
68-
override fun writeTrap(trap: String) {
44+
fun writeTrap(trap: String) {
6945
file.write(trap)
7046
}
71-
override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation_default> {
47+
fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation_default> {
7248
val startLine = fileEntry.getLineNumber(startOffset) + 1
7349
val startColumn = fileEntry.getColumnNumber(startOffset) + 1
7450
val endLine = fileEntry.getLineNumber(endOffset) + 1
@@ -80,64 +56,77 @@ class FileTrapWriter(
8056
return id
8157
}
8258
val labelMapping: MutableMap<String, Label<*>> = mutableMapOf<String, Label<*>>()
83-
override fun <T> getIdFor(label: String): Label<T> {
59+
fun <T> getIdFor(label: String, initialise: (Label<T>) -> Unit = {}): Label<T> {
8460
val maybeId = labelMapping.get(label)
8561
if(maybeId == null) {
8662
val id: Label<T> = getFreshId()
8763
labelMapping.put(label, id)
64+
writeTrap("$id = $label\n")
65+
initialise(id)
8866
return id
8967
} else {
9068
@Suppress("UNCHECKED_CAST")
9169
return maybeId as Label<T>
9270
}
9371
}
94-
override fun <T> getFreshId(): Label<T> {
72+
fun <T> getFreshId(): Label<T> {
9573
return Label(nextId++)
9674
}
9775
}
9876

99-
class KotlinExtractorVisitor(val trapDir: File, val srcDir: File) : IrElementVisitor<Unit, TrapWriter> {
100-
override fun visitElement(element: IrElement, data: TrapWriter) {
101-
extractorBug("Unrecognised IrElement: " + element.javaClass)
102-
if(data is RootTrapWriter) {
103-
extractorBug("... and outside any file!")
104-
}
105-
element.acceptChildren(this, data)
77+
fun extractFile(trapDir: File, srcDir: File, declaration: IrFile) {
78+
val filePath = declaration.path
79+
val file = File(filePath)
80+
val fileLabel = "@\"$filePath;sourcefile\""
81+
val basename = file.nameWithoutExtension
82+
val extension = file.extension
83+
val dest = Paths.get("$srcDir/${declaration.path}")
84+
val destDir = dest.getParent()
85+
Files.createDirectories(destDir)
86+
Files.copy(Paths.get(declaration.path), dest)
87+
88+
val trapFile = File("$trapDir/$filePath.trap")
89+
val trapFileDir = trapFile.getParentFile()
90+
trapFileDir.mkdirs()
91+
trapFile.bufferedWriter().use { trapFileBW ->
92+
val tw = TrapWriter(fileLabel, trapFileBW, declaration.fileEntry)
93+
val id: Label<DbFile> = tw.getIdFor(fileLabel)
94+
tw.writeFiles(id, filePath, basename, extension, 0)
95+
val fileExtractor = KotlinFileExtractor(tw)
96+
val pkg = declaration.fqName.asString()
97+
val pkgId = fileExtractor.extractPackage(pkg)
98+
tw.writeCupackage(id, pkgId)
99+
declaration.declarations.map { fileExtractor.extractDeclaration(it) }
106100
}
107-
override fun visitClass(declaration: IrClass, data: TrapWriter) {
108-
val id: Label<DbClass> = data.getFreshId()
109-
val pkgId: Label<DbPackage> = data.getFreshId()
110-
val locId = data.getLocation(declaration.startOffset, declaration.endOffset)
111-
val pkg = declaration.packageFqName?.asString() ?: ""
112-
val cls = declaration.name.asString()
113-
data.writeTrap("$pkgId = @\"pkg;$pkg\"\n")
114-
data.writePackages(pkgId, pkg)
115-
data.writeTrap("$id = @\"class;$pkg.$cls\"\n")
116-
data.writeClasses(id, cls, pkgId, id)
117-
data.writeHasLocation(id, locId)
118-
declaration.acceptChildren(this, data)
101+
}
102+
103+
class KotlinFileExtractor(val tw: TrapWriter) {
104+
fun extractPackage(pkg: String): Label<DbPackage> {
105+
val pkgLabel = "@\"package;$pkg\""
106+
val id: Label<DbPackage> = tw.getIdFor(pkgLabel, {
107+
tw.writePackages(it, pkg)
108+
})
109+
return id
119110
}
120-
override fun visitFile(declaration: IrFile, data: TrapWriter) {
121-
val filePath = declaration.path
122-
val file = File(filePath)
123-
val fileLabel = "@\"$filePath;sourcefile\""
124-
val basename = file.nameWithoutExtension
125-
val extension = file.extension
126-
val dest = Paths.get("$srcDir/${declaration.path}")
127-
val destDir = dest.getParent()
128-
Files.createDirectories(destDir)
129-
Files.copy(Paths.get(declaration.path), dest)
130111

131-
val trapFile = File("$trapDir/$filePath.trap")
132-
val trapFileDir = trapFile.getParentFile()
133-
trapFileDir.mkdirs()
134-
trapFile.bufferedWriter().use { trapFileBW ->
135-
val tw = FileTrapWriter(fileLabel, trapFileBW, declaration.fileEntry)
136-
val id: Label<DbFile> = tw.getIdFor(fileLabel)
137-
tw.writeTrap("$id = $fileLabel\n")
138-
tw.writeFiles(id, filePath, basename, extension, 0)
139-
declaration.acceptChildren(this, tw)
112+
fun extractDeclaration(declaration: IrDeclaration) {
113+
when (declaration) {
114+
is IrClass -> extractClass(declaration)
115+
else -> extractorBug("Unrecognised IrDeclaration: " + declaration.javaClass)
140116
}
141117
}
118+
119+
fun extractClass(declaration: IrClass) {
120+
val id: Label<DbClass> = tw.getFreshId()
121+
val locId = tw.getLocation(declaration.startOffset, declaration.endOffset)
122+
val pkg = declaration.packageFqName?.asString() ?: ""
123+
val cls = declaration.name.asString()
124+
val qualClassName = if (pkg.isEmpty()) cls else "$pkg.$cls"
125+
val pkgId = extractPackage(pkg)
126+
tw.writeTrap("$id = @\"class;$qualClassName\"\n")
127+
tw.writeClasses(id, cls, pkgId, id)
128+
tw.writeHasLocation(id, locId)
129+
declaration.declarations.map { extractDeclaration(it) }
130+
}
142131
}
143132

0 commit comments

Comments
 (0)