@@ -457,53 +457,93 @@ open class KotlinFileExtractor(
457457 extractDeclInitializers(c.declarations, false ) { Pair (blockId, obinitId) }
458458 }
459459
460- fun extractAnnotations (c : IrClass ): Int {
461- var count = 0
462- for (constructorCall : IrConstructorCall in c.annotations) {
463-
464- // todo: do not extract JvmName, what else?
460+ private fun extractAnnotations (c : IrClass ) {
461+ for ((idx, constructorCall : IrConstructorCall ) in c.annotations.withIndex()) {
462+ extractAnnotation(constructorCall, useClassSource(c), idx)
463+ }
464+ }
465465
466- val t = useType(constructorCall.type)
467- val annotated = useClassSource(c)
466+ private fun extractAnnotation (
467+ constructorCall : IrConstructorCall ,
468+ parent : Label <out DbExprparent >,
469+ idx : Int
470+ ): Label <out DbExpr > {
471+ val t = useType(constructorCall.type)
468472
469- val id = tw.getLabelFor<DbDeclannotation >(" @\" annotation;{$annotated };{${t.javaResult.id} }\" " )
470- tw.writeExprs_declannotation(id, t.javaResult.id, annotated, count ++ )
471- tw.writeExprsKotlinType(id, t.kotlinResult.id)
473+ val id = tw.getLabelFor<DbDeclannotation >(" @\" annotation;{$parent };{${t.javaResult.id} }\" " )
474+ tw.writeExprs_declannotation(id, t.javaResult.id, parent, idx )
475+ tw.writeExprsKotlinType(id, t.kotlinResult.id)
472476
473- val locId = tw.getLocation(constructorCall)
474- tw.writeHasLocation(id, locId)
477+ val locId = tw.getLocation(constructorCall)
478+ tw.writeHasLocation(id, locId)
475479
476- for (i in 0 until constructorCall.valueArgumentsCount) {
477- val param = constructorCall.symbol.owner.valueParameters[i]
478- val prop = constructorCall.symbol.owner.parentAsClass.declarations.filterIsInstance<IrProperty >().firstOrNull { it.name == param.name }
479- if (prop == null ) {
480- continue
481- }
480+ for (i in 0 until constructorCall.valueArgumentsCount) {
481+ val param = constructorCall.symbol.owner.valueParameters[i]
482+ val prop = constructorCall.symbol.owner.parentAsClass.declarations
483+ .filterIsInstance<IrProperty >()
484+ .first { it.name == param.name }
485+ val v = constructorCall.getValueArgument(i) ? : param.defaultValue?.expression
486+ val exprId = extractAnnotationValueExpression(v, id, i)
487+ if (exprId != null ) {
488+ tw.writeAnnotValue(id, useFunction(prop.getter!! ), exprId)
489+ }
490+ }
491+ return id
492+ }
482493
483- val v = constructorCall.getValueArgument(i) ? : param.defaultValue?.expression
494+ private fun extractAnnotationValueExpression (
495+ v : IrExpression ? ,
496+ parent : Label <out DbExprparent >,
497+ idx : Int ): Label <out DbExpr >? {
484498
485- when (v) {
486- is IrConst <* > -> {
487- val exprId = extractConstant(v, id, i)
488- if (exprId != null ) {
499+ return when (v) {
500+ is IrConst <* > -> {
501+ extractConstant(v, parent, idx)
502+ }
503+ is IrGetEnumValue -> {
504+ extractEnumValue(v, parent, idx, null , null )
505+ }
506+ is IrClassReference -> {
507+ extractClassReference(v, parent, idx, null , null )
508+ }
509+ is IrConstructorCall -> {
510+ extractAnnotation(v, parent, idx)
511+ }
512+ is IrVararg -> {
513+ val eId = tw.getFreshIdLabel<DbArrayinit >()
514+ val type = useType(v.type)
515+ tw.writeExprs_arrayinit(eId, type.javaResult.id, parent, idx)
516+ tw.writeExprsKotlinType(eId, type.kotlinResult.id)
517+ tw.writeHasLocation(eId, tw.getLocation(v))
489518
490- tw.writeAnnotValue(id, useFunction<DbMethod >(prop.getter!! ), exprId)
519+ v.elements.forEachIndexed { index, irVarargElement -> run {
520+ val argExpr = when (irVarargElement) {
521+ is IrExpression -> irVarargElement
522+ is IrSpreadElement -> irVarargElement.expression
523+ else -> {
524+ logger.errorElement(" Unrecognised IrVarargElement: " + irVarargElement.javaClass, irVarargElement)
525+ null
491526 }
492527 }
493- /*
494- Integer types;
495- Enum types;
496- String type;
497- Classes;
498- Other annotation types;
499- Arrays of any type listed above.
500- */
528+ extractAnnotationValueExpression(argExpr, eId, index)
529+ } }
530+
531+ eId
532+ }
533+ // is IrErrorExpression
534+ // null
535+ else -> {
536+ val eId = tw.getFreshIdLabel<DbErrorexpr >()
537+ val type = useType(v?.type ? : pluginContext.irBuiltIns.unitType)
538+ tw.writeExprs_errorexpr(eId, type.javaResult.id, parent, idx)
539+ tw.writeExprsKotlinType(eId, type.kotlinResult.id)
501540
541+ if (v != null ) {
542+ tw.writeHasLocation(eId, tw.getLocation(v))
502543 }
544+ eId
503545 }
504546 }
505-
506- return count
507547 }
508548
509549 fun extractClassSource (c : IrClass , extractDeclarations : Boolean , extractStaticInitializer : Boolean , extractPrivateMembers : Boolean , extractFunctionBodies : Boolean ): Label <out DbClassorinterface > {
@@ -2160,7 +2200,7 @@ open class KotlinFileExtractor(
21602200 extractValueArguments(argParent, idxOffset)
21612201 }
21622202
2163- private fun extractStaticTypeAccessQualifierUnchecked (parent : IrDeclarationParent , parentExpr : Label <out DbExprparent >, locId : Label <DbLocation >, enclosingCallable : Label <out DbCallable >, enclosingStmt : Label <out DbStmt >) {
2203+ private fun extractStaticTypeAccessQualifierUnchecked (parent : IrDeclarationParent , parentExpr : Label <out DbExprparent >, locId : Label <DbLocation >, enclosingCallable : Label <out DbCallable >? , enclosingStmt : Label <out DbStmt >? ) {
21642204 if (parent is IrClass ) {
21652205 extractTypeAccessRecursive(parent.toRawType(), locId, parentExpr, - 1 , enclosingCallable, enclosingStmt)
21662206 } else if (parent is IrFile ) {
@@ -2170,7 +2210,7 @@ open class KotlinFileExtractor(
21702210 }
21712211 }
21722212
2173- private fun extractStaticTypeAccessQualifier (target : IrDeclaration , parentExpr : Label <out DbExprparent >, locId : Label <DbLocation >, enclosingCallable : Label <out DbCallable >, enclosingStmt : Label <out DbStmt >) {
2213+ private fun extractStaticTypeAccessQualifier (target : IrDeclaration , parentExpr : Label <out DbExprparent >, locId : Label <DbLocation >, enclosingCallable : Label <out DbCallable >? , enclosingStmt : Label <out DbStmt >? ) {
21742214 if (target.shouldExtractAsStatic) {
21752215 extractStaticTypeAccessQualifierUnchecked(target.parent, parentExpr, locId, enclosingCallable, enclosingStmt)
21762216 }
@@ -3691,19 +3731,7 @@ open class KotlinFileExtractor(
36913731 }
36923732 is IrGetEnumValue -> {
36933733 val exprParent = parent.expr(e, callable)
3694- val id = tw.getFreshIdLabel<DbVaraccess >()
3695- val type = useType(e.type)
3696- val locId = tw.getLocation(e)
3697- tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
3698- tw.writeExprsKotlinType(id, type.kotlinResult.id)
3699- extractExprContext(id, locId, callable, exprParent.enclosingStmt)
3700-
3701- val owner = getBoundSymbolOwner(e.symbol, e) ? : return
3702-
3703- val vId = useEnumEntry(owner)
3704- tw.writeVariableBinding(id, vId)
3705-
3706- extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
3734+ val id = extractEnumValue(e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
37073735 }
37083736 is IrSetValue ,
37093737 is IrSetField -> {
@@ -3947,14 +3975,7 @@ open class KotlinFileExtractor(
39473975 }
39483976 is IrClassReference -> {
39493977 val exprParent = parent.expr(e, callable)
3950- val id = tw.getFreshIdLabel<DbTypeliteral >()
3951- val locId = tw.getLocation(e)
3952- val type = useType(e.type)
3953- tw.writeExprs_typeliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx)
3954- tw.writeExprsKotlinType(id, type.kotlinResult.id)
3955- extractExprContext(id, locId, callable, exprParent.enclosingStmt)
3956-
3957- extractTypeAccessRecursive(e.classType, locId, id, 0 , callable, exprParent.enclosingStmt)
3978+ extractClassReference(e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
39583979 }
39593980 is IrPropertyReference -> {
39603981 extractPropertyReference(" property reference" , e, e.getter, e.setter, e.field, parent, callable)
@@ -4153,6 +4174,53 @@ open class KotlinFileExtractor(
41534174 extractExpressionExpr(loop.condition, callable, id, 0 , id)
41544175 }
41554176
4177+ private fun extractClassReference (
4178+ e : IrClassReference ,
4179+ parent : Label <out DbExprparent >,
4180+ idx : Int ,
4181+ enclosingCallable : Label <out DbCallable >? ,
4182+ enclosingStmt : Label <out DbStmt >?
4183+ ): Label <out DbExpr > {
4184+ val id = tw.getFreshIdLabel<DbTypeliteral >()
4185+ val locId = tw.getLocation(e)
4186+ val type = useType(e.type)
4187+ tw.writeExprs_typeliteral(id, type.javaResult.id, parent, idx)
4188+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
4189+ tw.writeHasLocation(id, locId)
4190+
4191+ enclosingCallable?.let { tw.writeCallableEnclosingExpr(id, it) }
4192+ enclosingStmt?.let { tw.writeStatementEnclosingExpr(id, it) }
4193+
4194+ extractTypeAccessRecursive(e.classType, locId, id, 0 , enclosingCallable, enclosingStmt)
4195+ return id
4196+ }
4197+
4198+ private fun extractEnumValue (
4199+ e : IrGetEnumValue ,
4200+ parent : Label <out DbExprparent >,
4201+ idx : Int ,
4202+ enclosingCallable : Label <out DbCallable >? ,
4203+ enclosingStmt : Label <out DbStmt >?
4204+ ): Label <out DbExpr > {
4205+ val id = tw.getFreshIdLabel<DbVaraccess >()
4206+ val type = useType(e.type)
4207+ val locId = tw.getLocation(e)
4208+ tw.writeExprs_varaccess(id, type.javaResult.id, parent, idx)
4209+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
4210+ tw.writeHasLocation(id, locId)
4211+
4212+ enclosingCallable?.let { tw.writeCallableEnclosingExpr(id, it) }
4213+ enclosingStmt?.let { tw.writeStatementEnclosingExpr(id, it) }
4214+
4215+ val owner = getBoundSymbolOwner(e.symbol, e) ? : return id
4216+
4217+ val vId = useEnumEntry(owner)
4218+ tw.writeVariableBinding(id, vId)
4219+
4220+ extractStaticTypeAccessQualifier(owner, id, locId, enclosingCallable, enclosingStmt)
4221+ return id
4222+ }
4223+
41564224 // Render a string literal as it might occur in Kotlin source. Note this is a reasonable guess; the real source
41574225 // could use other escape sequences to describe the same String. Importantly, this is the same guess the Java
41584226 // extractor makes regarding string literals occurring within annotations, which we need to coincide with to ensure
@@ -5091,10 +5159,14 @@ open class KotlinFileExtractor(
50915159 /* *
50925160 * Extracts a single type access expression with enclosing callable and statement.
50935161 */
5094- private fun extractTypeAccess (type : TypeResults , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , enclosingCallable : Label <out DbCallable >, enclosingStmt : Label <out DbStmt >): Label <out DbExpr > {
5162+ private fun extractTypeAccess (type : TypeResults , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , enclosingCallable : Label <out DbCallable >? , enclosingStmt : Label <out DbStmt >? ): Label <out DbExpr > {
50955163 val id = extractTypeAccess(type, location, parent, idx)
5096- tw.writeCallableEnclosingExpr(id, enclosingCallable)
5097- tw.writeStatementEnclosingExpr(id, enclosingStmt)
5164+ if (enclosingCallable != null ) {
5165+ tw.writeCallableEnclosingExpr(id, enclosingCallable)
5166+ }
5167+ if (enclosingStmt != null ) {
5168+ tw.writeStatementEnclosingExpr(id, enclosingStmt)
5169+ }
50985170 return id
50995171 }
51005172
@@ -5136,7 +5208,7 @@ open class KotlinFileExtractor(
51365208 /* *
51375209 * Extracts a type access expression and its child type access expressions in case of a generic type. Nested generics are also handled.
51385210 */
5139- private fun extractTypeAccessRecursive (t : IrType , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , enclosingCallable : Label <out DbCallable >, enclosingStmt : Label <out DbStmt >, typeContext : TypeContext = TypeContext .OTHER ): Label <out DbExpr > {
5211+ private fun extractTypeAccessRecursive (t : IrType , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , enclosingCallable : Label <out DbCallable >? , enclosingStmt : Label <out DbStmt >? , typeContext : TypeContext = TypeContext .OTHER ): Label <out DbExpr > {
51405212 // TODO: `useType` substitutes types to their java equivalent, and sometimes that also means changing the number of type arguments. The below logic doesn't take this into account.
51415213 // For example `KFunction2<Int,Double,String>` becomes `KFunction<String>` with three child type access expressions: `Int`, `Double`, `String`.
51425214 val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx, enclosingCallable, enclosingStmt)
@@ -5154,8 +5226,8 @@ open class KotlinFileExtractor(
51545226 typeArgs : List <IrType >,
51555227 location : Label <DbLocation >,
51565228 parentExpr : Label <out DbExprparent >,
5157- enclosingCallable : Label <out DbCallable >,
5158- enclosingStmt : Label <out DbStmt >,
5229+ enclosingCallable : Label <out DbCallable >? ,
5230+ enclosingStmt : Label <out DbStmt >? ,
51595231 startIndex : Int = 0,
51605232 reverse : Boolean = false
51615233 ) {
0 commit comments