@@ -620,7 +620,7 @@ open class KotlinFileExtractor(
620620 }
621621
622622 fun extractCall (c : IrCall , callable : Label <out DbCallable >, parent : Label <out DbExprparent >, idx : Int , enclosingStmt : Label <out DbStmt >) {
623- fun isFunction (pkgName : String , className : String , fName : String ): Boolean {
623+ fun isFunction (pkgName : String , className : String , fName : String , hasQuestionMark : Boolean = false ): Boolean {
624624 val verbose = false
625625 fun verboseln (s : String ) { if (verbose) println (s) }
626626 verboseln(" Attempting match for $pkgName $className $fName " )
@@ -632,7 +632,14 @@ open class KotlinFileExtractor(
632632 val extensionReceiverParameter = target.extensionReceiverParameter
633633 // TODO: Are both branches of this `if` possible?:
634634 val targetClass = if (extensionReceiverParameter == null ) target.parent
635- else (extensionReceiverParameter.type as ? IrSimpleType )?.classifier?.owner
635+ else {
636+ val st = extensionReceiverParameter.type as ? IrSimpleType
637+ if (st?.hasQuestionMark != hasQuestionMark) {
638+ verboseln(" Nullablility of type didn't match" )
639+ return false
640+ }
641+ st?.classifier?.owner
642+ }
636643 if (targetClass !is IrClass ) {
637644 verboseln(" No match as didn't find target class" )
638645 return false
@@ -663,6 +670,49 @@ open class KotlinFileExtractor(
663670 isFunction(" kotlin" , " Double" , fName)
664671 }
665672
673+ fun extractMethodAccess (callTarget : IrFunction , extractTypeArguments : Boolean = true){
674+ val id = tw.getFreshIdLabel<DbMethodaccess >()
675+ val type = useType(c.type)
676+ val locId = tw.getLocation(c)
677+ val methodId = useFunction<DbMethod >(callTarget)
678+ tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
679+ tw.writeHasLocation(id, locId)
680+ tw.writeCallableEnclosingExpr(id, callable)
681+ tw.writeCallableBinding(id, methodId)
682+ tw.writeStatementEnclosingExpr(id, enclosingStmt)
683+
684+ if (extractTypeArguments) {
685+ // type arguments at index -2, -3, ...
686+ extractTypeArguments(c, id, callable, enclosingStmt, - 2 , true )
687+ }
688+
689+ val dr = c.dispatchReceiver
690+ if (dr != null ) {
691+ extractExpressionExpr(dr, callable, id, - 1 , enclosingStmt)
692+ }
693+ for (i in 0 until c.valueArgumentsCount) {
694+ val arg = c.getValueArgument(i)
695+ if (arg != null ) {
696+ extractExpressionExpr(arg, callable, id, i, enclosingStmt)
697+ }
698+ }
699+ }
700+
701+ fun extractSpecialEnumFunction (fnName : String ){
702+ if (c.typeArgumentsCount != 1 ) {
703+ logger.warnElement(Severity .ErrorSevere , " Expected to find exactly one type argument" , c)
704+ return
705+ }
706+
707+ val func = ((c.getTypeArgument(0 ) as ? IrSimpleType )?.classifier?.owner as ? IrClass )?.declarations?.find { it is IrFunction && it.name.asString() == fnName }
708+ if (func == null ) {
709+ logger.warnElement(Severity .ErrorSevere , " Couldn't find function $fnName on enum type" , c)
710+ return
711+ }
712+
713+ extractMethodAccess(func as IrFunction , false )
714+ }
715+
666716 fun binopDisp (id : Label <out DbExpr >) {
667717 val locId = tw.getLocation(c)
668718 tw.writeHasLocation(id, locId)
@@ -693,12 +743,24 @@ open class KotlinFileExtractor(
693743 val dr = c.dispatchReceiver
694744 when {
695745 c.origin == IrStatementOrigin .PLUS &&
696- (isNumericFunction(" plus" ) || isFunction(" kotlin" , " String" , " plus" )) -> {
746+ (isNumericFunction(" plus" )
747+ || isFunction(" kotlin" , " String" , " plus" )
748+ || isFunction(" kotlin" , " String" , " plus" , true ) // TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
749+ ) -> {
697750 val id = tw.getFreshIdLabel<DbAddexpr >()
698751 val type = useType(c.type)
699752 tw.writeExprs_addexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
700753 binopDisp(id)
701754 }
755+ isFunction(" kotlin" , " String" , " plus" , true ) -> {
756+ // TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
757+ val func = pluginContext.irBuiltIns.stringType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == " plus" }
758+ if (func == null ) {
759+ logger.warnElement(Severity .ErrorSevere , " Couldn't find plus function on string type" , c)
760+ return
761+ }
762+ extractMethodAccess(func as IrFunction )
763+ }
702764 c.origin == IrStatementOrigin .MINUS && isNumericFunction(" minus" ) -> {
703765 val id = tw.getFreshIdLabel<DbSubexpr >()
704766 val type = useType(c.type)
@@ -840,6 +902,21 @@ open class KotlinFileExtractor(
840902 // TODO
841903 logger.warnElement(Severity .ErrorSevere , " Unhandled builtin" , c)
842904 }
905+ isFunction(" kotlin" , " Any" , " toString" , true ) -> {
906+ // TODO: this is not correct. `a.toString()` becomes `(a?:"\"null\"").toString()`
907+ val func = pluginContext.irBuiltIns.anyType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == " toString" }
908+ if (func == null ) {
909+ logger.warnElement(Severity .ErrorSevere , " Couldn't find toString function" , c)
910+ return
911+ }
912+ extractMethodAccess(func as IrFunction )
913+ }
914+ isBuiltinCallKotlin(c, " enumValues" ) -> {
915+ extractSpecialEnumFunction(" values" )
916+ }
917+ isBuiltinCallKotlin(c, " enumValueOf" ) -> {
918+ extractSpecialEnumFunction(" valueOf" )
919+ }
843920 isBuiltinCallKotlin(c, " arrayOfNulls" ) -> {
844921 val id = tw.getFreshIdLabel<DbArraycreationexpr >()
845922 val type = useType(c.type)
@@ -922,28 +999,7 @@ open class KotlinFileExtractor(
922999 }
9231000 }
9241001 else -> {
925- val id = tw.getFreshIdLabel<DbMethodaccess >()
926- val type = useType(c.type)
927- val locId = tw.getLocation(c)
928- val methodId = useFunction<DbMethod >(c.symbol.owner)
929- tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
930- tw.writeHasLocation(id, locId)
931- tw.writeCallableEnclosingExpr(id, callable)
932- tw.writeCallableBinding(id, methodId)
933- tw.writeStatementEnclosingExpr(id, enclosingStmt)
934-
935- // type arguments at index -2, -3, ...
936- extractTypeArguments(c, id, callable, enclosingStmt, - 2 , true )
937-
938- if (dr != null ) {
939- extractExpressionExpr(dr, callable, id, - 1 , enclosingStmt)
940- }
941- for (i in 0 until c.valueArgumentsCount) {
942- val arg = c.getValueArgument(i)
943- if (arg != null ) {
944- extractExpressionExpr(arg, callable, id, i, enclosingStmt)
945- }
946- }
1002+ extractMethodAccess(c.symbol.owner)
9471003 }
9481004 }
9491005 }
0 commit comments