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

Skip to content

Commit 49a4e47

Browse files
committed
Kotlin: Extract methods
1 parent 6dd1027 commit 49a4e47

6 files changed

Lines changed: 116 additions & 11 deletions

File tree

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

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ import org.jetbrains.kotlin.ir.declarations.path
1212
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
1313
import org.jetbrains.kotlin.ir.declarations.IrClass
1414
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
15+
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
1516
import org.jetbrains.kotlin.ir.declarations.IrFile
17+
import org.jetbrains.kotlin.ir.declarations.IrFunction
18+
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
1619
import org.jetbrains.kotlin.ir.util.dump
1720
import org.jetbrains.kotlin.ir.util.packageFqName
1821
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
1922
import org.jetbrains.kotlin.ir.IrFileEntry
23+
import org.jetbrains.kotlin.ir.types.IrType
24+
import org.jetbrains.kotlin.ir.types.IrSimpleType
2025

2126
class KotlinExtractorExtension(private val tests: List<String>) : IrGenerationExtension {
2227
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
@@ -96,37 +101,100 @@ fun extractFile(trapDir: File, srcDir: File, declaration: IrFile) {
96101
val pkg = declaration.fqName.asString()
97102
val pkgId = fileExtractor.extractPackage(pkg)
98103
tw.writeCupackage(id, pkgId)
99-
declaration.declarations.map { fileExtractor.extractDeclaration(it) }
104+
declaration.declarations.map { fileExtractor.extractDeclaration(it, pkgId) }
100105
}
101106
}
102107

103108
class KotlinFileExtractor(val tw: TrapWriter) {
104-
fun extractPackage(pkg: String): Label<DbPackage> {
109+
fun usePackage(pkg: String): Label<out DbPackage> {
110+
return extractPackage(pkg)
111+
}
112+
113+
fun extractPackage(pkg: String): Label<out DbPackage> {
105114
val pkgLabel = "@\"package;$pkg\""
106115
val id: Label<DbPackage> = tw.getIdFor(pkgLabel, {
107116
tw.writePackages(it, pkg)
108117
})
109118
return id
110119
}
111120

112-
fun extractDeclaration(declaration: IrDeclaration) {
121+
fun extractDeclaration(declaration: IrDeclaration, parentid: Label<out DbPackage_or_reftype>) {
113122
when (declaration) {
114123
is IrClass -> extractClass(declaration)
124+
is IrFunction -> extractFunction(declaration, parentid)
115125
else -> extractorBug("Unrecognised IrDeclaration: " + declaration.javaClass)
116126
}
117127
}
118128

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()
129+
@Suppress("UNUSED_PARAMETER")
130+
fun useSimpleType(c: IrSimpleType): Label<out DbPrimitive> {
131+
// TODO: This shouldn't assume all SimpleType's are Int
132+
val label = "@\"type;int\""
133+
val id: Label<DbPrimitive> = tw.getIdFor(label, {
134+
tw.writePrimitives(it, "int")
135+
})
136+
return id
137+
}
138+
139+
fun useClass(c: IrClass): Label<out DbClass> {
140+
val pkg = c.packageFqName?.asString() ?: ""
141+
val cls = c.name.asString()
124142
val qualClassName = if (pkg.isEmpty()) cls else "$pkg.$cls"
143+
val label = "@\"class;$qualClassName\""
144+
val id: Label<DbClass> = tw.getIdFor(label)
145+
return id
146+
}
147+
148+
fun extractClass(c: IrClass) {
149+
val id = useClass(c)
150+
val locId = tw.getLocation(c.startOffset, c.endOffset)
151+
val pkg = c.packageFqName?.asString() ?: ""
152+
val cls = c.name.asString()
125153
val pkgId = extractPackage(pkg)
126-
tw.writeTrap("$id = @\"class;$qualClassName\"\n")
127154
tw.writeClasses(id, cls, pkgId, id)
128155
tw.writeHasLocation(id, locId)
129-
declaration.declarations.map { extractDeclaration(it) }
156+
c.declarations.map { extractDeclaration(it, id) }
157+
}
158+
159+
fun useType(t: IrType): Label<out DbType> {
160+
when(t) {
161+
is IrSimpleType -> return useSimpleType(t)
162+
is IrClass -> return useClass(t)
163+
else -> {
164+
extractorBug("Unrecognised IrType: " + t.javaClass)
165+
return Label(0)
166+
}
167+
}
168+
}
169+
170+
fun useDeclarationParent(dp: IrDeclarationParent): Label<out DbPackage_or_reftype> {
171+
when(dp) {
172+
is IrFile -> return usePackage(dp.fqName.asString())
173+
is IrClass -> return useClass(dp)
174+
else -> {
175+
extractorBug("Unrecognised IrDeclarationParent: " + dp.javaClass)
176+
return Label(0)
177+
}
178+
}
179+
}
180+
181+
fun useFunction(f: IrFunction): Label<out DbMethod> {
182+
val paramTypeIds = f.valueParameters.joinToString() { "{${useType(it.type).toString()}}" }
183+
val returnTypeId = useType(f.returnType)
184+
val parentId = useDeclarationParent(f.parent)
185+
val label = "@\"callable;{$parentId}.${f.name.asString()}($paramTypeIds){$returnTypeId}\""
186+
val id: Label<DbMethod> = tw.getIdFor(label)
187+
return id
188+
}
189+
190+
fun extractFunction(f: IrFunction, parentid: Label<out DbPackage_or_reftype>) {
191+
val id = useFunction(f)
192+
val locId = tw.getLocation(f.startOffset, f.endOffset)
193+
val signature = "TODO"
194+
val returnTypeId = useType(f.returnType)
195+
tw.writeMethods(id, f.name.asString(), signature, returnTypeId, parentid, id)
196+
tw.writeHasLocation(id, locId)
130197
}
198+
131199
}
132200

java/ql/lib/config/semmlecode.dbscheme

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,14 @@ constrs(
332332
int sourceid: @constructor ref
333333
);
334334

335+
@package_or_reftype = @package | @reftype
336+
335337
methods(
336338
unique int id: @method,
337339
string nodeName: string ref,
338340
string signature: string ref,
339341
int typeid: @type ref,
340-
int parentid: @reftype ref,
342+
int parentid: @package_or_reftype ref,
341343
int sourceid: @method ref
342344
);
343345

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| methods2.kt:7:1:10:1 | <init> |
2+
| methods2.kt:7:1:10:1 | equals |
3+
| methods2.kt:7:1:10:1 | hashCode |
4+
| methods2.kt:7:1:10:1 | toString |
5+
| methods2.kt:8:5:9:5 | fooBarClassMethod |
6+
| methods.kt:5:1:8:1 | <init> |
7+
| methods.kt:5:1:8:1 | equals |
8+
| methods.kt:5:1:8:1 | hashCode |
9+
| methods.kt:5:1:8:1 | toString |
10+
| methods.kt:6:5:7:5 | classMethod |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
fun topLevelMethod(x: Int, y: Int) {
3+
}
4+
5+
class Class {
6+
fun classMethod(x: Int, y: Int) {
7+
}
8+
}
9+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java
2+
3+
from Method m
4+
select m
5+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
package foo.bar
3+
4+
fun fooBarTopLevelMethod(x: Int, y: Int) {
5+
}
6+
7+
class Class {
8+
fun fooBarClassMethod(x: Int, y: Int) {
9+
}
10+
}
11+

0 commit comments

Comments
 (0)