@@ -3605,6 +3605,24 @@ public void usesClassMethod(String cls, String method) {
36053605 gradleDependency = "classpath 'com.android.tools.build:gradle:8.1.0'\n " ;
36063606 }
36073607 }
3608+ boolean hasKotlinSources = hasSourceFileWithExtension (new File (projectDir , "src/main/java" ), ".kt" );
3609+ String kotlinVersion = request .getArg ("requireKotlinStdlib" , "" ).trim ();
3610+ if (hasKotlinSources && kotlinVersion .length () == 0 ) {
3611+ kotlinVersion = useGradle8 ? "1.9.22" : "1.7.22" ;
3612+ }
3613+ String kotlinPluginApply = "" ;
3614+ String kotlinRuntimeDependency = "" ;
3615+ if (hasKotlinSources ) {
3616+ if (!request .getArg ("android.topDependency" , "" ).contains ("kotlin-gradle-plugin" )) {
3617+ gradleDependency += "classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:" + kotlinVersion + "'\n " ;
3618+ }
3619+ kotlinPluginApply = "apply plugin: 'kotlin-android'\n " ;
3620+ String gradleDeps = request .getArg ("android.gradleDep" , "" );
3621+ if (!additionalDependencies .contains ("org.jetbrains.kotlin:kotlin-stdlib" )
3622+ && !gradleDeps .contains ("org.jetbrains.kotlin:kotlin-stdlib" )) {
3623+ kotlinRuntimeDependency = " implementation 'org.jetbrains.kotlin:kotlin-stdlib:" + kotlinVersion + "'\n " ;
3624+ }
3625+ }
36083626 gradleDependency += request .getArg ("android.topDependency" , "" );
36093627
36103628 String compileSdkVersion = "'android-21'" ;
@@ -3743,6 +3761,7 @@ public void usesClassMethod(String cls, String method) {
37433761 }
37443762
37453763 String gradleProps = "apply plugin: 'com.android.application'\n "
3764+ + kotlinPluginApply
37463765 + request .getArg ("android.gradlePlugin" , "" )
37473766 + "\n "
37483767 + "buildscript {\n "
@@ -3826,6 +3845,7 @@ public void usesClassMethod(String cls, String method) {
38263845 + "dependencies {\n "
38273846 + " " +compile +" fileTree(dir: 'libs', include: ['*.jar'])\n "
38283847 + request .getArg ("android.supportv4Dep" ,supportV4Default ) + "\n "
3848+ + kotlinRuntimeDependency
38293849 + addNewlineIfMissing (additionalDependencies )
38303850 + addNewlineIfMissing (request .getArg ("android.gradleDep" , "" ))
38313851 + addNewlineIfMissing (aarDependencies )
@@ -3994,27 +4014,7 @@ protected String registerNativeImplementationsAndCreateStubs(ClassLoader parentC
39944014 String javaImplSourceFile = "package " + currentNative .getPackage ().getName () + ";\n \n "
39954015 + "import com.codename1.ui.PeerComponent;\n \n "
39964016 + "public class " + currentNative .getSimpleName () + "Stub implements " + currentNative .getSimpleName () + "{\n "
3997- + " private final Object impl = createImpl();\n \n "
3998- + " private static Object createImpl() {\n "
3999- + " try {\n "
4000- + " return Class.forName(\" " + currentNative .getName () + getImplSuffix () + "\" ).newInstance();\n "
4001- + " } catch (Throwable t) {\n "
4002- + " throw new RuntimeException(\" Failed to instantiate native implementation for " + currentNative .getName () + "\" , t);\n "
4003- + " }\n "
4004- + " }\n \n "
4005- + " private Object __cn1Invoke(String methodName, Object[] args) {\n "
4006- + " try {\n "
4007- + " java.lang.reflect.Method[] methods = impl.getClass().getMethods();\n "
4008- + " for (java.lang.reflect.Method method : methods) {\n "
4009- + " if (method.getName().equals(methodName) && method.getParameterTypes().length == args.length) {\n "
4010- + " return method.invoke(impl, args);\n "
4011- + " }\n "
4012- + " }\n "
4013- + " throw new RuntimeException(methodName + \" with \" + args.length + \" args\" );\n "
4014- + " } catch (Throwable t) {\n "
4015- + " throw new RuntimeException(\" Failed to invoke native method \" + methodName, t);\n "
4016- + " }\n "
4017- + " }\n \n " ;
4017+ + " private " + currentNative .getSimpleName () + getImplSuffix () + " impl = new " + currentNative .getSimpleName () + getImplSuffix () + "();\n \n " ;
40184018
40194019 for (Method m : currentNative .getMethods ()) {
40204020 String name = m .getName ();
@@ -4042,34 +4042,13 @@ protected String registerNativeImplementationsAndCreateStubs(ClassLoader parentC
40424042 }
40434043 }
40444044 javaImplSourceFile += ") {\n " ;
4045- String invocationExpression = "__cn1Invoke(\" " + name + "\" , new Object[]{" + args + "})" ;
40464045 if (Void .class == returnType || Void .TYPE == returnType ) {
4047- javaImplSourceFile += " " + invocationExpression + ";\n }\n \n " ;
4046+ javaImplSourceFile += " impl. " + name + "(" + args + ") ;\n }\n \n " ;
40484047 } else {
40494048 if (returnType .getName ().equals ("com.codename1.ui.PeerComponent" )) {
4050- javaImplSourceFile += " return " + generatePeerComponentCreationCode (invocationExpression ) + ";\n }\n \n " ;
4051- } else if (returnType .isPrimitive ()) {
4052- if (returnType == Boolean .TYPE ) {
4053- javaImplSourceFile += " return ((Boolean)" + invocationExpression + ").booleanValue();\n }\n \n " ;
4054- } else if (returnType == Integer .TYPE ) {
4055- javaImplSourceFile += " return ((Integer)" + invocationExpression + ").intValue();\n }\n \n " ;
4056- } else if (returnType == Long .TYPE ) {
4057- javaImplSourceFile += " return ((Long)" + invocationExpression + ").longValue();\n }\n \n " ;
4058- } else if (returnType == Byte .TYPE ) {
4059- javaImplSourceFile += " return ((Byte)" + invocationExpression + ").byteValue();\n }\n \n " ;
4060- } else if (returnType == Short .TYPE ) {
4061- javaImplSourceFile += " return ((Short)" + invocationExpression + ").shortValue();\n }\n \n " ;
4062- } else if (returnType == Character .TYPE ) {
4063- javaImplSourceFile += " return ((Character)" + invocationExpression + ").charValue();\n }\n \n " ;
4064- } else if (returnType == Float .TYPE ) {
4065- javaImplSourceFile += " return ((Float)" + invocationExpression + ").floatValue();\n }\n \n " ;
4066- } else if (returnType == Double .TYPE ) {
4067- javaImplSourceFile += " return ((Double)" + invocationExpression + ").doubleValue();\n }\n \n " ;
4068- } else {
4069- javaImplSourceFile += " return (" + returnType .getSimpleName () + ")" + invocationExpression + ";\n }\n \n " ;
4070- }
4049+ javaImplSourceFile += " return " + generatePeerComponentCreationCode ("impl." + name + "(" + args + ")" ) + ";\n }\n \n " ;
40714050 } else {
4072- javaImplSourceFile += " return ( " + returnType . getSimpleName () + ") " + invocationExpression + ";\n }\n \n " ;
4051+ javaImplSourceFile += " return impl. " + name + "( " + args + ") ;\n }\n \n " ;
40734052 }
40744053 }
40754054 }
@@ -4412,7 +4391,7 @@ public void unzip(InputStream source, File classesDir, File resDir, File sourceD
44124391 if (entryName .endsWith (".class" )) {
44134392 destFile = new File (classesDir , entryName );
44144393 } else {
4415- if (entryName .endsWith (".java" ) || entryName .endsWith (".m" ) || entryName .endsWith (".h" )) {
4394+ if (entryName .endsWith (".java" ) || entryName .endsWith (".kt" ) || entryName . endsWith ( ".swift" ) || entryName . endsWith ( ". m" ) || entryName .endsWith (".h" )) {
44164395 destFile = new File (sourceDir , entryName );
44174396 } else {
44184397 if (entryName .endsWith (".jar" ) || entryName .endsWith (".a" ) || entryName .endsWith (".dylib" ) || entryName .endsWith (".andlib" ) || entryName .endsWith (".aar" )) {
@@ -4766,6 +4745,25 @@ private Integer parseSdkInt(String value) {
47664745 }
47674746 }
47684747
4748+ private boolean hasSourceFileWithExtension (File dir , String extension ) {
4749+ if (dir == null || !dir .exists ()) {
4750+ return false ;
4751+ }
4752+ if (dir .isFile ()) {
4753+ return dir .getName ().endsWith (extension );
4754+ }
4755+ File [] children = dir .listFiles ();
4756+ if (children == null ) {
4757+ return false ;
4758+ }
4759+ for (File child : children ) {
4760+ if (hasSourceFileWithExtension (child , extension )) {
4761+ return true ;
4762+ }
4763+ }
4764+ return false ;
4765+ }
4766+
47694767 private void stripKotlin (File dummyClassesDir ) {
47704768 String [] skipDirectories = new String [] {
47714769 "org" + File .separator + "jetbrains" + File .separator + "annotations" ,
0 commit comments