Skip to content

Commit de0a9d8

Browse files
authored
Fixed kotlin native interfaces and removed reflection nonsense (#4728)
Related to #3274
1 parent bf566c8 commit de0a9d8

2 files changed

Lines changed: 46 additions & 48 deletions

File tree

maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/AndroidGradleBuilder.java

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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",

maven/codenameone-maven-plugin/src/main/java/com/codename1/builders/Executor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ private void copyDir(File dir, File classesDir, File resDir, File sourceDir, Fil
10891089
destFile = new File(classesDir, fileName);
10901090
}
10911091
} else {
1092-
if (fileName.endsWith(".java") || fileName.endsWith(".m") || fileName.endsWith(".h") || fileName.endsWith(".cs")) {
1092+
if (fileName.endsWith(".java") || fileName.endsWith(".kt") || fileName.endsWith(".swift") || fileName.endsWith(".m") || fileName.endsWith(".h") || fileName.endsWith(".cs")) {
10931093
destFile = new File(sourceDir, fileName);
10941094
} else {
10951095
if (fileName.endsWith(".jar") || fileName.endsWith(".a") || fileName.endsWith(".dylib")) {
@@ -1319,7 +1319,7 @@ public void unzip(InputStream source, File classesDir, File resDir, File sourceD
13191319
destFile = new File(classesDir, entryName);
13201320
}
13211321
} else {
1322-
if (entryName.endsWith(".java") || entryName.endsWith(".m") || entryName.endsWith(".h") || entryName.endsWith(".cs")) {
1322+
if (entryName.endsWith(".java") || entryName.endsWith(".kt") || entryName.endsWith(".swift") || entryName.endsWith(".m") || entryName.endsWith(".h") || entryName.endsWith(".cs")) {
13231323
destFile = new File(sourceDir, entryName);
13241324
} else {
13251325
if (entryName.endsWith(".jar") || entryName.endsWith(".a") || entryName.endsWith(".dylib") || entryName.endsWith(".andlib") || entryName.endsWith(".aar") || entryName.endsWith(dll)) {

0 commit comments

Comments
 (0)