@@ -1753,7 +1753,7 @@ open class KotlinFileExtractor(
17531753 private fun extractsDefaultsCall (
17541754 syntacticCallTarget : IrFunction ,
17551755 locId : Label <DbLocation >,
1756- callsite : IrCall ,
1756+ resultType : IrType ,
17571757 enclosingCallable : Label <out DbCallable >,
17581758 callsiteParent : Label <out DbExprparent >,
17591759 childIdx : Int ,
@@ -1768,7 +1768,7 @@ open class KotlinFileExtractor(
17681768 useFunction<DbCallable >(callTarget)
17691769 }
17701770 val defaultMethodLabel = getDefaultsMethodLabel(callTarget)
1771- val id = extractMethodAccessWithoutArgs(callsite.type , locId, enclosingCallable, callsiteParent, childIdx, enclosingStmt, defaultMethodLabel)
1771+ val id = extractMethodAccessWithoutArgs(resultType , locId, enclosingCallable, callsiteParent, childIdx, enclosingStmt, defaultMethodLabel)
17721772
17731773 if (callTarget.isLocalFunction()) {
17741774 extractTypeAccess(getLocallyVisibleFunctionLabels(callTarget).type, locId, id, - 1 , enclosingCallable, enclosingStmt)
@@ -1871,7 +1871,8 @@ open class KotlinFileExtractor(
18711871
18721872 fun extractRawMethodAccess (
18731873 syntacticCallTarget : IrFunction ,
1874- callsite : IrCall ,
1874+ locElement : IrElement ,
1875+ resultType : IrType ,
18751876 enclosingCallable : Label <out DbCallable >,
18761877 callsiteParent : Label <out DbExprparent >,
18771878 childIdx : Int ,
@@ -1883,13 +1884,13 @@ open class KotlinFileExtractor(
18831884 extractClassTypeArguments : Boolean = false,
18841885 superQualifierSymbol : IrClassSymbol ? = null) {
18851886
1886- val locId = tw.getLocation(callsite )
1887+ val locId = tw.getLocation(locElement )
18871888
18881889 if (valueArguments.any { it == null }) {
18891890 extractsDefaultsCall(
18901891 syntacticCallTarget,
18911892 locId,
1892- callsite ,
1893+ resultType ,
18931894 enclosingCallable,
18941895 callsiteParent,
18951896 childIdx,
@@ -1902,7 +1903,7 @@ open class KotlinFileExtractor(
19021903 extractRawMethodAccess(
19031904 syntacticCallTarget,
19041905 locId,
1905- callsite.type ,
1906+ resultType ,
19061907 enclosingCallable,
19071908 callsiteParent,
19081909 childIdx,
@@ -2233,7 +2234,7 @@ open class KotlinFileExtractor(
22332234 return
22342235 }
22352236
2236- extractRawMethodAccess(syntacticCallTarget, c, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments, c.superQualifierSymbol)
2237+ extractRawMethodAccess(syntacticCallTarget, c, c.type, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments, c.superQualifierSymbol)
22372238 }
22382239
22392240 fun extractSpecialEnumFunction (fnName : String ){
@@ -2337,7 +2338,7 @@ open class KotlinFileExtractor(
23372338 }
23382339 isFunction(target, " kotlin" , " String" , " plus" , true ) -> {
23392340 findJdkIntrinsicOrWarn(" stringPlus" , c)?.let { stringPlusFn ->
2340- extractRawMethodAccess(stringPlusFn, c, callable, parent, idx, enclosingStmt, listOf (c.extensionReceiver, c.getValueArgument(0 )), null , null )
2341+ extractRawMethodAccess(stringPlusFn, c, c.type, callable, parent, idx, enclosingStmt, listOf (c.extensionReceiver, c.getValueArgument(0 )), null , null )
23412342 }
23422343 }
23432344 isNumericFunction(target, listOf (" plus" , " minus" , " times" , " div" , " rem" , " and" , " or" , " xor" , " shl" , " shr" , " ushr" )) -> {
@@ -2582,7 +2583,7 @@ open class KotlinFileExtractor(
25822583 }
25832584 isFunction(target, " kotlin" , " Any" , " toString" , true ) -> {
25842585 stringValueOfObjectMethod?.let {
2585- extractRawMethodAccess(it, c, callable, parent, idx, enclosingStmt, listOf (c.extensionReceiver), null , null )
2586+ extractRawMethodAccess(it, c, c.type, callable, parent, idx, enclosingStmt, listOf (c.extensionReceiver), null , null )
25862587 }
25872588 }
25882589 isBuiltinCallKotlin(c, " enumValues" ) -> {
@@ -2632,69 +2633,35 @@ open class KotlinFileExtractor(
26322633 || isBuiltinCallKotlin(c, " byteArrayOf" )
26332634 || isBuiltinCallKotlin(c, " booleanArrayOf" ) -> {
26342635
2635- val arg = if (c.valueArgumentsCount == 1 ) c.getValueArgument(0 ) else {
2636- logger.errorElement(" Expected to find only one (vararg) argument in ${c.symbol.owner.name.asString()} call" , c)
2637- null
2638- }?.let {
2639- if (it is IrVararg ) it else {
2640- logger.errorElement(" Expected to find vararg argument in ${c.symbol.owner.name.asString()} call" , c)
2641- null
2642- }
2643- }
26442636
2645- // If this is [someType]ArrayOf(*x), x, otherwise null
2646- val clonedArray = arg?.let {
2647- if (arg.elements.size == 1 ) {
2648- val onlyElement = arg.elements[0 ]
2649- if (onlyElement is IrSpreadElement )
2650- onlyElement.expression
2651- else null
2652- } else null
2653- }
2654-
2655- if (clonedArray != null ) {
2656- // This is an array clone: extract is as a call to java.lang.Object.clone
2657- objectCloneMethod?.let {
2658- extractRawMethodAccess(it, c, callable, parent, idx, enclosingStmt, listOf (), clonedArray, null )
2659- }
2637+ val isPrimitiveArrayCreation = ! isBuiltinCallKotlin(c, " arrayOf" )
2638+ val elementType = if (isPrimitiveArrayCreation) {
2639+ c.type.getArrayElementType(pluginContext.irBuiltIns)
26602640 } else {
2661- // This is array creation: extract it as a call to new ArrayType[] { ... }
2662- val id = tw.getFreshIdLabel<DbArraycreationexpr >()
2663- val type = useType(c.type)
2664- tw.writeExprs_arraycreationexpr(id, type.javaResult.id, parent, idx)
2665- tw.writeExprsKotlinType(id, type.kotlinResult.id)
2666- val locId = tw.getLocation(c)
2667- tw.writeHasLocation(id, locId)
2668- tw.writeCallableEnclosingExpr(id, callable)
2669-
2670- if (isBuiltinCallKotlin(c, " arrayOf" )) {
2671- if (c.typeArgumentsCount == 1 ) {
2672- val typeArgument = c.getTypeArgument(0 )
2673- if (typeArgument == null ) {
2641+ // TODO: is there any reason not to always use getArrayElementType?
2642+ if (c.typeArgumentsCount == 1 ) {
2643+ c.getTypeArgument(0 ).also {
2644+ if (it == null ) {
26742645 logger.errorElement(" Type argument missing in an arrayOf call" , c)
2675- } else {
2676- extractTypeAccessRecursive(typeArgument, locId, id, - 1 , callable, enclosingStmt, TypeContext .GENERIC_ARGUMENT )
26772646 }
2678- } else {
2679- logger.errorElement(" Expected to find one type argument in arrayOf call" , c )
26802647 }
26812648 } else {
2682- val elementType = c. type.getArrayElementType(pluginContext.irBuiltIns )
2683- extractTypeAccessRecursive(elementType, locId, id, - 1 , callable, enclosingStmt)
2649+ logger.errorElement( " Expected to find one type argument in arrayOf call " , c )
2650+ null
26842651 }
2652+ }
26852653
2686- arg?.let {
2687- val initId = tw.getFreshIdLabel<DbArrayinit >()
2688- tw.writeExprs_arrayinit(initId, type.javaResult.id, id, - 2 )
2689- tw.writeExprsKotlinType(initId, type.kotlinResult.id)
2690- tw.writeHasLocation(initId, locId)
2691- tw.writeCallableEnclosingExpr(initId, callable)
2692- tw.writeStatementEnclosingExpr(initId, enclosingStmt)
2693- it.elements.forEachIndexed { i, arg -> extractVarargElement(arg, callable, initId, i, enclosingStmt) }
2694-
2695- extractConstantInteger(it.elements.size, locId, id, 0 , callable, enclosingStmt)
2654+ val arg = if (c.valueArgumentsCount == 1 ) c.getValueArgument(0 ) else {
2655+ logger.errorElement(" Expected to find only one (vararg) argument in ${c.symbol.owner.name.asString()} call" , c)
2656+ null
2657+ }?.let {
2658+ if (it is IrVararg ) it else {
2659+ logger.errorElement(" Expected to find vararg argument in ${c.symbol.owner.name.asString()} call" , c)
2660+ null
26962661 }
26972662 }
2663+
2664+ extractArrayCreation(arg, c.type, elementType, isPrimitiveArrayCreation, c, parent, idx, callable, enclosingStmt)
26982665 }
26992666 isBuiltinCall(c, " <get-java>" , " kotlin.jvm" ) -> {
27002667 // Special case for KClass<*>.java, which is used in the Parcelize plugin. In normal cases, this is already rewritten to the property referenced below:
@@ -2714,7 +2681,7 @@ open class KotlinFileExtractor(
27142681 val argType = (ext.type as ? IrSimpleType )?.arguments?.firstOrNull()?.typeOrNull
27152682 val typeArguments = if (argType == null ) listOf () else listOf (argType)
27162683
2717- extractRawMethodAccess(getter, c, callable, parent, idx, enclosingStmt, listOf (), null , ext, typeArguments)
2684+ extractRawMethodAccess(getter, c, c.type, callable, parent, idx, enclosingStmt, listOf (), null , ext, typeArguments)
27182685 }
27192686 }
27202687 isFunction(target, " kotlin" , " (some array type)" , { isArrayType(it) }, " iterator" ) -> {
@@ -2745,7 +2712,7 @@ open class KotlinFileExtractor(
27452712 else -> pluginContext.irBuiltIns.anyNType
27462713 }
27472714 }
2748- extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf (c.dispatchReceiver), null , null , typeArgs)
2715+ extractRawMethodAccess(iteratorFn, c, c.type, callable, parent, idx, enclosingStmt, listOf (c.dispatchReceiver), null , null , typeArgs)
27492716 }
27502717 }
27512718 }
@@ -2834,6 +2801,7 @@ open class KotlinFileExtractor(
28342801 extractRawMethodAccess(
28352802 realCallee,
28362803 c,
2804+ c.type,
28372805 callable,
28382806 parent,
28392807 idx,
@@ -2861,6 +2829,7 @@ open class KotlinFileExtractor(
28612829 extractRawMethodAccess(
28622830 realCallee,
28632831 c,
2832+ c.type,
28642833 callable,
28652834 parent,
28662835 idx,
@@ -2878,6 +2847,51 @@ open class KotlinFileExtractor(
28782847 }
28792848 }
28802849
2850+ private fun extractArrayCreation (elementList : IrVararg ? , resultType : IrType , elementType : IrType ? , allowPrimitiveElementType : Boolean , locElement : IrElement , parent : Label <out DbExprparent >, idx : Int , enclosingCallable : Label <out DbCallable >, enclosingStmt : Label <out DbStmt >) {
2851+ // If this is [someType]ArrayOf(*x), x, otherwise null
2852+ val clonedArray = elementList?.let {
2853+ if (it.elements.size == 1 ) {
2854+ val onlyElement = it.elements[0 ]
2855+ if (onlyElement is IrSpreadElement )
2856+ onlyElement.expression
2857+ else null
2858+ } else null
2859+ }
2860+
2861+ if (clonedArray != null ) {
2862+ // This is an array clone: extract is as a call to java.lang.Object.clone
2863+ objectCloneMethod?.let {
2864+ extractRawMethodAccess(it, locElement, resultType, enclosingCallable, parent, idx, enclosingStmt, listOf (), clonedArray, null )
2865+ }
2866+ } else {
2867+ // This is array creation: extract it as a call to new ArrayType[] { ... }
2868+ val id = tw.getFreshIdLabel<DbArraycreationexpr >()
2869+ val type = useType(resultType)
2870+ tw.writeExprs_arraycreationexpr(id, type.javaResult.id, parent, idx)
2871+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
2872+ val locId = tw.getLocation(locElement)
2873+ tw.writeHasLocation(id, locId)
2874+ tw.writeCallableEnclosingExpr(id, enclosingCallable)
2875+
2876+ if (elementType != null ) {
2877+ val typeContext = if (allowPrimitiveElementType) TypeContext .OTHER else TypeContext .GENERIC_ARGUMENT
2878+ extractTypeAccessRecursive(elementType, locId, id, - 1 , enclosingCallable, enclosingStmt, typeContext)
2879+ }
2880+
2881+ if (elementList != null ) {
2882+ val initId = tw.getFreshIdLabel<DbArrayinit >()
2883+ tw.writeExprs_arrayinit(initId, type.javaResult.id, id, - 2 )
2884+ tw.writeExprsKotlinType(initId, type.kotlinResult.id)
2885+ tw.writeHasLocation(initId, locId)
2886+ tw.writeCallableEnclosingExpr(initId, enclosingCallable)
2887+ tw.writeStatementEnclosingExpr(initId, enclosingStmt)
2888+ elementList.elements.forEachIndexed { i, arg -> extractVarargElement(arg, enclosingCallable, initId, i, enclosingStmt) }
2889+
2890+ extractConstantInteger(elementList.elements.size, locId, id, 0 , enclosingCallable, enclosingStmt)
2891+ }
2892+ }
2893+ }
2894+
28812895 private fun extractNewExpr (
28822896 methodId : Label <out DbConstructor >,
28832897 constructedType : TypeResults ,
@@ -3661,14 +3675,12 @@ open class KotlinFileExtractor(
36613675 extractTypeOperatorCall(e, callable, exprParent.parent, exprParent.idx, exprParent.enclosingStmt)
36623676 }
36633677 is IrVararg -> {
3664- var spread = e.elements.getOrNull(0 ) as ? IrSpreadElement
3665- if (spread == null || e.elements.size != 1 ) {
3666- logger.errorElement(" Unexpected IrVararg" , e)
3667- return
3668- }
36693678 // There are lowered IR cases when the vararg expression is not within a call, such as
3670- // val temp0 = [*expr]
3671- extractExpression(spread.expression, callable, parent)
3679+ // val temp0 = [*expr].
3680+ // This AST element can also occur as a collection literal in an annotation class, such as
3681+ // annotation class Ann(val strings: Array<String> = [])
3682+ val exprParent = parent.expr(e, callable)
3683+ extractArrayCreation(e, e.type, e.varargElementType, true , e, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
36723684 }
36733685 is IrGetObjectValue -> {
36743686 // For `object MyObject { ... }`, the .class has an
0 commit comments