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

Skip to content

Commit ebf91b7

Browse files
tamasvajkigfoo
authored andcommitted
Revert moving extraction to SourceFileExtractor
1 parent 01f4655 commit ebf91b7

4 files changed

Lines changed: 134 additions & 153 deletions

File tree

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

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,39 @@ open class KotlinFileExtractor(
123123
return id
124124
}
125125

126+
private val anonymousTypeMapping: MutableMap<IrClass, TypeResults> = mutableMapOf()
127+
128+
fun useAnonymousClass(c: IrClass): TypeResults {
129+
var res = anonymousTypeMapping[c]
130+
if (res == null) {
131+
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
132+
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
133+
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
134+
res = TypeResults(javaResult, kotlinResult)
135+
anonymousTypeMapping[c] = res
136+
}
137+
138+
return res
139+
}
140+
141+
private fun extractAnonymousClassStmt(c: IrClass, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
142+
@Suppress("UNCHECKED_CAST")
143+
val id = extractClassSource(c) as Label<out DbClass>
144+
extractAnonymousClassStmt(id, c, callable, parent, idx)
145+
}
146+
147+
private fun extractAnonymousClassStmt(id: Label<out DbClass>, locElement: IrElement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
148+
val stmtId = tw.getFreshIdLabel<DbAnonymousclassdeclstmt>()
149+
tw.writeStmts_anonymousclassdeclstmt(stmtId, parent, idx, callable)
150+
tw.writeKtAnonymousClassDeclarationStmts(stmtId, id)
151+
val locId = tw.getLocation(locElement)
152+
tw.writeHasLocation(stmtId, locId)
153+
}
154+
126155
fun extractClassSource(c: IrClass): Label<out DbClassorinterface> {
127156
val id = if (c.isAnonymousObject) {
128157
@Suppress("UNCHECKED_CAST")
129-
withSourceFile(c.fileOrNull!!).useAnonymousClass(c).javaResult.id as Label<out DbClass>
158+
useAnonymousClass(c).javaResult.id as Label<out DbClass>
130159
} else {
131160
useClassSource(c)
132161
}
@@ -156,7 +185,7 @@ open class KotlinFileExtractor(
156185
val parentId =
157186
if (parent.isAnonymousObject) {
158187
@Suppress("UNCHECKED_CAST")
159-
withSourceFile(c.fileOrNull!!).useAnonymousClass(c).javaResult.id as Label<out DbClass>
188+
useAnonymousClass(c).javaResult.id as Label<out DbClass>
160189
} else {
161190
useClassInstance(parent, listOf()).typeResult.id
162191
}
@@ -323,7 +352,7 @@ open class KotlinFileExtractor(
323352

324353
val id =
325354
if (f.isLocalFunction())
326-
withSourceFile(f.fileOrNull!!).getLocalFunctionLabels(f).function
355+
getLocalFunctionLabels(f).function
327356
else
328357
useFunction<DbCallable>(f)
329358

@@ -507,16 +536,15 @@ open class KotlinFileExtractor(
507536
}
508537
is IrClass -> {
509538
if (s.isAnonymousObject) {
510-
withSourceFile(s.fileOrNull!!).extractAnonymousClassStmt(s, callable, parent, idx)
539+
extractAnonymousClassStmt(s, callable, parent, idx)
511540
} else {
512541
logger.warnElement(Severity.ErrorSevere, "Found non anonymous IrClass as IrStatement: " + s.javaClass, s)
513542
}
514543
}
515544
is IrFunction -> {
516545
if (s.isLocalFunction()) {
517-
val extractor = withSourceFile(s.fileOrNull!!)
518-
val classId = extractor.extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType))
519-
extractor.extractAnonymousClassStmt(classId, s, callable, parent, idx)
546+
val classId = extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType))
547+
extractAnonymousClassStmt(classId, s, callable, parent, idx)
520548
} else {
521549
logger.warnElement(Severity.ErrorSevere, "Expected to find local function", s)
522550
}
@@ -684,7 +712,7 @@ open class KotlinFileExtractor(
684712
}
685713

686714
if (callTarget.isLocalFunction()) {
687-
val ids = withSourceFile(callTarget.fileOrNull!!).getLocalFunctionLabels(callTarget)
715+
val ids = getLocalFunctionLabels(callTarget)
688716

689717
val methodId = ids.function
690718
tw.writeCallableBinding(id, methodId)
@@ -1063,7 +1091,7 @@ open class KotlinFileExtractor(
10631091

10641092
val c = (e.type as IrSimpleType).classifier.owner as IrClass
10651093

1066-
type = withSourceFile(c.fileOrNull!!).useAnonymousClass(c)
1094+
type = useAnonymousClass(c)
10671095

10681096
@Suppress("UNCHECKED_CAST")
10691097
tw.writeIsAnonymClass(type.javaResult.id as Label<DbClass>, id)
@@ -1737,4 +1765,71 @@ open class KotlinFileExtractor(
17371765

17381766
private val IrType.isAnonymous: Boolean
17391767
get() = ((this as? IrSimpleType)?.classifier?.owner as? IrClass)?.isAnonymousObject ?: false
1768+
1769+
1770+
private val generatedLocalFunctionTypeMapping: MutableMap<IrFunction, LocalFunctionLabels> = mutableMapOf()
1771+
1772+
data class LocalFunctionLabels(val type: TypeResults, val constructor: Label<DbConstructor>, val function: Label<DbMethod>)
1773+
1774+
fun getLocalFunctionLabels(f: IrFunction): LocalFunctionLabels {
1775+
if (!f.isLocalFunction()){
1776+
logger.warnElement(Severity.ErrorSevere, "Extracting a non-local function as a local one", f)
1777+
}
1778+
1779+
var res = generatedLocalFunctionTypeMapping[f]
1780+
if (res == null) {
1781+
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
1782+
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
1783+
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
1784+
res = LocalFunctionLabels(
1785+
TypeResults(javaResult, kotlinResult),
1786+
tw.getFreshIdLabel(),
1787+
tw.getFreshIdLabel())
1788+
generatedLocalFunctionTypeMapping[f] = res
1789+
}
1790+
1791+
return res
1792+
}
1793+
1794+
fun extractGeneratedClass(localFunction: IrFunction, superTypes: List<IrType>) : Label<out DbClass> {
1795+
val ids = getLocalFunctionLabels(localFunction)
1796+
1797+
// Write class
1798+
@Suppress("UNCHECKED_CAST")
1799+
val id = ids.type.javaResult.id as Label<out DbClass>
1800+
val pkgId = extractPackage("")
1801+
tw.writeClasses(id, "", pkgId, id)
1802+
val locId = tw.getLocation(localFunction)
1803+
tw.writeHasLocation(id, locId)
1804+
1805+
// Extract local function as a member
1806+
extractFunction(localFunction, id)
1807+
1808+
// Extract constructor
1809+
tw.writeConstrs(ids.constructor, "", "", ids.type.javaResult.id, ids.type.kotlinResult.id, id, ids.constructor)
1810+
tw.writeHasLocation(ids.constructor, locId)
1811+
1812+
// Constructor body
1813+
val constructorBlockId = tw.getFreshIdLabel<DbBlock>()
1814+
tw.writeStmts_block(constructorBlockId, ids.constructor, 0, ids.constructor)
1815+
tw.writeHasLocation(constructorBlockId, locId)
1816+
1817+
// Super call
1818+
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
1819+
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.function)
1820+
1821+
val baseConstructor = superTypes.first().classOrNull!!.owner.declarations.find { it is IrFunction && it.symbol is IrConstructorSymbol }
1822+
val baseConstructorId = useFunction<DbConstructor>(baseConstructor as IrFunction)
1823+
1824+
tw.writeHasLocation(superCallId, locId)
1825+
@Suppress("UNCHECKED_CAST")
1826+
tw.writeCallableBinding(superCallId as Label<DbCaller>, baseConstructorId)
1827+
1828+
// TODO: We might need to add an `<obinit>` function, and a call to it to match other classes
1829+
1830+
addModifiers(id, "public", "static", "final")
1831+
extractClassSupertypes(superTypes, listOf(), id)
1832+
1833+
return id
1834+
}
17401835
}

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

Lines changed: 1 addition & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ package com.github.codeql
22

33
import com.github.codeql.comments.CommentExtractor
44
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
5-
import org.jetbrains.kotlin.ir.IrElement
65
import org.jetbrains.kotlin.ir.declarations.IrClass
76
import org.jetbrains.kotlin.ir.declarations.IrFile
8-
import org.jetbrains.kotlin.ir.declarations.IrFunction
9-
import org.jetbrains.kotlin.ir.declarations.IrVariable
107
import org.jetbrains.kotlin.ir.expressions.IrConst
118
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
12-
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
139
import org.jetbrains.kotlin.ir.types.IrSimpleType
14-
import org.jetbrains.kotlin.ir.types.IrType
15-
import org.jetbrains.kotlin.ir.types.classOrNull
1610
import org.jetbrains.kotlin.ir.util.packageFqName
1711
import org.jetbrains.kotlin.ir.util.IdSignature
1812

@@ -27,32 +21,7 @@ class KotlinSourceFileExtractor(
2721
) :
2822
KotlinFileExtractor(logger, tw, null, externalClassExtractor, primitiveTypeMapping, pluginContext) {
2923

30-
init {
31-
if (!stateCache.containsKey(file)){
32-
stateCache[file] = SourceFileExtractionState()
33-
}
34-
}
35-
36-
data class SourceFileExtractionState(val anonymousTypeMapping: MutableMap<IrClass, TypeResults> = mutableMapOf(),
37-
val generatedLocalFunctionTypeMapping: MutableMap<IrFunction, LocalFunctionLabels> = mutableMapOf(),
38-
/**
39-
* It is not easy to assign keys to local variables, so they get
40-
* given `*` IDs. However, the same variable may be referred to
41-
* from distant places in the IR, so we need a way to find out
42-
* which label is used for a given local variable. This information
43-
* is stored in this mapping.
44-
*/
45-
val variableLabelMapping: MutableMap<IrVariable, Label<DbLocalvar>> = mutableMapOf())
46-
47-
companion object {
48-
private val stateCache: MutableMap<IrFile, SourceFileExtractionState> = mutableMapOf()
49-
}
50-
51-
private val fileExtractionState by lazy {
52-
stateCache[file]!!
53-
}
54-
55-
private val fileClass by lazy {
24+
val fileClass by lazy {
5625
extractFileClass(file)
5726
}
5827

@@ -101,109 +70,4 @@ class KotlinSourceFileExtractor(
10170
return id
10271
}
10372

104-
/**
105-
* This returns the label used for a local variable, creating one
106-
* if none currently exists.
107-
*/
108-
fun <T> getVariableLabelFor(v: IrVariable): Label<DbLocalvar> {
109-
val maybeLabel = fileExtractionState.variableLabelMapping[v]
110-
if (maybeLabel == null) {
111-
val label = tw.getFreshIdLabel<DbLocalvar>()
112-
fileExtractionState.variableLabelMapping[v] = label
113-
return label
114-
} else {
115-
return maybeLabel
116-
}
117-
}
118-
119-
fun useAnonymousClass(c: IrClass): TypeResults {
120-
var res = fileExtractionState.anonymousTypeMapping[c]
121-
if (res == null) {
122-
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
123-
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
124-
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
125-
res = TypeResults(javaResult, kotlinResult)
126-
fileExtractionState.anonymousTypeMapping[c] = res
127-
}
128-
129-
return res
130-
}
131-
132-
data class LocalFunctionLabels(val type: TypeResults, val constructor: Label<DbConstructor>, val function: Label<DbMethod>)
133-
134-
fun getLocalFunctionLabels(f: IrFunction): LocalFunctionLabels {
135-
if (!f.isLocalFunction()){
136-
logger.warnElement(Severity.ErrorSevere, "Extracting a non-local function as a local one", f)
137-
}
138-
139-
var res = fileExtractionState.generatedLocalFunctionTypeMapping[f]
140-
if (res == null) {
141-
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
142-
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
143-
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
144-
res = LocalFunctionLabels(
145-
TypeResults(javaResult, kotlinResult),
146-
tw.getFreshIdLabel(),
147-
tw.getFreshIdLabel())
148-
fileExtractionState.generatedLocalFunctionTypeMapping[f] = res
149-
}
150-
151-
return res
152-
}
153-
154-
fun extractGeneratedClass(localFunction: IrFunction, superTypes: List<IrType>) : Label<out DbClass> {
155-
val ids = getLocalFunctionLabels(localFunction)
156-
157-
// Write class
158-
@Suppress("UNCHECKED_CAST")
159-
val id = ids.type.javaResult.id as Label<out DbClass>
160-
val pkgId = extractPackage("")
161-
tw.writeClasses(id, "", pkgId, id)
162-
val locId = tw.getLocation(localFunction)
163-
tw.writeHasLocation(id, locId)
164-
165-
// Extract local function as a member
166-
extractFunction(localFunction, id)
167-
168-
// Extract constructor
169-
tw.writeConstrs(ids.constructor, "", "", ids.type.javaResult.id, ids.type.kotlinResult.id, id, ids.constructor)
170-
tw.writeHasLocation(ids.constructor, locId)
171-
172-
// Constructor body
173-
val constructorBlockId = tw.getFreshIdLabel<DbBlock>()
174-
tw.writeStmts_block(constructorBlockId, ids.constructor, 0, ids.constructor)
175-
tw.writeHasLocation(constructorBlockId, locId)
176-
177-
// Super call
178-
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
179-
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.function)
180-
181-
val baseConstructor = superTypes.first().classOrNull!!.owner.declarations.find { it is IrFunction && it.symbol is IrConstructorSymbol }
182-
val baseConstructorId = useFunction<DbConstructor>(baseConstructor as IrFunction)
183-
184-
tw.writeHasLocation(superCallId, locId)
185-
@Suppress("UNCHECKED_CAST")
186-
tw.writeCallableBinding(superCallId as Label<DbCaller>, baseConstructorId)
187-
188-
// TODO: We might need to add an `<obinit>` function, and a call to it to match other classes
189-
190-
addModifiers(id, "public", "static", "final")
191-
extractClassSupertypes(superTypes, listOf(), id)
192-
193-
return id
194-
}
195-
196-
fun extractAnonymousClassStmt(c: IrClass, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
197-
@Suppress("UNCHECKED_CAST")
198-
val id = extractClassSource(c) as Label<out DbClass>
199-
extractAnonymousClassStmt(id, c, callable, parent, idx)
200-
}
201-
202-
fun extractAnonymousClassStmt(id: Label<out DbClass>, locElement: IrElement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
203-
val stmtId = tw.getFreshIdLabel<DbAnonymousclassdeclstmt>()
204-
tw.writeStmts_anonymousclassdeclstmt(stmtId, parent, idx, callable)
205-
tw.writeKtAnonymousClassDeclarationStmts(stmtId, id)
206-
val locId = tw.getLocation(locElement)
207-
tw.writeHasLocation(stmtId, locId)
208-
}
20973
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ open class KotlinUsesExtractor(
6666
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
6767
?.owner
6868

69-
fun withSourceFile(clsFile: IrFile): KotlinSourceFileExtractor {
69+
private fun withSourceFile(clsFile: IrFile): KotlinFileExtractor {
7070
val newTrapWriter = tw.makeSourceFileTrapWriter(clsFile, false)
7171
val newLogger = FileLogger(logger.logCounter, newTrapWriter)
7272
return KotlinSourceFileExtractor(newLogger, newTrapWriter, clsFile, externalClassExtractor, primitiveTypeMapping, pluginContext)
@@ -75,7 +75,7 @@ open class KotlinUsesExtractor(
7575
/**
7676
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.
7777
*/
78-
fun withSourceFileOfClass(cls: IrClass): KotlinFileExtractor {
78+
private fun withSourceFileOfClass(cls: IrClass): KotlinFileExtractor {
7979
val clsFile = cls.fileOrNull
8080

8181
if (isExternalDeclaration(cls) || clsFile == null) {
@@ -720,8 +720,8 @@ class X {
720720
fun useTypeAlias(ta: IrTypeAlias): Label<out DbKt_type_alias> =
721721
tw.getLabelFor(getTypeAliasLabel(ta))
722722

723-
fun useVariable(v: IrVariable): Label<DbLocalvar> {
724-
return withSourceFile(v.fileOrNull!!).getVariableLabelFor<DbLocalvar>(v)
723+
fun useVariable(v: IrVariable): Label<out DbLocalvar> {
724+
return tw.getVariableLabelFor<DbLocalvar>(v)
725725
}
726726

727727
fun withQuestionMark(t: IrType, hasQuestionMark: Boolean) = if(hasQuestionMark) t.makeNullable() else t.makeNotNull()

0 commit comments

Comments
 (0)