diff --git a/java/kotlin-extractor2/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor2/src/main/kotlin/KotlinFileExtractor.kt index a090c71d714..ab6c73f4f5d 100644 --- a/java/kotlin-extractor2/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor2/src/main/kotlin/KotlinFileExtractor.kt @@ -5518,122 +5518,6 @@ OLD: KE1 addModifiers(id, "private") } - /** Extracts the class around a local function, a lambda, or a function reference. */ - private fun extractGeneratedClass( - ids: GeneratedClassLabels, - superTypes: List, - locId: Label, - elementToReportOn: IrElement, - declarationParent: IrDeclarationParent, - compilerGeneratedKindOverride: CompilerGeneratedKinds? = null, - superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() }, - extractSuperconstructorArgs: (Label) -> Unit = {}, - ): Label { - // Write class - val id = ids.type.javaResult.id.cast() - val pkgId = extractPackage("") - tw.writeClasses_or_interfaces(id, "", pkgId, id) - tw.writeCompiler_generated( - id, - (compilerGeneratedKindOverride ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind - ) - tw.writeHasLocation(id, locId) - - // Extract constructor - val unitType = useType(pluginContext.irBuiltIns.unitType, TypeContext.RETURN) - tw.writeConstrs(ids.constructor, "", "", unitType.javaResult.id, id, ids.constructor) - tw.writeConstrsKotlinType(ids.constructor, unitType.kotlinResult.id) - tw.writeHasLocation(ids.constructor, locId) - addModifiers(ids.constructor, "public") - - // Constructor body - val constructorBlockId = ids.constructorBlock - tw.writeStmts_block(constructorBlockId, ids.constructor, 0, ids.constructor) - tw.writeHasLocation(constructorBlockId, locId) - - // Super call - val baseClass = superTypes.first().classOrNull - if (baseClass == null) { - logger.warnElement("Cannot find base class", elementToReportOn) - } else { - val baseConstructor = - baseClass.owner.declarations.findSubType { - it.symbol is IrConstructorSymbol && superConstructorSelector(it) - } - if (baseConstructor == null) { - logger.warnElement("Cannot find base constructor", elementToReportOn) - } else { - val baseConstructorId = useFunction(baseConstructor) - if (baseConstructorId == null) { - logger.errorElement("Cannot find base constructor ID", elementToReportOn) - } else { - val superCallId = tw.getFreshIdLabel() - tw.writeStmts_superconstructorinvocationstmt( - superCallId, - constructorBlockId, - 0, - ids.constructor - ) - - tw.writeHasLocation(superCallId, locId) - tw.writeCallableBinding(superCallId.cast(), baseConstructorId) - extractSuperconstructorArgs(superCallId) - } - } - } - - addModifiers(id, "final") - addVisibilityModifierToLocalOrAnonymousClass(id) - extractClassSupertypes( - superTypes, - listOf(), - id, - isInterface = false, - inReceiverContext = true - ) - - extractEnclosingClass(declarationParent, id, null, locId, listOf()) - - return id - } - - /** - * Extracts the class around a local function or a lambda. The superclass must have a no-arg - * constructor. - */ - private fun extractGeneratedClass( - localFunction: IrFunction, - superTypes: List, - compilerGeneratedKindOverride: CompilerGeneratedKinds? = null - ): Label { - with("generated class", localFunction) { - val ids = getLocallyVisibleFunctionLabels(localFunction) - - val id = - extractGeneratedClass( - ids, - superTypes, - tw.getLocation(localFunction), - localFunction, - localFunction.parent, - compilerGeneratedKindOverride = compilerGeneratedKindOverride - ) - - // Extract local function as a member - extractFunction( - localFunction, - id, - extractBody = true, - extractMethodAndParameterTypeAccesses = true, - extractAnnotations = false, - null, - listOf() - ) - - return id - } - } - inner class DeclarationStackAdjuster( val declaration: KaDeclarationSymbol, val overriddenAttributes: OverriddenFunctionAttributes? = null @@ -5692,21 +5576,5 @@ OLD: KE1 logger.errorElement("Couldn't find current declaration parent", elementToReportOn) return dp } - - private enum class CompilerGeneratedKinds(val kind: Int) { - DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS(1), - GENERATED_DATA_CLASS_MEMBER(2), - DEFAULT_PROPERTY_ACCESSOR(3), - CLASS_INITIALISATION_METHOD(4), - ENUM_CLASS_SPECIAL_MEMBER(5), - DELEGATED_PROPERTY_GETTER(6), - DELEGATED_PROPERTY_SETTER(7), - JVMSTATIC_PROXY_METHOD(8), - JVMOVERLOADS_METHOD(9), - DEFAULT_ARGUMENTS_METHOD(10), - INTERFACE_FORWARDER(11), - ENUM_CONSTRUCTOR_ARGUMENT(12), - CALLABLE_CLASS(13), - } */ } diff --git a/java/kotlin-extractor2/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor2/src/main/kotlin/KotlinUsesExtractor.kt index 08cc416c06b..f32b3c643d6 100644 --- a/java/kotlin-extractor2/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor2/src/main/kotlin/KotlinUsesExtractor.kt @@ -1132,57 +1132,6 @@ open class KotlinUsesExtractor( .firstOrNull() ?: false - /** - * Class to hold labels for generated classes around local functions, lambdas, function - * references, and property references. - */ - open class GeneratedClassLabels( - val type: TypeResults, - val constructor: Label, - val constructorBlock: Label - ) - - /** - * Class to hold labels generated for locally visible functions, such as - * - local functions, - * - lambdas, and - * - wrappers around function references. - */ - class LocallyVisibleFunctionLabels( - type: TypeResults, - constructor: Label, - constructorBlock: Label, - val function: Label - ) : GeneratedClassLabels(type, constructor, constructorBlock) - - /** - * Gets the labels for functions belonging to - * - local functions, and - * - lambdas. - */ - fun getLocallyVisibleFunctionLabels(f: IrFunction): LocallyVisibleFunctionLabels { - if (!f.isLocalFunction()) { - logger.error("Extracting a non-local function as a local one") - } - - var res = tw.lm.locallyVisibleFunctionLabelMapping[f] - if (res == null) { - val javaResult = TypeResult(tw.getFreshIdLabel(), "", "") - val kotlinResult = TypeResult(tw.getFreshIdLabel(), "", "") - tw.writeKt_notnull_types(kotlinResult.id, javaResult.id) - res = - LocallyVisibleFunctionLabels( - TypeResults(javaResult, kotlinResult), - tw.getFreshIdLabel(), - tw.getFreshIdLabel(), - tw.getFreshIdLabel() - ) - tw.lm.locallyVisibleFunctionLabelMapping[f] = res - } - - return res - } - fun getExistingLocallyVisibleFunctionLabel(f: IrFunction): Label? { if (!f.isLocalFunction()) { return null diff --git a/java/kotlin-extractor2/src/main/kotlin/TrapWriter.kt b/java/kotlin-extractor2/src/main/kotlin/TrapWriter.kt index 13838106f49..c47e300b38e 100644 --- a/java/kotlin-extractor2/src/main/kotlin/TrapWriter.kt +++ b/java/kotlin-extractor2/src/main/kotlin/TrapWriter.kt @@ -1,14 +1,12 @@ package com.github.codeql -/* -OLD: KE1 -import com.github.codeql.KotlinUsesExtractor.LocallyVisibleFunctionLabels -*/ +import LocallyVisibleFunctionLabels import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.semmle.extractor.java.PopulateFile import com.semmle.util.unicode.UTF8Util +import org.jetbrains.kotlin.analysis.api.symbols.KaFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.KaVariableSymbol import java.io.BufferedWriter import java.io.File @@ -62,13 +60,37 @@ class TrapLabelManager { } } + private val locallyVisibleFunctionLabelMapping: MutableMap = + mutableMapOf() + + fun getLocallyVisibleFunctionLabelMapping( + key: KaFunctionSymbol + ): LocallyVisibleFunctionLabels { + lock.withLock { + return locallyVisibleFunctionLabelMapping[key]!! + } + } + + fun getOrAddLocallyVisibleFunctionLabelMapping( + key: KaFunctionSymbol, + add: (KaFunctionSymbol) -> LocallyVisibleFunctionLabels + ): LocallyVisibleFunctionLabels { + lock.withLock { + val res = locallyVisibleFunctionLabelMapping[key] + if (res != null) { + return res + } + + val labels = add(key) + locallyVisibleFunctionLabelMapping[key] = labels + return labels + } + } + /* OLD: KE1 val anonymousTypeMapping: MutableMap = mutableMapOf() - val locallyVisibleFunctionLabelMapping: MutableMap = - mutableMapOf() - /** * The set of labels of generic specialisations that we have extracted in this TRAP file. We * can't easily avoid duplication between TRAP files, as the labels contain references to other diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt b/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt index 30a3de415d5..786296b7ec9 100644 --- a/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt +++ b/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt @@ -1,6 +1,7 @@ package com.github.codeql import com.github.codeql.KotlinFileExtractor.StmtExprParent +import extractFunctionLiteral import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.analysis.api.KaSession import org.jetbrains.kotlin.analysis.api.resolution.* @@ -18,7 +19,6 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.parsing.parseNumericLiteral import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.utils.mapToIndex context(KaSession) private fun KotlinFileExtractor.extractExpressionBody(e: KtExpression, callable: Label) { @@ -1235,91 +1235,6 @@ private fun KotlinFileExtractor.extractExpression( is IrFunctionReference -> { extractFunctionReference(e, parent, callable) } - is IrFunctionExpression -> { - /* - * Extract generated class: - * ``` - * class C : Any, kotlin.FunctionI { - * constructor() { super(); } - * fun invoke(a0:T0, a1:T1, ... aI: TI): R { ... } - * } - * ``` - * or in case of big arity lambdas - * ``` - * class C : Any, kotlin.FunctionN { - * constructor() { super(); } - * fun invoke(a0:T0, a1:T1, ... aI: TI): R { ... } - * fun invoke(vararg args: Any?): R { - * return invoke(args[0] as T0, args[1] as T1, ..., args[I] as TI) - * } - * } - * ``` - **/ - - val ids = getLocallyVisibleFunctionLabels(e.function) - val locId = tw.getLocation(e) - - val ext = e.function.extensionReceiverParameter - val parameters = - if (ext != null) { - listOf(ext) + e.function.valueParameters - } else { - e.function.valueParameters - } - - var types = parameters.map { it.type } - types += e.function.returnType - - val isBigArity = types.size > BuiltInFunctionArity.BIG_ARITY - if (isBigArity) { - implementFunctionNInvoke(e.function, ids, locId, parameters) - } else { - addModifiers(ids.function, "override") - } - - val exprParent = parent.expr(e, callable) - val idLambdaExpr = tw.getFreshIdLabel() - tw.writeExprs_lambdaexpr( - idLambdaExpr, - ids.type.javaResult.id, - exprParent.parent, - exprParent.idx - ) - tw.writeExprsKotlinType(idLambdaExpr, ids.type.kotlinResult.id) - extractExprContext(idLambdaExpr, locId, callable, exprParent.enclosingStmt) - tw.writeCallableBinding(idLambdaExpr, ids.constructor) - - // todo: fix hard coded block body of lambda - tw.writeLambdaKind(idLambdaExpr, 1) - - val fnInterfaceType = getFunctionalInterfaceType(types) - if (fnInterfaceType == null) { - logger.warnElement( - "Cannot find functional interface type for function expression", - e - ) - } else { - val id = - extractGeneratedClass( - e - .function, // We're adding this function as a member, and - // changing its name to `invoke` to implement - // `kotlin.FunctionX<,,,>.invoke(,,)` - listOf(pluginContext.irBuiltIns.anyType, fnInterfaceType) - ) - - extractTypeAccessRecursive( - fnInterfaceType, - locId, - idLambdaExpr, - -3, - callable, - exprParent.enclosingStmt - ) - - tw.writeIsAnonymClass(id, idLambdaExpr) - } - } is IrClassReference -> { val exprParent = parent.expr(e, callable) extractClassReference( @@ -1353,6 +1268,16 @@ private fun KotlinFileExtractor.extractExpression( ) } */ + + is KtLambdaExpression -> { + // Propagate extraction to the wrapped function literal: + return extractExpression(e.functionLiteral, callable, parent) + } + + is KtFunctionLiteral -> { + return extractFunctionLiteral(e, callable, parent) + } + else -> { logger.errorElement("Unrecognised KtExpression: " + e.javaClass, e) } diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/Function.kt b/java/kotlin-extractor2/src/main/kotlin/entities/Function.kt index ae7bc63c1ed..bd2a11e1de4 100644 --- a/java/kotlin-extractor2/src/main/kotlin/entities/Function.kt +++ b/java/kotlin-extractor2/src/main/kotlin/entities/Function.kt @@ -212,13 +212,11 @@ private val IrDeclaration.isAnonymousFunction */ context(KaSession) fun KotlinUsesExtractor.getFunctionShortName(f: KaFunctionSymbol): FunctionNames { - /* OLD: KE1 - if (f.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction) + if (f.isLocal) return FunctionNames( - OperatorNameConventions.INVOKE.asString(), - OperatorNameConventions.INVOKE.asString() + "invoke", + "invoke" ) - */ fun getSuffixIfInternal() = "" /* OLD: KE1 if ( @@ -281,10 +279,12 @@ fun KotlinUsesExtractor.getFunctionShortName(f: KaFunctionSymbol): FunctionNames ) } } + + // TODO: Justify or drop !! + val name = if (f is KaConstructorSymbol) f.containingSymbol!!.name!! else f.name!! return FunctionNames( - // TODO: Justify or drop !! - getJvmName(f) ?: "${f.name!!.asString()}${getSuffixIfInternal()}", - f.name!!.identifier + getJvmName(f) ?: "${name.asString()}${getSuffixIfInternal()}", + name.identifier ) } @@ -534,6 +534,7 @@ OLD: KE1 } else { val shortNames = getFunctionShortName(f) */ + val shortNames = getFunctionShortName(f) val methodId = id.cast() extractMethod( methodId, @@ -541,7 +542,7 @@ OLD: KE1 OLD: KE1 locId, */ - f.name!!.asString(), // TODO: Remove !!, // OLD: KE1: shortNames.nameInDB, + shortNames.nameInDB, f.returnType, // OLD: KE1: substReturnType, paramsSignature, parentId, @@ -701,13 +702,10 @@ fun KotlinUsesExtractor.useFunction( noReplace: Boolean = false */ ): Label { - /* - OLD: KE1 - if (f.isLocalFunction()) { - val ids = getLocallyVisibleFunctionLabels(f) - return ids.function.cast() - } - */ + if (f.isLocal) { + val ids = tw.lm.getLocallyVisibleFunctionLabelMapping(f) + return ids.function.cast() + } val javaFun = f // TODO: kotlinFunctionToJavaEquivalent(f, noReplace) return useFunction(f, javaFun, parentId /* TODO , classTypeArgsIncludingOuterClasses */) } diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/FunctionalInterface.kt b/java/kotlin-extractor2/src/main/kotlin/entities/FunctionalInterface.kt new file mode 100644 index 00000000000..5cc73d1c17a --- /dev/null +++ b/java/kotlin-extractor2/src/main/kotlin/entities/FunctionalInterface.kt @@ -0,0 +1,315 @@ +import com.github.codeql.* +import com.github.codeql.KotlinFileExtractor.StmtExprParent +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.KaExperimentalApi +import org.jetbrains.kotlin.analysis.api.KaSession +import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.types.KaClassType +import org.jetbrains.kotlin.analysis.api.types.KaType +import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtFunctionLiteral + +/** + * Extract a lambda expression as a generated anonymous class implementing + * the appropriate functional interface. + * + * Extract generated class: + * ``` + * class C : Any, kotlin.FunctionI { + * constructor() { super(); } + * fun invoke(a0:T0, a1:T1, ... aI: TI): R { ... } + * } + * ``` + * or in case of big arity lambdas + * ``` + * class C : Any, kotlin.FunctionN { + * constructor() { super(); } + * fun invoke(a0:T0, a1:T1, ... aI: TI): R { ... } + * fun invoke(vararg args: Any?): R { + * return invoke(args[0] as T0, args[1] as T1, ..., args[I] as TI) + * } + * } + * ``` + **/ +context(KaSession) +fun KotlinFileExtractor.extractFunctionLiteral( + e: KtFunctionLiteral, + callable: Label, + parent: StmtExprParent +): Label { + + val locId = tw.getLocation(e) + val functionSymbol = e.symbol + val ids = getLocallyVisibleFunctionLabels(functionSymbol) + + // todo: is it possible that the receiver parameter is a dispatch receiver? + val ext = if (functionSymbol.isExtension) functionSymbol.receiverParameter else null + val parameterTypes = functionSymbol.valueParameters.map { (it as KaVariableSymbol).returnType }.toMutableList() + if (ext != null) { + parameterTypes.add(0, ext.type) + } + + parameterTypes += functionSymbol.returnType + + val isBigArity = parameterTypes.size > BuiltInFunctionArity.BIG_ARITY + if (isBigArity) { + // OLD: KE1 + // implementFunctionNInvoke(e.function, ids, locId, parameters) + } else { + addModifiers(ids.function, "override") + } + + val exprParent = parent.expr(e, callable) + val idLambdaExpr = tw.getFreshIdLabel() + tw.writeExprs_lambdaexpr( + idLambdaExpr, + ids.type.javaResult.id, + exprParent.parent, + exprParent.idx + ) + tw.writeExprsKotlinType(idLambdaExpr, ids.type.kotlinResult.id) + extractExprContext(idLambdaExpr, locId, callable, exprParent.enclosingStmt) + tw.writeCallableBinding(idLambdaExpr, ids.constructor) + + // todo: fix hard coded block body of lambda + tw.writeLambdaKind(idLambdaExpr, 1) + + val functionType = + e.functionType // TODO: change this type for BIG_ARITY lambdas, this should be kotlin.FunctionN and not kotlin.Function33<....,R>. The latter doesn't exist. + if (!functionType.isFunctionType) { + logger.warnElement( + "Cannot find functional interface type for function expression", + e + ) + } else { + val id = + extractGeneratedClass( + // We're adding this function as a member, and + // changing its name to `invoke` to implement + // `kotlin.FunctionX<,,,>.invoke(,,)` + functionSymbol, + e, + listOf(builtinTypes.any, functionType) + ) + + /* + OLD: KE1 + extractTypeAccessRecursive( + fnInterfaceType, + locId, + idLambdaExpr, + -3, + callable, + exprParent.enclosingStmt + ) + */ + + tw.writeIsAnonymClass(id, idLambdaExpr) + } + + return idLambdaExpr +} + +/** + * Gets the labels for functions belonging to + * - local functions, and + * - lambdas. + */ +private fun KotlinFileExtractor.getLocallyVisibleFunctionLabels(f: KaAnonymousFunctionSymbol): LocallyVisibleFunctionLabels { + if (!f.isLocal) { + logger.error("Extracting a non-local function as a local one") + } + + return tw.lm.getOrAddLocallyVisibleFunctionLabelMapping(f) { + val classId = tw.getFreshIdLabel() + val javaResult = TypeResult(classId/* , "TODO", "TODO" */) + val kotlinTypeId = + tw.getLabelFor("@\"kt_class;{$classId}\"") { + tw.writeKt_class_types(it, classId) + } + val kotlinResult = TypeResult(kotlinTypeId /* , "TODO", "TODO" */) + + LocallyVisibleFunctionLabels( + type = TypeResults(javaResult, kotlinResult), + constructor = tw.getFreshIdLabel(), + constructorBlock = tw.getFreshIdLabel(), + function = tw.getFreshIdLabel() + ) + } +} + +/** + * Extracts the class around a local function or a lambda. The superclass must have a no-arg + * constructor. + */ +context(KaSession) +private fun KotlinFileExtractor.extractGeneratedClass( + localFunction: KaFunctionSymbol, + elementToReportOn: PsiElement, + superTypes: List, + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null // OLD: KE1 +): Label { + val ids = tw.lm.getLocallyVisibleFunctionLabelMapping(localFunction) + + val id = + extractGeneratedClass( + ids, + superTypes, + tw.getLocation(elementToReportOn), + elementToReportOn, + compilerGeneratedKindOverride = compilerGeneratedKindOverride + /* + OLD: KE1 + localFunction.parent, + */ + ) + + // Extract local function as a member + extractFunction( + localFunction, + id, + /* + OLD: KE1 + extractBody = true, + extractMethodAndParameterTypeAccesses = true, + extractAnnotations = false, + null, + listOf() + */ + ) + + return id +} + +/** Extracts the class around a local function, a lambda, or a function reference. */ +context(KaSession) +@OptIn(KaExperimentalApi::class) +private fun KotlinFileExtractor.extractGeneratedClass( + ids: GeneratedClassLabels, + superTypes: List, + locId: Label, + elementToReportOn: PsiElement, + compilerGeneratedKindOverride: CompilerGeneratedKinds? = null, + /* + OLD: KE1 + declarationParent: IrDeclarationParent, + superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() }, + extractSuperconstructorArgs: (Label) -> Unit = {}, + */ +): Label { + // Write class + val id = ids.type.javaResult.id.cast() + val pkgId = extractPackage("") + tw.writeClasses_or_interfaces(id, "", pkgId, id) + tw.writeCompiler_generated( + id, + (compilerGeneratedKindOverride ?: CompilerGeneratedKinds.CALLABLE_CLASS).kind + ) + tw.writeHasLocation(id, locId) + + // Extract constructor + val unitType = useType(builtinTypes.unit/*TODO , TypeContext.RETURN*/) + tw.writeConstrs(ids.constructor, "", "", unitType.javaResult.id, id, ids.constructor) + tw.writeConstrsKotlinType(ids.constructor, unitType.kotlinResult.id) + tw.writeHasLocation(ids.constructor, locId) + addModifiers(ids.constructor, "public") + + // Constructor body + val constructorBlockId = ids.constructorBlock + tw.writeStmts_block(constructorBlockId, ids.constructor, 0, ids.constructor) + tw.writeHasLocation(constructorBlockId, locId) + + // Super call + // TODO: we should check if this is class or not + val baseClass = superTypes.first() as? KaClassType // superTypes.first().classOrNull + if (baseClass == null) { + logger.warnElement("Cannot find base class", elementToReportOn) + } else { + val baseConstructor = + baseClass.scope?.declarationScope?.constructors?.find { + // TODO: OLD KE1 superConstructorSelector(it) + true + } + if (baseConstructor == null) { + logger.warnElement("Cannot find base constructor", elementToReportOn) + } else { + val baseConstructorParentId = useDeclarationParentOf(baseConstructor, false) + if (baseConstructorParentId == null) { + logger.errorElement("Cannot find base constructor ID", elementToReportOn) + } else { + val baseConstructorId = useFunction(baseConstructor, baseConstructorParentId) + val superCallId = tw.getFreshIdLabel() + tw.writeStmts_superconstructorinvocationstmt( + superCallId, + constructorBlockId, + 0, + ids.constructor + ) + + tw.writeHasLocation(superCallId, locId) + tw.writeCallableBinding(superCallId.cast(), baseConstructorId) + // TODO: OLD KE1 extractSuperconstructorArgs(superCallId) + } + } + } + + addModifiers(id, "final") + addModifiers(id, "private") + //OLD: KE1 + // extractClassSupertypes( + // superTypes, + // //listOf(), + // id, + // //isInterface = false, + // //inReceiverContext = true + // ) + + // TODO: OLD KE1: + // extractEnclosingClass(declarationParent, id, null, locId, listOf()) + + return id +} + +/** + * Class to hold labels for generated classes around local functions, lambdas, function + * references, and property references. + */ +open class GeneratedClassLabels( + val type: TypeResults, + val constructor: Label, + val constructorBlock: Label +) + +/** + * Class to hold labels generated for locally visible functions, such as + * - local functions, + * - lambdas, and + * - wrappers around function references. + */ +class LocallyVisibleFunctionLabels( + type: TypeResults, + constructor: Label, + constructorBlock: Label, + val function: Label +) : GeneratedClassLabels(type, constructor, constructorBlock) + + +private enum class CompilerGeneratedKinds(val kind: Int) { + // OLD: KE1 + // DECLARING_CLASSES_OF_ADAPTER_FUNCTIONS(1), + // GENERATED_DATA_CLASS_MEMBER(2), + // DEFAULT_PROPERTY_ACCESSOR(3), + // CLASS_INITIALISATION_METHOD(4), + // ENUM_CLASS_SPECIAL_MEMBER(5), + // DELEGATED_PROPERTY_GETTER(6), + // DELEGATED_PROPERTY_SETTER(7), + // JVMSTATIC_PROXY_METHOD(8), + // JVMOVERLOADS_METHOD(9), + // DEFAULT_ARGUMENTS_METHOD(10), + // INTERFACE_FORWARDER(11), + // ENUM_CONSTRUCTOR_ARGUMENT(12), + CALLABLE_CLASS(13), +} \ No newline at end of file